c - C 中的数组语法和指针

标签 c arrays string pointers malloc

我对 C 中数组的理解是否正确? 数组只不过是一种语法上的便利,例如,当您在 C 代码中声明一个数组时:

type my_array[x];

编译器认为它等同于:

type *my_array = malloc(sizeof(*my_array) * x);

使用 free 系统调用,一旦我们离开 my_array 的范围,就会释放 my_array

一旦声明了my_array

my_array[y];

不过是:

*(my_array + y)

将其转为字符串;我也想知道幕后发生了什么

char *my_string = "Hello"

my_string = "Hello"

最佳答案

不是,数组对象就是数组对象。 C 有一些奇怪的规则,使它看起来数组和指针是相同的东西,或者至少非常相似,但它们绝对不是。

本声明:

int my_array[100];

创建一个数组对象;对象的大小是 100 * sizeof (int)。它不会创建指针对象。

没有malloc(),甚至是隐含的。 my_array 的存储分配方式与同一范围内声明的任何对象的存储分配方式相同。

可能会让您感到困惑的是,在大多数(但不是所有)上下文中,数组类型的表达式被隐式转换为指向数组第一个元素的指针。 (这为您提供了一个指针值;仍然没有指针对象。)如果数组表达式是一元 &sizeof 的操作数,则不会发生此转换。 &my_array 为您提供数组的地址,而不是一些不存在的指针对象的地址。 sizeof my_array 是整个数组的大小 (100 * sizeof (int)`),而不是指针的大小。

另外,如果你定义一个数组类型的函数参数:

void func(int param[]) { ... }

它在编译时被调整为一个指针:

void func(int *param) { ... }

这不是转换;在那个上下文中(并且仅在那个上下文中),int param[] 真正意味着 int *param

另外,数组索引:

my_array[3] = 42;

是根据指针算法定义的——这意味着前缀 my_array 必须先转换为指针,然后才能对其进行索引。

要记住的最重要的一点是:数组不是指针。指针不是数组。

comp.lang.c FAQ 的第 6 节很好地解释了这一切。

Once my_array is declared

my_array[y];

is nothing more but :

*(my_array + y)

是的,因为 my_array 被转换为指针,并且定义了 [] 运算符,所以 x[y] 表示 *(x+y).

Transposing this to character strings; i was also wondering what was happening behind the curtain with

char *my_string = "Hello"

and

my_string = "Hello"

"Hello" 是一个字符串文字。它是 char[6] 类型的表达式,引用匿名静态分配的数组对象。如果它出现在赋值或初始值设定项的 RHS 上,它会像任何数组表达式一样被转换为指针。第一行初始化 my_string,使其指向 “Hello” 的第一个字符。第二个是做同样事情的指针赋值。

那么这个呢?

char str[] = "Hello";

这是第三个不发生数组到指针转换的上下文。 str 从字符串文字的大小中获取其大小,并将数组复制到 str。这与:

char str[] = { 'H', 'e', 'l', 'l', 'o', '\0' };

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

相关文章:

c - 解释这个程序的输出

objective-c - C 函数和对 Objective-C 实例变量的访问

c++ - 空终止字符串的基本原理是什么?

javascript - 在 JavaScript 或 Typescript 中删除数组数组中的对象

ios - 如何在Swift语言中比较两个忽略大小写的字符串?

python - 解析字符串以查找并删除 float

c++ - OpenSSL 解密 - EVP_DecryptFinal_ex 失败

c - 带有基本参数的 strtod

javascript - 如何访问字典中的特定元素?

java - 使用线程填充 JList