简体   繁体   English

如何使用指针符号访问2d数组中的结构元素?

[英]How to access structural elements in a 2d array with a pointer notation?

English is not my first language so I'm not sure if I formulated the question the right way. 英语不是我的母语,所以我不确定我是否以正确的方式提出了这个问题。 If anyone would like to correct me feel free to do so. 如果有人想纠正我,请随时这样做。 Now, 现在,

I understand that arr[i][j] is the same as *(arr+i+j) but, now I have this 我知道arr[i][j]*(arr+i+j)但是现在我有了这个

struct whatever{
int n;
int k;};
int main()
{
    struct whatever arr[4][4];
}

and I need to know how to access 'n' inside the structure via the pointer notation . 而且我需要知道如何通过指针符号访问结构内部的n I tried (*(arr+i+j).n) 我试过了(*(arr+i+j).n)

(it just gives an error ': request for member 'n' in something not a structure or union) (它只给出错误':在结构或联合中请求成员'n')

and a whole lot of other variations and I can't find anything related on the forums for the past 2 hours. 以及其他许多变化,在过去2小时内,我在论坛上找不到任何相关内容。

*(arr + i + j) is the same as arr[i + j] . *(arr + i + j)arr[i + j]

( *(a + b) is a[b] – the above are also equivalent to (arr + j)[i] , i[j + arr] , and (i + j)[arr] . But don't go there.) *(a + b)a[b] –上面的内容也等效于(arr + j)[i]i[j + arr](i + j)[arr] 。但是不要去那里。)

arr[i][j] is *(*(arr + i) + j) . arr[i][j]*(*(arr + i) + j)
(Or *(j + *(i + arr)) . Don't do it.) (或者*(j + *(i + arr)) 。不要这样做。)

The sensible thing to do, if you're not taking part in an obfuscation contest, is to not use pointer arithmetic when you can avoid it. 如果您不参加混淆竞赛,那么明智的做法是在可以避免的情况下不要使用指针算法。
Pointer arithmetic makes it very easy to write code that seems right, is completely wrong, and still compiles and then has to be debugged when you could have done something useful instead. 指针算术可以很容易地编写看似正确,完全错误的代码,并且仍然可以进行编译,然后在可以做一些有用的事情时进行调试。

As I noted in a comment : 正如我在评论中指出的:

You'd need to write (*(*(arr + i) + j)).n — which is an excellent reason for using the arr[i][j].n notation. 您需要编写(*(*(arr + i) + j)).n这是使用arr[i][j].n表示法的一个很好的理由。 I had to build it up piecemeal from the inside out: *(arr + i) gives the result of arr[i] ; 我必须从内到外逐步构建它: *(arr + i)给出arr[i]的结果; you then have to treat that as a pointer expression and give it the *(ptr + j) treatment; 然后,您必须将其视为指针表达式,并给予*(ptr + j)处理; and then the precedence rules say . 然后优先规则说. binds tighter than * , so you need the extra parentheses. 绑定比*更紧密,因此您需要额外的括号。 Except as an academic exercise, don't write that using pointers and dereferences. 除作为学术练习外,请勿使用指针和取消引用来编写。

You can also omit the outer parentheses and * by using the arrow -> operator instead of the dot . 您也可以通过使用箭头->运算符代替点来省略外括号和* . operator: (*(arr + i) + j)->n . 运算符: (*(arr + i) + j)->n

Here's some code: 这是一些代码:

#include <stdio.h>

struct whatever{
    int n;
    int k;
};

int main(void)
{
    struct whatever arr[4][4] = { [2] = { [3] = { 371, 4 } } };
    printf("arr[2][3].n           = %d\n", arr[2][3].n);
    int i = 2;
    int j = 3;
    printf("(*(*(arr + %d) + %d)).n = %d\n", i, j, (*(*(arr + i) + j)).n);
    printf("(*(arr + %d) + %d)->n   = %d\n", i, j, (*(arr + i) + j)->n);
    return 0;
}

And the output is: 输出为:

arr[2][3].n           = 371
(*(*(arr + 2) + 3)).n = 371
(*(arr + 2) + 3)->n   = 371

(The initialization uses C99 designated initializers to set element arr[2][3] to the value (struct whatever){ 371, 4 } — which is the compound literal notation for the element of type struct whatever ; compound literals are a C99 feature too.) (初始化使用C99指定的初始化程序将元素arr[2][3]设置为值(struct whatever){ 371, 4 } —这是struct whatever类型的元素的复合文字符号;复合文字是C99的功能太。)

This code was compiled by GCC 7.2.0 on a Mac running macOS High Sierra 10.13.2. 该代码由GCC 7.2.0在运行macOS High Sierra 10.13.2的Mac上编译而成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM