首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【C语言】指针笔试题1

【C语言】指针笔试题1

作者头像
苏兮
发布2026-01-13 17:12:50
发布2026-01-13 17:12:50
710
举报

C语言学习

前言:

经过前面指针基础指针进阶1指针进阶2的学习,咱们对指针已经有了深入的理解,那咱们就来看看指针相关的一些笔试题!

指针和数组笔试题解析

一维数组

看一下下面代码输出都是什么?

代码语言:javascript
复制
#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 + 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;
}

咱们可以自己先试着来分析分析。 结果:

请添加图片描述
请添加图片描述

解释:

代码语言:javascript
复制
#include<stdio.h>
int main()
{
	int a[] = { 1,2,3,4 };
	
	printf("%d\n", sizeof(a));    
	//数组名遇见sizeof就是数组元素总大小,即为16(字节)
	printf("%d\n", sizeof(a + 0));
	//看起来与上一个一样,但是,两者还是有区别:
	//单是数组名遇见sizeof的话,就是数组元素总大小;但是这里数组名已经和0进行的算术运算
	//即为首元素地址+0,为首元素地址,故输出为4(32位机器)。
	printf("%d\n", sizeof(*a));   
	//数组名为首元素地址,*解引用操作后为4(int型数据),输出为4
	printf("%d\n", sizeof(a + 1));
	//这个和第二个有点像,首元素地址+1;为第二个元素地址,故大小为4;
	printf("%d\n", sizeof(a[1])); 
	//第二个元素大小,即为4;
	printf("%d\n", sizeof(*(a + 1)));
	//a + 1数组第二个元素的地址;*(a + 1)数组第二个元素;
	//那看起来与a[1]的意思是一样的,其实,a[1]与*(a + 1)是等效的,a[1]是*(a + 1)的简写,
	// 故sizeof(*(a + 1))也为4;
	printf("%d\n", sizeof(&a));   
	//&a取出数组的地址,地址即为4(32位);
	printf("%d\n", sizeof(*&a));  
	//*&抵消,和第一个一样,输出为16;
	//或者这样思考:&a取出数组的地址,*&a解引用找到数组,sizeof(*&a)计算数组大小;即为16;
	printf("%d\n", sizeof(&a + 1));
	//&a取出数组地址,&a + 1地址跳过这个数组(对于这个数组跳16个字节)
	//但它还是地址,即sizeof(&a + 1)为4(32位);
	printf("%d\n", sizeof(&a[0])); 
	//a[0]为数组首元素,&a[0]首元素地址,sizeof(&a[0])即为地址大小,4(32位)
	printf("%d\n", sizeof(&a[0] + 1));
	//&a[0]首元素地址,&a[0] + 1首元素地址+1,还是地址,即大小为4(32位机器)
	return 0;
}
//主要体会什么叫数组的地址,弄清楚它与首元素地址的区别;

字符数组1

看一下下面代码输出都是什么?

代码语言:javascript
复制
#include<stdio.h>
int main()
{
	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));
	return 0;
}

输出:

在这里插入图片描述
在这里插入图片描述

解释:

代码语言:javascript
复制
int main()
{
	char arr[] = { 'a','b','c','d','e','f' };

	printf("%d\n", sizeof(arr));	
	//数组名遇见sizeof就为整个数组大小,故为6
	printf("%d\n", sizeof(arr + 0));
	//同一维数组,数组名在进行算术运算的时候为首元素地址,
	//地址为4(32位机器)
	printf("%d\n", sizeof(*arr));	
	//*arr首元素地址*解引用,即为首元素,为1字节
	printf("%d\n", sizeof(arr[1])); 
	//数组第二个元素,大小为1;
	printf("%d\n", sizeof(&arr));   
	//数组地址,为4(32位机器)
	printf("%d\n", sizeof(&arr + 1));
	//数组地址+1,还是地址,为4(32位机器)
	printf("%d\n", sizeof(&arr[0] + 1));
	//首元素的地址+1,还是地址,为4(32位机器)
	return 0;
}

字符数组2

看一下下面代码输出都是什么?

代码语言:javascript
复制
#include<stdio.h>
int main()
{
	char arr[] = { 'a','b','c','d','e','f' };
	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;
}

介于这两串代码会出现访存错误(不属于你的程序),无法输出,咱们就看可以输出的

代码语言:javascript
复制
	printf("%d\n", strlen(*arr));
	printf("%d\n", strlen(arr[1]));

输出:

在这里插入图片描述
在这里插入图片描述

解释:

代码语言:javascript
复制
int main()
{
	char arr[] = { 'a','b','c','d','e','f' };
	
	//对strlen函数简介:
	// 返回类型为字符串大小;
	// 参数为字符串地址
	// 是用来计算字符串大小的函数,遇到'\0'停止,

	printf("%d\n", strlen(arr));      
	//对于数组arr没有'\0',咱们不知道从首元素地址起哪里有'\0',
	//故不知道输出为多少,
	printf("%d\n", strlen(arr + 0));  
	//解释同上;
	printf("%d\n", strlen(*arr));	  
	//*arr对首元素地址*解引用,即为首元素,
	//它会把'a'(97)当作内存地址去访问,会有意想不到的错误
	printf("%d\n", strlen(arr[1]));   
	//解释同上;
	printf("%d\n", strlen(&arr));     
	//&arr为数组地址,虽然实参类型与形参类型不同,
	//但是形参会将实参的类型转化为与自己相同的类型后再在接受,即隐式类型转化;
	//故输出与strlen(arr)相同
	printf("%d\n", strlen(&arr + 1));  
	//&arr + 1跳过整个数组之后的地址,之后道理同上虽然传过去的是数组地址,
	//但是会发生隐式类型转化,因为跳过了6个元素,故它的输出比上一个少6;
	printf("%d\n", strlen(&arr[0] + 1));
	//首元素地址+1,故输出比strlen(arr)少1
	return 0;
}

字符数组3

看一下下面代码输出都是什么?

代码语言:javascript
复制
#include<stdio.h>
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;
}

与字符数组2中类似的就不再解释了:

代码语言:javascript
复制
int main()
{
	char arr[] = "abcdef";
	printf("%d\n", sizeof(arr));	
	//数组名遇见sizeof就为整个数组大小,但是咱们这里要注意
	//字符串后面还有一个隐藏的\0呢,所以应该为7,
	printf("%d\n", sizeof(arr + 0));//4
	printf("%d\n", sizeof(*arr));   //1
	printf("%d\n", sizeof(arr[1])); //1
	printf("%d\n", sizeof(&arr));   //4
	printf("%d\n", sizeof(&arr + 1));//4
	printf("%d\n", sizeof(&arr[0] + 1));//4
	printf("%d\n", strlen(arr));   
	//注意:
	//strlen遇见\0就停止,即为6
	printf("%d\n", strlen(arr + 0));
	//6
	printf("%d\n", strlen(*arr));
	//访问内存失败
	printf("%d\n", strlen(arr[1]));
	//访问内存失败
	printf("%d\n", strlen(&arr));
	//6
	printf("%d\n", strlen(&arr + 1));
	//随机,直到遇到\0
	printf("%d\n", strlen(&arr[0] + 1));
	//5
	return 0;
}

字符数组4

代码语言:javascript
复制
int main()
{
	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));
	return 0;
}

首先,咱们先对char* p = "abcdef"解释一下:

p作为一个字符指针,它需要接收字符的地址 所以这个代码的意思是:将字符串的第一个元素的地址给p

解释:

代码语言:javascript
复制
int main()
{
	char* p = "abcdef";
	printf("%d\n", sizeof(p));    
	//p首元素地址,大小为4(32位机器)
	printf("%d\n", sizeof(p + 1));
	//p + 1第二个元素地址,大小为4(32位机器)
	printf("%d\n", sizeof(*p));   
	//*p首元素地址解引用即为首元素,大小为1
	printf("%d\n", sizeof(p[0])); 
	//p[0]前面说过,相当于*p+0;即与前一个一样,为1;
	printf("%d\n", sizeof(&p));   
	//p为首元素地址,即字符指针,&p则为二级指针,二级指针也是指针呀,大小为4(32位机器)
	printf("%d\n", sizeof(&p + 1));
	//&p二级指针,&p + 1二级指针跳过一个一级指针(32位机器为4字节),但是它还是地址
	//所以为4(32位机器)
	printf("%d\n", sizeof(&p[0] + 1));
	//p[0]即为a,&p[0]取出首元素地址,&p[0] + 1首元素地址+1,第二个元素地址,大小为4(32位机器)
	printf("%d\n", strlen(p));     
	//传入首元素地址,即求的是字符串长度,为6;
	printf("%d\n", strlen(p + 1)); 
	//传入第二个元素地址,即求的是从第二个元素起的字符串长度,为5;
	//printf("%d\n", strlen(*p));    
	//传入首元素,等效于strlen('a')->strlen(98);会导致内存访问错误;
	//printf("%d\n", strlen(p[0]));  
	//同上,内存访问错误
	printf("%d\n", strlen(&p));    
	//&p,二级指针,结果未知
	printf("%d\n", strlen(&p + 1));
	//同上,结果未知,且两者无联系;
	printf("%d\n", strlen(&p[0] + 1));
	//&p[0]为首元素地址,&p[0] + 1为第二个元素的地址,
	//即求的是从第二个元素起的字符串长度,为5
	return 0;
}

输出(内存访问错误无输出):

在这里插入图片描述
在这里插入图片描述

二维数组

代码语言:javascript
复制
int main()
{
	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;
}

输出

在这里插入图片描述
在这里插入图片描述

解析:

代码语言:javascript
复制
int main()
{
	int a[3][4] = { 0 };
	//未完全初始化,默认其他为0;
	printf("%d\n", sizeof(a));        
	//同上,整个数组大小,即为48;
	printf("%d\n", sizeof(a[0][0]));  
	//第0行第0列元素大小,即为4(int);
	printf("%d\n", sizeof(a[0]));	  
	//a[0]代表第0行元素,即一维数组,故大小为4*4(int),为16;
	printf("%d\n", sizeof(a[0] + 1)); 
	//a[0]进行算数运算时,和一维数组一样,代表第0行数组(一维数组)的首元素(第0个元素)地址,
	//a[0] + 1即为第0行第一个元素地址,故大小为4(32位机器);
	printf("%d\n", sizeof(*(a[0] + 1)));
	//a[0] + 1为第0行第一个元素地址,*解引用即为第0行第一个元素,故大小为4;
	printf("%d\n", sizeof(a + 1));		
	//二维数组数组名为第0行地址(一维数组地址),数组名a + 1即为第1行地址(一维数组地址),
	//地址大小为4(32位机器)
	printf("%d\n", sizeof(*(a + 1)));   
	//a + 1为第1行地址,*解引用即为第1行元素,故大小为16;
	printf("%d\n", sizeof(&a[0] + 1));  
	//a[0]表示第0行(即一维数组),&a[0]表示第0行地址,&a[0] + 1即为第1行地址,大小为4(32位机器);
	printf("%d\n", sizeof(*(&a[0] + 1)));
	//&a[0] + 1为第1行地址,*解引用则为第1行元素,大小为16;
	printf("%d\n", sizeof(*a));			 
	//a为首行元素地址(一维数组地址),*解引用即为首行元素,大小为16;
	printf("%d\n", sizeof(a[3]));        
	//很明显,已经越界了,但是sizeof不计算表达式,仅分析类型,因此即使越界也不会报错。
	//所以咱们还是来看看,a[3]->*(a+3),同上,还是16;

	return 0;
}

所以咱们这里可以再进行一次总结

数组名的意义:

  1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
  2. & 数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
  3. 除此之外所有的数组名都表示首元素的地址。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-08-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • C语言学习
  • 前言:
  • 指针和数组笔试题解析
    • 一维数组
    • 字符数组1
    • 字符数组2
    • 字符数组3
    • 字符数组4
    • 二维数组
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档