指针和数组笔试题解析

2 篇文章 0 订阅
1 篇文章 0 订阅

目录

首先我们得先了解strlen函数和sizeof操作符,数组名的意义。

 一.strlen

二.sizeof

 三.数组名

四.指针和数组笔试题

五.指针和数组笔试题解析

5.1一维数组

5.2字符数组

5.3.二维数组

前言:

        代码看上去枯燥,但一定有你不会的,保持空杯心态,里面的知识是对你的基础功是否扎实检验!!!

首先我们得先了解strlen函数和sizeof操作符,数组名的意义。

 一.strlen

srtlen是计算字符串长度的函数,头文件是#include<string.h>,遇到\0停止(\0的ASCII码值是0,所以遇到0也停止),计算长度不包括\0

二.sizeof

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<stdio.h>
#include<string.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));
	//字符数组
	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;
}

五.指针和数组笔试题解析

5.1一维数组

	//一维数组
	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;

5.2字符数组

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));

5.3.二维数组

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]));//代码没有问题

制作不易,你们的支持是作者最大的动力!!!不要吝啬你们的小心心哦

  • 15
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值