广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C语言常见的指针笔试题解析
  • 625
分享到

C语言常见的指针笔试题解析

C语言指针笔试题解析C语言指针笔试题C语言指针 2022-11-13 18:11:02 625人浏览 八月长安
摘要

目录笔试题1笔试题2笔试题3笔试题4笔试题5笔试题6笔试题7笔试题8在我们学习指针之后,应该在实际应用中去理解和掌握它,毕竟实践才是检验真理的唯一标准,我们以后在找工作的过程中免不了

在我们学习指针之后,应该在实际应用中去理解和掌握它,毕竟实践才是检验真理的唯一标准,我们以后在找工作的过程中免不了会遇到与指针相关的试题,本篇文章可以帮助我们提前了解一些常见的指针考点。在学习这篇文章之前可以根据需要对指针进行简要复习。

注:本篇文章所有代码均在X86环境下运行。

笔试题1

#include <stdio.h>
int main()
{
	int a[5] = { 1,2,3,4,5 };
	int* pa = (int*)(&a + 1);
	//&a取的是整个数组的地址,&a的类型为数组指针类型int(*)[5],(int*)是将其强制转换为int* 类型的指针,使其与pa的指针类型相同
	printf("%d %d", *(a + 1), *(pa-1));//输出结果为 2 5
	return 0;
}

解析:

int* pa = (int*)(&a+1)中&a取的是整个数组的地址,(&a+1)的类型为数组指针类型int(*)[5],指向的地址跳过一个a数组的大小,(int*)是将其强制转换为int* 类型的指针,使其与pa的指针类型相同。

由上图可知*(a + 1)得到的值为2,*(pa-1)得到的值为5。

笔试题2

#include <stdio.h>
struct stu {
	int num;
	char* pcname;
	short sdata;
	char ch[2];
	short sarr[4];
}* ps;//p是一个结构体指针变量
//已知,结构体stu类型的变量大小是20个字节
int main()
{
	ps = (struct stu*)0x100000;//强制类型转换为struct stu*
	printf("%p\n", ps + 0x1);//00100014
	printf("%p\n", (unsigned long)ps + 0x1);//00100001
	printf("%p\n", (unsigned long*)ps + 0x1);//00100004
	return 0;
}

解析:

本题考察的是指针±整数指针的变化,ps = (struct stu*)0x100000中ps是结构体指针变量,凡是放在指针变量中的都被当成地址处理,0x100000被强制类型转换为struct stu*类型的指针,放在ps中,此时0x100000就被当成地址处理。

ps + 0x1中,0x1是十六进制数字1,转换成十进制也是1。所以ps+0x1就是ps+1,意思是ps向后走struct stu*类型的字节大小,如 char* 类型的指针+1就是向后走1个字节,因为char占1个字节;int*类型的指针+1就是向后走4个字节,因为int类型占4个字节。而题中ps是struct stu*类型,+1就是向后走20个字节。20转换成十六进制为0x14,0x100000+0x14=0x100014。

(unsigned long)ps + 0x1是将结构体指针变量ps强制类型转换为unsigned long类型,ps+1就是向后走1个字节,unsigned long是无符号长整型,整型+1就是+1,所以为0x100001。

(unsigned long*)ps + 0x1是将无符号长整形ps强制类型转换为unsigned long*类型,ps+1就是向后走4个字节,因为unsigned long类型大小为4个字节,最后为0x100004。

%p–输出的是地址,0x表示数字是十六进制,地址往往以十六进制的形式输出,在X86环境下,地址由4个字节组成,转换为地址后,该代码输出结果为00100014 00100001 00100004。

笔试题3

#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);//输出结果为 4 20000000
	return 0;
}

解析:

%x- - -以十六进制输出。

(int*)(&a + 1)&a取得是整个数组的地址,它的类型为int(*)[4],&a+1跳过一个数组的大小,即跳过16个字节,再强制类型转换为(int*)ptr[-1]*(ptr-1),所以输出为4。

(int*)((int)a + 1)((int)a+1)是将a强制类型转换为int类型后+1,a是数组名,代表着数组首元素的地址。将数组中的元素转换成十六进制后为a[]={0x00000001,0x00000002,0x00000003,0x00000004},VS中采用的是小端存储,在内存中表示如下图。

假设一个数的地址以十六进制表示为0x00000015,强制类型转换成整型之后为21,21+1=22,22转换成十六进制为0x00000016,所以强制类型转换成整型之后再+1相当于地址向后移动了1个字节。因此((int)a + 1)表示a的地址向后移动了1个字节,所以在*ptr2中,从a的位置向后读4个字节,即00000002,因为是小端存储,在读取时就以小端的方式读,所以结果为20000000。

笔试题4

#include <stdio.h>
int main()
{
	int a[3][2] = { (0,1),(2,3),(4,5) };
	//逗号表达式:按照从左到右依次计算,整个表达式的结果为最后一个表达式的值。
	//int a[3][2] = { 1,3,5 };
	int* p;
	p = a[0];
	//a[0],在二维数组中,把每一行都看成一维数组的时候,a[0]是第一行的数组名,数组名表示首元素的地址,即a[0]=&a[0][0]
	printf("%d", p[0]);//输出结果为 1
	//p等于a[0],p[0]等于*(&a[0][0]+0),即数组第一个元素的值。
	return 0;
}

解析:

int a[3][2] = { (0,1),(2,3),(4,5) }中含有逗号表达式(逗号表达式:按照从左到右依次计算,整个表达式的结果为最后一个表达式的值)。计算之后得到数组为int a[3][2] = { 1,3,5 }p = a[0]将a[0]赋值给整型指针变量p,在二维数组中,把每一行都看成一维数组的时候,a[0]表示第一行的数组名,数组名表示首元素的地址,即a[0]=&a[0][0]。p[0]中p等于a[0],p[0]等于*(p+0)等于*(&a[0][0]+0),即数组第一个元素的值1。

笔试题5

#include <stdio.h>
int main()
{
	int arr[5][5];
	int(*p)[4];
	p = arr;
	printf("%p %d\n", &p[4][2] - &arr[4][2], &p[4][2] - &arr[4][2]);//输出结果为 FFFFFFFC -4
	return 0;
}

解析:

本题考察的是指针-指针。int(*p)[4]是数组指针类型,p = arrarr是二维数组数组名,数组名就是首元素的地址,在二维数组中首元素地址就是第一行的地址即&arr[0]&arr[0]int(*)[5]类型数组指针接收,将int(*)[5]类型赋给int(*)[4]类型,可以编译,虽然不会报错但是有警告,因为p是int(*)[4]类型,p+1的时候向后走4个整型,具体可见下图:

p[4][2]可以写成*(*(p+4)+2),位置如上图所示,指针和指针相减的绝对值是元素之间的个数,&p[4][2] - &arr[4][2]是低地址-高地址,得到的是-4。

-4的原码、反码和补码如下表所示:

原码、反码、补码
原码10000000000000000000000000000100
反码11111111111111111111111111111011
补码11111111111111111111111111111100

用%d打印的时候打印的是原码。

%p–输出地址,地址没有原码、反码和补码,在内存中存的是补码,因为打印的地址是一个明确的数-4,打印的时候就把补码当成地址打印,补码转换成十六进制就是FFFFFFFC。

笔试题6

#include <stdio.h>
int main()
{
	int a[2][5] = { 1,2,3,4,5,6,7,8,9,10 };
	int* ptr1 = (int*)(&a + 1);
	int* ptr2 = (int*)(*(a + 1));
	printf("%d %d", *(ptr1 - 1), *(ptr2 - 1));//输出结果为 10 5
	return 0;
}

解析:

&a+1跳过整个二维数组,然后强制类型转换为(int*)类型,*((a+1))中,a是二维数组数组名,表示数组首元素的地址,在二维数组中,数组首元素的地址即第一行的地址,第一行的数组名可以用a[0]表示,*(a+1)可以表示成*(&a[0]+1),&a[0]是int(*)[5]类型,+1之后到二维数组的第二行,所以(*(a+1))就是a[1],a[1]就是第二行数组名,也表示第二行首元素的地址&a[1][0]

笔试题7

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

解析:

char* a[] = { "work","at","alibaba" }a[]是字符指针数组,存的是字符串首字符的地址,char** pa表示pa指向char*类型,char** pa = a表示pa指向a,a是数组名,表示数组首元素的地址,此时,pa指向数组中的第一个元素,pa++表示pa跳过一个char*类型,则pa此时指向数组中的第二个元素,*pa取出数组中第二个元素的首地址,打印字符串。

笔试题8

#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);//输出结果为POINT
	printf("%s\n", *-- *++cpp+3);//输出结果为ER
	printf("%s\n", *cpp[-2]+3);//输出结果为ST
	printf("%s\n", cpp[-1][-1]+1);//输出结果为EW
	return 0;
}

解析:

c数组中存的是字符串首字符的地址,c+1c是数组名,数组名表示数组首元素的地址,因为数组c里面的数据类型是char*类型的,存放的是字符串首字符的地址,数组首元素就是字符的地址,地址的地址要用二级指针来接收,所以用char**c+1之后指向数组c中第二个元素的地址,c+2指向第三个元素的地址,c+3指向第四个元素的地址,而c数组中的元素都是字符串首字符的地址。数组cp中的元素类型都是char**类型,要用char***类型接收。

cpp指向的类型是 char**char*** cpp = cpcp是数组名,表示数组首元素的地址,刚开始三级指针 cpp指向 cp数组中的 c+3的地址,**++cpp++cpp之后指向c+2的地址,第一次解引用 *++cpp(解引用操作得到的是指针指向地址中所存放的内容),得到的是c+2c+2指向的是数组c中第三个元素的地址,再次解引用之后得到的是c数组中存放字符串POINT首字符的地址,打印字符串得到POINT。

*-- *++cpp+3+ 的优先级比++--*的优先级低,所以+3放在最后计算, ++cpp执行后cpp指向cp数组c+1的地址,解引用得到c+1--(c+1)执行后cp数组中元素c+1变为cc指向数组c中第一个元素的地址,解引用之后得到字符串ENTER首字符的地址,+3向后移动3个字节,得到ER。

*cpp[-2]+3等于*(*(cpp-2))+3(cpp-2)表示指向数组cpc+3的地址,但是cpp指向的位置没有发生改变,*(cpp-2)表示解引用之后得到c+3c+3指向数组c中第四个元素的地址,再次解引用得到的是字符串FIRST首字符的地址,+3向后移动三个字节,打印ST。

cpp[-1][-1]+1等于*(*(cpp-1)-1)+1,因为cpp指向的位置没有发生改变,所以cpp-1指向数组cpc+2的地址,*(cpp-1)后得到c+2*(cpp-1)-1等于(c+2)-1c+1c+1指向数组c中第二个元素的地址,*(*(cpp-1)-1)执行后得到字符串NEW首字符的地址,+1向后移动1个字节指向E,打印字符串为EW。

到此这篇关于C语言常见的指针笔试题解析的文章就介绍到这了,更多相关C语言指针内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C语言常见的指针笔试题解析

本文链接: https://www.lsjlt.com/news/170232.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C语言常见的指针笔试题解析
    目录笔试题1笔试题2笔试题3笔试题4笔试题5笔试题6笔试题7笔试题8在我们学习指针之后,应该在实际应用中去理解和掌握它,毕竟实践才是检验真理的唯一标准,我们以后在找工作的过程中免不了...
    99+
    2022-11-13
    C语言指针笔试题解析 C语言指针笔试题 C语言指针
  • C语言指针笔试题全面解析
    目录前言一、指针笔试题 1.题目如图:2.题目如图: 3.题目如图:4.题目如图:   5.题目如图:6.题目如图:7.题目如图:&...
    99+
    2022-11-12
  • C语言经典指针笔试题详解
    目录题目一(有关传值调用与非法访问)题目二 (返回栈空间地址的问题 )题目三 (区别传值调用的传址调用)题目四 (free释放的时机)🎇结尾:题目一(有关传值调用与非...
    99+
    2022-11-12
  • C语言中指针和数组试题详解分析
    目录数组题:程序一(一维数组):字符数组程序二(字符数组):程序三(字符数组):程序四(字符数组):程序五(字符数组):二维数组程序六( 二维数组):指针题程序七( 指针):程序八(...
    99+
    2022-11-12
  • 【C进阶】指针和数组笔试题解析
    做题之前我们先来回顾一下 对于数组名的理解:除了以下两种情况,数组名表示的都是数组首元素的地址 (1)sizeof(数组名):这里的数组名表示整个数组 (2)&(数组名) :这里的数组名也表示整个数组 一、一维数组 int a[]...
    99+
    2023-09-26
    c语言 算法 开发语言
  • C语言中二级指针解析(指向指针的指针)
    目录二级指针(指向指针的指针)二级指针的定义与理解二级指针定义格式二级指针赋值实例二级指针(指向指针的指针) 指针可以指向一份普通类型的数据,例如 int、double、char 等...
    99+
    2022-11-13
  • C语言八道笔试题精讲带你掌握指针
    目录题目一题目二题目三题目四题目五题目六题目七题目八为了题目的准确性和我们一般学习过程中的习惯,这里所有的题目代码都是在 X86 环境(32 位平台)下运行的。 题目一 #inclu...
    99+
    2022-11-13
  • C语言 指针综合解析
    目录指针总结1.指针的本质1.1 指针的定义1.2 取地址操作符与取值操作符2.指针的使用场景2.1 指针的传递2.2 指针的偏移(指针的加减)2.3 指针与自增、自减运算符2.4 ...
    99+
    2022-11-12
  • C语言利用面试真题理解指针的使用
    目录前言笔试题一笔试题二笔试题三笔试题四笔试题五笔试题六笔试题七笔试题八前言 大家好~我又来了,今天给大家带来的是指针的几道笔试题,希望能够加强大家对指针知识的把握,指针就应该这样学...
    99+
    2022-11-13
    C语言 指针 C语言 面试 指针
  • C语言中指针常量和常量指针的区别
    在面试中我们经常会被面试官问到什么是常量指针,什么又是指针常量。 指针常量就是指针本身是常量,指针里面所存储的内容(内存地址)是常量,不能改变。但是,对应内存地址里存的内容是可以通过...
    99+
    2022-11-12
  • C语言的指针类型详细解析
    指针存储了内存的地址,同时指针是有类型的,如int*,float*,那么,一个自然的猜想就是指针变量应该存储这两方面的信息:地址和指针类型,比如,就像下面的结构体:复制代码 代码如下...
    99+
    2022-11-15
    C语言 指针类型
  • C语言sizeof和strlen的指针和数组面试题详解
    目录一、概念         sizeof:strlen:二、例题及解析2.1 一维数组2.2 字符数...
    99+
    2022-11-13
  • C语言浅析指针的使用
    目录指针等价形式转换函数指针主函数指针 指针是一个变量 (1) 作用:只能存储地址的值 (2) 大小:32位操作系统中占4字节;64位操作系统中占8字节 (3) 取地址:& ...
    99+
    2022-11-13
  • C语言的空类型指针,空指针,野指针详解
    目录空类型指针-void*空指针-NULL野指针造成野指针的原因1.指针未初始化2.指针越界访问3.指针指向的空间已经释放避免野指针总结空类型指针-void* void是空类型,vo...
    99+
    2022-11-12
  • C语言结构体指针案例解析
    写结构体指针前,先说一下 . 号和 -> 的区别 记得当初刚学C语言的时候,搞不清结构体的 . 号和 -> ,经常混淆二...
    99+
    2022-11-12
  • C语言例题讲解指针与数组
    目录1.概要复习2.指针与数组笔试题2.1一维数组2.2字符数组2.3字符串数组2.4字符串指针2.5二维数组1.概要复习 本篇的内容主要围绕指针与数组、指针与字符串等之间的关系,以...
    99+
    2022-11-13
  • C语言常见的面试题有哪些
    这篇文章主要讲解了“C语言常见的面试题有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C语言常见的面试题有哪些”吧!第1题:c语言有哪些核心的特征可移植性很强。模块化能力很强。灵活性很高...
    99+
    2023-06-04
  • C++中常见的空指针异常问题解决方案
    C++中常见的空指针异常问题解决方案引言:在C++编程中,空指针异常是一种常见的错误类型。当程序试图访问指向空地址的指针时,就会导致空指针异常的发生。在大型项目中,空指针异常可能会导致程序崩溃或产生不可预期的行为。因此,开发人员需要了解如何...
    99+
    2023-10-22
    C++ 解决方案 空指针异常
  • C语言的数组指针与函数指针详解
    目录前言函数指针语法数组指针与指针数组总结前言 数组指针和函数指针都是C语言比较难的知识点,尤其是函数指针,并且函数指针在开发中有着巨大的作用。 函数指针语法 定义一个函数指针,并通...
    99+
    2022-11-13
  • 深入理解C语言的指针
    目录起源进程内存布局栈设置分配方式特点堆分配方式特点堆与栈区别扩展总结起源 之前在知乎上看了一句话,指针是C的精髓,也是初学者的一个坎。换句话说,内存管理是C的精髓,C/C++可以直...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作