数组名、strlen、sizeof的详细讲解看完足以掌握和区分他们。

文章详细阐述了在C语言中,数组名在不同情况下的含义,以及sizeof和strlen函数的区别。数组名通常代表数组的首元素地址,但在sizeof运算中表示整个数组的大小。strlen函数用于计算字符串长度,必须以终止。在不同平台和数据类型中,指针的大小也有所不同。此外,还通过示例解释了二维数组的处理方式。
摘要由CSDN通过智能技术生成

要彻底搞清楚数组名在不同情况下所代表的含义和strlen、sizeof的区别我们首先要明白以下几点点:

重点!!!!!!!!!!!

重点!!!!!!!!!!!

重点!!!!!!!!!!!
1.**sizeof(数组名)**这种形式下只有数组名单独放在括号里时,数组名表示的是整个数组,sizeof计算的是整个数组的大小;
2.**&数组名**这种形式下数组名表示的是整个数组,取地址取出的是整个数组的地址,虽然数组的首元素的地址和数组的首地址相同但是两个所代表的意义不同;

除了上面1和2这两种特殊情况外所有的数组名都是数组首元素的地址


3.**二维数组中首元素是二维数组中的第一个一维数组**;例如arr[3][4]这个二维数组的首元素就是arr[0];

4.在32为平台上指针大小为4,在64位平台上指针大小为8;

5.strlen是函数,只能计算从char类型的大小遇到'\0'才能停止,而sizeof是关键字也是运算符,可以计算任何类型的大小;

6.在sizeof中的表达式是不计算的;


下面我通过一些典型的例子来说明:
在一维数组中:

int a[] = {1,2,3,4};
printf("%d\n",sizeof(a));//16-----这里数组名单独放在sizeof中表示的是整个数组,计算整个数组的大小;
printf("%d\n",sizeof(a+0));//4/8----这里sizeof括号里面放的是a+0,虽然计算后还是a但是数组名没有单独一个放在sizeof内所以表示的不是整个数组,而代表的是数组首元素地址,在32为平台上指针大小为4,在64位平台上指针大小为8;
printf("%d\n",sizeof(*a));//4-------这里a是数组首元素的地址,对*a是数组第一个元素a[0],计算的是a[0]的大小;
printf("%d\n",sizeof(a+1));//4/8-----这里a是数组首元素的地址,a+1是数组第二个元素的地址;
printf("%d\n",sizeof(a[1]));//4------a[1]是数组二个元素,这里计算的是第二个元素的大小;
printf("%d\n",sizeof(&a));//4/8-----&a取出的是整个数组的地址,是地址那么大小就位4/8;
printf("%d\n",sizeof(*&a));//16-----&a取出的是整个数组的地址,*&a是整个数组,计算的是整个数组的大小,&和*相当于抵消了;
printf("%d\n",sizeof(&a+1));//4/8-----&a取出的是整个数组的地址,&a+1是数组后面的地址,但是还是地址则大小就位4/8;
printf("%d\n",sizeof(&a[0]));//4/8----&a[0]取出的是数组首元素的地址;
printf("%d\n",sizeof(&a[0]+1));4/8----&a[0]+1取出的是数组第二个元素的地址;

在字符数组中:

char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", sizeof(arr));//6------这里数组名单独放在sizeof中表示的是整个数组,计算整个数组的大小;
printf("%d\n", sizeof(arr+0));//1-----这里sizeof括号里面放的是arr+0,虽然计算后还是arr但是数组名没有单独一个放在sizeof内所以表示的不是整个数组,而代表的是数组首元素地址,在32为平台上指针大小为4,在64位平台上指针大小为8;
printf("%d\n", sizeof(*arr));//1-----这里arr是数组首元素的地址,对*arr是数组第一个元素arr[0],计算的是arr[0]的大小;
printf("%d\n", sizeof(arr[1]));//1------arr[1]是数组二个元素,这里计算的是第二个元素的大小;
printf("%d\n", sizeof(&arr));//4/8-----&arr取出的是整个数组的地址,是地址那么大小就位4/8;
printf("%d\n", sizeof(&arr+1));//4/8---&arr取出的是整个数组的地址,&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));//随机值----这里arr是数组首元素地址,strlen是有遇到'\0'才会停下来,因为不知道后面何时才会遇到所以是随机的;
printf("%d\n", strlen(*arr));//err-----strlen函数的形参是一个指针,将数组元素传给strlen函数时是不合法的;
printf("%d\n", strlen(arr[1]));//err-----strlen函数的形参是一个指针,将数组元素传给strlen函数时是不合法的;
printf("%d\n", strlen(&arr));//随机值---&arr取出的是整个数组的地址,strlen是有遇到'\0'才会停下来,因为不知道后面何时才会遇到所以是随机的;
printf("%d\n", strlen(&arr+1));//随机值-6 -----这里&arr是数组的首地址,&arr+1跳过的是整个数组,strlen是有遇到'\0'才会停下来,因为不知道后面何时才会遇到所以是随机的,但是与上面一个随机值差6;
printf("%d\n", strlen(&arr[0]+1));//随机值-1 ------&arr[0]+1取出的是数组第二个元素的地址
char arr[] = "abcdef";//这里有字符串的结束标志'\0';
printf("%d\n", sizeof(arr));//7---arr表示的是整个数组,计算的是整个数组的大小,但是这里'\0'也要计算在里面;
printf("%d\n", sizeof(arr+0));//4/8---arr没有单独放在sizeof中所以表示的是数组首元素的地址;
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----arr表示的是数组首元素的地址,strlen遇到字符串结束标志就会停下来;
printf("%d\n", strlen(arr+0));//6
printf("%d\n", strlen(*arr));//err
printf("%d\n", strlen(arr[1]));//err
printf("%d\n", strlen(&arr));//6
printf("%d\n", strlen(&arr+1));//随机值----&arr取出的是整个数组的地址,&arr+1后跳过整个数组,何时遇到'\0'是未知的;
printf("%d\n", strlen(&arr[0]+1));//5

在字符指针中:

char *p = "abcdef";//字符指针p中存放的是字符出串首字符的地址;
printf("%d\n", sizeof(p));//4/8---这里的p指针,所以大小是4/8;
printf("%d\n", sizeof(p+1));//4/8----p中存放的是字符出串首字符的地址,p+1之后指向第二个字符,还是地址;
printf("%d\n", sizeof(*p));//1-----*p就是第一个字符,计算的是第一个字符的大小;
printf("%d\n", sizeof(p[0]));//1----p[0]是等价与*p的,所以计算的是第一个字符的大小;
printf("%d\n", sizeof(&p));//4/8----这里的p指针,&p取出的是指针p的地址,所以大小为4/8;
printf("%d\n", sizeof(&p+1));//4/8-----&p+1还是地址,所以大小为4/8;
printf("%d\n", sizeof(&p[0]+1));//4/8----&p[0]是字符串中字符b的地址;
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));//随机值------&p取出的是指针p的地址,strlen何时遇到'\0'是未知的;
printf("%d\n", strlen(&p+1));//随机值----&p取出的是指针p的地址再加1,何时strlen何时遇到'\0'也是未知的,但是与上一个随机值之间毫无关系;
printf("%d\n", strlen(&p[0]+1));//5

在二维数组中:

int a[3][4] = {0};//二维数组的首元素是a[0];
printf("%d\n",sizeof(a));//48-------数组名单独放在是sizeof中表示整个数组,计算的是整个数组的大小;
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]是二维数组第一行的数组名,但是它没有单独放在sizeof中,所以表示的是第一行的第二个元素即a[0][0]的地址;
printf("%d\n",sizeof(*(a[0]+1)));//4----*(a[0]+1)第一行的第二个元素,计算的是第一行的第二个元素的大小;
printf("%d\n",sizeof(a+1));//4/8------a没有单独放在sizeof中所表示的是第一行的地址,a+1是第二行的地址,是地址所以大小为4/8;
printf("%d\n",sizeof(*(a+1)));//16----a+1是第二行的地址,所以*(a+1)计算的就是整个第二行的大小;
printf("%d\n",sizeof(&a[0]+1));//4/8----&a[0]取出的是第一行的地址,&a[0]+1就是第二行的地址;
printf("%d\n",sizeof(*(&a[0]+1)));//16----&a[0]+1是第二行的地址,*(&a[0]+1)就是整个第二行,计算的是整个第二行的大小;
printf("%d\n",sizeof(*a));//16----a数组名没有单独放在是sizeof中表示数组第一行的地址,*a就是整个第一行,计算的是第一行的大小;
printf("%d\n",sizeof(a[3]));//16-----根据类型属性,两个属性一个是值属性:int a=2+3;就体现的值属性;类型属性:int a;是int 类型就体现类型属性,在sizeof中的表达式是不计算的,所以在这里a[3]是不会去越界访问的,直接根据数组的类型推断出a[3];

在sizeof中的表达式是不计算的例子:

#include<stdio.h>
int main()
{
     int a=4;
     short b=3;
    printf("%d",sizeof(b=a+3));//2
    printf("%d",b);//3
    return 0;
}

在sizeof中的表达式b=a+3没有进行计算;

总结:要牢记数组名代表的意义!!!!!!!

数组名的意义:
1. sizeof( 数组名 ) ,这里的数组名表示整个数组,计算的是整个数组的大小。
2. & 数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
3. 除此之外所有的数组名都表示首元素的地址。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

只会写bug,不会改bug

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

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

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

打赏作者

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

抵扣说明:

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

余额充值