指针笔试题讲解-----让指针简单易懂(2)

目录

回顾上篇重点 :

一.笔试题 ( 1 ) 

二.笔试题 ( 2 )

科普进制知识点

(1) 二进制

(2) 八进制

(3)十六进制

三.笔试题( 3 )

四.笔试题( 4 )

五.笔试题( 5 )

六.笔试题( 6 )


回顾上篇重点 :

数组名的理解 :   数组名就是首元素地址                                                                                

 但是有两个例外:      

1. sizeof(数组名)这里的数组名表示整个数组的大小,sizeof(数组名)计算的是整个数组的大小,单位是字节                                                                                                              

2. &数组名   这里的数组名表示整个数组 ,&数组名取出的是数组的地址


指针变量的大小和类型无关,不管什么类型的指针变量,大小都是4/8个字节
指针变量是用来存放地址的,地址存放需要多大空间,指针变量的大小就是几个字节
32位环境下,地址是32个二进制位,需要4个字节,所以指针变量的大小就是4个字节
64位环境下,地址是64个二进制位,需要8个字节,所以指针变量的大小就是8个字节 


strlen函数,只有遇到 ' \0 ' 时才停止  

sizeof ()是C语言中常用的运算符,可以计算操作数的大小

博主个人建议 : 自己先做一遍,看看哪个做错了,然后再看博主的解释

                          做对的题,自己想想因为什么得这个数,看看与博主的解释一样不

一.笔试题 ( 1 ) 

#include
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)_第1张图片  指针笔试题讲解-----让指针简单易懂(2)_第2张图片 

由上期重点可知:&数组名 , 这里的数组名表示整个数组 ,&数组名取出的是数组的地址

 ptr = &a+1 ,ptr - 1在4和5之间所以*(ptr-1)是 5 ;

*(a+1) ,单独的数组名表示整个数组的大小,除此之外都是首元素地址,所以(a + 1)是首元素地址 + 1 也就是 2

二.笔试题 ( 2 )

//由于还没学习结构体,这里告知结构体的大小是20个字节
//X86 环境下演示
struct Test
{
	int Num;
	char* pcName;
	short sDate;
	char cha[2];
	short sBa[4];
} * p;
//假设p 的值为0x100000。 如下表表达式的值分别为多少?
//已知,结构体Test类型的变量大小是20个字节
//0x开头的数字是16进制的数字
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;
}

注意 :笔试题全套多到防不胜防,看到结果后,请问多少人掉进沟里了

这是一个结构体指针,在 x86 环境下它为20个字节

指针在进行加减法运算时,会跳过其所对应的字节数;例如int* a;在它进行+1后会跳过4个字节

题目中0x是表示十六进制............题目中 p 是一个20个字节的结构体指针,p+1也就是跳过20个字节也就是 0x100000+20(转换成十六进制是+14)所以最后结果为0x100014,关于进制转换不懂的可以看下面的进制的知识点科普

unsigned是类型强制转换,有多少人认为第二个printf输出的0x100004呢,掉进沟里了吧 

此时的p不是指针,而是一个无符号长整型变量,+1只是加了一个字节,打印出来是0x100001

第三个printf,强制转换成了无符号整形指针,+1后其实是跳过了4个字节,打印出来是0x100004

指针笔试题讲解-----让指针简单易懂(2)_第3张图片

科普进制知识点


(1) 二进制

二进制由 0 和 1 两个数字组成,使用时必须以0b或0B(不区分大小写)开头

例如: 0000 00011 十进制为 3   1*1+1*2

         0000 00101 十进制为 5   1*1+1*4

(2) 八进制

八进制由 0~7 八个数字组成,使用时必须以0开头(注意是数字 0,不是字母 o)

例如:015                 十进制为 13       1*8+5*1

         -0101               十进制为 -65    -(1*64+1*1) 

(3)十六进制


十六进制由数字 0~9、字母 A~F 或 a~f(不区分大小写)组成,使用时必须以0x或0X(不区分大小写)开头

例如:  0X2A;              十进制为 42      2*16+10 

         -0XA0               十进制为 -160  -(10*16+0)

三.笔试题( 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;
}

注意 : %x是以十六进制的形式输出整数

指针笔试题讲解-----让指针简单易懂(2)_第4张图片ptr1 = &a + 1

指针笔试题讲解-----让指针简单易懂(2)_第5张图片

第一个printf,这个是强制转换为 int* 形式,ptr1所在的位置是ptr [-1] ,以十六进制打印的话就是4

第二个printf  用到了数据在内存中的存储,如下

大端:是数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中。低地址-->>高数据   例如:手机

 小端:是指数据的地位保存在内存的低地址中,数据的高位则保存在内存的高地址中。低地址-->>低数据    例如:电脑

a是数组首元素的地址,但是题目中强制转化成了int(整形变量),+1跳过了一个字节所以如上面图2把01跳了过去,上面解释了小端的存储形式,低地址就是低数据所以打印出来应该是20000000

四.笔试题( 4 )

#include 
int main()
{
	int a[3][2] = { (0, 1), (2, 3), (4, 5) };
	int* p;
	p = a[0];
	printf("%d", p[0]);//?
	return 0;
}

注意:这个也是有坑的 ,二维数组里面定义的方式是小括号!!!!!

传递后面的数字,所以p[0]的值是1

打印的结果就是1

指针笔试题讲解-----让指针简单易懂(2)_第6张图片正确的是这么画的

五.笔试题( 5 )

int main()
{
	int a[5][5];
	int(*p)[4];//数组指针
	p = a;//类型合适吗?   
	//a - int(*)[5]
	//p - int(*)[4]

	printf("%p, %d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
	//
	//%p是打印地址,认为内存中存储的补码就是地址
	//
	return 0;
}

 指针笔试题讲解-----让指针简单易懂(2)_第7张图片

题目中说了a 一个五行五列的数组,*p是一个行省略四列的数组,,如上图, &p[4][2] - &a[4][2]他们两个相减等于-4,所以%d的值为-4,由于-4不是指针,打印他的十六进制形式就是FFFFFFFC

六.笔试题( 6 )

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

 指针笔试题讲解-----让指针简单易懂(2)_第8张图片

*(ptr1-1)也就是*(&aa+1-1)最后结果是10

*(ptr2-1)也就是(*(aa+1)-1最后结果是5 

 指针笔试题讲解-----让指针简单易懂(2)_第9张图片

还有两道笔试题,在更新下一章的时候补充,记得点个关注,要不然容易找不到!!!!

下一章更新字符串函数,敬请期待

如果有解释的不对或者不清晰,麻烦大佬们海涵,如果可以烦请从评论区指出,我一定会加以修改,万分感谢

最后麻烦大佬们动一下发财的小手一键三连,万分感谢

你可能感兴趣的:(算法,c#,c语言)