指针和数组笔试题深度解析(下)一

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 指针和数组笔试题深度解析(下)

前言


上期我们介绍了strlen、sizeof的各种用法,本期带大家来学习指针类的笔试题。大家也要多多思考才行。


指针笔试题


首先我们来了解两点:


%p是打印地址

%x是以16进制形式打印


题一


#include<stdio.h>
int main()
{                 //程序的结果是什么?
  int a[5] = { 1, 2, 3, 4, 5 };
  int *prt = (int *)(&a + 1);
  printf( "%d,%d", *(a + 1), *(prt - 1));
  return 0;
}


输出:2,5

分析:

我们知道 &a+1 里 &a 取出的是整个数组地址(&a的类型是 int(*)[5] ,该类型大小为5个字节长度) +1 是跳过整个数组,指向的位置如图:


652e212b07604b2f9729a1a0fd9c0e9f.png


前面加个 (int *) 是强制类型转换的意思,将 int( * )[5] 类型强制转换为 int 类型,那么该类型的变量加一减一所跳过长度就是4字节(上期有讲过指针变量加一减一步长)

因此,prt - 1 所指向的位置如下图:


961bbfa558c1499889e0bf36593ef8b3.png


解引用就得到 5 ,(a + 1)==>a[1] ,也就是2.


题二


我们来看一道关于结构体指针的例题:


#include<stdio.h>
struct Test
{
  int Num;
  char* pcName;
  short sDate;
  char cha[2];
  short sBa[4];
}*p;
//假设 p 的值为0x100000。 如下表表达式的值分别为多少?
//已知,结构体Test类型的变量大小是20个字节
int main()
{
  p = (struct Test*)0x100000;    //因为0x100000的类型是int型,所以要强制类型转换
  printf("%p\n", p + 0x1);
  printf("%p\n", (unsigned long)p + 0x1);
  printf("%p\n", (unsigned int*)p + 0x1);
  return 0;
}


本题考查指针加一步长多少?

输出:


6a28d0059ee4455db9cf12e714ef8e89.png


分析:


p = (struct Test*)0x100000;    
  printf("%p\n", p + 0x1);    //00100014    
  //指针 p 所指向的类型是 struct Test ,该类型占20字节单位,因此加一跳过20字节。
  printf("%p\n", (unsigned long)p + 0x1);   //00100001
  //强制类型转换为 unsigned long 类型,就是一个整数,整数加一就是加一个字节
  printf("%p\n", (unsigned int*)p + 0x1);   //00100004
  //强制类型转换为 unsigned int* 类型,p就指向一个无符号整型,占4个字节,加一就是加4个字节


题三


#include<stdio.h>
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

分析:


int a[4] = { 1, 2, 3, 4 };
  int* ptr1 = (int*)(&a + 1);      //&a取出整个数组地址,加一跳过整个数组,强制类型转换为int *型,prt1指针指向下图1位置
  int* ptr2 = (int*)((int)a + 1);  //将首元素地址强制类型转换为整型,加一跳过一个字节,再转换回来,int*类型解引用访问4个字节,见图二
  printf("%x,%x", ptr1[-1], *ptr2);   //prt1[-1]==>*(prt1-1),prt1-1指向下图1位置


图一:


e85359704bb64a75b8022a40daec9ab0.png


图二:


e5fa6053239a4d02bb9067b1800360ea.png


题四


#include <stdio.h>
int main()
{
  int a[3][2] = { (0, 1), (2, 3), (4, 5) };   数组的初始化内容有逗号表达式,实际上数组初始化的是1,3,5
  //如果要将上数全部存进去,可以这样写{{0,1},{2,3},{4,5}},或者{0,1,2,3,4,5}
  int* p;
  p = a[0];
  printf("%d", p[0]);
  return 0;
}


输出:1

解析:


int a[3][2] = { (0, 1), (2, 3), (4, 5) };
  int* p;
  p = a[0];    //将a[0][0]存放入p中
  printf("%d", p[0]);


题五


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


输出:


7db28c48753c4cbcbdc977a9b6d3dad7.png


解析:

p的首地址指向a的首地址,我们将数组a画出来,指针p指向的数组是4个元素,如下:


c0066b908c1149338b630a7f24105c2c.png


所以,p[4][2]和a[4][2]如图:


67ca0da91b074966990f724d2a6625c4.png


&p[4][2] - &a[4][2],指针相减结果就是两地址间的元素个数,就是4,但是它是小的减大的所以是-4,以%p打印就是FFFFFFFC,以%d打印就是-4


相关文章
|
2月前
使用指针访问数组元素
【10月更文挑战第30天】使用指针访问数组元素。
46 3
|
2月前
|
存储 程序员 编译器
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
|
2月前
|
存储 C语言 计算机视觉
在C语言中指针数组和数组指针在动态内存分配中的应用
在C语言中,指针数组和数组指针均可用于动态内存分配。指针数组是数组的每个元素都是指针,可用于指向多个动态分配的内存块;数组指针则指向一个数组,可动态分配和管理大型数据结构。两者结合使用,灵活高效地管理内存。
|
2月前
|
容器
在使用指针数组进行动态内存分配时,如何避免内存泄漏
在使用指针数组进行动态内存分配时,避免内存泄漏的关键在于确保每个分配的内存块都能被正确释放。具体做法包括:1. 分配后立即检查是否成功;2. 使用完成后及时释放内存;3. 避免重复释放同一内存地址;4. 尽量使用智能指针或容器类管理内存。
|
2月前
|
存储 NoSQL 编译器
C 语言中指针数组与数组指针的辨析与应用
在C语言中,指针数组和数组指针是两个容易混淆但用途不同的概念。指针数组是一个数组,其元素是指针类型;而数组指针是指向数组的指针。两者在声明、使用及内存布局上各有特点,正确理解它们有助于更高效地编程。
|
1月前
|
存储 程序员 C++
深入解析C++中的函数指针与`typedef`的妙用
本文深入解析了C++中的函数指针及其与`typedef`的结合使用。通过图示和代码示例,详细介绍了函数指针的基本概念、声明和使用方法,并展示了如何利用`typedef`简化复杂的函数指针声明,提升代码的可读性和可维护性。
80 0
|
2月前
|
存储 人工智能 算法
数据结构实验之C 语言的函数数组指针结构体知识
本实验旨在复习C语言中的函数、数组、指针、结构体与共用体等核心概念,并通过具体编程任务加深理解。任务包括输出100以内所有素数、逆序排列一维数组、查找二维数组中的鞍点、利用指针输出二维数组元素,以及使用结构体和共用体处理教师与学生信息。每个任务不仅强化了基本语法的应用,还涉及到了算法逻辑的设计与优化。实验结果显示,学生能够有效掌握并运用这些知识完成指定任务。
68 4
|
2月前
使用指针访问数组元素
【10月更文挑战第31天】使用指针访问数组元素。
54 2
|
2月前
|
算法 索引
单链表题+数组题(快慢指针和左右指针)
单链表题+数组题(快慢指针和左右指针)
43 1
|
2月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
108 2

热门文章

最新文章

推荐镜像

更多