数组,指针 易混题解析(二)

目录

一.基础

1.

2.

二.中等

[1. 坑](#1. 坑)

2.

3.指针+1到底加什么

三.偏难

[1.(小端 x86)](#1.(小端 x86))

2.通过数组指针进行偏移的时候怎么偏移

[3. 大BOSS](#3. 大BOSS)

(1)**++cpp

[(2)*-- * ++cpp + 3](#(2)*-- * ++cpp + 3)

[(3)*cpp[-2] + 3](#(3)*cpp[-2] + 3)

[(4)cpp[-1][-1] + 1](#(4)cpp[-1][-1] + 1)


一.基础

1.

cpp 复制代码
int main()
{
	int a[5] = { 1, 2, 3, 4, 5 };
	int* ptr = (int*)(&a + 1);
	printf("%d,%d", *(a + 1), *(ptr - 1));
	return 0;
}

&a 是整个数组的地址,类型:int (*)[5] &a+1 的类型还是 int (*)[5]

存到 int * 类型的指针 ptr 中,要强制类型转换。

答案:2 5

2.

cpp 复制代码
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;
}

&aa 是整个数组的地址

*(aa+1) 等价于 aa[1] 是第二行的数组名,是第二行第一个元素的地址。

答案:5 10

二.中等

1. 坑

cpp 复制代码
int main()
{
    int a[3][2] = { (0, 1), (2, 3), (4, 5) };
    int* p;
    p = a[0];
    printf( "%d", p[0]);
 return 0;
}

坑:二维数组内部分行的时候,要用 { } 。 这里的 ( )是3个逗号表达式。

所以题目等价于:

cpp 复制代码
int main()
{
	int a[3][2] = { 1, 3, 5 };
	int* p;
	p = a[0];
	printf("%d", p[0]);
	return 0;
}

a[0] 是第一行的数组名,是第一行首元素的地址。 p[0] 等价于 * (p + 0)

答案:1

2.

cpp 复制代码
int main()
{
	char* a[] = { "work","at","alibaba" };
	char** pa = a;
	pa++;
	printf("%s\n", *pa);
	return 0;
}

这里的 char* * pa ,第二个 * 告诉我 pa 是指针 ,指向的是 char* 类型的元素

这里的 a 是数组名,首元素的地址,传给 pa 。pa++ 后, pa 指向 a 第二个空间的地址。

*pa 解引用,a 第二个空间放的是 (char * 类型)'a' 的地址。从这里开始打印,直至 \0

答案:at

3.指针+1到底加什么

指针+1,+的是指针指向对象的大小。

cpp 复制代码
//由于还没学习结构体,这里告知结构体的大小是20个字节
struct Test
{
	int Num;
	char* pcName;
	short sDate;
	char cha[2];
	short sBa[4];
}*p;
//假设p 的值为0x100000。 如下表表达式的值分别为多少?
//已知,结构体Test类型的变量大小是20个字节
int main()
{
	printf("%p\n", p + 0x1);
	printf("%p\n", (unsigned long)p + 0x1);
	printf("%p\n", (unsigned int*)p + 0x1);
	return 0;
}
  1. p 是结构体指针,+1,+的就是一个结构体大小。+20 之后为 0x00100014

  2. p 被强制转换为整型,p 里面的值被强制转换为整数。+1 结果为 0x00100001

  3. p 是整型指针,整型指针+1,跳过1个整型。整型4字节。 结果为:0x00100004

三.偏难

1.(小端 x86)

cpp 复制代码
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);
    // %x :以16进制打印
	return 0;
}

ptr1[-1] 是 *(ptr1 - 1)

注意:指针+1,+的是指针指向对象的大小。

a 是数组首元素的地址,假设为 0x0012ff40 被强制转换为 int (不是指针)。+1后为:0x0012ff41

再被转换为 int * 整型指针 ptr2。

但是,一个整型是4个字节,0x0012ff41 之加了一个字节,ptr2 并不指向 2 所在的地址

找到 ptr2 所指向的位置,再向后访问4个字节

答案:4 ,2000000

2.通过数组指针进行偏移的时候怎么偏移

cpp 复制代码
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;
}

p是指向4个整型的数组指针。对 指针 p+1,跳过4个整型

p 的类型:int (*)[4] a 的类型:int (*)[5]

p[4][2] --- *(*(p+4)+2)

指针-指针,结果是中间元素个数。大-小为正,小-大为负。所以题目中相减结果为 -4

-4 用 %d 打印还是 -4 用 %p 打印:

cpp 复制代码
-4
原码:10000000000000000000000000000100
反码:11111111111111111111111111111011
补码:11111111111111111111111111111100

-4 在内存中以补码形式存放,用 %p 打印时,就认为11111111111111111111111111111100是地址。

地址不存在什么原反补。类似于16进制打印:0x ff ff ff fc

3. 大BOSS

cpp 复制代码
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)**++cpp

cpp 里面存放的是 char** 的地址。++跳过一个 char** 的数据

**++cpp 最终拿到 POINT 里面 P 的地址

结果:POINT

(2)*-- * ++cpp + 3

先 ++cpp ,解引用。**-- 给里面的值自减1,修改了这块地址。**再解引用。+3 后,指向 E 的地址。

结果:ER

(3)*cpp[-2] + 3

cpp[-2] ---- * (cpp - 2) 整个表达式转换:** (cpp - 2) + 3

结果:ST

(4)cpp[-1][-1] + 1

转换:* (* (cpp - 1) - 1) + 1

* (cpp - 1) - 1 这个表达式拿到的值是 c + 1 。不改变里面的值

结果:EW

本篇的分享就到这里了,感谢观看 ,如果对你有帮助,别忘了点赞+收藏+关注

小编会以自己学习过程中遇到的问题为素材,持续为您推送文章。

相关推荐
烂蜻蜓4 分钟前
深度解读 C 语言运算符:编程运算的核心工具
java·c语言·前端
喜欢理工科1 小时前
18 C语言标准头文件
c语言·python·算法·c语言标准头文件
sakabu3 小时前
Linux安装MySQL数据库并使用C语言进行数据库开发
linux·c语言·数据库·笔记·mysql·数据库开发
Peter_Deng.4 小时前
单片机 - 位运算详解(`&`、`|`、`~`、`^`、`>>`、`<<`)
c语言·单片机·嵌入式硬件
阿巴~阿巴~5 小时前
2024年3月全国计算机等级考试真题(二级C语言)
c语言
王RuaRua6 小时前
[数据结构]1.时间复杂度和空间复杂度
c语言·数据结构·算法
wuqingshun3141597 小时前
蓝桥杯 R格式
c语言·c++·算法·职场和发展·蓝桥杯·r语言
努力努力再努力wz7 小时前
【c++入门系列】:引用以及内联函数详解
java·运维·服务器·c语言·开发语言·c++
三体世界8 小时前
C++ STL 序列式容器之(三)-- List
java·c语言·开发语言·c++·windows·list·visual studio
慕洋男孩9 小时前
LeetCode(977):有序数组的平方
c语言·leetcode