存储/从指针数组中获取值

时间:2016-01-02 02:57:48

标签: c arrays pointers

我想创建一个数组,我可以在其中添加一些变量,然后从地址中获取它们的值,

这是代码:

 SDL_Rect *arraypos[4];

 arraypos[1] = &poskey.x;
 arraypos[2] = &poskey.y;
 arraypos[3] = &posletter.x;
 arraypos[4] = &posletter.y;

posletterposkey struct输入:SDL_Rect了解更多信息:

enter link description here

我做了一点测试,看看它是否有效:

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 

地址,其余为零。

我不知道在其上创建指针表和存储地址的适当方法是什么,以及如何从这些地址中提取值并对其应用一些修改。

谢谢。

3 个答案:

答案 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_Rectposkey是静态声明的类型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 managementC dynamic memory allocationgarbage 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