目录
首先我们得先了解strlen函数和sizeof操作符,数组名的意义。
一.strlen
二.sizeof
三.数组名
四.指针和数组笔试题
五.指针和数组笔试题解析
5.1一维数组
5.2字符数组
5.3.二维数组
前言:
代码看上去枯燥,但一定有你不会的,保持空杯心态,里面的知识是对你的基础功是否扎实检验!!!
srtlen是计算字符串长度的函数,头文件是#include
sizeof是操作符,而且是单目操作符,计算一个变量或者类型所占空间大小的,返回类型是%zu,计算结果是字节
常用来计算数组长度:
重点:
sizeof(表达式不进行运算)
像下面sizeof( )内,是赋值表达式,赋值这个动作根部就不会产生,他计算的是num类型的大小
short = 2个字节
但是像下面的表达式:
a+1是个表达式,求的是a+1的值的类型所占空间大小
a是首地址 ,+ 1到2的地址,这个值是地址,是地址就是4/8个字节。
32位平台是4个字节,64位平台是8个字节
关于数组名
数组名是数组首元素的地址
但是有2个例外:
1. sizeof(数组名) - 数组名表示整个数组(只限于单独在sizeof中),计算的是整个数组的大小,单位是字节
2. &数组名 - 数组名也表示整个数组,取出的是整个数组的地址
除了这个2个例外,你见到的所有的数组名都表示首元素的地址
把题给你们写出输出结果:
#include
#include
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));
//字符数组
char arr[] = { 'a','b','c','d','e','f' };
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));
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));
char* p = "abcdef";
printf("%d\n", sizeof(p));
printf("%d\n", sizeof(p + 1));
printf("%d\n", sizeof(*p));
printf("%d\n", sizeof(p[0]));
printf("%d\n", sizeof(&p));
printf("%d\n", sizeof(&p + 1));
printf("%d\n", sizeof(&p[0] + 1));
printf("%d\n", strlen(p));
printf("%d\n", strlen(p + 1));
printf("%d\n", strlen(*p));
printf("%d\n", strlen(p[0]));
printf("%d\n", strlen(&p));
printf("%d\n", strlen(&p + 1));
printf("%d\n", strlen(&p[0] + 1));
//二维数组
int a[3][4] = { 0 };
printf("%d\n", sizeof(a));
printf("%d\n", sizeof(a[0][0]));
printf("%d\n", sizeof(a[0]));
printf("%d\n", sizeof(a[0] + 1));
printf("%d\n", sizeof(*(a[0] + 1)));
printf("%d\n", sizeof(a + 1));
printf("%d\n", sizeof(*(a + 1)));
printf("%d\n", sizeof(&a[0] + 1));
printf("%d\n", sizeof(*(&a[0] + 1)));
printf("%d\n", sizeof(*a));
printf("%d\n", sizeof(a[3]));
return 0;
}
//一维数组
int a[] = { 1,2,3,4 };
//16,a作为数组名单独放在sizeof内部,计算的是数组的总大小,单位是字节
printf("%d\n", sizeof(a));
//a+0还是数组首元素的地址,是地址大小就是 4/8 个字节
//a并非单独放在sizeof内部,也没有&,所以数组名a就是数组首元素的地址
printf("%d\n", sizeof(a + 0));
//4,a是首元素的地址,*a就是首元素,sizeof(*a)就算的就是首元素的大小
printf("%d\n", sizeof(*a));
//4/8,a是首元素的地址,a+1是第二个元素的地址,sizeof(a+1)计算的是指针的大小
printf("%d\n", sizeof(a + 1));
//a[1]就是数组的第二个元素,sizeof(a[1])的大小 - 4个字节
printf("%d\n", sizeof(a[1]));
//4/8,&a取出的数组的地址,数组的地址,也是地址呀,sizeof(&a)就是 4/8 个字节
printf("%d\n", sizeof(&a));
//4,&a是数组的地址,是数组指针类型,*&a是都数组指针解引用,访问一个数组的大小
//16字节
//sizeof(*&a) ==> sizeof(a) =16
printf("%d\n", sizeof(*&a));
//4/8,&a数组的地址,&a+1跳过整个数组,&a+1还是地址,是 4/8 个字节
printf("%d\n", sizeof(&a + 1));
//4/8,a[0]是数组的第一个元素,&a[0]是第一个元素的地址,是 4/8 个字节
printf("%d\n", sizeof(&a[0]));
//4/8,&a[0]是第一个元素的地址,&a[0]+1就是第二个元素的地址,是 4/8 个字节
printf("%d\n", sizeof(&a[0] + 1));
return 0;
1.
//字符数组
char arr[] = { 'a','b','c','d','e','f' };
//6,arr是数组名,并且是单独放在sizeof内部,计算的是数组总大小,单位是字节 - 6
printf("%d\n", sizeof(arr));
//4/8,arr是数组名,并非单独放在sizeof内部,arr表示首元素的地址,arr+0还是首元素的地址
printf("%d\n", sizeof(arr + 0));
//1,arr是首元素的地址,*arr就是首元素,sizeof计算的是首元素的大小,是1字节
printf("%d\n", sizeof(*arr));
//1,arr[1]是数组的第二个元素,sizeof(arr[1])计算的是第二个元素的大小,1个字节
printf("%d\n", sizeof(arr[1]));
//4/8,取出的是数组的地址,sizeof(&arr))计算的是数组的地址的大小,是地址就是4/8字节
printf("%d\n", sizeof(&arr));
//4/8,&arr是数组的地址,&arr+1跳过整个数组,指向'f'的后边,&arr+1的本质还是地址,是地址就是4/8字节
printf("%d\n", sizeof(&arr + 1));
//4/8,&arr[0]是‘a’的地址,&arr[0]+1是'b'的地址,是地址就是4/8字节
printf("%d\n", sizeof(&arr[0] + 1));
2.
//字符数组
char arr[] = { 'a','b','c','d','e','f' };
//随机值,随机值,arr是数组名,但是没有放在sizeof内部,也没&,arr就是首元素的地址
//strlen得到arr后,从arr数组首元素的地方开始计算字符串的长度,直到直到\0,但是arr数组中没有
//\0,arr内存的后边是否有\0,在什么位置
//是不确定的,所以\0之前出现了多少个字符是随机的。
printf("%d\n", strlen(arr));
//随机值,arr是数组首元素的地址,arr+0还是首元素的地址
printf("%d\n", strlen(arr + 0));
//err,arr是数组首元素的地址,*arr 是首元素 - ‘a’ - 97
//strlen就把‘a’的ASCII码值 97 当成了地址
//err 会非法访问内存
printf("%d\n", strlen(*arr));
//err,和上个一样,arr[1] - 'b' - 98 - err
printf("%d\n", strlen(arr[1]));
//随机值,&arr是数组的地址,数组的地址也是指向数组起始位置,和第一个案例一样
printf("%d\n", strlen(&arr));
//随机值
printf("%d\n", strlen(&arr + 1));
//随机值,
printf("%d\n", strlen(&arr[0] + 1));
3.
char arr[] = "abcdef";
//7,字符串中后面是自带一个‘\0’的,abcdef\0 - 7字节
printf("%d\n", sizeof(arr));
//4/8,arr不是单独存在sizeof中,他是首元素地址, +0 任然是,是地址计算 - 4/8
printf("%d\n", sizeof(arr + 0));
//1,首地址解引用,就是首元素,char类型的就是1个字节
printf("%d\n", sizeof(*arr));
//1,第二个元素,任然是元素,char类型的就是1个字节
printf("%d\n", sizeof(arr[1]));
//4/8,取出的整个数组的地址,但你是地址就是 - 4/8
printf("%d\n", sizeof(&arr));
//4/8,取出整个数组的地址+1,跳到\0后面,但你任然是地址,是地址就是 - 4/8
printf("%d\n", sizeof(&arr + 1));
//4/8,arr[0]是首元素,&就是首元素地址,+1跳到b的地址,是地址就是 - 4/8
printf("%d\n", sizeof(&arr[0] + 1));
4.
char arr[] = "abcdef";
//6,arr是首元素地址,往后计数遇到\0停止,计数不包括\0
printf("%d\n", strlen(arr));
//6,加0任然是首元素地址,往后计数遇到\0停止,计数不包括\0
printf("%d\n", strlen(arr + 0));
//err,arr是首元素地址,解引用就是a - ASII码值是97,strlen要的是地址,他去访问97的地址,
//编译器是不允许的,这里的空间根本就没有给你开辟空间
printf("%d\n", strlen(*arr));
//err,arr[1]是b元素,b - ASCII码值是98,和上述同理
printf("%d\n", strlen(arr[1]));
//6,&arr虽然是整个元素的地址,但他指向的任然是第一个元素
printf("%d\n", strlen(&arr));
//随机值,整个元素+1,跳到\0后面,但是后面什么时候遇到\0是未知的,所以是随机值
printf("%d\n", strlen(&arr + 1));
//5,arr[0]是首元素a,&便是a的地址+1,变成b的地址,往后计数遇到\0停止
printf("%d\n", strlen(&arr[0] + 1));
5.
char* p = "abcdef";
//4/8,p是指针变量,指针用来存放地址的,是地址计是 - 4/8
printf("%d\n", sizeof(p));
//4/8,相当于地址加了一,还是地址 - 4/8
printf("%d\n", sizeof(p + 1));
//1,这是一个char*的指针,解引用只能访问一个字节,就是a - 1个字节
printf("%d\n", sizeof(*p));
//1,和上述同理
printf("%d\n", sizeof(p[0]));
//4/8,p也有自己的地址,&p取出了整个p的地址,任然指向p的首元素地址
printf("%d\n", sizeof(&p));
//4/8,&p是整个元素的地址,+1跳过整个p但任然是地址,是地址就是 - 4/8
printf("%d\n", sizeof(&p + 1));
//4/8,p[0]是p首元素,&取出首元素地址,+1 p的第二个元素的地址
printf("%d\n", sizeof(&p[0] + 1));
6.
char* p = "abcdef";
//6,p指向了字符串首元素地址
printf("%d\n", strlen(p));
//5,指向字符串第二个元素的地址
printf("%d\n", strlen(p + 1));
//err,取出首元素地址a - ASCII码值是97,strlen要的是地址,他去访问97的地址
//编译器是不允许的,这里的空间根本就没有给你开辟空间
printf("%d\n", strlen(*p));
//err,上述一样
printf("%d\n", strlen(p[0]));
//随机值,&p是取出p的地址,地址是编译器给你分配的,你无法确定什么时候可以遇到\0
printf("%d\n", strlen(&p));
//随机值,&p是取出p的地址,+1跳过p的地址,但任然无法确定什么时候可以遇到\0
printf("%d\n", strlen(&p + 1));
//随机值,p[0]是首元素,&取出首元素地址,+1,p第二个元素的地址,无法确定什么时候遇到\0
printf("%d\n", strlen(&p[0] + 1));
int a[3][4] = { 0 };
//48,二维数组的数组名也是数组名,这里也表示整个数组,但依然指向首元素地址
// 3(行) * 4(列) * 4(int大小) = 48
printf("%d\n", sizeof(a));
//4,这里直接访问到了[0][0]的元素,计算了他的大小
printf("%d\n", sizeof(a[0][0]));
//16,把二维数组的每一行看做一维数组的时候,a[0]是第一行的数组名,第一行的数组名单独放在sizeof内部
//计算的是第一行的总大小,单位是字节 - 16
printf("%d\n", sizeof(a[0]));
//a[0]虽然是第一行的数组名,但是并非单独放在sizeof内部
//a[0]作为第一行的数组名并非表示整个第一行这个数组,a[0]就是第一行首元素的地址,a[0]--> &a[0][0] - int*
//a[0]+1,跳过一个int,是a[0][1]的地址 4/8字节
printf("%d\n", sizeof(a[0] + 1));
//4,a[0]+1是第一行第二个元素的地址,所以*(a[0]+1)就是a[0][1],大小是4个字节
printf("%d\n", sizeof(*(a[0] + 1)));
//4/8,a[0]虽然是第一行的数组名,但是并非单独放在sizeof内部
//a[0]作为第一行的数组名并非表示整个第一行这个数组,a[0]就是第一行首元素的地址,a[0]--> &a[0][0] - int*
//a[0]+1,跳过一个int,是a[0][1]的地址 4/8字节
printf("%d\n", sizeof(a + 1));
//16,a+1是第二行的地址,*(a+1) 找到的就是第二行,sizeof(*(a + 1))计算的就是第二行的大小
//*(a+1) --> a[1]
//sizeof(*(a + 1)) --> sizeof(a[1])
printf("%d\n", sizeof(*(a + 1)));
//4/8,&a[0]是第一行的地址,&a[0]+1就是第二行的地址,sizeof(&a[0] + 1)计算的第二行地址大小
printf("%d\n", sizeof(&a[0] + 1));
//16,&a[0] + 1是第二行的地址,*(&a[0] + 1)拿到的就是第二行,大小就是16个字节
//*(&a[0]+1) --> a[1]
printf("%d\n", sizeof(*(&a[0] + 1)));
//16,a表示首元素的地址,就是第一行的地址 - &a[0]
//*a - 拿到的就是第一行 - 大小就是16个字节
//*a -> *(a+0) -> a[0]
printf("%d\n", sizeof(*a));
//16,a[3]是二维数组的第4行,虽然没有第四行,但是类型能够确定,
// 大小就是确定的。大小就是一行的大小,单位是字节 - 16
//能够分析出 a[3]的类型是:int [4]
printf("%d\n", sizeof(a[3]));//代码没有问题
制作不易,你们的支持是作者最大的动力!!!不要吝啬你们的小心心哦