使用指针算法打印 3D 数组元素的指针
Printing a pointer of an 3D array element using pointer arithmetics
我正在测试如何使用数组名和指针算法来访问数组元素,我想出了这个程序:
#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;
}
尽管程序可以正常运行并正确打印所有内容:
7th element (pointer): 0x7ffd4b09a1c8
8th element (pointer): 0x7ffd4b09a1d0
我在编译时收到警告,对于我在 printf()
中使用 %p
占位符的每一行都说这样的话:
warning: format ‘%p’ expects argument of type ‘void *’, but argument 2 has type ‘int *’ [-Wformat=]
printf("7th element (pointer): %p\n", *(*(a + 1) + 1) + 0);
~^ ~~~~~~~~~~~~~~~~~~~
%ls
所以乍一看,我似乎必须简单地将指针指向 (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 个元素计算了一个不同的地址,这个地址只比前面的 elemnet 地址大 1 个字节:
7th element (pointer): 0x7ffd9e5e1bf8
8th element (pointer): 0x7ffd9e5e1bf9
我也试过这样修复(多加了一个大括号):
printf("8th element (pointer): %p\n", (void *)((*(a + 1) + 1) + 1));
并且警告消失了,但地址的计算方式仍然不同:
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 不会 return 任何警告。
我正在测试如何使用数组名和指针算法来访问数组元素,我想出了这个程序:
#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;
}
尽管程序可以正常运行并正确打印所有内容:
7th element (pointer): 0x7ffd4b09a1c8
8th element (pointer): 0x7ffd4b09a1d0
我在编译时收到警告,对于我在 printf()
中使用 %p
占位符的每一行都说这样的话:
warning: format ‘%p’ expects argument of type ‘void *’, but argument 2 has type ‘int *’ [-Wformat=]
printf("7th element (pointer): %p\n", *(*(a + 1) + 1) + 0);
~^ ~~~~~~~~~~~~~~~~~~~
%ls
所以乍一看,我似乎必须简单地将指针指向 (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 个元素计算了一个不同的地址,这个地址只比前面的 elemnet 地址大 1 个字节:
7th element (pointer): 0x7ffd9e5e1bf8
8th element (pointer): 0x7ffd9e5e1bf9
我也试过这样修复(多加了一个大括号):
printf("8th element (pointer): %p\n", (void *)((*(a + 1) + 1) + 1));
并且警告消失了,但地址的计算方式仍然不同:
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 不会 return 任何警告。