强化c指针与数组的运用

C语言强化指针与数组练习

目标

1.掌握sizeof和strlen的具体用法。
2.掌握指针与数组。
进入正题之前,请大家牢记以下几点
1.sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
2.&数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
3.除此之外,所有的数组名都表示首元素的地址。
然后我们来看下面的题目


题目:

sizeof() 是一个判断数据类型或者表达式长度的运算符
int main()
{
	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));	
	return 0;
}

题目分析:

printf("%d\n", sizeof(a)); // 16

a是数组名,sizeof(数组名)表示计算整个数组的大小


printf("%d\n", sizeof(a + 0));// 4或8 

这里的sizeof(a+0) 数组名不是单独放在sizeof中的,所以这里的a表示数组首元素的地址,那么首元素地址+0,就还是首元素地址,所以sizeof(a+0)计算的是数组首元素的地址的大小。(注意:无论什么类型数据地址的大小在32位系统环境下是4字节,在64位系统环境下是8字节)


printf("%d\n", sizeof(*a)); // 4  
a是首元素的地址,*a就得到了 1。所以sizeof(*a),就是计算int在内存中的大小。(int在内存中的大小为4)

printf("%d\n", sizeof(a + 1)); // 4或8 这里与第二个同理

printf("%d\n", sizeof(a[1])); // 4  a[1]取到a下标为1的数字2,所以还是计算int在内存中的大小

printf("%d\n", sizeof(&a)); // 4或8 &a取到的是整个数组的地址,所以是计算地址大小

printf("%d\n", sizeof(*&a)); // 16 &a取到的是整个数组的地址,*&a得到1,2,3,4 所以4x4=16

printf("%d\n", sizeof(&a + 1)); // 4或8   &a+1的位置如图,计算地址大小。

在这里插入图片描述

printf("%d\n", sizeof(&a[0])); // 4或8  a[0]拿到1,&a[0]拿到1的地址,计算地址大小。

printf("%d\n", sizeof(&a[0] + 1));	// 4或8  如图位置的地址,计算地址大小

在这里插入图片描述


题目:

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));

题目解析:

printf("%d\n", sizeof(arr)); // 6  
sizeof(arr)表示计算整个arr,char类型在内存中占1个字节,1X6=6

printf("%d\n", sizeof(arr+0)); // 4或8
sizeof(arr+0) arr不是单独存在在sizeof()中,所以arr+0表示的是a元素的地址,所以计算的是地址。

printf("%d\n", sizeof(*arr));// 1 
arr是数组名表示数组首元素的地址,*arr取到数组首元素a,a是char类型在内存中占1个字节的大小

printf("%d\n", sizeof(arr[1]));// 1 
arr[1]取到数组下标为1的元素b,b是char类型再内存中占1字节

printf("%d\n", sizeof(&arr)); //4/8 
&arr取出的是整个数组的地址,所以在sizeof()中计算的是地址的大小4字节或8字节

printf("%d\n", sizeof(&arr+1)); // 4或8
&arr取的是整个数组的地址,&arr+1表示到这个数组的下一个位置中,如图

在这里插入图片描述

printf("%d\n", sizeof(&arr[0]+1));// 4或8
&arr[0]取到的是a元素的地址,&arr[0]+1表示b元素的地址。如图

在这里插入图片描述


题目:

strlen():计算的是字符串str的长度,从字符的首地址开始遍历,以 ‘\0’ 为结束标志,然后将计算的长度返回,计算的长度并不包含’\0’。

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));

题目解析:

printf("%d\n", strlen(arr)); // 随机数

arr取到是首元素的地址,strlen函数遇到’\0’才会停,但arr在内存中是这么存放的。如图
在这里插入图片描述
没有\0,所以会在arr内存后一直找,直到找到\0。

	printf("%d\n", strlen(arr+0)); // 随机值
	arr+0拿到的是a的地址,拿到a的地址之后接着往后找'\0',同上图
	
	printf("%d\n", strlen(*arr)); //  error
	*arr拿到了a元素,但srtlen函数需要接收一个地址,直接传元素会出错
	
	printf("%d\n", strlen(arr[1])); //error
	arr[1]取到的是元素b,srtlen函数需要接收一个地址,直接传元素会出错
	
	printf("%d\n", strlen(&arr)); //随机值
	&arr 取到的是整一个数组的地址,如图

在这里插入图片描述

printf("%d\n", strlen(&arr+1)); // 随机值-6
如图

在这里插入图片描述

printf("%d\n", strlen(&arr[0]+1)); //随机值-1
如图

在这里插入图片描述

题目:


char arr[] = "abcdef";

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));

题目分析:

printf("%d\n", sizeof(arr)); //  7 
sizeof(数组名)会计算整个数组的大小,并且会计算'\0'

如图:

在这里插入图片描述

printf("%d\n", sizeof(arr+0)); // 4或8
arr+0拿到的是地址,计算的地址的大小

printf("%d\n", sizeof(*arr)); // 1
*arr取到的是数组首元素a,sizeof(*arr)计算的a的大小 1*1=1

printf("%d\n", sizeof(arr[1])); // 1
arr[1]取到数组下标为1的元素 b,计算大小 1*1=1

printf("%d\n", sizeof(&arr)); // 4或8
&arr取到的是整个数组的地址,sizeof(&arr)计算的是地址的大小

printf("%d\n", sizeof(&arr+1)); // 4或8
如图,计算该位置地址的大小

在这里插入图片描述

printf("%d\n", sizeof(&arr[0]+1)); // 4或8
如图,计算该位置的地址

在这里插入图片描述


题目:

char arr[] = "abcdef";

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));


题目分析:

在这里插入图片描述

printf("%d\n", strlen(arr)); // 6
arr是数组名,这里表示首元素的地址,strlen遇到’\0‘ 返回首元素到到‘\0’的元素个数。

printf("%d\n", strlen(arr+0)); // 6
arr+0,也是首元素的地址。同上。

printf("%d\n", strlen(*arr)); // error
arr表示首元素地址,*arr拿到单个元素a,而strlen接收的是地址(size_t strlen (const char* str)),传入单个元素会导致报错

printf("%d\n", strlen(arr[1])); //error
arr[1]取到数组下标为1的元素 b,同上

printf("%d\n", strlen(&arr)); //6
&arr取到的是整个数组的地址,如图

在这里插入图片描述

printf("%d\n", strlen(&arr+1)); // 随机值
如图 直到找到’\0‘

在这里插入图片描述

printf("%d\n", strlen(&arr[0]+1)); //5
如图

在这里插入图片描述


题目:

char* p = "abcdef";

printf("%d\n", sizeof(p));
printf("%d\n", sizeof(p+1));
printf("%d\n", sizeof(*p));
printf("%d\n", sizeof(p[0]));
printf("%d\n", sizeof(&p));
printf("%d\n", sizeof(&p+1));
printf("%d\n", sizeof(&p[0]+1));

题目分析:

在这里插入图片描述

printf("%d\n", sizeof(p)); // 4或8
p中存了的是a的地址,这里计算的是地址的大小

printf("%d\n", sizeof(p+1)); //4或8
同上

printf("%d\n", sizeof(*p)); // 1
*p拿到的是元素a,a的大小 1*1 = 0

printf("%d\n", sizeof(p[0])); // 1
p[0]拿到的是元素a,a的大小1*1=0
	
printf("%d\n", sizeof(&p)); // 4或8
&p取到的是p的地址,所以是计算地址的大小
	
printf("%d\n", sizeof(&p+1)); // 4或8
如图

在这里插入图片描述

printf("%d\n", sizeof(&p[0]+1)); 4或8
p[0]是a元素,&p[0]取到p的元素,+1找到b的地址。计算b地址大小

题目:

char* p = "abcdef";

printf("%d\n", strlen(p)); 
printf("%d\n", strlen(p+1)); 
printf("%d\n", strlen(*p)); 
printf("%d\n", strlen(p[0])); 
printf("%d\n", strlen(&p)); 
printf("%d\n", strlen(&p+1));
printf("%d\n", strlen(&p[0]+1)); 

题目分析:

在这里插入图片描述

printf("%d\n", strlen(p)); //  6
p中存的是a的地址,传给strlen后直接计算字符串的大小。

printf("%d\n", strlen(p+1)); // 5
a的地址加一,得到b的地址,从b处开始计算字符串的大小

printf("%d\n", strlen(*p)); //error  取到字符a
printf("%d\n", strlen(p[0])); // error 取到字符a
strlen需要是的地址,直接传字符会报错!
	
printf("%d\n", strlen(&p)); //随机值
如图

在这里插入图片描述

printf("%d\n", strlen(&p+1)); //随机值
如图

在这里插入图片描述

printf("%d\n", strlen(&p[0]+1)); //5
p[0]是a元素,&p[0]取到p的元素,*p[0]+1找到b的地址,从b处开始计算字符串大小

题目:

int a[3][4] = {0};

printf("%d\n", sizeof(a));
printf("%d\n", sizeof(a[0][0]));
printf("%d\n", sizeof(a[0]));
printf("%d\n", sizeof(a[0]+1));
printf("%d\n", sizeof(*(a[0]+1)));
printf("%d\n", sizeof(a+1));
printf("%d\n", sizeof(*(a+1)));
printf("%d\n", sizeof(&a[0]+1));
printf("%d\n", sizeof(*(&a[0]+1)));
printf("%d\n", sizeof(*a));
printf("%d\n", sizeof(a[3]));


题目分析:

printf("%d\n", sizeof(a)); //  48
3*4*sizeof(int) = 3*4*4 = 48

printf("%d\n", sizeof(a[0][0])); //4或8
代表第一行第一个元素

printf("%d\n", sizeof(a[0])); //16
这里将a[0]理解为二维数组第一行的数组名
那么sizeof(a[0])就是计算第一行数组的大小,4*sizeof(int) = 4*4 = 16

printf("%d\n", sizeof(a[0]+1)); // 4或8
a[0]作为数组名没有单独存放在sizeof()中
可以将a[0]+1理解为 a[0][1]
也没有取地址,所以a[0]算是第一行第一个元素地址
a[0]+1就是第一行第二个元素地址。	

printf("%d\n", sizeof(*(a[0]+1))); // 4
*(a[0]+1) 可以看做 *(a[0][1]) 拿到的是第一行第2个元素,计算的是元素的大小.

printf("%d\n", sizeof(a+1)); // 4或8
a是二维数组的数组名,并没有取地址,也没有单独放在sizeof()中
所以a就表示首元素的地址,即第一行的地址,a+1就是第二行的地址,计算的是地址的大小。

printf("%d\n", sizeof(*(a+1))); // 16
a+1是第二行的地址,*(a+1)取到第二行的所以元素,计算的是元素大小,4*4= 16

printf("%d\n", sizeof(&a[0]+1)); //4或8
a[0]是数组名,&a[0]取到第一行的地址,&a[0]+1就表示第二行的地址,计算地址大小

printf("%d\n", sizeof(*(&a[0]+1))); // 16
&a[0]+1表示第二行的地址,*(&a[0]+1)拿到第二行的所以元素,计算元素大小,4*4 = 16

printf("%d\n", sizeof(*a)); // 16
a是数组名,即没有取地址,也没有单独放在sizeof()中,所以在这里表示首元素的地址,即第一行的地址
*a就是取到第一行所有的元素,所以计算的是元素的大小 4*4 = 16

printf("%d\n", sizeof(a[3])); //16
a[3]是第4行的数组名(如果有的话),所以不存在,也可以通过类型来计算大小的

总结

1.sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
2.&数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
3.除此之外,所有的数组名都表示首元素的地址。
4.strlen函数接收的是地址,并且遇到’\0’才会返回。
5.数组arr可以 arr[2] <=>*(arr+2) <=> *(2+arr) <=> 2[arr]

以上。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值