关于sizeof和strlen和数组

能清楚的认识sizeof和strlen与数组间的关系对我们学习C语言有很大的帮助,这两者看似简单,实则也大有讲究。

举个例子:int a[3]={1,2,3};   求sizeof(a)   很简单对吧,a是整形数组,所以sizeof(a)=3*4=12。

那下面这两个呢?

sizeof(a+0);
sizeof(*a);

这两者的结果又是什么呢?相信有些小白们已经蒙了吧。其实这里就很考验我们对于数组名和指针的理解。先给出答案:sizeof(a+0)=4/8(这里求的是指针类型的大小),sizeof(*a)=4(这里求的是整形的大小)接下我们来仔细探讨一下它们之间的关系:

数组名

关于数组名,通常情况下,它代表首元素的地址,比如数组名a代表a[0]元素的地址,数组名c代表字符'a'元素的地址。

int a[3]={1,2,3};
char c[3]="abc";

但重点是它的两个特殊情况:

1、在sizeof内部,如sizeof(a)它求的是整个数组的大小,此时数组名a代表整个数组

2、&a 此时a也表示整个数组,因为它取的是整个数组的地址

此时有人疑问,取整个数组的地址不还是首元素的地址吗??表面理解是这样,但当我们对它进行这样的操作时,它会报错,此时它不是一个整形指针,而是整形数组指针。

应该用数组指针赋值:

虽然它们指针内容一样,但类型实实在在的从整形指针变为数组指针。
ok,总结一下,两个特殊情况:

1、sizeof(数组名)(这里的数组名一定要是单独存在,任何其它的内容都会更改其特殊意义)

2、&数组名

所以sizeof(a+0)里面的a已经不属于特殊情况了,a不是单独存在,a还是通常情况的首元素地址,a+0还是首元素的地址,sizeof(地址)只能等于4或8,这取决于系统是64位还是32位(详情请看我的另一篇文章:从CPU对内存数据访问的角度来让你彻底明白什么是指针),同理sizeof(*a)也不属于特殊情况它等同于sizeof(a[0]),计算的是整形的大小4。

既然sizeof(a)计算的是a数组的大小,那么sizeof(&a)呢?前面我们说&a属于一种特殊情况,也指的是整个数组的地址,那么sizeof(&a)计算的也是整个数组的大小??肯定不是。&a虽然取的是整个数组的地址,但它也是一种地址,地址的大小就是4/8,所以sizeof(&a)的大小就是4/8。

sizeof

关于sizeof,你需要知道的是:

1、它是一个操作符

2、sizeof计算操作数所占内存的大小,单位是字节。

3、sizeof不关注内容中放什么数据

关于第三点我们要时刻牢记,比如:

虽然a[100]越界,但并没有报错,以及:

可以看出sizeof(a=b+4)仅仅计算了short类型a(short类型的大小为2)的大小,且a的值不变。这是sizeof的一个非常重要的特殊性质,一定要牢记。

strlen

首先,strlen是一个函数,不是操作符,它的声明:

size_t strlen(const char* p);

我们都知道strlen能够求出字符串的长度,但你是否知道一些细节上的问题呢?

 比如:

char ch[3]={'a','b','c'};

此时你知道strlen(ch)等于多少吗??其实我也不知道,因为它是一个随机数。

那么:

char chh[3]="abc";

此时的strlen(chh)等于多少??strlen(*chh)又等于多少???

要想弄清上面的问题,需要知道strlen的三个特性:

1、strlen是库函数,传入的参数是地址,使⽤需要包含头⽂件 string.h
2、srtlen是求字符串⻓度的,统计的是 \0 之前字符的隔个数
3、关注内存中是否有 \0 ,如果没有 \0 ,就会持续往后找,可 能会越界
根据2和3我们知道strlen会持续寻找\0,所以当 char ch[3]={'a','b','c'}; 里面存的是一个个字符时,\0并不会默认的跟在字符后面,所以strlen(ch) (ch是数组首元素字符'a'的地址)中找不到\0就会持续往后找\0,这时的strlen的停止寻找就是随机的,因为内存分配是随机的,什么时候遇到\0也是随机的。
而chh中的是字符串,串的结尾默认有\0,所以strlen(chh)结果为3。
而根据1特性,strlen接收的参数是地址,因此strlen(*chh)和str(*ch)解引用后的字符都会被转换为ASC码并当成地址,此时就会报错:
所以:
strlen(ch) = 随机数
strlen(chh) = 3
strlen(*chh) 和strlen(*ch) 报错               
综上,strlen和sizeof对数组的操作不只是表面上的定义那么简单,我们刚学时会感觉它们之间的规则有些复杂,但实际理解一些关键特性后,很多代码都会迎刃而解。这里只是讲了一维数组,还有二维数组,它的sizeof应用也有很多讲究,但万变不离其宗,理解好本篇内容,二维数组也不在话下。如果帮到你,请点个赞,谢谢啦(:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值