从0开始学c语言-30- 指针不练习?还真觉得自己会了~

本文是一系列C语言指针练习的详解,涵盖数组、字符指针、二维数组、指针运算等多个方面。通过对比分析和实际操作,深化对指针地址的理解,帮助读者掌握指针在C语言中的应用。
摘要由CSDN通过智能技术生成

上一篇:从0开始学c语言-29-数据储存练习、筑基期练习、两步翻转_阿秋的阿秋不是阿秋的博客-CSDN博客

应有的基础:

从0开始学c语言-28-qsort函数、 数组和指针参数、函数指针数组(转移表)、回调函数_阿秋的阿秋不是阿秋的博客-CSDN博客

从0开始学c语言-27-字符指针,指针数组和数组指针_阿秋的阿秋不是阿秋的博客-CSDN博客

目录

练习1:int arr[ ]

 练习2:char arr[ ] zifu

 对比

 练习3:char arr[ ]

 对比\0

 练习4:char*p

对比 

 练习5:二维数组

 练习6:判断程序结果

练习7:第一眼没看出来的考点(重点看)

***指针和地址的新理解***

分析题

练习8:%x?int+1?(又被击败)

对于非指针+1的步长理解(地址神奇~)

练习9:有点陷阱

练习10:二维数组指针运用、指针运算、%p打印整型

练习11:二维数组

练习12:char*a[ ]

练习13:char***之终极练习


练习1:int arr[ ]

应有的知识:

数组名的意义:
1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
2. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
3. 除此之外所有的数组名都表示首元素的地址。
//一维数组
int a[] = {1,2,3,4};
printf("%d\n",sizeof(a));
printf("%d\n",sizeof(a+0));
printf("%d\n",sizeof(*a));
printf("%d\n",sizeof(a+1));
printf("%d\n",sizeof(a[1]));
printf("%d\n",sizeof(&a));
printf("%d\n",sizeof(*&a));
printf("%d\n",sizeof(&a+1));
printf("%d\n",sizeof(&a[0]));
printf("%d\n",sizeof(&a[0]+1));

请思考每个printf函数输出的结果是多少。

开始讲

int a[] = {1,2,3,4};
printf("%d\n",sizeof(a));

a单纯的数组名实际上就是数组首元素的地址,那么地址的大小在32位系统上是4byte,在64位系统上是8byte大小。但是呢,sizeof当中的数组名则代表整个数组,这一点要特别注意,那么a数组的大小就是4个int的大小,也就是16byte。

int a[] = {1,2,3,4};
printf("%d\n",sizeof(a+0));

实际上地址就是指针,那么a+0就代表a这个指针向后挪动了0步。且a本身指向数组首元素,+0表示一步没有挪动。

int a[] = {1,2,3,4};
printf("%d\n",sizeof(*a));

我们知道a是指针,*a就是对指针进行解引用,a指向数组首元素,那么*a就是在访问数组首元素,而数组首元素的类型是int,int的大小是4byte。

int a[] = {1,2,3,4};
printf("%d\n",sizeof(a+1));

a+0和a+1都是指针,只不过一个指向首元素,一个指向下标为1的元素。

int a[] = {1,2,3,4};
printf("%d\n",sizeof(a[1]));

a[1]代表数组下标为1的元素,而这个元素的类型是int,那么就是4byte。

int a[] = {1,2,3,4};
printf("%d\n",sizeof(&a));

我们早在前面说过,

1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
2. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
那么现在是sizeof和&数组名组合到一起,这时候,sizeof当中的&数组名,则是计算的 【指向整个数组的指针】的大小。
printf("%d\n",sizeof(*&a));

现在在&a前面加上了*, 而*&a=a,a又在sizeof当中,那就代表我们访问了整个数组,应该是16byte。

int a[] = {1,2,3,4};
printf("%d\n",sizeof(&a+1));

&a代表指向整个数组的指针,那么+1则会让指针向后挪动一步,这一步的大小是整个数组的大小,我们计算的还是 指针的大小。

int a[] = {1,2,3,4};
printf("%d\n",sizeof(&a[0]));

&a[0]是什么意思?

如果讲结合性的话,我还不太熟练,只能放图监视给你看

 也就是说&a[0]=&(a[0])

意思是取出数组第一个元素的地址,本质上是个指针。
printf("%d\n",sizeof(&a[0]+1));

那么同样的,&a[0]+1就代表指向第一个元素的指针向后走了一步,而这一步的大小是一个int,也就是指向了下标为1的元素。

现在看看结果,是否符合我们的推理。

 练习2:char arr[ ] zifu

char arr[] = { 'a','b','c','d','e','f' };
	printf("%d\n", sizeof(arr));
	printf("%d\n", sizeof(arr + 0));
	printf("%d\n", sizeof(*arr));
	printf("%d\n", sizeof(arr[1]));
	printf("%d\n", sizeof(&arr));
	printf("%d\n", sizeof(&arr + 1));
	printf("%d\n", sizeof(&arr[0] + 1));

实际上,这题和上面那道题几乎一模一样。我就把解释写在代码里了哈。

char arr[] = { 'a','b','c','d','e','f' };
	printf("%d\n", sizeof(arr));
//整个数组的大小,6
	printf("%d\n", sizeof(arr + 0));
//指向下标1的指针,4/8 ,8代表64位系统的结果
	printf("%d\n", sizeof(*arr));
//访问数组第一个元素,1
	printf("%d\n", sizeof(arr[1]));
//访问数组第一个元素,1
	printf("%d\n", sizeof(&arr));
//指向整个数组的指针,4/8
	printf("%d\n", sizeof(&arr + 1));
//指向整个数组的指针向后挪动一步,4/8
	printf("%d\n", sizeof(&arr[0] + 1));
//指向数组第一个元素的指针向后挪动一步,4/8

 对比

char arr[] = { 'a','b','c','d','e','f' };
printf("%d\n", strlen(arr));
printf("%d\n", strlen(arr+0));
printf("%d\n", strlen(*arr));
printf("%d\n", strlen(arr[1]));
printf("%d\n", strlen(&arr));
printf("%d\n", strlen(&arr+1));
printf("%d\n", strlen(&arr[0]+1));

实际上大体也是一样的,只不过我们换成了strlen,那就要特别注意\0。

char arr[] = { 'a','b','c','d','e','f' };
    printf("%d\n", strlen(arr));
//没有\0,随机值
    printf("%d\n", strlen(arr+0));
//没有\0,随机值
    printf("%d\n", strlen(*arr));
//*arr不是指针,不能计算
    printf("%d\n", strlen(arr[1]));
//arr[1]不是指针,不能计算
    printf("%d\n", strlen(&arr));
//没有\0,随机值
    printf("%d\n", strlen(&arr+1));
//没有\0,随机值-6  因为是指向整个数组的指针向后挪一步
    printf("%d\n", strlen(&arr[0]+1));
//没有\0,随机值-1 因为是指向一个元素的指针向后挪一步

很多警告,主要看类型不同的警告,正如我们所说,*arr和arr[0]是不能计算的,

在注释掉后,计算的结果就像我们注释里说的。

 练习3:char arr[ ]

char arr[] = "abcdef";
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(arr+0));
printf("%d\n", sizeof(*arr));
printf("%d\n&
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值