C语言指针笔试真题整理(8道)(上)

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: C语言指针笔试真题整理(8道)

前言

本篇文章整理了一些指针的笔试题,适合初学者以及对于指针掌握并不是很牢固的朋友阅读,当然,大佬想做着玩的话可以看一看第八题~

分类:循序渐进的难度:前三题和第七题是简单题,第四题有陷阱,5、6、8比较复杂(8最难)

希望能帮助到大家更好的理解指针,话不多说我们直接开始。

1

题干

下面代码的运行结果是什么

int main()
{
  int a[5] = { 1, 2, 3, 4, 5 };
  int* ptr = (int*)(&a + 1);
  printf("%d,%d", *(a + 1), *(ptr - 1));
  return 0;
}

答案

2,5

解析

我们采用画图的方式来一步一步的分析

*(ptr - 1)

首先,明确&a+1在内存中的位置,(&a+1)是数组指针类型

其次,将(&a+1)转换成int*类型,再存储进整形指针ptr里,

int* ptr = (int*)(&a + 1);

位置如图

然后,ptr是整形指针,所以减一,ptr向前移动一个整型,就指向5了

那么,*(ptr - 1)存储的就是5了

*(a + 1)

a此处是首元素地址,加一指向2,解引用之后,结果就是2

2

题干

假设p 的值为0x100000。 如下表表达式的值分别为多少?
已知,结构体Test类型的变量大小是20个字节
(关于结构体类型的大小,之后的文章会做详细说明)
struct Test
{
  int Num;
  char* pcName;
  short sDate;
  char cha[2];
  short sBa[4];
}* p;
int main()
{
  p = (struct Test*)0x100000;
  printf("%p\n", p + 0x1);
  printf("%p\n", (unsigned long)p + 0x1);
  printf("%p\n", (unsigned int*)p + 0x1);
  return 0;
}

答案

0x00100014
0x00100001
0x00100004

解析

本题考察的就是不同类型的指针加一,结果是什么

小提示:

0x1虽然是十六进制,但还是1

p是指针,指针与整数的运算,移动多少位,取决于指针变量的大小

p + 0x1

p是结构体指针,大小是20个字节,

p + 0x1,就相当于加了20个字节,所以就是0x00100014

(unsigned long)p + 0x1

p转换成了整型,已经不是指针了,而整型与整数的运算就是直接的加减

所以结果就是0x00100001

(unsigned int*)p + 0x1

p转换成了无符号整型指针,加一,跳过一个无符号整型,四个字节

结果就是0x00100004

3

题干

小端环境下,程序运行结果是什么

int main()
{
  int a[4] = { 1, 2, 3, 4 };
  int* ptr1 = (int*)(&a + 1);
  int* ptr2 = (int*)((int)a + 1);
  printf("%x,%x", ptr1[-1], *ptr2);
  return 0;
}

答案

4,2000000

解析

数组的存储方式如下

ptr1

(&a + 1),如图

之后,(int*)(&a + 1)将(&a + 1),转换成整型指针,再赋给ptr1

ptr1[-1]

转换一下:

ptr1[-1] == ptr+(-1)== *(ptr-1)

等于使prt1向前移动一个整型的大小,也就是4个字节

如图:蓝色箭头

所以打印结果就是0x4

ptr2

(int)a

将a强制转化成int类型,再加一,

之后再转换成整型指针,相当于较之前向后移动了一个字节

画个图方便大家理解

ptr2,就指向图中黄色的位置

*ptr2

ptr2是整型指针,解引用后能向后访问四个字节,粉色的四个字节

结果就是:0x2000000

4

题干

#include <stdio.h>
int main()
{
  int a[3][2] = { (0, 1), (2, 3), (4, 5) };
  int* p;
  p = a[0];
  printf("%d", p[0]);
  return 0;
}

答案

1

解析

我们逐层来分析

()逗号表达式

注意,数组在初始化时没有用{},而用的是()

那么这里就是逗号表达式,我们都知道逗号表达式最后一个表达式为结果,

所以数组在初始化后,结果如下

p = a[0]

a[0]是第一行元素的数组名

并且,此时, a[0]既没有放在sizeof内,又没有取地址,

所以,这里的 a[0]指的就是第一行元素的首元素地址,就是1的地址

p[0]

p[0] == *(p+0)

所以就是1

5

题干

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]);
  return 0;
}

答案

FFFFFFFC,-4

解析

此处为了方便理解和美观,我们将二维数组表示成一维数组

p[4][2]

p是指针数组,指向数组,数组里有四个元素,每个元素都是整型

图解:

p[4][2]就表示为

*(*(p+4)+2)

(p+4)指向的是一个有四个元素的数组,每个元素都是int类型,

*(p+4)之后得到这个有四个元素的数组,

那么*(p+4)就相当于数组名,也就是首元素的地址

加2之后,得到下图:

p = a

p指向的数组只有4个元素,但数组名a此时指向的是第一行元素,而第一行有五个元素,

放不下,只能放四个进去,所以在运行时,会报警告:

//p的类型可以表示为int(*)[4]

//a的类型可以表示为int (*)[5]

“int (*)[4]”和“int (*)[5]”数组的下标不同

当然,程序这样也可以强行运行

图解:

a[4][2]

如图:

&p[4][2] - &a[4][2]

经过上面的解释,我们可以理解他们各自的含义

下面进行二者取出地址之后,再相减,也就是指针变量减指针变量

二者相减,得到的是他们之间的元素个数,为4

我们又知道,数据在存储时是从低地址向高地址存储的,所以, &p[4][2]更小,得到的结果是-4

%p与%d

%p

用%p的形式来打印的话,输出的是-4在内存中的存储形式,也就是补码

下面进行详细说明

//原码:
10000000000000000000000000000100
//反码:
11111111111111111111111111111011
//补码:
11111111111111111111111111111110

但是,这里解释一下%p

%p在打印时认为打印的是地址(这里可以简单地认为是无符号数),所以就直接以16进制的形式打印

11111111111111111111111111111110

提示:二进制中1111对应十六进制中的F

打印结果:

FFFFFFFC

%d

用%d的形式来打印的话,输出结果就是-4

相关文章
|
2月前
|
存储 NoSQL 编译器
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
指针是一个变量,它存储另一个变量的内存地址。换句话说,指针“指向”存储在内存中的某个数据。
122 3
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
|
2月前
|
存储 编译器 C语言
【C语言】指针大小知多少 ?一场探寻C语言深处的冒险 !
在C语言中,指针的大小(即指针变量占用的内存大小)是由计算机的体系结构(例如32位还是64位)和编译器决定的。
143 9
|
2月前
|
安全 程序员 C语言
【C语言】指针的爱恨纠葛:常量指针vs指向常量的指针
在C语言中,“常量指针”和“指向常量的指针”是两个重要的指针概念。它们在控制指针的行为和数据的可修改性方面发挥着关键作用。理解这两个概念有助于编写更安全、有效的代码。本文将深入探讨这两个概念,包括定义、语法、实际应用、复杂示例、最佳实践以及常见问题。
59 7
|
3月前
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
246 13
|
3月前
|
存储 程序员 编译器
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
|
3月前
|
算法 C语言
C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项
本文深入讲解了C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项,通过实例演示了文件操作的基本流程,帮助读者掌握这一重要技能,提升程序开发能力。
205 3
|
3月前
|
存储 算法 程序员
C 语言指针详解 —— 内存操控的魔法棒
《C 语言指针详解》深入浅出地讲解了指针的概念、使用方法及其在内存操作中的重要作用,被誉为程序员手中的“内存操控魔法棒”。本书适合C语言初学者及希望深化理解指针机制的开发者阅读。
|
3月前
|
程序员 C语言
C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门
C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门。本文深入探讨了指针的基本概念、声明方式、动态内存分配、函数参数传递、指针运算及与数组和函数的关系,强调了正确使用指针的重要性,并鼓励读者通过实践掌握这一关键技能。
69 1
|
3月前
|
存储 C语言 计算机视觉
在C语言中指针数组和数组指针在动态内存分配中的应用
在C语言中,指针数组和数组指针均可用于动态内存分配。指针数组是数组的每个元素都是指针,可用于指向多个动态分配的内存块;数组指针则指向一个数组,可动态分配和管理大型数据结构。两者结合使用,灵活高效地管理内存。
|
3月前
|
存储 NoSQL 编译器
C 语言中指针数组与数组指针的辨析与应用
在C语言中,指针数组和数组指针是两个容易混淆但用途不同的概念。指针数组是一个数组,其元素是指针类型;而数组指针是指向数组的指针。两者在声明、使用及内存布局上各有特点,正确理解它们有助于更高效地编程。

热门文章

最新文章