1. sizeof和strlen的对⽐?
1.1sizeof
讲解之前我们先来温习一个知识点:数组名的理解
数组名是首元素的地址但是有两个列外:
1. sizeof(数组名),这里的数组名表示整个数组,sizeof(数组名)计算的是整个数组的大小,单位是字节。
2. &数组名,这里的数组名表示整个数组,&数组名取出的是数组的地址。
1.1 sizeof?
在学习操作符的时候,我们学习了 sizeof , sizeof 计算变量所占内存内存空间⼤⼩的,单位是
字节,如果操作数是类型的话,计算的是使⽤类型创建的变量所占内存空间的⼤⼩。
sizeof 只关注占⽤内存空间的⼤⼩,不在乎内存中存放什么数据。
我们使用代码为大家解释
#include<stdio.h>
int main()
{
//一维数组
int a[]={ 1,2,3,4 }; //4个元素,每个元素是int类型(4个字节) 共16个字节
printf(%d\n" ,sizeof(a));
// 数组名a单独放在sizeof内部,数组名表示整个数组,计算整个数组大小,共16个字节。
printf(%d\n" ,sizeof(a+0));
// a并非单独放在sizeof内部,有没有&,所以数组名是数组首元素地址。(a+0)还是首元素地址,大小就是4/8 byte(取决于平台大小)
printf(%d\n" ,sizeof(*a));
// a并非单独放在sizeof内部,也没有&,所以数组名a是数组首元素的地址。 //*a就是 首元素(a首元素址,对a解引用就得到了a) //*a == a[0]
printf(%d\n" ,sizeof(a+1));
// a并非单独放在sizeof内部,也没有&,所以数组名a是首元素地址,a+1就是第二个元素的地址 a+1 ==&a[1]
printf(%d\n" ,sizeof(a[1]));
// 就是数组第二个元素,这里是计算第二个元素的大小,单位是字节-4
printf(%d\n" ,sizeof(&a));
// &a--是取出数组的地址,但是数组的地址也是地址,是地址就是 4/8个byte. //数组的地址 和 数组首元素地址 本质的区别是类型的区别,并非大小。
//a -- int* int * p = a;
//&a -- int(*)[4] int (*p)[4] = &a;
printf(%d\n" ,sizeof(*&a));
// 对数组指针解引用访问一个数组的大小写,单位是字节。
printf(%d\n" ,sizeof(&a+1));
// &a是数组的地址,&a+1也是地址但是指向什么地方?我会在下面为大家画图解释。
解释一下sizeof(&a+1)。
我们在前面提到过数组指针类型 int (*p)[4] = &a; &a+1 跳过多少个字节取决于它的类型 数组
整形指针是四个字节所以&a+1跳过四个字节,指向4的位置。
以上是整形数组的相关知识,我们还有一些字符数组的知识需要了解。
关键点拨:指针变量的大小和类型无关,不管什么类型的指针变量,大小都是4/8个字节。
指针变量是用来存放地址的,地址存放需要多大空间,指针变量的大小就是几字节。
在32位环境下,地址是32个二进制,需要4个字节,所以指针变量的大小就是4个字节.
在64位环境下,地址是64个二进制,需要8个字节,所以指针变量的大小就是8个字节.
int main()
{
//字符数组
char arr[]={ 'a','b','c','d','e','f' }; //6
printf("%d\n", sizeof(arr));
// 数组名单独放入sizeof内部,计算的是整个数组的大小单位是字节 6
printf("%d\n", sizeof(arr+0));
// arr是首元素地址 == &arr[0] 是地址就是4/8个字节
printf("%d\n", sizeof(*arr));
// arr数组名表示首元素地址 *arr就是首元素,大小就是1byte。
printf("%d\n", sizeof(arr[1]));
// 就是第二个元素
printf("%d\n", sizeof(&arr));
// &arr是数组的地址,sizeof(&arr)就是4/8个字节。
printf("%d\n", sizeof(&arr+1));
// &arr+1 是指向f后面的那个元素的地址。
以上是一维数组,那如果是二维数组呢?
我们先来理解一下二维数组:二维数组可以理解为一维数组的数组。
假设访问第一个一维数组 a[ 0 ] [ j ].
#include<stdio.h>
int main()
{
int a[3][4]={ 0 };
printf("%zd\n", sizeof(a));
// 48-a 数组名单独放在sizeof内部,表示整个数组,sizeof(a)计算的是数组的大小,单位是字节。
printf("%zd\n", sizeof(a[0][0]));
// 4-a[0][0]是数组的第一行第一个元素,这里计算的就是第一个元素的大小,单位是字节。
printf("%zd\n", sizeof(a[0]));
// a[0]是第一行这个一维数组的数组名,数组名单独放在了sizeof内部。
// a[0]就表示整个第一行这个一维数组,sizeof(a[0])计算的整个第一行这个数组的大小。
printf("%zd\n", sizeof(*(a[0]+1));
//a[0]+1是第一行第二个元素的地址,*(a[0]+1)就是第一行第二个元素
printf("%zd\n", sizeof(a[0]+1));
//a[0]并非单独放在sizeof内部,也没有&,所以a[0]表示第一行这个一维数组首元素的地址
//也就是第一行第一个元素的地址
//a[0]==&a[0][0]
printf("%zd\n", sizeof(a+1);
//a作为二维数组的数组名,并没有单独放在sizeof内部,也没有&,a就是数组首元素的地址,也就是第一行的地址
//a+1就是第二行的地址
printf("%zd\n", sizeof(*(a+1));
//a+1是第二行的地址,*(a+1)就是第二行,计算的就是第二行的大小
我们来看一道面试题
该如何分析呢?
首先我们该明白(&a+1)是怎么回事? 其实在前面我们已经提到过了
因为&,取出的是整个数组的地址,所以跳过的是整个数组 。
那么我们不难得出
ptr 指向5后面的地方,ptr-1指向4和5之间,又因为是int类型,所以ptr-1就指向5.
以上是关于sizeof的相关知识,我们接下来为大家带来strlen相关知识。
1.2 strlen
strlen 求字符串长度
统计的是在字符串中\0之前出现字符的个数。
#include<stdio.h>
int main()
{
//定义一个字符数组
char arr[]={ 'a','b','c','d','e','f' };
printf("%d\n", strlen(arr));
//arr是首元素地址
printf("%d\n", strlen(arr+0));
//arr是首元素地址,arr+0还是首元素地址
printf("%d\n", strlen(*arr));
//arr是首元素地址, *arr就是首元素 - ‘a’-97
//站在strlen的角度,认为传参进去的‘a'-97 就是地址。97作为地址,直接访问,就是非法访问。
printf("%d\n", strlen(arr[1]));
//传参传进去的是‘b’,b是98作为地址也是非法访问。
printf("%d\n", strlen(&arr));
//随机值
printf("%d\n", strlen(&arr+1));
//随机值
因为没有\0(结束标志),所以是随机值。这个随机值是大于6的。
数组的内容到这里就结束了。
后面会持续更新结构体,字符串相关知识,请大家持续关注。