C语言数组进阶-数组名的理解和计算

在之前我们关于数组的内容中,我们已经提出了关于数组名的理解

一般情况下,数组名是数组首元素的地址,但有两个例外:

1.sizeof(数组名)是计算整个数组的大小 2.&数组名是取出的整个数组的地址

sizeof不管后面是啥,只判断这个东西的长度

整型数组

现在给出我们这样的一个数组,然我们进行相关的判断

int a[] = { 1,2,3,4 };
	printf("%zd\n", sizeof(a));        //1
	printf("%zd\n", sizeof(a + 0));    //2
	printf("%zd\n", sizeof(*a));        //3
	printf("%zd\n", sizeof(a + 1));      //4
	printf("%zd\n", sizeof(a[1]));    //5
	printf("%zd\n", sizeof(&a));        //6
	printf("%zd\n", sizeof(*&a));        //7
	printf("%zd\n", sizeof(&a + 1));       //8
	printf("%zd\n", sizeof(&a[0]));    //9
	printf("%zd\n", sizeof(&a[0] + 1));        //10

式子一:sizeof+数组,整个数组的长度,单位是字节,因此是4 * 4 = 16

式子二:并不是sizeof中只有数组,因此此时是数组首元素的地址,+0还是首元素的地址,地址的字节是4/8

式子三:a是首元素地址,*a是首元素,大小4

式子四:第二个元素的地址,4/8

式子五:a[1]是第二个元素,4

式子六:取出的是数组的地址,4/8

式子七:取出了数组的地址,解引用后是整个数组a,因此是16

式子八:取出整个数组的地址,跳过这个数组后的地址,4/8

式子九:取出首元素的地址,4/8

式子十:取出第二个元素的地址,4/8

字符串数组(一)

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

这个数组只有六个元素

式子一:整个数组的长度,1 * 6 = 6

式子二:第一个元素的地址,4/8

式子三:arr是一个元素的地址,*arr是第一个元素,是char类型,1

式子四:第二个元素,1

式子五:取出整个数组的地址,地址的大小是4/8

式子六:取出整个数组的地址,跳过了一个数组,4/8

式子七:取出第二个元素的地址,4/8

那么,对于strlen呢?

strlen是判断字符串长度的,是从括号里的地址开始,直到\0位置为止

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

式子一:arr代表数组首元素的地址,由于无\0,故是随机值

式子二:数组首元素的地址,随机值

式子三:数组的首元素,'a'- -> 97,相当于取97地址,err,读取位置访问冲突,报错

式子四:数组的第二个元素,'b'-->98,err

式子五:取出整个数组的地址,数组的地址就是首元素的地址,随机值

式子六:跳过一个数组以后的地址,随机值

式子七:从第二个元素的地址开始,随机值

那么对于另一种字符串数组呢?

字符串数组(二)

char arr[] = "abcdef";
	printf("%d\n", sizeof(arr));    //1
	printf("%d\n", sizeof(arr + 0));        //2
	printf("%d\n", sizeof(*arr));    //3
	printf("%d\n", sizeof(&arr));    //4
	printf("%d\n", sizeof(&arr+1));    //5
	printf("%d\n", sizeof(&arr[0]+1));    //6

式子一:计算数组的长度,不要忘记隐藏的\0,7

式子二:数组首元素的地址,大小4/8

式子三:arr是数组的首元素地址,*arr是数组的首元素,char类型,1

式子四:取出整个数组的地址,大小4/8

式子五:跳过一个数组后的地址,4/8

式子六:第二个元素的地址,4/8


char arr[] = "abcdef";
printf("%d\n", strlen(arr));    //1
printf("%d\n", strlen(arr+0));        //2
printf("%d\n", strlen(*arr));    //3
printf("%d\n", strlen(arr[1]));        //4
printf("%d\n", strlen(&arr));    //5
printf("%d\n", strlen(&arr+1));    //6
printf("%d\n", strlen(&arr[0]+1));        //7

式子一:长度为6

式子二:首元素的地址,向后数,也是6

式子三:*arr代表首元素,'a'-->97,err

式子四:数组的第二个元素,'b'-->98,err

式子五:取出arr的地址,6

式子六:跳过一个数组后的地址,随机值

式子七:从第二个元素开始的地址,计算5

字符串数组(三)

char* p = "abcdef"; 
printf("%d\n", sizeof(p));//p是指针变量,计算的指针变量的大小,4/8字节
printf("%d\n", sizeof(p + 1));//'b'的地址,4/8
printf("%d\n", sizeof(*p));//p的类型是char*,*p是char,a,1
printf("%d\n", sizeof(p[0]));//p[0]-->*(p+0)-->*p-->'a',1
printf("%d\n", sizeof(&p));//取出的是p的地址,4/8
printf("%d\n", sizeof(&p + 1));//跳过p指针变量后的地址,是4/8
printf("%d\n", sizeof(&p[0] + 1));//第二个元素的地址

式子一:p是指针变量,计算指针变量的大小,4/8

式子二:'b'的地址,4/8

式子三:p是指针,*p是a,大小1

式子四:a,大小是1

式子五:p是指针,&p是二级指针,也是指针,4/8

式子六:跳过p后的地址,4/8

式子七:第二个元素的地址

char* p = "abcdef";
printf("%d\n", strlen(p));//6
printf("%d\n", strlen(p + 1));//5
printf("%d\n", strlen(*p));//97,err
printf("%d\n", strlen(p[0]));//err
printf("%d\n", strlen(&p));//&p是指针变量p的地址,与字符串"abcdef"关系不大
//从p这个指针变量起始位置开始数的,p的地址是什么不知道,随机值
printf("%d\n", strlen(&p + 1));//随机值
printf("%d\n", strlen(&p[0] + 1));//5

式子一:p是指针变量,指向a的位置,6

式子二:指向b,5

式子三:*p是字符a-->97,err

式子四:也是字符a

式子五:二级指针,不清楚大小,随机值

式子六:二级指针后跳过p,随机值

式子七:从第二个元素地址开始计算,5

二维数组

int a[3][4] = { 0 };
printf("%d\n", sizeof(a));//a是数组名,单独放在sizeof内部,计算数组大小48
printf("%d\n", sizeof(a[0][0]));//第一行的第一个元素,4个字节
printf("%d\n", sizeof(a[0]));//第一行的数组名,数组名单独放在sizeof,计算数组大小,16
printf("%d\n", sizeof(a[0] + 1));//a[0]并没有单独放在内部,这里的a[0]是数组的首元素地址
								//等价于&a[0][0],+1后是a[0][1]的地址,4/8
printf("%d\n", sizeof(*(a[0] + 1)));//第一行第二个元素,4
printf("%d\n", sizeof(a + 1));//a作为数组没有单独放在内部,a表示数组首元素地址
							//二维数组首元素的地址就是第一行的地址,跳过一行指向第二行
							//a+1是数组指针,指针大小4/8	
printf("%d\n", sizeof(*(a + 1)));//*(a + 1)代表第二行 - 16
									//*(a + 1) == a[1],是第二行的数组名
printf("%d\n", sizeof(&a[0] + 1));//a[0]是第一行数组名,&a[0]第一行的地址,
								  //+1,跳过第一行,第二行的地址,4/8个字节
printf("%d\n", sizeof(*(&a[0] + 1)));//第二行,*(&a[0] + 1) == *(a + 1),16
printf("%d\n", sizeof(*a));//a代表第一行的地址,*a代表第一行,16
printf("%d\n", sizeof(a[3]));//a[3]无需真实访问,仅仅通过类型的推断就能算出长度
							//a[3]是第四行的数组名,大小单独放在sizeof内部,计算第四行的大小,16

式子一:计算整个数组的大小 4 * 12

式子二:计算第一行首元素,int类型,4

式子三:a[0]代表第一行,可以理解为一维数组,大小是16

式子四:a[0]代表的是地址,+1后也是地址,4/8

式子五:第一行第二个元素,4

式子六:第二行的地址,4/8

式子七:第二行,4 * 4 = 16

式子八:第二行的地址,4/8

式子九:第二行,16

式子十:第一行,16

式子十一:被认为了第四行,尽管没有,但不会实际运算,只会根据他的类型 int [4]判断出这一行可能是4个元素,大小是16

感谢您的观看

总结

sizeof + 地址 = 4/8

strlen一般来说只能加地址

  • 35
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值