我想创建一个数组,我可以在其中添加一些变量,然后从地址中获取它们的值,
这是代码:
SDL_Rect *arraypos[4];
arraypos[1] = &poskey.x;
arraypos[2] = &poskey.y;
arraypos[3] = &posletter.x;
arraypos[4] = &posletter.y;
posletter
和poskey
struct
输入:SDL_Rect
了解更多信息:
我做了一点测试,看看它是否有效:
printf("%d \n",arraypos[1]);
printf("%d \n",*arraypos[1]);
printf("%d \n",*arraypos[2]);
printf("%d \n",*arraypos[3]);
如果我说得对:''指针'旁边的'*'会给你变量的值。
但我得到的只是这个警告:
key.c: In function ‘main’:
key.c:49:17: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
arraypos[1] = &poskey.x;
^
key.c:50:17: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
arraypos[2] = &poskey.y;
^
key.c:51:17: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
arraypos[3] = &posletter.x;
^
key.c:52:17: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
arraypos[4] = &posletter.y;
^
key.c:55:12: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat=]
printf("%d \n",arraypos[1]);
^
我试图忽略它们但是当我执行该程序时:
rafiq@rafiq-Vostro-3500:~/Desktop/AI$ ./a.out
-1500334368
0
0
0
地址,其余为零。
我不知道在其上创建指针表和存储地址的适当方法是什么,以及如何从这些地址中提取值并对其应用一些修改。
谢谢。
答案 0 :(得分:2)
很难从问题陈述中准确确定您的意图。是否打算声明指针数组以键入SDL_Rect
,或者您是否确实要声明和数组int 。无论如何,具有(4个元素)的数组的数组索引是0-3
,C中的所有数组都是zero
索引。 e.g:
arraypos[0]
arraypos[1]
arraypos[2]
arraypos[3]
键入数组
的示例根据您对问题陈述的编辑,您声明要“创建一个指针表并在其上存储地址”。如果你的意图是声明一个类型为4
的指针数组(SDL_Rect
),那么下面就可以了:
SDL_Rect *arraypos[4];
执行此操作时,arraypos
的每个元素都是未分配的指针,以便键入SDL_Rect
。这没有任何问题,但您必须明白,这与声明4
单独指向SDL_Rect
的单独指针(例如SDL_Rect *pointer1;
然后SDL_Rect *pointer2
;等等没有什么不同。 。)这将简单地声明类型为SDL_Rect
的4 未分配的指针。
这意味着尝试单独存储整数值的地址作为arraypos
的元素会违反严格别名规则,即使{的大小为{ {1}}和SDL_Rect
是相同的。 (参见:C标准的第6.5.6和6.5.7节)
您可以在每个元素中正确存储的是int
类型的地址。因此,如果您SDL_Rect
和poskey
是静态声明的类型posletter
,则可以进行以下分配:
SDL_Rect
每个arraypos元素现在都包含指向(例如a的地址)类型arraypos[0] = &poskey;
arraypos[1] = &posletter;
的指针。然后,您可以通过以下方式访问每个地址的SDL_Rect
值:
x, y, w, h
使用这种情况的通用结构的简短示例是:
包括
arraypos[0]->x;
arraypos[0]->y;
arraypos[1]->x;
arraypos[1]->y;
...
<强>输出强>
typedef struct {
int x;
int y;
} SDL_Rect;
int main (void) {
SDL_Rect poskey = { 5, 9 };
SDL_Rect posletter = { 3, 7 };
SDL_Rect *arraypos[4] = {NULL};
size_t i;
arraypos[0] = &poskey;
arraypos[1] = &posletter;
/* arraypos[2] & arraypos[3] are not used in this case */
for (i = 0; i < 2; i++) {
printf (" arraypos[%zu]->x : %d\n", i, arraypos[i]->x);
printf (" arraypos[%zu]->y : %d\n", i, arraypos[i]->y);
}
return 0;
}
整数数组的示例
另一方面,您要为$ ./bin/arraypos2
arraypos[0]->x : 5
arraypos[0]->y : 9
arraypos[1]->x : 3
arraypos[1]->y : 7
的每个元素分配int
值,因此您似乎需要一个整数数组,例如:
arraypos
然后,您已将int arraypos[4] = {0}; /* always initialize your variables */
声明为arraypos
int
类型的*数组。然后,您可以为每个索引位置4
分配整数值(请记住 - 所有数组在C中都是0-3
索引。一个简短的例子(没有SDL_Rect,但使用通用结构)将是:
zero
<强>输出强>
#include <stdio.h>
typedef struct {
int x;
int y;
} SDL_Rect;
int main (void) {
SDL_Rect poskey = { 5, 9 };
SDL_Rect posletter = { 3, 7 };
int arraypos[4] = {0};
size_t i;
arraypos[0] = poskey.x;
arraypos[1] = poskey.y;
arraypos[2] = posletter.x;
arraypos[3] = posletter.y;
for (i = 0; i < sizeof arraypos/sizeof *arraypos; i++)
printf (" arraypos[%zu] : %d\n", i, arraypos[i]);
return 0;
}
考虑一下你试图表达的情况,然后告诉我你是否还有其他问题。
答案 1 :(得分:1)
有些事情看起来不对。
首先,指针数组的类型。你声明了
SDL_Rect *arraypos[4]; // wrong type
所以你保证数组的每个元素都是指向SDL_Rect
的指针。但显然你想要指向int
的指针,因为元素将包含指向int
变量的指针,即int*
。要声明通用指针,请使用void*
。所以你想要
int* arraypos[4];
以后再设置一些元素:
arraypos[1] = &poskey.y;
请记住,数组的第一个元素在C!中有索引0
。
然后,要打印一些地址,请使用%p
并将该地址转换为(void*)
,所以
printf("second pointer is %p\n", (void*)arraypos[1]);
您不应该使用%d
,因为在Linux / x86_64 int
上有4个字节,指针有8个字节。
void*
可以被认为是每种指针类型的常见超类型。所以它并不是指向void
的指针,而是指向任何东西或任何指针的指针。
我强烈建议你花几个小时阅读一本好的C编程书;指针的概念很棘手且必不可少。特别是,您需要了解pointer aliasing的含义。另请阅读virtual address spaces(因为指针是此类空间中的地址,对于桌面,笔记本电脑或服务器操作系统上的大多数C实现)。
当然,要取消引用指针,请使用C的*
一元前缀dereference operator,例如
printf("second pointer contains %d\n", *arraypos[1]);
如果您发现符号混乱,请使用括号,例如*(arraypos[1])
但不要将解除引用运算符视为给出某个变量的值(但某些内存位置的值)。要更改引用的内存位置的值,请使用赋值左侧的dereference运算符,例如*(arraypos[1]) = 3;
;当然你也可以指定指针,所以arraypos[2] = arraypos[1];
正在制作一个指针别名。
指针是内存位置(或memory addresses),与variable不同(例如,在递归函数中,该递归函数的每个call frame都有一个位置局部变量)。指针可以指向一些动态分配的堆内存区域。阅读memory management,C dynamic memory allocation,garbage collection(至少有关GC的术语和概念)。
害怕undefined behavior&amp; buffer overflow
编译所有警告&amp;调试信息(gcc -Wall -Wextra -g
)并改进您的代码,直到您完全没有警告为止。然后使用调试器(gdb
)&amp; valgrind如果有的话。在gdb
debugger中逐步运行您的计划step
,然后p
修改程序的各种变量。
答案 2 :(得分:0)
开始,这一行:SDL_Rect * arraypos [4];定义了一个包含4个指向struct SDL_Rect,
实例的指针的数组不是'* int'
的4个实例推荐:
int *arraypos[4];
// the rest of the 'setting the pointers' code is unchanged
// the rest of the printf() code is unchanged