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

目录

一.基础

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) 等价于 aa1 是第二行的数组名,是第二行第一个元素的地址。

答案: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;
}

a0 是第一行的数组名,是第一行首元素的地址。 p0 等价于 * (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

p42 --- *(*(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

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

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

相关推荐
麻瓜老宋10 小时前
AI开发C语言应用按步走,表达式计算器calc的第二十二步,分号赋值链式修复、TOKEN_ASSIGN
c语言·开发语言·atomcode
SilentSlot15 小时前
【C/C++】手写 DPDK 协议栈(十一):基于 PPS、SYN 比例和源 IP 熵的 DDoS 检测
c语言·c++·tcp/ip
冻柠檬飞冰走茶17 小时前
PTA基础编程题目集 7-15 计算圆周率(C语言实现)
c语言·开发语言·数据结构·算法
Rabitebla19 小时前
C++ 内存管理全面复习:从内存分布到 operator new/delete
java·c语言·开发语言·c++·算法·leetcode
SilentSlot19 小时前
【C/C++】手写 DPDK 协议栈(八):用五元组 Hash 加速连接定位
c语言·c++·哈希算法
Tisfy20 小时前
LeetCode 3517.最小回文排列 I:排序(Python两行版) / 计数(O(n)时间+O(C)空间+字符串原地修改)
c语言·python·leetcode·字符串·排序·计数排序·回文
菜鸟的升级路20 小时前
C语言栈刷题:LeetCode 20 有效的括号完整解题笔记
c语言·笔记·leetcode
冻柠檬飞冰走茶20 小时前
PTA基础编程题目集 7-13 日K蜡烛图(C语言实现)
c语言·开发语言·数据结构·算法
SilentSlot1 天前
【C/C++】手写 DPDK 协议栈(十二):TCP 并发与自实现 epoll 的就绪事件分发
c语言·c++·tcp/ip
SilentSlot1 天前
【C/C++】手写 DPDK 协议栈(六):TCP 三次握手、状态机与数据回显
c语言·c++·tcp/ip