C语言中数组,数组和&array [0]之间有什么区别?

Cir*_*Bop 2 c arrays pointers

我在C语言中学习数组和指针时感到困惑,为什么ch,&ch,&ch [0]恰好彼此相等,而sptr,&sptr和sptr [0]不是?这是我的源代码:

int main(void)
    {
        char ch[7] = { '1','2','3','4','5','6','0' };
        char *sptr = "132456";
        double db[4] = { 1.0,2.0,3.0,4.0 };
        printf("\n%p  %p  %p\n", ch, &ch,&ch[0]);
        printf("\n%p  %p  %p\n", sptr, &sptr,&sptr[0]);
        printf("\n%p  %p  %p\n", db, &db,&db[0]);
        return 0;

    }
Run Code Online (Sandbox Code Playgroud)

我机器上的输入是:

00FDFD68  00FDFD68  00FDFD68

00037CD0  00FDFD5C  00037CD0

00FDFD34  00FDFD34  00FDFD34
Run Code Online (Sandbox Code Playgroud)

dav*_*mac 6

在大多数(尽管不是全部)上下文中,数组"衰减"为指向其第一个元素的指针.这就是为什么ch,并&ch[0]在你的榜样(数组元素访问具有比运营商"的地址为"更高的优先级,因此后者也可以写成相同&(ch[0])).

剩下的&ch是一个数组不会衰减成指针的情况; 相反,你得到了数组的地址.当然,这与数组的第一个元素的地址相同 - 但是,重要的是,它具有不同的类型; 它是类型char (*)[7],即指向具有7个元素的char数组的指针.另外两个指针是类型的char *,即指向个体的指针char.

既然sptr是一个指针,&sptr那个指针的地址自然会有所不同.&sptr[0]相当于sptr + 0,当然等于sptr.

你不明白为什么sptr&sptr产生不同的地址表明对指针的误解.指针是一个固定大小的对象,其值可以引用(指向)特定类型的某个任意对象.因为它本身就是一个对象,所以可以使指针指向不同的对象.另一方面,数组变量始终(在其生命周期内)引用相同的数组对象.

在您的示例输出中:

00037CD0  00FDFD5C  00037CD0
Run Code Online (Sandbox Code Playgroud)

第一个值00037CD0是sptr点的位置- 也就是说,它是字符串常量"132456"的内存位置.第二个值00FDFD5C是sptr变量本身的地址.这表明在地址00FDFD5C处有一个指针对象,它保存值00037CD0.

从本质上讲,两种情况之间的区别归结为:

  • 数组的地址与其第一个元素的地址相同
  • 另一方面,指针的地址与指针当前指向的内容无关.


Som*_*ude 5

如果我们将其“绘制”出来,您的数组ch在内存中将如下所示:

+-----+-----+-----+-----+-----+-----+-----+
| '1'| '2'| '3'| '4'| '5'| '6'| '0'|
+-----+-----+-----+-----+-----+-----+-----+
^^
| |
| &ch[1]
|
&ch
^
|
&ch[0]

正如您所看到的,两者&ch&ch[0]指向同一位置。但这两个表达式之间有一个重要的区别:是指向数组的&ch指针,而是指向数组中元素的指针。这两个指针具有不同的类型:具有类型而具有类型。即使两者都是指向同一位置的指针,类型的差异也会使其在语义上有很大不同。&ch[0]&chchar (*)[7]&ch[0]char *

现在来看看如何array融入这一切。对于任何数组或指针a和索引i,表达式a[i]等于*(a + i)。这意味着&a[i]等于&*(a + i)。地址运算符和解引用运算符相互抵消,这意味着&a[i]等于(a + i)。如果索引为零,则&a[0]等于(a + 0),但由于向任何内容添加零都是无操作,因此它也等于 ,而(a)等于a。因此&a[0]等于a. 当您看到有人说数组衰减为指向其第一个元素的指针时,这就是他们的意思。在表达式中使用数组a与使用 相同&a[0]


在一个不相关的注释中,该数组ch可能是字符数组,但它不是字符串。这是因为在 C 语言中字符串实际上称为空终止字符串。在这种情况下,单词“null”不是空指针,而是整数(不是字符)零。

这意味着您不能使用ch任何需要字符串的函数,因为这会导致未定义的行为,因为它们超出了寻找终止符的范围。