前言
小伙伴们们让我们一起开始学习今天的内容吧!今天的内容超棒的哦!废话不多说,让我们开始学习叭!
1.一维数组
在开始之前我们需要来回忆一些相关知识点。sizeof是一个操作数用来计算类型所占空间的大小,计算时不包括\0。数组名表示首元素地址但是有两个例外:sizeof(数组名)计算的是整个数组的长度,&数组名取的是整个数组的地址。回忆结束直接上代码!
1.1整型数组
#include<stdio.h>
int main()
{
int a[] = { 1,2,3,4 };
printf("%d\n", sizeof(a));
printf("%d\n", sizeof(a+0));
printf("%d\n", sizeof(*a));
printf("%d\n", sizeof(a+1));
printf("%d\n", sizeof(a[1]));
printf("%d\n", sizeof(&a));
printf("%d\n", sizeof(*&a));
printf("%d\n", sizeof(&a+1));
printf("%d\n", sizeof(&a[0]));
printf("%d\n", sizeof(&a[0]+1));
return 0;
}
变量在内存中开辟空间
如上图,此时我们再来一个个分析代码叭
int a[] = { 1,2,3,4 };
printf("%d\n", sizeof(a));
第一个求的是sizeof(a)的大小,哦豁,这刚好时上面提到的例外数组名单独放在sizeof中计算的是整个数组的地址!整型数组,一个元素的大小是4个字节一共有4个元素,那么此时整个数组的大小为16个字节!
printf("%d\n", sizeof(a+0));
再来分析一下,这里不是数组名单独放在sizeof内部,说明此时数组名表示首元素地址!a+0地址没有变化还是首元素的地址。地址的大小是4/8个字节!
printf("%d\n", sizeof(*a));
这里依旧不是数组名单独放在sizeof内部,依旧表示数组首元素地址,就相当于&a[0],在进行解引用操作*(&a[0])得到a[0]也就是1,此时在计算大小就相当于sizeof(int)结果为4个字节
printf("%d\n", sizeof(a+1));
sizeof内部不是单独的数组名,a还是表示数组名首地址。a+1来到数组第二个元素的地址,&a[0]+1,地址的大小还是4/8个字节
printf("%d\n", sizeof(a[1]));
a[1]也就是数组第二个元素即2,此时得到的是4个字节
printf("%d\n", sizeof(&a));
&数组名,表示拿到整个数组的地址,此时sizeof计算的是地址的大小。地址依然是4/8个字节
printf("%d\n", sizeof(*&a));
&和*会相互抵消,*&a就剩下了a,此时计算的是sizeof(a),计算的是整个数组的大小,结果为16个字节
printf("%d\n", sizeof(&a+1));
&a取出整个数组的地址,在进行加1会跳过一个数组的大小,此时sizeof计算的依旧是地址,结果是4/8个字节
printf("%d\n", sizeof(&a[0]));
&a[0]取出第一个元素的地址,sizeof计算的依旧是地址的大小,结果依然是4/8个字节
printf("%d\n", sizeof(&a[0]+1));
&a[0]+1取出的是数组第二个元素的地址,sizeof计算的依旧是地址的大小结果是4/8个字节
运行一下代码来看看结果叭,在vs中使用的是x86所以地址的大小是4字节
1.2字符数组
还记得sizeof和strlen的区别吗?sizeof是一个操作数用来计算类型所占空间大小,不包含\0;strlen是一个库函数使用之前要引用头文件string.h,专门计算字符串大小遇到\0停止。字符数组的初始化有两种:char arr[]={'a','b'}和char arr[ ]="ab",二者的区别在于第二种初始化中隐藏个\0而第一种则没有
int main()
{
char arr[] = { 'a','b','c','d','e','f' };
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(arr));
printf("%d\n", strlen(arr));
printf("%d\n", strlen(arr));
printf("%d\n", strlen(arr));
printf("%d\n", strlen(arr));
printf("%d\n", strlen(arr));
printf("%d\n", strlen(arr));
printf("%d\n", strlen(arr));
return 0;
}
来分析叭
printf("%d\n", sizeof(arr));
sizeof(数组名)求的是整个数组的地址,一个char类型大小为1个字节,字符数组有6个元素,那么整个数组的大小为6字节
printf("%d\n", sizeof(arr+0));
arr表示单独放在sizeof内部表示数组首元素的地址,arr+0依旧是数组首元素的地址!地址的大小是4/8个字节
printf("%d\n", sizeof(*arr));
arr还是表示数组首元素的地址,相当于&arr[0],在进行解引用*(&arr[0])-->arr[0],即sizeof计算的是数组第一个元素的大小,即1个字节
printf("%d\n", sizeof(arr[1]));
这里直接计算的就是数组第二个元素的大小,结果为1字节
printf("%d\n", sizeof(&arr));
&数组名,取得是整个数组的地址,所以sizeof计算的是地址的大小,结果为4/8
printf("%d\n", sizeof(&arr+1));
&arr取出整个数组的地址,加1之后跳过一个数组而大小,sizeof计算的还是地址的大小,结果为4/8
printf("%d\n", sizeof(&arr[0]+1));
&arr[0]取出数组第一个元素的地址,&arr[0]+1-->&arr[1]取出数组第二个元素的地址,sizeof计算的是地址的大小,结果为4/8
printf("%d\n", strlen(arr));
strlen计算遇\0之前的字符个数,但arr中没有\0。因此计算结果为随机值
printf("%d\n", strlen(arr+0));
arr+0依旧表示数组首元素的地址,依旧是因为没有\0,所以结果是随机值
printf("%d\n", strlen(*arr));
arr表示数组首元素即&arr[0],*&arr[0]-->arr[0],所以可以变成strlen(arr[0]),根据cplusplus可以发现strlen的参数是char*的指针,所以此时计算得到的结果是error
printf("%d\n", strlen(arr[1]));
解释同上,结果是error
printf("%d\n", strlen(&arr));
&arr取到的是整个数组的地址,此时strlen计算的是地址的大小,但由于arr中没有\0,结果依然是随机值
printf("%d\n", strlen(&arr+1));
&arr取到的是整个数组的地址,&arr+1跳过一个数组的地址,由于依旧没有\0,结果依然是随机值
printf("%d\n", strlen(&arr[0]+1));
&arr[0]+1得到的是数组第二个元素的地址,但由于arr中没有\0,结果依然是随机值
运行一下看看结果叭
再来一组不同的
int main()
{
char arr[] = "abcdef";
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(arr+0));
printf("%d\n", sizeof(*arr));
printf("%d\n", sizeof(arr[1]));
printf("%d\n", sizeof(&arr));
printf("%d\n", sizeof(&arr+1));
printf("%d\n", sizeof(&arr[0]+1));
printf("%d\n", strlen(arr));
printf("%d\n", strlen(arr+0));
printf("%d\n", strlen(*arr));
printf("%d\n", strlen(arr[1]));
printf("%d\n", strlen(&arr));
printf("%d\n", strlen(&arr+1));
printf("%d\n", strlen(&arr[0]+1));
return 0;
}
来看看有什么不一样叭,貌似求得都一样只有字符数组不一样!
printf("%d\n", sizeof(arr));
sizeof(数组名)计算整个数组的大小,sizeof用于计算所占内存的大小包括\0.。所以计算结果为7
printf("%d\n", sizeof(arr+0));
arr+0还是表示数组首元素的地址,地址的大小是4/8
printf("%d\n", sizeof(*arr));
*arr-->*(&arr[0])-->arr[0],sizeof计算数组第一个元素的大小,结果为1字节
printf("%d\n", sizeof(arr[1]));
sizeof计算数组第一个元素的大小,结果为1字节
printf("%d\n", sizeof(&arr));
&arr取出的是整个数组的地址,因此sizeof计算的是地址的大小,结果为4/8
printf("%d\n", sizeof(&arr+1));
&arr取出的是整个数组的地址,&arr+1跳过一整个数组的地址,sizeof计算的依旧是地址的大小,结果为4/8
printf("%d\n", sizeof(&arr[0]+1));
&arr[0]+1-->&arr[1],得到数组第二个元素的地址,sizeof计算的依旧是地址的大小,结果为4/8
printf("%d\n", strlen(arr));
char arr[]="abcdef"中隐藏了一个\0,strlen计算的是遇到\0之前的字符个数,因此结果为6
printf("%d\n", strlen(arr+0));
arr+0表示数组首元素的地址,strlen计算的是遇到\0之前的字符个数,因此结果为6
printf("%d\n", strlen(*arr));
strlen的参数需要char*指针,*arr-->*&arr[0]-->arr[0],而不需要具体的数,因此结果为error
printf("%d\n", strlen(arr[1]));
解释同上
printf("%d\n", strlen(&arr));
&arr取出的是整个数组的地址,但是&arr和&arr[0]的地址一样都是从数组首元素地址、
那&arr和&arr[0]有什么区别呢,再用代码看看叭
int main()
{
char arr[] = "abcdef";
printf("%p\n", &arr[0]);
printf("%p\n", &arr[0] + 1);
printf("%p\n", &arr);
printf("%p\n", &arr + 1);
return 0;
}
会发现&arr[0]+1跳过了一个字节而&arr+1跳过了7个字节,为啥是七个字节呢,这是因为sizeof计算数组的大小是7字节
再回到这道题上来,strlen(&arr)还是从数组首元素地址开始计算遇到\0停止,结果为6
printf("%d\n", strlen(&arr+1));
&arr+1哈哈上面有说到的情况欸,那么strlen(&arr+1)的结果是啥呢?没错又是随机值
printf("%d\n", strlen(&arr[0]+1));
&arr[0]+1-->&arr[1]得到的是数组第二个元素的地址,所以strlen在进计算时从第二个元素地址开始往后算,所以结果为5
ok,以上就是今天的学习啦,后面的内容明天再写啦