Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用指针算法打印三维数组元素的指针_C_Pointers_Multidimensional Array_Pointer Arithmetic - Fatal编程技术网

C 使用指针算法打印三维数组元素的指针

C 使用指针算法打印三维数组元素的指针,c,pointers,multidimensional-array,pointer-arithmetic,C,Pointers,Multidimensional Array,Pointer Arithmetic,我正在测试如何使用数组名和指针算法来访问数组元素,我提出了以下程序: #include <stdio.h> int main(){ // definition of array using designators int a[2][2][2] = { [0] = {[0] = {1, 2}, [1] = {3, 4}}, [1] = {[0] = {5, 6}, [1] = {7, 8}} }; printf("7

我正在测试如何使用数组名和指针算法来访问数组元素,我提出了以下程序:

#include <stdio.h>

int main(){

    // definition of array using designators
    int a[2][2][2] = {
        [0] = {[0] = {1, 2}, [1] = {3, 4}},
        [1] = {[0] = {5, 6}, [1] = {7, 8}}
    };

    printf("7th  element (pointer):  %p\n", *(*(a + 1) + 1) + 0);
    printf("8th  element (pointer):  %p\n", *(*(a + 1) + 1) + 1);

    return 0;
}
我在编译时收到警告,对我使用
%p
的每一行中的
printf()

因此,乍一看,我似乎必须简单地将指针投射到
(void*)
,如果我这样做并更改行:

printf("8th  element (pointer):  %p\n", *(*(a + 1) + 1) + 1);
这一行:

printf("8th  element (pointer):  %p\n", (void *)(*(a + 1) + 1) + 1);
我得到一个警告:

warning: pointer of type ‘void *’ used in arithmetic [-Wpointer-arith]
  printf("8th  element (pointer):  %p\n", (void *)(*(a + 1) + 1) + 1);
                                                             ^
编译器为第8个元素计算一个不同的地址,该地址仅比前一个元素的地址大1字节:

7th  element (pointer):  0x7ffd9e5e1bf8
8th  element (pointer):  0x7ffd9e5e1bf9
我也试着像这样修复它(又添加了一个大括号):

警告消失了,但地址的计算方式仍然不同:

7th  element (pointer):  0x7ffca6c6c468
8th  element (pointer):  0x7ffca6c6c470

看起来编译器需要指针类型来计算地址,如果我强制转换它,它将无法正确计算地址。有人知道我能做些什么来删除警告并以正确的方式计算地址吗?

如果您需要将算术设置为
int*
,并将值视为
void*
,请在执行算术后转换该值:

printf("7th  element (pointer):  %p\n", (void *)((int*)*(*(a + 1) + 1) + 0));
printf("8th  element (pointer):  %p\n", (void *)((int*)*(*(a + 1) + 1) + 1));

您可以将指针存储到单独的变量中,并将其传递给printf:

void *ptr7th = (*(*(a + 1) + 1) + 0);
void *ptr8th = (*(*(a + 1) + 1) + 1);
printf("7th  element (pointer):  %p\n", ptr7th);
printf("8th  element (pointer):  %p\n", ptr8th);

使用带有
-Wall
参数的gcc 9.3.0版不会返回任何警告。

&a[1][1][1]
更容易阅读,只是输入错误。您要做的是添加
(void*)(expr)
,其中
expr
是原始代码中的表达式。您实际做的是删除一个
*
,然后添加cast.@DavidC.Rankin我完全同意,但是,我对C的所有内容都感兴趣。不用担心,数组索引或指针表示法是完全等效的,所以任何一种方法都可以(尽管您将失去许多使用指针表示法
:)的新用户)
@DavidC.Rankin我个人认为这不仅仅是对新用户的挑战。这也会给有经验的用户带来问题,因为像这样的符号需要更多的处理/维护,以证明表达式是否正确,并为读者证明这些表达式实际上在做什么。这样一来,宝贵的时间就被浪费了。除非它不能提供真正的好处,否则我会选择数组索引版本。啊!很好的解决方案!非常感谢你。我也能够省略对
int
的类型转换,它仍然像这样工作
(void*)(*(*(a+1)+1))
7th  element (pointer):  0x7ffca6c6c468
8th  element (pointer):  0x7ffca6c6c470
printf("7th  element (pointer):  %p\n", (void *)((int*)*(*(a + 1) + 1) + 0));
printf("8th  element (pointer):  %p\n", (void *)((int*)*(*(a + 1) + 1) + 1));
void *ptr7th = (*(*(a + 1) + 1) + 0);
void *ptr8th = (*(*(a + 1) + 1) + 1);
printf("7th  element (pointer):  %p\n", ptr7th);
printf("8th  element (pointer):  %p\n", ptr8th);