c - 了解 C 中的数组指针初始化语法

标签 c arrays

<分区>

我有 Java 背景,在 C 中我对 C 数组语法有点困惑。

当我在 C 中初始化数组时,我会这样做:

int arr[5];

据我正确理解,这实际上给出了一个指向 arr 的指针,该指针指向堆栈中数组的第一个元素。

但是后来我不明白为什么数组初始化看起来不像这样,因为我们收到了一个指针:

int* arr[5];

这给了我一些我不明白的东西。也许是 5 个指针的数组?

另一方面,这又是完全有效的:

int arr[5];
int* p = arr;

那么为什么要这样做呢?初始化语法不应该使用 int* 而不是 int 吗,因为我们实际上收到了一个指针?

最佳答案

在 C 语法中,此行声明了一个包含 5 个指向 int 的指针的数组。

int* arr[5];

下面声明了一个包含 5 个 int 的数组。

int arr[5];

上面这行代码告诉编译器在从 &arr[0] 开始的相邻内存地址中保留 5 倍于 int 大小的内存。虽然 arr 不是指针,但如果用作名称 arr 本身,它会衰减为指向第一个槽的指针(因此 arr 是相当于 &a[0]).

int* p = arr; 

p 是指向int 的普通指针,分配给一个有效的内存地址,与arr(或&arr[ 0])

数组和指针不同。第一个区别是“arr”是一个常量,不能重新分配给其他地址。

例如以下是无效的

arr++;

虽然以下是有效

p++;

此外,指针需要额外的取消引用底层 ASM 操作,而数组则不需要

char arr[7];
char *p = arr;

数组索引

比较这一行和它的 ASM 指令:

char a = arr[7];

0041137E mov al,byte ptr [_array_place+7 (417007h)]

00411383 mov byte ptr [a],al


指针索引:

使用这一行及其 ASM 指令:

char b = p[7];

00412DD7 mov eax,dword ptr [ptr_arg]

00412DDA mov cl,byte ptr [eax+7]

00412DDD mov byte ptr [b],cl


数组可以衰减到指向第一个元素的指针。这种情况经常发生,例如当您将它们作为函数参数传递时。在这种情况下,将它们视为被调用函数内的指针。您最终可以将它们标记为 constant pointers or pointers to constant or constant pointers to constant .

我希望这能澄清。

关于c - 了解 C 中的数组指针初始化语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50433848/

相关文章:

c - strsep() 没有按预期工作

c - LPdir 未实现,它是做什么用的?

c - 替换数组中的元素

c - Microplax 应用中的 Lwip 缓冲区

c - 段错误,地址越界

sql - 来自 PostgreSQL jsonb 数组的值查询

c - 指向数组的指针与数组名称有何不同?

java - 修改数组列表中的某个元素

php - 将数据库查询结果格式化为 JSON 数组并读入表单

c# - "System.ArgumentException: ' 不存在从对象类型 Newtonsoft.Json.Linq.JValue 到已知托管提供程序 native 类型的映射。