前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >第七节——指针笔试题(让你不再害怕指针)

第七节——指针笔试题(让你不再害怕指针)

作者头像
egoist祈
发布2025-01-23 13:22:20
发布2025-01-23 13:22:20
5900
代码可运行
举报
文章被收录于专栏:egoistegoist
运行总次数:0
代码可运行

知识回顾: sizeof和strlen的对比

sizeof: 计算变量所占内存内存空间大小的,单位是字节,如果操作数是类型的话,计算的是使⽤类型创建的变量所占内存空间的大小

strlen: 统计的是字符串中\0之前的字符的个数。

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

2.1 一维数组

首先:sizeof数组名和&数组名是两个特例:详见此文章

代码语言:javascript
代码运行次数:0
复制
#include<stdio.h>

int main()
{
	int a[] = { 1,2,3,4 };
	printf("%zd\n", sizeof(a));//16
	printf("%zd\n", sizeof(a + 0));//4/8
	printf("%zd\n", sizeof(*a));//4
	printf("%zd\n", sizeof(a + 1));//4/8
	printf("%zd\n", sizeof(a[1]));//4
	printf("%zd\n", sizeof(&a));//4/8
	printf("%zd\n", sizeof(*&a));//16

	printf("%zd\n", sizeof(&a + 1));//4/8
	printf("%zd\n", sizeof(&a[0]));//4/8
	printf("%zd\n", sizeof(&a[0] + 1));//4/8
}

2.2 字符数组

代码1

代码语言:javascript
代码运行次数:0
复制
#include<stdio.h>

int main()
{
	char arr[] = { 'a','b','c','d','e','f' };
	printf("%zd\n", sizeof(arr));//6
	printf("%zd\n", sizeof(arr + 0));//4/8
	printf("%zd\n", sizeof(*arr));//1
	printf("%zd\n", sizeof(arr[1]));//1
	printf("%zd\n", sizeof(&arr));//4/8
	printf("%zd\n", sizeof(&arr + 1));//4/8
	printf("%zd\n", sizeof(&arr[0] + 1));//4/8
	return 0;
}

代码2

代码语言:javascript
代码运行次数:0
复制
#include<stdio.h>

int main()
{
	char arr[] = { 'a','b','c','d','e','f' };
	printf("%zd\n", strlen(arr));//随机值
	printf("%zd\n", strlen(arr + 0));//随机值
	printf("%zd\n", strlen(*arr));err
	
	printf("%zd\n", strlen(arr[1]));//err
	printf("%zd\n", strlen(&arr));//随机值

	printf("%zd\n", strlen(&arr + 1));//随机值-1
	printf("%zd\n", strlen(&arr[0] + 1));//随机值-1
	return 0;
}

代码3、4

理解了上面两个代码后,用这个思路再来写下以下两个代码

sizeof计算字符串

代码语言:javascript
代码运行次数:0
复制
#include<stdio.h>

int main()
{
	char arr[] = "abcdef";
	printf("%zd\n", sizeof(arr));//7
	printf("%zd\n", sizeof(arr + 0));//4/8
	printf("%zd\n", sizeof(*arr));//1
	printf("%zd\n", sizeof(arr[1]));//1
	printf("%zd\n", sizeof(&arr));//4/8
	printf("%zd\n", sizeof(&arr + 1));//4/8
	printf("%zd\n", sizeof(&arr[0] + 1));//4/8
	return 0;
}

strlen计算字符串

代码语言:javascript
代码运行次数:0
复制
#include<stdio.h>

int main()
{
	char arr[] = "abcdef";
	printf("%zd\n", strlen(arr));//6
	printf("%zd\n", strlen(arr + 0));//6
	printf("%zd\n", strlen(*arr));//err
	printf("%zd\n", strlen(arr[1]));//err
	printf("%zd\n", strlen(&arr));//6
	printf("%zd\n", strlen(&arr + 1));//随机值
	printf("%zd\n", strlen(&arr[0] + 1));//5
	return 0;
}

代码5

代码语言:javascript
代码运行次数:0
复制
#include<stdio.h>

int main()
{
	char* p = "abcdef";
	printf("%zd\n", sizeof(p));//4/8
	printf("%zd\n", sizeof(p + 1));//4/8
	printf("%zd\n", sizeof(*p));//1
	printf("%zd\n", sizeof(p[0]));//1
	
	printf("%zd\n", sizeof(&p));//4/8
	printf("%zd\n", sizeof(&p + 1));//4/8
	printf("%zd\n", sizeof(&p[0] + 1));//4/8
	return 0;
}

代码6

代码语言:javascript
代码运行次数:0
复制
#inlude<stdio.h>

int main()
{
	char* p = "abcdef";
	printf("%zd\n", strlen(p));//6
	printf("%zd\n", strlen(p + 1));//5
	printf("%zd\n", strlen(*p));//err
	printf("%zd\n", strlen(p[0]));//err
	printf("%zd\n", strlen(&p));//随机值
	printf("%zd\n", strlen(&p + 1));//随机值	
	printf("%zd\n", strlen(&p[0] + 1));//5
	return 0;
}

2.3 二维数组

代码语言:javascript
代码运行次数:0
复制
#include<stdio.h>

int main()
{
	int a[3][4] = { 0 };
	printf("%zd\n", sizeof(a));//3*4*4=48
	printf("%zd\n", sizeof(a[0][0]));//4
	printf("%zd\n", sizeof(a[0]));//16
	printf("%zd\n", sizeof(a[0] + 1));//4/8
	printf("%zd\n", sizeof(*(a[0] + 1)));//4
	printf("%zd\n", sizeof(a + 1));//4/8
	
	printf("%zd\n", sizeof(*(a + 1)));//16
	
	printf("%zd\n", sizeof(&a[0] + 1));//4/8
	printf("%zd\n", sizeof(*(&a[0] + 1)));//16
    printf("%zd\n", sizeof(*a));//16
	printf("%zd\n", sizeof(a[3]));//16
	return 0;
}

3. 指针运算笔试题解析

3.1 题目1:

代码语言:javascript
代码运行次数:0
复制
#include<stdio.h>

int main()
{
	int a[5] = { 1, 2, 3, 4, 5 };

	int* ptr = (int*)(&a + 1);
	printf("%d,%d", *(a + 1), *(ptr - 1));// 2  5
	return 0;
}

3.2 题目2:

代码语言:javascript
代码运行次数:0
复制
//在X86环境下
//假设结构体的⼤⼩是20个字节
//程序输出的结果是啥?
#include<stdio.h>

struct Test
{
	int Num;
	char* pcName;
	short sDate;
	char cha[2];
	short sBa[4];
}*p = (struct Test*)0x100000;

int main()
{
	printf("%p\n", p + 0x1);
	printf("%p\n", (unsigned long)p + 0x1);
	printf("%p\n", (unsigned int*)p + 0x1);
	return 0;
}

3.3 题目3:

逗号表达式相关赘述见此章节

代码语言:javascript
代码运行次数:0
复制
#include <stdio.h>

int main()
{
	int a[3][2] = { (0, 1), (2, 3), (4, 5) };
	//                逗号表达式
	// 1 3
	// 5 0
	// 0 0
	int* p;
	p = a[0];
	printf("%d", p[0]);//1
	return 0;
}

3.4 题目4:

代码语言:javascript
代码运行次数:0
复制
#include<stdio.h>

int main()
{
	int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	int* ptr1 = (int*)(&aa + 1);
	int* ptr2 = (int*)(*(aa + 1));
	printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));
	return 0;
}

3.5 题目5:

代码语言:javascript
代码运行次数:0
复制
//假设环境是x86环境,程序输出的结果是啥?
#include<stdio.h>

int main()
{
	int a[5][5];
	int(*p)[4];
	p = a;
	printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);  
	//%p-->FF FF FF FC  %d-->-4
	//内存中的补码直接以16进制的形式打印
	//-4的原码
	//10000000 00000000 00000000 00000100  -->原码
	//11111111 11111111 11111111 11111011  -->反码
	//1111 1111 1111 1111 1111 1111 1111 1100  -->补码
	//  F    F   F     F    F   F    F    C
	return 0;
}

3.6 题目6:

代码语言:javascript
代码运行次数:0
复制
#include<stdio.h>

int main()
{
	char* a[] = { "work","at","alibaba" };
	char** pa = a;
	pa++;
	printf("%s\n", *pa);//at
	return 0;
}

3.7 题目7:

代码语言:javascript
代码运行次数:0
复制
#include<stdio.h>

int main()
{
	char* c[] = { "ENTER","NEW","POINT","FIRST" };
	char** cp[] = { c + 3,c + 2,c + 1,c };
	char*** cpp = cp;
	printf("%s\n", **++cpp);
	printf("%s\n", *-- * ++cpp + 3);
	printf("%s\n", *cpp[-2] + 3);
	printf("%s\n", cpp[-1][-1] + 1);
	return 0;
}

这道考题旨在对指针的理解,我们来逐次分析这段代码。 首先:

  1. 创建了数组指针,c[0]指向了ENTER,并且指向其元素的地址E;
  2. c[1]指向NEW,接下来同理。
  3. 接着用二级数组指针接收数组指针c,cp[0]指向了c+3,同理如图所示。
  4. 又用一个三级指针来接收二级指针。

接下来一段段剖析接下来代码。

本来cpp指向了cp的首元素的地址,++cpp使其指向了cp的第二个元素的地址,两次解引用则得到了POINT。

++cpp指向了cp的第三个元素的地址,然后解引用再–指向c的首元素的地址==,再次解引用得到ENTER的首元素地址,然后+3得到E的地址。

cpp[-2]等同于*(cpp-2),因此cpp[-2]指向了cp的首元素的地址,再解引用得到c的第四个元素的地址,然后+3指向了S这个元素地址。

cpp[-1][-1]等同于*(*(cpp-1)-1),即得到了NEW的首元素的地址,再+1得到E的地址。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-12-14,如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 知识回顾: sizeof和strlen的对比
  • 2. 数组和指针笔试题解析
  • 2.1 一维数组
  • 2.2 字符数组
    • 代码1
    • 代码2
    • 代码3、4
    • 代码5
    • 代码6
  • 2.3 二维数组
  • 3. 指针运算笔试题解析
  • 3.1 题目1:
  • 3.2 题目2:
  • 3.3 题目3:
  • 3.4 题目4:
  • 3.5 题目5:
  • 3.6 题目6:
  • 3.7 题目7:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档