gpt4 book ai didi

c - 通过C中的数组名称和指针访问2D数组元素

转载 作者:行者123 更新时间:2023-11-30 19:03:21 24 4
gpt4 key购买 nike

我对2D阵列有点困惑。特别用公式a[i][j] = *(*(a+i)+j)
 在提出疑问之前,我想提及一下我对符号'*''&'的看法。我认为'&'是一个将“变量”作为操作数并给出“变量地址”的运算符,而'*'将“变量的地址”作为操作数并给出“变量”作为输出,因此

1.*(address)---->>(gives variable)

2.&(variable)---->>(gives address)

(请告诉我这个概念是否错误)

现在假设有一个二维数组“ a”,如下所示:

a[3][2]={{1,2,3},{4,5,6},{7,8,9},{10,11,12}}


现在我想使用该公式访问数组块的最后一个元素,即 a[3][2]

第一怀疑

所以按公式:

 a[3][2]=*(*(a+3)+2) // 1


我已经读到a + 3给出了4rt行的第一个元素的地址,即 &a[3][0]
但是我见过有人说写a等效于 &a[0][0]。因此代入方程式(1)

a[3][2] *(*(&a[0][0] +3)+2)


因此,在 &a[0][0]上加3意味着给出块 a[1][0] .....(在 a[0][0]之前的三个块)的地址。因此,此处(a + 3)已将我们指向 &a[1][0],而不是 &a[3][0]

第二怀疑

假设现在求值(a + 3)确实给了我a [3] [0]的地址(正确)。所以等式(1)现在变成

a[3][2]=*(*(&a[3][0])+2)

使用我的概念

*(address of variable)---->>(gives variable)

所以 *(&a[3][0])= a[3][0]。因此a [3] [0]应该是一个存储值10的变量。现在,我们有了 a[3][2]=*(10+2)=*(12)。但是,现在 '*'运算符需要地址作为输入,并且我们给出的r值不是地址,因此应该给出错误。

我知道我的概念中有很多错误,但是我是一个初学者,刚开始使用C语言作为我在编程领域的第一个话题,请帮帮我。

最佳答案

我认为'&'是一个将变量作为操作数并给出该变量地址的运算符...


这不是很正确。我们应该阐明什么是“变量”。在C语言中,通常称为变量的是标识符和对象。标识符是我们用作名称的文本字符串。例如,在int xyz;中,“ xyz”是标识符。对象是用于表示值的内存区域。因此,在int xyz;中,对象是编译器保留在内存中某个位置的几个字节(通常为四个)。

&运算符提供了将其应用于的对象(或函数)的地址。请注意,不需要将其应用于变量,只需将其应用于任何对象(或函数)即可。因此,除了命名对象之外,还可以将其应用于某些计算对象(如&a[i+4])或字符串文字(&"abc")或复合文字(& (int []) {3, 4, 5})。


  …和'*'可逆地将变量的地址作为操作数,并将变量作为输出,


*获取一个指向对象(或函数,此处不再进一步讨论)的指针,并生成该对象(具体来说,是一个指定该对象的左值)。该对象不必是命名变量的对象。它可以是数组元素,也可以是动态分配的对象,也可以是其他对象。


  现在假设有一个二维数组“ a”,如下所示:
  
  a [3] [2] = {{1,2,3},{4,5,6},{7,8,9},{10,11,12}}


这不是正确的数组定义,因为它没有元素类型,并且说数组的维数是3和2,但是初始化程序列表显示维数应该是4和3。让我们将其更正为:

int a[4][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12} };



  我已经读过a + 3给出了第四行的第一个元素的地址,即&a [3] [0]。


不完全的。在表达式 a+3中, a指定一个数组。该数组会自动转换为指向其第一个元素的指针,因此等效于 &a[0]。请注意,此表达式的类型是3个 int的数组-它是 a的子数组。当我们加3时,编译器将计数3个子数组,因此 a+3指向子数组编号3(从0开始编号)。因此, a+3等效于 &a[3]

&a[3]是子数组编号3的地址。这与 &a[3][0]是不相同的,它是子数组编号3的元素编号0的地址。尽管它们实际上指向内存中的同一位置,但是它们具有不同的类型,并且编译器将它们区别对待。


  但是我见过有人说写a等效于&a [0] [0]。


那是不对的。 a等效于 &a[0],它是指向 a第一个元素的指针。 a的第一个元素本身是一个数组;它是 a[0],而不是 a[0][0]。尽管 &a[0]&a[0][0]实际上可以指向内存中的同一位置,但是它们具有不同的类型,并且编译器将对它们进行不同的处理。


  因此代入方程式(1)


由于 a不等同于 &a[0][0],因此不能用后者代替前者。

让我们回到您提到的公式:


  a [i] [j] = *(*(a + i)+ j)


这是对的。回想一下 a将自动转换为 &a[0]。然后 &a[0]+i计数 i子数组,加法的结果等于 &a[i]。然后,在 *(a+i)中,应用 *运算符。这会将 &a[i]更改为 *&a[i]。由于 &a[i]指向 a[i],所以 *&a[i]a[i]

现在,我们已经确定 *(a+i)变为 a[i],并且我们想知道 *(a+i)+j是什么。实际上,我们在问 a[i]+j是什么。因此,我们必须弄清楚在此表达式中 a[i]会发生什么。

回想一下 a[i]a的子数组。因此它本身就是一个数组。在表达式中使用数组时,数组会自动转换为其第一个元素的地址(用作 sizeof或一元 &的操作数时除外)。因此 a[i]转换为 &a[i][0]。然后我们添加 j,生成 &a[i][0] + j。由于 &a[i][0]是指向 int的指针,因此编译器对 j int进行计数并生成指向 a[i][j]的指针。即, *(a+i)+j的结果为 &a[i][j]。然后应用 *生成 *&a[i][j],即 a[i][j]

关于c - 通过C中的数组名称和指针访问2D数组元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54042358/

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