相信大家学c的时候,其他都好,但是遇到指针就有点头大。的确指针学起来有点晦涩难懂,但是指针是c的灵魂,可以说没有指针的c语言就像没有心脏的人,所以指针非常重要。❤️🔥❤️🔥❤️🔥
🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀
目录
熟话说熟能生巧,我多多练习一些指针的相信我们对指针就有更深的理解
提示:sizeof(数组名)-数组名表示整个数组-计算是整个数组的大小,&数组名-数组名表示整个数组,取出的是整个数组的地址除此之外,所有的数组名都是首元素的地址
题一
1. 整形数组 2. int a[]={1,2,3,4}; 3. printf("%d\n",sizeof(a));//16 4. printf("%d\n",sizeof(a+0));//8 5. printf("%d\n",sizeof(*a));//4 6. printf("%d\n",sizeof(a+1));//8 7. printf("%d\n",sizeof(a[1]));//4 8. 9. printf("%d\n",sizeof(&a));//8 10. printf("%d\n",sizeof(*&a));//16 11. printf("%d\n",sizeof(&a+1));//8 12. printf("%d\n",sizeof(&a[0]));//8 13. printf("%d\n",sizeof(&a[0]+1));//8
1. printf("%d\n",sizeof(a))//16
因为sizeof(数组名)-数组名表示整个数组的-计算是整个数组的大小,所以16个字节
2.printf("%d\n",sizeof(a+0));//8
由于他不是单独的sizeof(数组名),所以数组名表示首元素地址,a+0是首元素的地址,sizeof(a+0)计算的是地址的大小,32位平台是4,64位平台是8
3.printf("%d\n",sizeof(*a));//4
这a仍然是首元素的地址,然后解引用得到是求a[0]这个数大小,所以为4个字节
4.printf("%d\n",sizeof(a+1));//8
这a仍然是首元素的地址,a+1是第二个元素a[1]的地址,sizeof(a+1)计算的是地址的大小,32位平台是4,64位平台是8
5.printf("%d\n",sizeof(a[1]));//4
这求的就是a[1]这个元素的大小,4个字节
6.printf("%d\n",sizeof(&a));//8
&a虽然是数组的地址,但也是地址的大小,sizeof(&a)计算的是一个地址的大小,32位平台是4,64位平台是8
7.printf("%d\n",sizeof(*&a));//16
&a虽然是数组的地址,*(&a)就是整个数组,sizeof(*&a)求的整个数组的大小,16个字节
8.printf("%d\n",sizeof(&a+1));//8
&a+1指的是数组后面空间的地址,32位平台是4,64位平台是8
9.printf("%d\n",sizeof(&a[0]));//8
&a[0]就是第一元素的地址,32位平台是4,64位平台是8
10.printf("%d\n",sizeof(&a[0]+1));//8
&a[0]就是第一元素的地址,&a[0]+1就是第二个元素a[1]的地址,32位平台是4,64位平台是8
题二
1. 字符数组 2. char arr[]={'a','b','c','d','e','f'}; 3. printf("%d\n",sizeof(arr));//6 4. printf("%d\n",sizeof(arr+0));//8 5. printf("%d\n",sizeof(*arr));//1 6. printf("%d\n",sizeof(arr[1]));//1 7. printf("%d\n",sizeof(&arr));//8 8. printf("%d\n",sizeof(&arr+1));//8 9. printf("%d\n",sizeof(&arr[0]+1));//8 10. 11. printf("%d\n",strlen(arr));//随机值 12. printf("%d\n",strlen(arr+0));//随机值 13. printf("%d\n",strlen(*arr));//错误 14. printf("%d\n",strlen(arr[1]));//错误 15. printf("%d\n",strlen(&arr));//随机值 16. printf("%d\n",strlen(&arr+1));//随机值 17. printf("%d\n",strlen(&arr[0]+1));//随机值
1. printf("%d\n",sizeof(arr));//6
这有6个字符,所以整个数组大小为6
2. printf("%d\n",sizeof(arr+0));//8
由于他不是单独的sizeof(数组名),所以数组名表示首元素地址,a+0是首元素的地址, sizeof(a+0)计算的是地址的大小,32位平台是4,64位平台是8
3.printf("%d\n",sizeof(*arr));//1
*arr就是第一个元素a[0],所以大小就是1
4.printf("%d\n",sizeof(arr[1]));//1
arr[1]就是第二个元素,所以大小就是1
5.printf("%d\n",sizeof(&arr));//8
&arr表示整个数组的地址,32位平台是4,64位平台是8
6.printf("%d\n",sizeof(&arr+1));//8
&arr表示整个数组的地址,&arr+1表示这个数组后面的地址,32位平台是4,64位平台是8
7.printf("%d\n",sizeof(&arr[0]+1));//8
&arr[0]表示第一个元素的地址,&arr[0]+1表示第二个元素的地址&arr[1],32位平台是4,64位平台是8
8.printf("%d\n",strlen(arr));//随机值
strlen()是求字符的长度,遇见'\0'停止,由于arr中是单个字符,没有'\0',所以strlen()不知道什么时候停下
9.printf("%d\n",strlen(arr+0));//随机值
arr+0首元素的地址,strlen()是求字符的长度,遇见'\0'停止,由于arr中是单个字符,没有'\0',所以strlen()不知道什么时候停下
10.printf("%d\n",strlen(*arr));//错误
*arr是第一个元素,strlen会理解到你这是ASCII码值里的97,不是一个合法的地址,所以会发生错误
11.printf("%d\n",strlen(arr[1]));//错误
arr[1]是第二个元素,strlen会理解到你这是ASCII码值里的98,不是一个合法的地址,所以会发生错误
12.printf("%d\n",strlen(&arr));//随机值
&arr整个数组的地址,strlen()是求字符的长度,遇见'\0'停止,由于arr中是单个字符,没有'\0',所以strlen()不知道什么时候停下
13.printf("%d\n",strlen(&arr+1));//随机值
&arr+1整个数组后面的的地址,strlen()是求字符的长度,遇见'\0'停止,没有'\0',所以strlen()不知道什么时候停下
14.printf("%d\n",strlen(&arr[0]+1));//随机值
&arr[0]+1就是第二个元素的地址,strlen()是求字符的长度,遇见'\0'停止,由于arr中是单个字符,没有'\0',所以strlen()不知道什么时候停下
题三
1. 字符数组 2. char arr[]="abcdef"; 3. printf("%d\n",sizeof(arr));//7 4. printf("%d\n",sizeof(arr+0));//8 5. printf("%d\n",sizeof(*arr));//1 6. printf("%d\n",sizeof(arr[1]));//1 7. printf("%d\n",sizeof(&arr));//8 8. printf("%d\n",sizeof(&arr+1));//8 9. printf("%d\n",sizeof(&arr[0]+1));//8 10. 11. printf("%d\n",strlen(arr));//6 12. printf("%d\n",strlen(arr+0));//6 13. printf("%d\n",strlen(*arr));//错误 14. printf("%d\n",strlen(arr[1]));//错误 15. printf("%d\n",strlen(&arr));//6 16. printf("%d\n",strlen(&arr+1));//随机值 17. printf("%d\n",strlen(&arr[0]+1));//5
1.printf("%d\n",sizeof(arr));//7
arr为字符串,末尾会跟有'\0',sizeof(arr)计算的整个数的大小,所以为7
2.printf("%d\n",sizeof(arr+0));//8
arr+0是第一个元素的地址,32位平台是4,64位平台是8
3.printf("%d\n",sizeof(*arr));//1
*arr是第一个元素,大小为1
4.printf("%d\n",sizeof(arr[1]));//1
arr[1]是第二个元素,大小为1
5.printf("%d\n",sizeof(&arr));//8
&arr整个数组的地址,32位平台是4,64位平台是8
6.printf("%d\n",sizeof(&arr+1));//8
&arr整个数组的地址,&arr+1是整个数组后面的地址,32位平台是4,64位平台是8
7.printf("%d\n",sizeof(&arr[0]+1));//8
&arr[0]+1是第二个元素的地址,32位平台是4,64位平台是8
8.printf("%d\n",strlen(arr));//6
arr表示整个元素的地址,strlen遇到'\0'就停止,不会把'\0'计算在内,所以大小为6
9.printf("%d\n",strlen(arr+0));//6
arr+0表示首元素的地址,strlen遇到'\0'就停止,不会把'\0'计算在内,所以大小为6
10.printf("%d\n",strlen(*arr));//错误
*arr是第一个元素,strlen会理解到你这是ASCII码值里的97,不是一个合法的地址,所以会发生错误
11.printf("%d\n",strlen(arr[1]));//错误
arr[1]是第二个元素的地址,strlen会理解到你这是ASCII码值里的98,不是一个合法的地址,所以会发生错误
12.printf("%d\n",strlen(&arr));//6
&arr表示整个数组的地址,strlen遇到'\0'就停止,不会把'\0'计算在内,所以大小为6
13.printf("%d\n",strlen(&arr+1));//随机值
&arr+1是整个数组后面的地址,strlen()是求字符的长度,遇见'\0'停止,由于arr中是单个字符,没有'\0',所以strlen()不知道什么时候停下
14.printf("%d\n",strlen(&arr[0]+1));//5
&arr[0]+1是第二个元素元素的地址,从第二个元素到'\0',有5个元素,所以长度为5
题四
1. 字符数组 2. char* p="abcdef"; 3. printf("%d\n",sizeof(p));//8 4. printf("%d\n",sizeof(p+1));//8 5. printf("%d\n",sizeof(*p));//1 6. printf("%d\n",sizeof(p[0]));//1 7. printf("%d\n",sizeof(&p));//8 8. printf("%d\n",sizeof(&p+1));//8 9. printf("%d\n",sizeof(&p[0]+1));//8 10. 11. printf("%d\n",strlen(p));//6 12. printf("%d\n",strlen(p+1));//5 13. printf("%d\n",strlen(*p));//错误 14. printf("%d\n",strlen(p[0]));//错误 15. printf("%d\n",strlen(&p));//随机值 16. printf("%d\n",strlen(&p+1));//随机值 17. printf("%d\n",strlen(&p[0]+1));//5
1.printf("%d\n",sizeof(p));//8
sizeof(p)求的是指针变量的大小,32位平台是4,64位平台是8
2.printf("%d\n",sizeof(p+1));//8
p+1第二个元素的地址,32位平台是4,64位平台是8
3.printf("%d\n",sizeof(*p));//1
*p就是第一个元素,它的大小为1
4.printf("%d\n",sizeof(p[0]));//1
p[0]就是第一个元素,它的大小为1
5.printf("%d\n",sizeof(&p));//8
&p指针p的地址,32位平台是4,64位平台是8
6.printf("%d\n",sizeof(&p+1));//8
&p指针p的地址,&p+1还是内存里的地址,32位平台是4,64位平台是8
7.printf("%d\n",sizeof(&p[0]+1));//8
&p[0]+1第二个元素的地址,32位平台是4,64位平台是8
8.printf("%d\n",strlen(p));//6
p是首元素的地址,到'\0'停止,所以长度为6
9.printf("%d\n",strlen(p+1));//5
p+1是第二个元素的地址,到'\0'停止,所以长度为5
10.printf("%d\n",strlen(*p));//错误
*p是第一个元素,strlen会理解到你这是ASCII码值里的97,不是一个合法的地址,所以会发生错误
11.printf("%d\n",strlen(p[0]));//错误
p[0]是第一个元素,strlen会理解到你这是ASCII码值里的97,不是一个合法的地址,所以会发生错误
12.printf("%d\n",strlen(&p));//随机值
&p是指针p的地址,strlen()是求字符的长度,遇见'\0'停止,由于arr中是单个字符,没有'\0',所以strlen()不知道什么时候停下
13.printf("%d\n",strlen(&p+1));//随机值
&p+1是p后面的地址,strlen()是求字符的长度,遇见'\0'停止,由于arr中是单个字符,没有'\0',所以strlen()不知道什么时候停下
14. printf("%d\n",strlen(&p[0]+1));//5
&p[0]+1)是第二个元素的地址,到'\0'有5个元素,所以长度为5
题五
1. #include<stdio.h> 2. int main() 3. { 4. int arr[3][4]={0}; 5. printf("%d\n",sizeof(arr));//48 6. printf("%d\n",sizeof(arr[0][0]));//4 7. printf("%d\n",sizeof(arr[0]));//16 8. printf("%d\n",sizeof(arr[0]+1));//8 9. printf("%d\n",sizeof(*(arr[0]+1)));//4 10. printf("%d\n",sizeof(*(arr+1)));//16 11. printf("%d\n",sizeof(&arr[0]+1));//8 12. printf("%d\n",sizeof(*(&arr[0]+1)));//16 13. printf("%d\n",sizeof(*arr));//16 14. printf("%d\n",sizeof(arr[3]));//16 15. }
注:作为二维数组的数组名,没有&,没有单独放在sizeof中,所以就是第一行的数组名,解引用就是第一行的元素
1.printf("%d\n",sizeof(arr));//48
sizeof(arr)计算的是整个数组的大小
2.printf("%d\n",sizeof(arr[0][0]));//4
arr[0][0]第一个元素,大小为4
3.printf("%d\n",sizeof(arr[0]));//16
arr[0]第一行的数组名,看成一维数组,sizeof(arr[0])求的是第一行的元素的大小,大小为16
4.printf("%d\n",sizeof(arr[0]+1));//8
arr[0]+1第二行的数组名 ,sizeof(arr[0]+1)求的是第二行的元素的大小,大小为16
5.printf("%d\n",sizeof(*(arr[0]+1)));//4
arr[0]+1第二行的数组名 ,*(arr[0]+1)是第二行第一个元素,大小为4
6.printf("%d\n",sizeof(*(arr+1)));//16
*(arr+1)是第二行的所有元素,大小为16
7.printf("%d\n",sizeof(&arr[0]+1));//8
&arr[0]是第一行的地址,&arr[0]+1是第二行的地址,32位平台是4,64位平台是8
8.printf("%d\n",sizeof(*(&arr[0]+1)));//16
*(&arr[0]+1)是第二行的元素,大小为16
9.printf("%d\n",sizeof(*arr));//16
arr是第一行的数组名,*arr是第一行的元素,大小为16
10.printf("%d\n",sizeof(arr[3]));//16
arr[3]其实是第四行的地址,但实际上不存在,但也能通过类型计算其的大小
例如:
short s=5;
int a=4
printf("%d ",sizeof(s=a+6));//还是以s类型是,short,
printf("%d ",s);//5 sizeof()中的表达式是不参与运算的
题六
1. #include<stdio.h> 2. int main() 3. { 4. int a[3][2]={(0,1),(2,3),(4,5)};//a[0]为1,3 a[1]为5,0 a[2]为2,4 5. int* p; 6. p=a[0];//a[0]首元素的地址 7. printf("%d\n",p[0]);//p[0]等于*(p+0); 8. return 0; 9. }
int a[3][2]={(0,1),(2,3),(4,5)};这种逗号表达式的写法非常特殊,我们可以把这个二维数组等同于a[3][2]={1,3,5,0,2,4}
题七
1. #include<stdio.h> 2. int main() 3. { 4. int aa[2][5]={1,2,3,4,5,6,7,8,9,10}; 5. int* ptr1=(int *)(&aa+1); 6. int* ptr2=(int *)(*(aa+1)); 7. printf("%d %d ",*(ptr1-1),*(ptr2-1)); 8. return 0; 9. }
int* ptr1=(int *)(&aa+1):
&aa+1是数组后面的的地址,(int *)是将其强制转化为整形的地址,其实在这里意义不大,因为&aa+1本身就是整形地址类型
int* ptr2=(int *)(*(aa+1)):
aa+1是第二行的地址,*(aa+1)第二行第一个元素
printf("%d %d ",*(ptr1-1),*(ptr2-1)):
*(ptr1-1)就是最后一个元素的值10,*(ptr2-1)是第一行最后一个数的值5
题八
1. #include<stdio.h> 2. int main() 3. { 4. char* a[]={"work","at","alibaba"}; 5. char** pa=a; 6. pa++; 7. printf("%s\n",*pa); 8. return 0; 9. }
** pa存储的就是数组a的首元素地址, pa++就是第二个元素的地址,在解引用就是"at"了
题九
1. #include<stdio.h> 2. int main() 3. { 4. char* c[]={"ENTER","NEW","POINT","FIRST"}; 5. char** cp[]={c+3,c+2,c+1,c}; 6. char*** cpp=cp; 7. printf("%s\n",**++cpp); 8. printf("%s\n",*--* ++cpp +3); 9. printf("%s\n",*cpp[-2]+3); 10. printf("%s\n",cpp[-1][-1]+1); 11. return 0; 12. }
printf("%s\n",**++cpp):
++cpp就是cp[1]的地址,*++cpp这样解引用就是c[2]的地址,再解引用就是“POINT:
printf("%s\n",*--* ++cpp +3):
++cpp就是cp[2]的地址,* ++cpp得到的是c[1]的地址,--* ++cpp得到的是c[0]的地址,*--* ++cpp这样解引用就是“ENTER”,*--* ++cpp +3就是“ER”。
printf("%s\n",*cpp[-2]+3):
**(cpp-2)+3,cpp就是cp[2]的地址,cpp-2就是cp[0]的地址,**(cpp-2)就是“FIRST”,**(cpp-2)+3就是“ST”
printf("%s\n",cpp[-1][-1]+1):
*(*(cpp-1)-1)+1,cpp是cp[2]的地址,cpp-1就是cp[1]的地址,*(cpp-1)就是c[2]的地址,*(cpp-1)-1就是c[1]的地址,*(*(cpp-1)-1)就是“NEW”,*(*(cpp-1)-1)+1为“EW”
最后这道题,是这题里最具有价值题,是最浓缩的题,当然难度是相当大的,理解起来也比较复杂,其实解这种指针的题,我们可以画图,比如最后一道题
画图之后我们可以清晰了解这些指针怎么’‘运行的‘’。
🐶🐶🐶指针学习的内容差不多就是这些了,希望大家看这些关于指针的题,能够帮助帮助大家对指针的理解,如果大家还有不懂或者建议都可以发在评论区,我们共同探讨,共同学习,共同进步。谢谢大家! 💖💖💖
文章知识点与官方知识档案匹配