【C语言进阶7——指针的进阶(4)- 数组的练习 sizeof 和 strlen】


前言

前面已经介绍了数组和指针的知识点,并且用类比方法做了总结。先简要复习与本文练习相关的知识点:

  • 复习数组名
  • 操作符[ ] 和取地址 & 和 指针符号* 三者分别在一维和二维数组中,相互之间的联系
  • 复习sizeof
  • 复习strlen

要学以致用,才能更加深入的理解所学的知识点,因此本文主要是数组和指针相关知识点的练习:


1、 相关知识点复习

在前面的学习中,我们经常碰到数组名、sizeof、strlen,本文的练习也会用到它们,先对这些知识点进行复习。

1.1 复习数组名

前面在 【C语言基础5——数组(1)】4.2 和4.3小结 中已经初步学习过了数组名的知识点。

在进阶中更深入的学习了数组和指针后,对数组名理解更加深刻了,温故而知新,首先还是复习下数组名的知识点:

  • 数组名一般情况都是表示数组首元素的地址

但是有两个例外

  • sizeof(数组名),这里数组名表示的是整个数组,求取的整个数组的大小
  • &数组名,表示对整个数组取地址

1.2 操作符 [ ] 和取地址 & 和 指针符号* 三者之间的联系

type_t arr_name [const_n];
type_t 是指数组的元素类型
const_n 是一个常量表达式,用来指定数组的大小

学完指针后,对 [ ] 有了更加深刻的理解,将操作符[ ]和取地址 &、定义指针符号 *结合:

1.2.1 一维数组中三者的联系

在这里插入图片描述

1.2.2 二维数组中三者的联系

在这里插入图片描述
在这里插入图片描述

二维数组举例,对照上图和下面的代码分析,可见二维数组的知识点其实是很密集的:

int main()
{
	int a[2][3] = { {1,2,3},{4,5,6 } };
	return 0;
}

注意各个监视对象的类型,类型不一样代表的意义不一样:

在这里插入图片描述

1.3 复习sizeof

sizeof 是一个操作符,sizeof 计算的是对象所占内存的大小-单位是字节,不在乎内存中存放的是什么,只在乎内存大小

1.4 复习strlen

strlen 是一个库函数,功能:求字符串长度,从给定的地址向后访问字符,统计\0之前出现的字符个数。

2、 sizeof 一维整形数组 int a[] = { 1,2,3,4 }

int a[] = { 1,2,3,4 };
	printf("%d\n", sizeof(a));//sizeof(数组名),求取的是整个数组的大小 16
	printf("%d\n", sizeof(a + 0));//数组名不是单独使用,a+0表示首元素的地址,地址的大小就是 4/8
	printf("%d\n", sizeof(*a));//a表示首元素的地址,*a表示数组的首元素,求第一个元素的大小 4
	printf("%d\n", sizeof(a + 1));//a表示首元素的地址,a+1表示第二个元素的地址,求大小 4/8
	printf("%d\n", sizeof(a[1]));//a[1]表示数组第二个元素,求大小 4
	printf("%d\n", sizeof(&a));//&a表示整个数组的地址,求大小 4/8
	printf("%d\n", sizeof(*&a));//*&a 对整个数组的地址解引用,拿到整个数组,求大小 16
	printf("%d\n", sizeof(&a + 1));//&a+1表示跳过一个数组后的地址,求大小 4/8
	printf("%d\n", sizeof(&a[0]));//&a[0]首元素的地址,求大小 4/8
	printf("%d\n", sizeof(&a[0] + 1));//&a[0]+1数组第二个元素的地址,求大小 4/8

在这里插入图片描述

3、一维字符数组

3.1 sizeof 练习 char arr[ ] = { ‘a’,‘b’,‘c’,‘d’,‘e’,‘f’ }

char arr[] = { 'a','b','c','d','e','f' };
	printf("%d\n", sizeof(arr));//sizeod(数组名),所占内存大小。6个字符 ,求大小 6
	printf("%d\n", sizeof(arr + 0));//arr表示首元素的地址,arr+0表示首元素的地址,地址求大小 4/8
	printf("%d\n", sizeof(*arr));//arr表示首元素的地址,*arr取得首元素是一个字符,求大小 1
	printf("%d\n", sizeof(arr[1]));//arr[1]表示第二个元素,是一个字符,求大小 1
	printf("%d\n", sizeof(&arr));//&arr取整个数组的地址,地址求大小 4/8
	printf("%d\n", sizeof(&arr + 1));//&arr+1移动整个数组的地址,指向数组末尾,还是地址,求大小 4/8
	printf("%d\n", sizeof(&arr[0] + 1));//arr[0]首元素,&arr[0]取首元素的地址,&arr[0] + 1第二个元素的地址,求大小 4/8

该处使用的url网络请求的数据。

3.2 strlen 练习 char arr[ ] = { ‘a’,‘b’,‘c’,‘d’,‘e’,‘f’ }

char arr[] = { 'a','b','c','d','e','f' };//数组中没有'\0'
	//从数组首元素地址开始向后,一直到字符'\0'为止,
	printf("%d\n", strlen(arr));//数组的地址,求长度 随机值
	printf("%d\n", strlen(arr + 0));//arr首元素的地址,求长度 随机值
	//printf("%d\n", strlen(*arr));//arr首元素的地址,*arr取得首元素'a',97,97作为一个地址,不能访问,类似野指针,错误
	//printf("%d\n", strlen(arr[1]));//第二个元素,错误
	printf("%d\n", strlen(&arr));//&arr整个数组的地址, 求长度 随机值
	printf("%d\n", strlen(&arr + 1)); //&arr + 1移动整个数组的地址,指向数组末尾,还是地址,随机值,和上面差6
	printf("%d\n", strlen(&arr[0] + 1));//arr[0]首元素,&arr[0]取首元素的地址,&arr[0] + 1第二个元素的地址,随机值和上面差1

在这里插入图片描述

3.3 sizeof 练习 char arr[ ] = “abcdef”

char arr[] = "abcdef";//常量字符串,末尾隐藏字符'\0'
	printf("%d\n", sizeof(arr));//sizeod(数组名),数组所占内存大小。6个字符 加上末尾隐藏字符'\0',求大小 7
	printf("%d\n", sizeof(arr + 0));//arr不是2中例外,这里arr+0表示首元素的地址,求大小 4/8
	printf("%d\n", sizeof(*arr));//arr表示首元素的地址,*arr取得首元素'a',求大小 1
	printf("%d\n", sizeof(arr[1]));//arr[1]表示第二个元素'b',求大小 1
	printf("%d\n", sizeof(&arr));//&arr整个数组的地址,地址求大小 4/8
	printf("%d\n", sizeof(&arr + 1));//&arr+1移动整个数组的地址,指向数组末尾,还是地址,求大小 4/8
	printf("%d\n", sizeof(&arr[0] + 1));//arr[0]首元素,&arr[0]取首元素的地址,&arr[0] + 1第二个元素的地址,求大小 4/8

在这里插入图片描述

3.4 strlen 练习 char arr[ ] = “abcdef”

char arr[] = "abcdef";//常量字符串,末尾隐藏字符'\0'
	printf("%d\n", strlen(arr));//arr数组首元素的地址,求长度 6
	printf("%d\n", strlen(arr + 0));//arr首元素的地址,求长度 6
	//printf("%d\n", strlen(*arr));//arr首元素的地址,*arr取得首元素'a',97,97作为一个地址,不能访问,类似野指针,错误
	//printf("%d\n", strlen(arr[1]));//第二个元素,错误
	printf("%d\n", strlen(&arr));//&arr整个数组的地址,数值等同首元素的地址 求长度 6
	printf("%d\n", strlen(&arr + 1));//&arr + 1移动跳过整个数组的地址,指向数组末尾,还是地址,随机值
	printf("%d\n", strlen(&arr[0] + 1));//arr[0]首元素,&arr[0]取首元素的地址,&arr[0] + 1第二个元素的地址,5

在这里插入图片描述

3.5 sizeof 练习 char *p = “abcdef”

char *p = "abcdef";
等效于下面常见的代码,将字符串常量的首地址赋值给指针变量p
	char a[] = "abcdef";
	char *p = &a;
	p[0]=*(p+0)=*(a+0)=a[0]

在这里插入图片描述

char *p = "abcdef";
	printf("%d\n", sizeof(p));//p是指针变量,保存首元素地址,地址求大小 4/8
	printf("%d\n", sizeof(p + 1));//p+1,指针指向第二个元素'b'的地址, 求大小 4/8
	printf("%d\n", sizeof(*p));//*p取出首元素 'a',求大小 1
	printf("%d\n", sizeof(p[0]));//p[0]代表首元素 'a',求大小 1
	printf("%d\n", sizeof(&p));//&p 是指针变量p在内存中的地址, 地址求大小 4/8
	printf("%d\n", sizeof(&p + 1));//4/8 - &p+1是跳过p之后的地址,地址求大小 4/8
	printf("%d\n", sizeof(&p[0] + 1));//4/8 &p[0]是‘a’的地址,&p[0]+1就是b的地址,地址求大小 4/8

在这里插入图片描述

3.6 strlen 练习 char *p = “abcdef”

char *p = "abcdef";
printf("%d\n", strlen(p));//p是指针变量,保存首元素地址,求长度 6
	printf("%d\n", strlen(p + 1));//p+1,指针指向第二个元素'b'的地址, 求长度 5
	//printf("%d\n", strlen(*p));//*p取得首元素 'a' ,97,内存中97这个地址不能访问,类似野指针
	//printf("%d\n", strlen(p[0]));//p[0]得到首元素 'a',97,内存中97这个地址不能访问,类似野指针
	printf("%d\n", strlen(&p));//&p 是指针变量p在内存中的地址, 求长度 随机值
	printf("%d\n", strlen(&p + 1));// &p+1是跳过p之后的地址, 求长度 随机值 
	printf("%d\n", strlen(&p[0] + 1));// &p[0]是首元素‘a’的地址,&p[0]+1就是b的地址,求长度 5

在这里插入图片描述

4、 sizeof 二维整形数组 int a[ ][4] = { 0 }

int a[3][4] = { 0 };
	printf("%d\n", sizeof(a));//sizeof(a)求取整个数组的大小,48
	printf("%d\n", sizeof(a[0][0]));//(a[0][0]是第一行第一个元素,求大小 4
	printf("%d\n", sizeof(a[0]));//a[0]代表二维数组首元素,即第一行数组的数组名,sizeof(a[0])求第一行数字的大小 16
	printf("%d\n", sizeof(a[0] + 1));//a[0]第一行数组的数组名,没有放在sizeof里面,没有单独取地址,因此,a[0]代表第一行数组第1个元素的地址,a[0] +1是第一行数组第二个元素的地址,求大小 4
	printf("%d\n", sizeof(*(a[0] + 1)));//解引用取出第一行第二个元素,求大小 4
	printf("%d\n", sizeof(a + 1));//a不是两个例外,表示二维元素的首元素地址,a+1表示第二个元素的地址,就是第二行数组的地址,求大小 4
	printf("%d\n", sizeof(*(a + 1)));//*(a + 1)取出第二行数组,求大小 16
	printf("%d\n", sizeof(&a[0] + 1));//&a[0]第一行数组的地址,&a[0]+1 表示第二行数组的地址,求大小 4
	printf("%d\n", sizeof(*(&a[0] + 1)));//*(&a[0] + 1)取出第二行数组,求大小 16
	printf("%d\n", sizeof(*a));//a为首元素地址,*a取出首元素的内容,即第一行数组, 求大小 16
	printf("%d\n", sizeof(a[3]));//地址,a[3]也是int[4] 类型,里面的元素都是随机数值,求大小 16

在这里插入图片描述
在这里插入图片描述


总结

本文先复习了一些知识点,尤其是二维数组,要牢记数组名的一般情况和两个例外,通过sizeof 和 strlen 的练习,再次复习了数组和指针的知识点。

这段时间所学知识都是建立在前面的基础之上,知识不牢,地动山摇,要经常对前面所学的知识点进行复习。

若有地方总结错误,也请大家友好指正,谢谢大家! 下一篇继续更新数组和指针的练习。

  • 48
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 35
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 35
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

初学C语言者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值