前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >C语言-数组名与&数组名的细节注意

C语言-数组名与&数组名的细节注意

作者头像
HABuo
发布2024-11-19 18:28:11
发布2024-11-19 18:28:11
8700
代码可运行
举报
运行总次数:0
代码可运行

这篇博客将通过整型数组、字符数组、字符串放在数组中、以及二维数组的数组名与&数组名和各类特殊情况的题目讲解来使得我们对于指针与数组名具有更加深刻的了解。

注意:

sizeof(数组名) - 数组名表示整个数组的-计算的是整个数组的大小 &数组名 - 数组名表示整个数组,取出的是整个数组的地址 除此之外,所有的数组名都是数组首元素的地址 !!!


1.整型数组

代码语言:javascript
代码运行次数:0
复制
//sizeof(数组名) - 数组名表示整个数组的-计算的是整个数组的大小
//&数组名 - 数组名表示整个数组,取出的是整个数组的地址
//除此之外,所有的数组名都是数组首元素的地址
int a[] = {1,2,3,4};
printf("%d\n",sizeof(a));//16 - sizeof(数组名),计算的是整个数组的大小因此结果为:16
printf("%d\n",sizeof(a+0));//4/8 - 不是数组名,因此表示的是数组首元素的地址的大小
                           //因此64位平台是8,32位平台是4
printf("%d\n",sizeof(*a));//4 - a表示首元素的地址解引用访问的一个元素int
printf("%d\n",sizeof(a+1));//4/8 - 表示的是数组第一个元素的地址的大小
printf("%d\n",sizeof(a[1]));//4 - 第二个元素的大小

printf("%d\n",sizeof(&a));//4/8 - &a虽然数组的地址,但是也是地址,sizeof (&a)计算的是一个地址的大小
printf("%d\n",sizeof(*&a));//16 - 计算的数组的大小
printf("%d\n",sizeof(&a+1));//4/8 - &a + 是数组后面的空间的地址
printf("%d\n",sizeof(&a[0]));//4/8 - 第一个元素的地址的大小
printf("%d\n",sizeof(&a[0]+1));//4/8 - 第二个元素的地址的大小

2.字符数组 

代码语言:javascript
代码运行次数:0
复制
char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", sizeof(arr));//6
printf("%d\n", sizeof(arr+0));//4/8
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

printf("%d\n", strlen(arr));//随机值 - strlen是找'\0',而此时数组里面没有存放'\0',必然会访 
                            //问数组后面的内容
printf("%d\n", strlen(arr + 0));//随机值
printf("%d\n", strlen((const char*) *arr));//err
printf("%d\n", strlen((const char*) arr[1]));//err
printf("%d\n", strlen((const char*) &arr));//随机值
printf("%d\n", strlen((const char*) (&arr + 1)));//随机值-6
printf("%d\n", strlen(&arr[0] + 1));//随机值-1

printf("%d\n", strlen((const char*) *arr)); //err printf("%d\n", strlen((const char*) arr[1]));//err

*arr找到了数组中的'a',而'a'的Ascll码表值是97,而strlen函数会把97看成地址,97的16进制便是0x00000061,便出现如上图所示的错误。arr[1]也是同样的道理


3.字符串放在数组中

代码语言:javascript
代码运行次数:0
复制
char arr[] = "abcdef";
printf("%d\n", sizeof(arr));//7,该种方式数组里面存放的是:[a b c d e f \0]
printf("%d\n", sizeof(arr+0));//4/8
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

printf("%d\n", strlen(arr));//6 [a b c d e f \0]
printf("%d\n", strlen(arr+0));//6
printf("%d\n", strlen(*arr));//err
printf("%d\n", strlen(arr[1]));//err
printf("%d\n", strlen((const char*) &arr));//6
printf("%d\n", strlen((const char*) (&arr+1)));//随机值
printf("%d\n", strlen(&arr[0]+1));//5

代码语言:javascript
代码运行次数:0
复制
char *p = "abcdef";//这是把a的地址放在了指针变量p中
 printf("%d\n", sizeof(p));//4/8
 printf("%d\n", sizeof(p+1));//4/8
 printf("%d\n", sizeof(*p));//1
 printf("%d\n", sizeof(p[0]));//1
 printf("%d\n", sizeof(&p));//4/8
 printf("%d\n", sizeof(&p+1));//4/8
 printf("%d\n", sizeof(&p[0]+1));//4/8

 printf("%d\n", strlen(p));//6
 printf("%d\n", strlen(p+1));//5
 printf("%d\n", strlen(*p));//err
 printf("%d\n", strlen(p[0]));//err
 printf("%d\n", strlen(&p));//随机
 printf("%d\n", strlen(&p+1));//随机
 printf("%d\n", strlen(&p[0]+1));//5

 我们不但要知道结果是什么更应该知道它所对应的空间及其地址,如下所示:

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

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

 这两个随机值不存在联系,因为P中所存放的地址不确定,如:0x11223344,那这两个随机值便差了四个字节,但如果是0x11220044,\0在地址中出现那么&P便是两个字节,所以这两个随机值不存在必然的联系。


 4.二维数组

代码语言:javascript
代码运行次数:0
复制
int a[3][4] = {0};
 printf("%d\n",sizeof(a));//48 - 数组名放在sizeof内部表示整个数组,因此3*4*4=48
 printf("%d\n",sizeof(a[0][0]));//4
 printf("%d\n",sizeof(a[0]));//16 - a[0]可以看成二维数组中的第一行的“一维数组”的数组名
                             //因此也便是第一行的“一维数组”的数组名放在了sizeof内部
 printf("%d\n",sizeof(a[0]+1));//4/8 - a[0]+1是二维数组中的第一行的第二个元素的地址
 printf("%d\n",sizeof(*(a[0]+1)));//4 - 计算的是a[0]+1是二维数组中的第一行的第二个元素的大小
 printf("%d\n",sizeof(a+1));//4/8 - a表示二维数组的首元素地址,即第一行的“一维数组”的地址
                            //则a+1表示第二行的“一维数组”的地址
 printf("%d\n",sizeof(*(a+1)));//16 - 计算的是第二行的“一维数组”的大小
 printf("%d\n",sizeof(&a[0]+1));//4/8 - &a[0]取出的是二维数组中的第一行的“一维数组”的地址
                                //则&a[0]+1表示第二行的“一维数组”的地址
 printf("%d\n",sizeof(*(&a[0]+1)));//16 - 计算的是第二行的“一维数组”的大小
 printf("%d\n",sizeof(*a));//16 - 第一行的“一维数组”的大小
 printf("%d\n",sizeof(a[3]));//16 - a[3]其实是第四行的数组名 (如果有的话)
                             //所以其实不存在,也能通过类型计算大小的

在上述二维数组中比较难以理解的便是 a[0] 、 a+1 、&a[0]+1 、a[3],下面对其进行讲解:

对于二维数组如果把每一行都看作成一个一维数组那么a[0]就可以看作成一维数组的数组名,所以a[0]在sizeof(数组名)与&数组名情况之外下表示的是第一行的首元素的地址,&a[0]也就是取出的是第一行的一维数组的地址。

对a这个二维数组的数组名,它依然在sizeof(数组名)与&数组名情况之外下就表示首元素的地址,但是对于二维数组数组名所表示的首元素就是第一行。

对于a[3],这一空间随超出了我们所定义的二维数组的空间,但是sizeof内部是不参与运算的,因此也便不会产生越界访问的情况,至于16的计算是因为,sizeof所计算的是类属性,是按照一维数组的属性进行计算。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-08-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.整型数组
  • 2.字符数组 
  • 3.字符串放在数组中
  •  4.二维数组
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档