gpt4 book ai didi

c - 二维数组变量指针混淆

转载 作者:太空狗 更新时间:2023-10-29 14:57:56 25 4
gpt4 key购买 nike

我对二维数组(C语言)有一个基本的疑问。考虑如下声明二维数组

int array[3][5];

现在当我执行以下操作时,printf 下面的两个输出是相同的:

printf("%u\n", array);
printf("%u\n", *(array));

现在尝试以下操作:

printf("%u\n", array+1);
printf("%u\n", *(array)+1);

输出不同。我知道第二个 printf 指向数组[0][1],第一个指向数组[1][0]。这是如何运作的?数组是指向什么的指针?

提前致谢

最佳答案

我会尽量给你一个技术上正确的解释,这样你就会知道发生了什么。并不复杂,但确实违反直觉。

简介:

在 C 语言中,有“左值”,基本上表示在内存中某处有一个位置的“可分配”对象,以及表示“概念”值(不需要特别放置在任何地方)的“右值”。

例如,如果您定义 int a = 5;,则 a 是一个类型为 int 且值为 5 的左值。它也可以被解释为(或者更确切地说,转换为)一个 int 类型的右值。这样的右值仍然已知等于 5,但它不再包含有关 a 在内存中的位置的信息。

有些表达式需要左值(比如 operator= 的左边,因为你必须给一个对象赋值),有些需要右值(比如 operator+,因为你只在加法时需要整数值,或者运算符=)。如果一个表达式需要一个右值,但你传递了一个左值,那么它会被转换为一个右值。

此外,只有右值被传递给 C 中的函数(这意味着 C 是严格的按值调用,而不是按引用调用)。

一些例子:

int a = 1;
a; // a is an lvalue of type int and value 1
a = a+3; // here the `a` is converted to an rvalue of type int and value 1, then after the addition there's an assignment, on the lhs there's an lvalue `a` and an rvalue `4`

从左值到右值的转换通常是微不足道且不易察觉的(这就像从标记为 a 的架子上取走数字 5)。数组在这里基本上是个异常(exception)。

重要的是:C 中没有数组类型的右值。有指针左值和右值、整数左值和右值、结构左值和右值等……但只有左值数组。当您尝试将数组类型的左值转换为右值时,您不再拥有数组,而是指向数组第一个成员的指针。这是 C(和 C++)中数组混淆的根源。

解释:

  • 数组
  • *(数组)
  • 数组+1
  • *(array)+1

arrayint[3][5] 类型的左值(3 个 int,每 5 个 int 组成的数组)。当您尝试将它传递给一个函数时,它会收到一个类型为 int (*)[5] 的指针(指向 5 个整数的数组的指针),因为这是左值到右值转换后剩下的。

*(array) 是骗子。首先执行左值到右值,生成 int(*)[5] 类型的右值,然后 operator* 获取该右值并返回 类型的左值code>int[5],然后您尝试将其传递给函数。因此,它再次被转换为右值,产生 int*

array+1 导致数组被转换为 int(*)[5] 类型的右值并且该右值递增 1,因此(根据指针算法的规则)指针向前移动 1 * sizeof(int[5]) 字节。

*(array)+1:参见前面的 2 点,但是 int* 类型的最终右值会递增,同样根据指针算法规则,1 * sizeof(int)

这里没有神秘!

关于c - 二维数组变量指针混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8630054/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com