首页 > 其他分享 >【C语言】_指针面试题

【C语言】_指针面试题

时间:2025-01-14 14:32:14浏览次数:3  
标签:面试题 示例 int C语言 数组 cpp cp 指针

目录

1. 示例1

2. 示例2

3. 示例3

4. 示例4

5. 示例5

6. 示例6

7. 示例7


1. 示例1

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

运行结果如下:

分析:

(1)a=&a[0],a+1=&a[0]+1表示跳过1个整型元素后的地址,解引用得到2;

(2)&a得到整个数组的地址,&a+1表示跳过整个数组后的地址;

将&a+1强转为int*类型,命名为ptr,ptr-1表示前移1个整型元素后的地址,解引用得到5;

2. 示例2

#include<stdio.h>
// 假设结构体大小为20B,平台为x86
struct Test
{
	int Num;
	char* pcName;
	short sDate;
	char cha[2];
	short sBa[4];
}*p = (struct Test*)0x100000;   // p为结构体指针变量,值为0x100000
int main()
{
	printf("%p\n", p + 0x1);                // struct Test类型变量,+1即跳过20(0x14);
	printf("%p\n", (unsigned long)p + 0x1);	// 强转为长整型,+1即数值+1;
	printf("%p\n", (unsigned int*)p + 0x1); // 强转为int*类型(地址),+1即跳过4(x86)
	return 0;
}

运行结果如下(x86):

分析:

(1)struct Test* p=(struct Test*)0x100000表示创建struct Test*类型的结构体指针变量p,并赋值0x100000;(0x100000本身应为int型,故需强转为struct Test*类型)

(2)注意区别数值+1与指针+1,指针+1才与指针类型相关,数值+1就是简单的数值运算

(3)注意十六进制运算,20D=0x14H;

3. 示例3

#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)关于二维数组的初始化:

逐行初始化时,需使用{ } 而非( ),本例中二维数组的(x, y)被识别为表达式:(x, y)=y,

仅初始化了1、3、5三个元素,其余三个元素被默认初始化为0,故数组内容如下:

(2)对于二维数组a,a[0]即第1行的一维数组的数组名=第1行一维数组的首元素a[0][0],

即p = a[0] = &a[0][0],p[0] = *(p+0) = a[0][0] = 1;

4. 示例4

#include<stdio.h>
int main()
{
	int a[5][5];
	int(*p)[4];  // p为数组指针类型,p指向4个整型元素的数组
	p = a;
	printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
	return 0;
}

运行结果如下(x86):

分析:

(1)a既表示二维数组的数组名,也表示二维数组第1行的一维数组的地址,即a=&a[0];

即a是int (* ) [ 5 ] 类型,指向5个整型元素的数组,a为数组指针类型;

p为数组指针类型,指向4个整型元素的数组,即 int (* ) [ 4 ] 类型;

注:对于p=a,由于类型差异,编译器会报警告:

(2)关于输出的指针-指针,| 指针-指针 | = 指针之间的元素个数

有关指针运算,详见下文:

【C语言】_指针运算-CSDN博客icon-default.png?t=O83Ahttps://blog.csdn.net/m0_63299495/article/details/144916134(3)内存分布如下:

可见两地址相差4;

(4)对于%p和%d输出,%d用于打印有符号整数,%p用于打印地址(解析为无符号数)

-4D=(1000 0000 0000 0000 0000 0000 0000 0100)原

=(1111 1111 1111 1111 1111 11111 1111 1100)补 = 0xFFFF FFFCH;

5. 示例5

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

运行结果如下:

分析:

(1)aa=&aa[0],aa+1=&a[0]+1表示跳过一个整型元素,;

&aa得到整个数组的地址,&aa+1表示跳过一整个数组;

(2)对于 int* ptr2 = (int*)(*(aa + 1)) 的理解:

* (aa+1) = * (&a[0]+1 ) = * (&a[1] ) = a[1],

即第2行一维数组的数组名,又可解析为:a[1]=&a[1][0];

(3)内存分布如下:

6. 示例6

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

运行结果如下:

分析:

(1)对于char* a [ ] = {  "work", "at", "alibaba"  } 的理解:

① 对于常量字符串,可使用字符指针方式定义,如:

char* p="abcdef"表示p=&('a'),表示:将常量字符串的首字符的地址赋给字符指针变量p;

② char* a[ ] 表示以数组名为a的数组的元素为char*类型,即a为指针数组,

结合①分析可知:a数组中存放分别指向'w', 'a', 'a'的字符指针变量;

关于常量字符串,参考下文:

【C语言】_字符数组与常量字符串-CSDN博客icon-default.png?t=O83Ahttps://blog.csdn.net/m0_63299495/article/details/145016708(2)pa=a=&a[0],pa++即pa=pa+1=&a[0]+1,由于&a[0]为char*类型,+1则跳过一个char*类型元素,故&a[0]+1=&a[1],指向"at"的'a';

(3)关于%s打印:使用%s打印时,从给定地址开始打印字符串,直至'\0'

(4)内存分布如下:

7. 示例7

#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)未进行自增、自减或解引用操作前的内存分布如下:

(2)对于第一行输出:

++cpp使得cpp存放cp+1,第一次解引用得到cp+1;

cp+1指向c+2,第二次解引用得到c+2;

c+2指向'P',%s输出得到POINT,故输出POINT;

(3)对于第二行输出:

首先明确+优先级最低,其次明确自增++的累计作用,即受第一行影响。

++cpp使得cpp存放cp+2,指向c+1,第一次解引用得到c+1;

--(c+1)使得cp+2指向的空间的内容变为c,c指向ENTER,第二次解引用得到ENTER;

此时char*类型指针c指向'E'(ENTER的第一个E),+3则指向'E'(ENTER的第二个E),%s打印ER:

(4)对于第三行输出:

*cpp[-2] +3即 **( cpp-2 ) +3,cpp-2使得cpp存放内容为cp,第一次解引用得到cp;

cp指向c+3,第二次解引用得到c+3;

c+3指向'F',+3使得c+3指向‘S’,%s打印字符串,输出ST;

(5)对于第四行输出:

cpp [-1] [-1] + 1 即 * ( * ( cpp-1 ) - 1) +1,

cpp-1使得cpp存放的内容为cp+1,第一次解引用得到cp+1;

cp+1指向c+2, 再-1使得cp+1指向c+1,第二次解引用得到c+1;

(c+1)指向NEW,再-1使得c+1指向'E',%s输出得到EW,打印EW;

注:注意不要混淆++与+,--与-,自增++自减--会改变该变量的值(输出一、输出二)输出时进行+-操作只会作用于输出结果,不会改变变量的值(输出三、输出四)

标签:面试题,示例,int,C语言,数组,cpp,cp,指针
From: https://blog.csdn.net/m0_63299495/article/details/145113650

相关文章

  • 【C语言】_字符函数
    目录1.字符分类函数1.1相关函数及其功能1.2使用示例2.字符转换函数2.1相关函数及其功能2.2使用示例1.字符分类函数1.1相关函数及其功能函数其参数符合下列条件则返回真iscntrl任何控制字符isspace空白字符:空格'';换页'\f';换行:'\n';回车:'\r';制表符:'\t';垂直制......
  • 嵌入式基础 C语言预科准备
    一、C语言的基本结构(1)、第一个C程序:helloworld配置部署好vsCode之后,就可以直接在上面写代码了,新建一个新的C程序文件,向屏幕输出一串字符“HelloWorld!”下面,从整体上来分析一下这个最简单的C语言程序,将这个最简程序的各个部分剖析清楚,明白我们写下的每一个字符的具体......
  • 重回C语言之老兵重装上阵(五)C语言作用域规则
    C语言中的作用域(Scope)定义了一个变量或函数名可以被访问的范围。作用域规则帮助我们了解变量和函数在代码中有效的区域。C语言中的作用域主要分为两类:变量作用域和函数作用域。1.作用域的类型C语言的作用域主要可以分为以下几种类型:块作用域(BlockScope):在代码块......
  • 重回C语言之老兵重装上阵(四)vscode配置C语言多文件编译运行
    眨眼睛第一次使用vscode写C语言多文件项目发现插件默认配置只能单文件编译,勃然大怒,于是怒了一下首先明确这一件事,只要有环境C文件就能通过命令行编译,插件只是简化输入命令行的工具,所以我们只需修改插件编译的配置即可一.首先我们需要下载对应插件点击跳转具体插件安装......
  • 大学生一站式C语言
    本文是对菜鸟教程的总结与学习经验window环境配置VisualStudio是由微软公司开发的集成开发环境(IDE),被广泛用于开发各种应用软件,包括桌面程序、网站、移动应用程序等。它提供了一整套开发工具和服务,包括代码编辑器、调试器、版本控制工具等,可以为开发者提供高效、流畅的编......
  • 双指针习题:Binary Deque
    14.BinaryDeque题面翻译BinaryDeque-洛谷|计算机科学教育新生态(luogu.com.cn)有多组数据。每组数据给出\(n\)个数,每个数为\(0\)或\(1\)。你可以选择从两边删数,求至少删几个数才可以使剩下的数总和为\(s\)。如果不能达到\(s\),则输出\(-1\)。题目描述Sla......
  • 查找总价格为目标值的两个商品、三数之和--------双指针的方法解决问题
    OJ题:LCR179.查找总价格为目标值的两个商品-力扣(LeetCode)OJ题:15.三数之和-力扣(LeetCode)一、 查找总价格为目标值的两个商品(俩数之和)1.题目描述购物车内的商品价格按照升序记录于数组 price。请在购物车中找到两个商品的价格总和刚好是 target。若存在多种情况,返回......
  • Java Dubbo 面试题
    谈谈你理解的Dubbo?Dubbo是一个高性能的JavaRPC框架,它提供了服务的注册、发现、调用以及监控等功能,使得开发者可以方便地构建分布式系统和服务化架构。服务治理:Dubbo提供了一套服务治理的解决方案,包括服务的注册、发现、负载均衡、容错和监控等。高性能:Dubbo支持多种协议,如Du......
  • Java高级开发工程师面试题3道
    面试题1:内存泄漏与垃圾回收机制问题:在最近的一个项目中,我们遇到了一个内存泄漏的问题。我们的应用程序运行一段时间后,JVM的堆空间使用率逐渐增加,直到最终触发了OutOfMemoryError错误。你能分析一下可能的原因,并给出解决办法吗?请用具体的例子来说明。回答:内存泄漏是指程......
  • 14. C语言 指针(深入理解)
    本章目录:前言:什么是指针?内存与地址:指针的基础指针的声明与使用指针变量的声明指针与地址的关系空指针与野指针空指针(NULLPointer)野指针(DanglingPointer)指针进阶:从数组到函数指针与数组指针数组指向指针的指针函数指针指针的算术运算常见错误与调试技巧总结前......