【C语言】指针练习题目

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

前言(C语言与指针,指针与题?)

提示:这里可以添加本文要记录的大概内容:

指针,是C语言的灵魂所在,而题目,是掌握指针的关键,下面通过精选几道题目,带同学深入理解指针精妙之处~


提示:以下是本篇文章正文内容,下面案例可供参考

T1:

#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));
  return 0;
}
//程序的结果是什么?

题解:(下面通过图文解析来刨析本题目)

答案:2,5

为了便于大家理解,特地给大家作了图为大家参考:

1.首先,代码创建了一个每个元素为int类型的,名字叫做a,的一维数组,共计5个元素

2.之后代码(取地址数组名+1)这个取地址数组名怎么理解?这是整个数组的地址,这个取地址数组名的类型是int ✳[5],加一会跳过整个数组,地址来到数字5后面的内存空间,之后再将这个地址强制类型转换为int*类型

3.最后打印:第一个✳(a+1)是数组名加1,数组名是数组首元素的地址,其类型是int类型,加一会跳过一个int类型的长度空间,来到指向数字2的地址,解引用这个指向数字2的地址,会得到数字2,同理,ptr因为被强制转换为int类型,所以str-1会跳过一个int类型大小的空间,指向数字5的空间,解引用拿到数字5

T2:

//在X86环境下
//假设结构体的⼤⼩是20个字节
//程序输出的结构是啥?
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;
}

答案:0x100014,0x10001,0x10004;

同样,为了便于大家理解,我们以图的形式对main函数之前的代码加以解析,再以文字的形式简单介绍一下后面的代码含义:

之后,我们再来分析main函数中的打印函数:

1.p+0x10x1是一个十六进制数字,其值还是数字1,p是一个指针变量,是一个地址,一个指针加整数,跳过多大内存取决于变量p的类型的内存大小,我们从题目中可以看到,该结构体大小为20,所以跳过20个字节,得到地址:0x100014;

2.剩下两个的话,还是同样的道理,,但是需要注意:指针p加一个数字1跳过的字节取决于p类型的大小,但是一个数字加上一个数字是几就是几… p被强转为无符号longlong类型,,属于整形类型,不是指针!!!所以跳过1个字节到答案0x10001;

3.第三个跟第一个同理,指针加整数跳过几个字节取决于p指针的类型,int是4个字节,加一就是加一个int类型大小,跳过4个字节,得到答案0x10004。

T3:

代码如下(示例):

#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

解析:

这个题目,不知道有没有同学进坑呢?以为二维数组的存储方式是这样的:

但是,因为里面是逗号表达式,小括号里面的数字取最后一个,所以是这样滴:

1.int*p;这是创建了一个指向int类型的指针变量p;

2.之后有同学就奇怪了,怎么好像把第一行给p了???我们把二维数组首元素a【0】也就等同于一维数组a【0】第一行的名称,数组名称又等同于一维数组a【0】首元素的地址,也就是把数字1的地址给了p!!!

3.我们打印的时候,p【0】可以理解为✳(p+0),所以说顺利解引用拿到了数字1并进行打印~

T4:

//假设环境是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]);
  return 0;
}

答案:FFFFFFFC,-4

解析:

本题的主要奇怪的地方呢是,数组a是由5个一维数组int【5】组成的,但是创建变量接收的时候,变量的类型是int*【4】的类型,我们下面通过画图来进一步理解:


我们知道:

&p[4][2]可以等价于&✳(✳(p+4)+2)

&a[4][2]可以理解为&✳(✳(a+4)+2)

那么放在咱们数组中,可以得出以下图表:

1.指针减指针,得到的是两者间的元素个数,所以说呢,第二个空答案是-4(因为是小地址-大地址)

2.至于第一个空,因为要打印地址,是按照16进制形式进行打印,并且编译器先把-4转变成为补码,-4变成11111111111111111111111111111100,而对于地址没有反码补码的概念,编译器将这个-4的补码直接转换为地址,变成FFFFFFFC,并打印出来~

T5:

#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;
}

答案:10,5

解析:

我们通过画图的形式,来进一步展示本题目中的逻辑关系,请仔细看图:

为什么ptr1-1往前走一个元素大小呢?因为被强转为了int*类型; str2也是一样的道理。

T6:

#include <stdio.h>
int main()
{
  char* a[] = { "work","at","alibaba" };
  char** pa = a;
  pa++;
  printf("%s\n", *pa);
  return 0;
}

答案:at

解析:

首先,

我们解引用pa,拿到的是a+1的内容,a+1的内容是一个地址,我们打印字符串的时候就是需要字符串首字母的地址,遇到\0停止打印,这样顺利打印at;

T7:

代码如下:

#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;
}

答案:POINT ER ST EW

解析:前面已经做过了六道指针题目,相比大家对于指针以及指针类型理解已经有了一定的认知,不妨最后一题我稍作解释,留下一部分空间供大家发挥:

总结(指针的理解)

本文以题目为切入点,举了7道典型题目,分别考究了对于指针的不同角度理解。

希望同学们对指针的理解能够有更深入的理解,加深理解~

相关文章
|
2月前
|
存储 编译器 C语言
【C语言】【指针1】指针难?看这个就够了!
【C语言】【指针1】指针难?看这个就够了!
|
26天前
|
存储 C语言
【C语言基础】一篇文章搞懂指针的基本使用
本文介绍了指针的概念及其在编程中的应用。指针本质上是内存地址,通过指针变量存储并间接访问内存中的值。定义指针变量的基本格式为 `基类型 *指针变量名`。取地址操作符`&`用于获取变量地址,取值操作符`*`用于获取地址对应的数据。指针的应用场景包括传递变量地址以实现在函数间修改值,以及通过对指针进行偏移来访问数组元素等。此外,还介绍了如何使用`malloc`动态申请堆内存,并需手动释放。
|
29天前
|
存储 人工智能 C语言
C语言程序设计核心详解 第八章 指针超详细讲解_指针变量_二维数组指针_指向字符串指针
本文详细讲解了C语言中的指针,包括指针变量的定义与引用、指向数组及字符串的指针变量等。首先介绍了指针变量的基本概念和定义格式,随后通过多个示例展示了如何使用指针变量来操作普通变量、数组和字符串。文章还深入探讨了指向函数的指针变量以及指针数组的概念,并解释了空指针的意义和使用场景。通过丰富的代码示例和图形化展示,帮助读者更好地理解和掌握C语言中的指针知识。
|
2月前
|
C语言
C语言------指针
这篇文章是关于C语言中指针的实训,通过示例代码展示了指针的基本概念、定义、赋值、使用和传递,以及指针运算和指针在函数参数中的应用,如交换两个变量的值和找出两个数中的较小值。
C语言------指针
|
1月前
|
存储 安全 C语言
C语言 二级指针应用场景
本文介绍了二级指针在 C 语言中的应用,
|
2月前
|
存储 编译器 C语言
【C语言篇】深入理解指针2
代码 const char* pstr = "hello world."; 特别容易让初学者以为是把字符串 hello world.放 到字符指针 pstr ⾥了,但是本质是把字符串 hello world. 首字符的地址放到了pstr中。
22 1
|
2月前
|
存储 程序员 编译器
【C语言篇】深入理解指针1
assert.h 头⽂件定义了宏 assert() ,⽤于在运⾏时确保程序符合指定条件,如果不符合,就报错终⽌运⾏。这个宏常常被称为“断⾔”。
24 1
|
2月前
|
存储 搜索推荐 C语言
C语言中的指针函数:深入探索与应用
C语言中的指针函数:深入探索与应用
|
2月前
|
C语言 Python
C语言指针(2)
C语言指针(2)
26 5
|
2月前
|
存储 C语言
C语言指针(1)
C语言指针(1)
24 5