课程章节:
- 课程名称:物联网/嵌入式工程师
- 章节名称:第2周之第三讲 1-9 至 1-10 C语言中的指针:多级指针的使用
- 讲师姓名:大白老师
课程内容:
C语言中的指针:多级指针的使用
指针的设计规则
本质:所有的指针都是用来保存地址的,只不过因为保存地址的数据类型不同,从而
拥有多种指类型.
规则:一级指针变量是用来保存普通变量的地址.
二级指针变量是用来保存一级指针变量本身自己的地址.
三级指针变量是用来保存二级指针变量本身自己的地址.
......
以二级指针为例:
定义方式 如下:
数据类型 ** 变量名;
int a = 10;
int *p = &a;
int **q = &p;
====================
p = &a; //*p = *(&a) *p <===> a
q = &p; //*q = *(&p) ===> *q = p; **q <===> *p<===>a
指针的使用结论
指针变量大小
- 在32bit的系统中,所有的指针变量都是4bytes
- 在64bit的系统中,所有的指针变量都是8bytes
代码示例
#include <stdio.h>
int main()
{
int *p = NULL;
char **p_char = (char **)&p;
short **p_short = (short **)&p;
int **p_int = (int **)&p;
printf("sizeof(p_char) = %lu\n",sizeof(p_char));
printf("sizeof(p_short) = %lu\n",sizeof(p_short));
printf("sizeof(p_int) = %lu\n",sizeof(p_int));
return 0;
}
指针偏移大小
- 在32bit的系统中,多级指针(二级和二级以上)在移动的每次移动都是4bytes. 因为一个指针大小是4bytes
- 在64bit的系统中,多级指针(二级和二级以上)在移动的每次移动都是8bytes. 因为一个指针大小是8bytes
代码示例
#include <stdio.h>
int main()
{
int *p = NULL;
char **p_char = (char **)&p;
short **p_short = (short **)&p;
int **p_int = (int **)&p;
printf("p_char = %p\n",p_char);
printf("p_short = %p\n",p_short);
printf("p_int = %p\n",p_int);
printf("============================\n");
p_char ++;
p_short ++;
p_int ++;
printf("p_char = %p\n",p_char); //偏移4bytes
printf("p_short = %p\n",p_short); //偏移4bytes
printf("p_int = %p\n",p_int); //偏移4bytes
return 0;
}
二级指针和一维数组的转换
int a[5] = {10,20,30,40,50};
int *p = a;
int **q = &p; // q <===>&p *q <===>*(&p) *q<===>p
而根据一维数组得出结论:
a[i] <===>*(a + i)<===>*(p + i)<===>p[i]
且当前 *q<===>p,故
*(p + i)<===>p[i]<===>*(*q + i) <===>(*q)[i]
代码示例
#include <stdio.h>
// int a[5];
// int *p = a;
// int **q = &p; //q = &p *q<===>*(&p)<====>p
// 结论: a[i]<===>*(a + i)<===>*(p + i)<===>p[i]<====>*(*q + i)<===>(*q)[i]
int main()
{
int a[5] = {10,11,12,13,14};
int *p = a;
int **q = &p; //q = &p; *q<===>*(&p)<===>p
//a[3] = 13
printf("a[3] = %d\n",a[3]);
printf("*(a + 3) = %d\n",*(a + 3));
printf("*(p + 3) = %d\n",*(p + 3));
printf("p[3] = %d\n",p[3]);
printf("==========================\n");
//a[3]
printf("*(*q + 3) = %d\n",*(*q + 3));
printf("(*q)[3] = %d\n",(*q)[3]);
return 0;
}
学习笔记:
课后任务
练习
int a[5] = {1,3,5,7,9};
int *p = NULL;
int **q = NULL;
//1.要求搭建通过p输出数组中所有的内容
//2.要求搭建通过q输出数组中所有的内容
代码
#include <stdio.h>
int main()
{
int a[5] = {1,3,5,7,9};
int *p = NULL;
int **q = NULL;
p = a; // a <==> &a[0]
q = &p; // q = &p; *q<==>*(&p)<==>p
for (int i = 0; i < sizeof(a)/sizeof(a[0]); i++)
{
//
printf("a[%d] = %d \n",i,a[i]);
// 1.要求搭建通过p输出数组中所有的内容
printf("*(p + %d) = %d \n",i,*(p+i));
// 2.要求搭建通过q输出数组中所有的内容
printf("*(*q + %d) = %d \n",i,*(*q+i));
// 2.要求搭建通过q输出数组中所有的内容
printf("(*q)[%d] = %d \n",i,(*q)[i]);
//
printf("\n");
}
return 0;
}
课程评价:
通过对多级指针的学习,明白了 * 和 & 互为逆运算,得到了这样的推导代码:
int *p = NULL;
int **q = NULL;
p = a; // a <==> &a[0]
q = &p; // q = &p; *q<==>*(&p)<==>p