C语言sizeof的实战例子

实战例子1

经过这些例子,可以加深对sizeof,数组,数组名,取数组地址,地址加一,指针,指针加一的理解,一定要特别注意数组名在不同场景下的含义

一:数组名是数组首元素的地址

但是有2个例外

  1. sizeof(数组名):数组名表示整个数组,计算的是整个数组的大小,单位是字节
  2. &数组名:数组名表示整个数组,取出的是整个数组的地址,如&arr,当&arr+1时,打印的是相隔arr数组大小的地址

除此之外,所有的数组名都是数组首元素的地址

二:指针的大小:32位平台下都是4字节,64位平台下都是8字节

三: strlen -函数:求字符串长度的,找’\0’之前出现的字符个数;sizeof -操作符:算变量/类型所占内存大小,单位是字节

strlen函数原型:size_t strlen ( const char * str ); 参数是指向字符类型的指针

记住上面的规则后,让我们开始吧~

int a[ ] = { 1,2,3,4 }; //4*4=16

printf( "%d\n", sizeof(a)) ;	//16	整个数组的大小是16

printf("%d\n", sizeof(a + 0));	/*4或8 	a + 0是第一个元素的地址,sizeof(a + 0)计算的是地址的大小,sizeof后面跟的不是单										  个a,就不是一整个数组*/

printf ("%d\n", sizeof(*a));	//4		*a是数组的第一个元素,sizeof(*a)计算的是第一个元素的大小

printf ("%d\n", sizeof(a + 1));	//4或8	a + 1是第二个元素的地址,sizeof(a+1)计算的地址的大小

printf ( "%d\n", sizeof(a[1]));	//4 	计算的是第二个元素的大小
printf ("%d\n", sizeof(&a));		//4/8 	    &a取出的是整个数组的地址,但也是地址,计算的是一个地址的大小

printf ( "%d\n", sizeof(*&a));		//16	    先取出整个数组的地址,再解引用,得到的还是整个数组,计算的数组的大小

printf ("%d\n", sizeof(&a + 1)); 	/*4/8		&a得到一整个数组的地址,+1后跳过一整个数组,是数组最后一个元素后面的												 空间的地址*/
printf ( "%d\n", sizeof(&a[0]));	//4/8		第一个元素的地址

printf ( "%d\n", sizeof(&a[0] + 1));	//4/8	 第二个元素的地址

char arr[ ]= { ‘a’, ‘b’,‘c’, ‘d’ , ‘e’, ‘f’ };

printf ("%d\n", sizeof(arr));	 	//6			整个数组的大小为6

printf ("%d\n", sizeof(arr + 0));	//4/8		首元素地址+0还是地址

printf ("%d\n", sizeof(*arr));		//1		首元素地址解引用得到字符a,大小是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	&arr[0]是第一个元素的地址,+1后是第二个元素的地址
printf("%d\n",strlen(arr));		//随机值,从首元素地址开始找,strlen会一直找到'\0'为止

printf ("%d\n", strlen(arr + 0));	//随机值,首元素地址加0还是首元素地址

printf ("%d\n", strlen(*arr));	/*error,首元素地址解引用得到的是字符'a',ASCII码值是97,而strlen函数的参数是(char* 									str),接收的是地址*/

printf ("%d\n", strlen(arr[1]));	//error,同理,把字符'b'传过去也是出错

printf ("%d\n", strlen(&arr));		/*随机值,取一整个数组的地址传给strlen函数时,也会被强制类型转换为char*类型,也是从首									元素地址开始找起*/

printf ("%d\n", strlen(&arr + 1));	/*随机值-6,取一整个数组地址后+1,就跳到了该数组最后一个元素的后一个地址,相比从首元素开始找,此时直接跳过了数组的长度,所以要-6,但找的结果仍然是随机值*/

printf ("%d\n", strlen(&arr[0]+ 1));	/*随机值-1,取首元素的地址后+1,得到第二个元素的地址,跳过了一个元素长度,所以要-1;*/

char arr[ ]= “abcdef” ;

内存存放形式:[a b c d e f \0]

printf ("%d\n", sizeof(arr));		//7		双引号""默认在最后加上'\0',sizeof会把'\0'也算上

printf ("%d\n", sizeof(arr + 0));	//4/8	首元素地址+0还是地址

printf ("%d\n", sizeof(*arr));		//1		首元素地址解引用得到字符'a','a'的大小

printf ("%d\n", sizeof(arr[1]));	//1		字符'b'的大小

printf ("%d\n", sizeof(&arr));		//4/8		取一整个数组的地址

printf ("%d\n", sizeof(&arr + 1));	//4/8		跳过一整个数组后还是地址

printf ("%d\n", sizeof(&arr[0]+ 1));		//4/8		第二个元素的地址
printf ("%d\n", strlen(arr));		//6		strlen从首元素开始向后检索字符,遇到'\0'就停下,不包括'\0'

printf ("%d\n", strlen(arr + 0));	//6		首元素地址+0还是从首元素开始检索

printf ("%d\n", strlen(*arr));		//error

printf ("%d\n", strlen(arr[1]));	//error

printf ("%d\n", strlen(&arr));		//6		  一整个数组的地址,传给strlen也是从首地址开始

printf ("%d\n", strlen(&arr + 1));	//随机值	 取出一整个数组的地址后+1,跳过一整个数组,跳到'\0'的后一个地址,开始检索时不知什么时候会找到'\0'

printf ("%d\n", strlen(&arr[0] + 1));	//5	从第二个元素开始找

实战例子2

char* p = “abcdef” ;

指针p指向一块连续的常量空间,[a b c d e f \0]

printf ("%d\n", sizeof(p));			//4/8		求的是p指针的大小

printf ("%d\n", sizeof(p + 1));		//4/8		p指向的是字符a的地址,+1就指向字符b的地址,终究还是地址

printf ("%d\n", sizeof(*p));		//1			p指针解引用得到字符a,大小为1

printf ("%d\n", sizeof(p[0]));		//1			p[0] == *(p+0),得到字符a,大小为1

printf ("%d\n", sizeof(&p));		//4/8		取指针p自己的地址

printf("%d\n", sizeof(&p + 1));		//4/8		跳过一个p的地址,即指针p的后一块地址空间

printf("%d\n", sizeof(&p[0] + 1));	//4/8		&p[0]得到第一个元素的地址,+1得到第二个元素的地址
printf("%d \n", strlen(p));			//6	

printf ("%d \n", strlen(p + 1));	//5		p指向第一个字符地址,+1后指向第二个字符地址

printf ("%d\n", strlen(*p));		//error

printf ("%d\n", strlen(p[0]));		//error

printf ("%d\n", strlen (&p));		//随机值	取p指针自身的地址,因为p占4/8个字节,从首字节开始找,不知何时才找到'\0'

printf ("%d \n", strlen (&p + 1));		//随机值	从p指针最后一个字节的后一个地址开始找,也不知何时找到'\0',因为不确定p指针中有没有'\0',所以这个随机值并没有-1,跟上一个随机值没有联系

printf ("%d\n", strlen ( &p[0] + 1));	//5		从第二个元素开始找

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

a[0]:第一行一维数组的数组名

a[1]:第二行一维数组的数组名

a[2]:第三行一维数组的数组名

printf ("%d\n", sizeof(a)) ;		//48	3*4*sizeof(int),sizeof里是单独的二维数组名,就表示一整个二维数组的大小

printf ("%d\n", sizeof(a[0][0]));		//4	 第一行第一个元素值,整型元素大小是4

printf ("%d\n", sizeof(a[0]));		//16	a[0]表示整个第一行,数组名a[0]单独放在sizeof内部,sizeof(a[0])计算的就是第一行一维数组的大小!

printf ("%d\n", sizeof(a[0]+ 1));		//4/8		a[0]作为数组名并没有单独出现在sizeof内,也没取地址,所以a[0]就是第一行第一个元素的地址,a[0]+1就是第一行第二个元素的地址

printf ("%d\n", sizeof(*(a[0] + 1)));		//4		第一行第二个元素值

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

printf ("%d\n", sizeof(*(a + 1)));		//16		因为*(a+1) == a[1],a[1]表示的是第二行的地址,由因为sizeof(a[1])是单独放在sizeof内部的,表示第二行一整个一维数组的地址,所以求的是一整个一位数组的大小

printf ("%d\n", sizeof(&a[0] + 1));		//4/8	&a[0]+1 == a+1	a[0]是第一行的数组名,&a[0]取出的是第一行整个一维数组的地址,+1后就是第二行整个一维数组的地址

printf ("%d\n", sizeof(*(&a[0]+ 1)));	//16	*(&a[0]+1) == *(a+1)	&a[0]+1得到的就是第二行整个一维数组的地址,解引用得到一整个第二行一维数组,所以大小是16

printf ("%d\n", sizeof(*a));		//16		*a == *(a+0) == a[0],a是二维数组的数组名,并没有取地址,也没有单独放在sizeof内,表示第一行的地址,等于第一行数组名单独放到sizeof中,相当于求第一行整个一维数组的大小

printf ("%d\n", sizeof(a[3]));		//16		a[3]的类型是 int [4],其实是第四行的数组名(如果有的话),此时sizeof并不会真正去访问a[3]的地址,只是根据其类型计算出大小,sizeof()内部的表达式是不算的!	比如表达式:3+5	具有:1.值属性 -> 8	2.类型属性 -> int,sizeof就是推测出类型属性从而计算大小的
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值