2017-02-27 73 views
-2

据我所知,这个数组[1]和数组+ 1实际上是两种写入相同内容的方式。不过,我最近一直在研究void指针和数组,并使这个程序来测试我对它的理解。阵列+ 1工作阵列[1]不起作用

#include <stdio.h> 
#include <stdlib.h> 

int main(void){ 
    void** data; 
    data = malloc(sizeof(int)*2); 
    *((int*)data) = 5; 
    *((int*)(data+1)) = 10; 
    printf("%d\n", *((int*)data)); 
    printf("%d\n", *((int*)(data+1))); 
    free(data); 
    return 0; 
} 

这是工作程序的版本,由于某种原因,但是这个版本不

#include <stdio.h> 
#include <stdlib.h> 

int main(void){ 
    void** data; 
    data = malloc(sizeof(int)*2); 
    *((int*)data[0]) = 5; 
    *((int*)data[1]) = 10; 
    printf("%d\n", *((int*)data)); 
    printf("%d\n", *((int*)data1])); 
    free(data); 
    return 0; 
} 

我不能完全让编译器错误,但程序简单地停止运行,我已经在一台使用gcc的win 10计算机上编译,下面的标志为-pedantic-errors -Wall,就像我之前说过的,程序编译但运行时我得到了经典的Program.exe has stopped working错误消息,至今我真的无法想到为什么其中一个原因会工作,其他人不会。

+7

否:'数组[1]'与'*(a + 1)'相同 - “*”表示所有区别。 –

+2

在你的第二个例子中,你有:'printf(“%d \ n”,*((int *)data1]));' - 缺少'['。 –

+0

你为什么使用void指针? –

回答

-2

第一:请改变data类型int*或至少void*。 不要与void**混乱,除非你需要传递给函数一个指针。

second: change data[0/1] to &data[0/1]data[]是一个参数,而&data[]是他的指针。如果您仍然使用void*选择*((int*)data+?)。如果yopu更改为int*则使用data[?]

第三:为什么要在这个函数中使用指针?这不是一个需要指针的函数。我建议在这种情况下使用数组而不是指针。如果你已经知道你的参数的类型和大小,那么你最好使用数组。更舒适。

+2

你能解释为什么他必须做这些事吗? –

+0

我做过.......... –

2

data+1无效C.您无法对void指针进行指针运算,因为这没有任何意义。

因此,你似乎在非标准垃圾模式下使用gcc(默认设置),它将void指针算术转换为字符算术并因此程序编译,但是作为非标准的C. data+1意味着+ 1字节,而不是+1 int

使用gcc作为标准C编译器代替-std=c11 -pedantic-errors。然后将代码更改为(int*)data+1

另外void**是没有意义的,应该是void*。请注意,(int*)data[0]的意思是“做指针运算上void**类型,然后把结果给int*,这是一个运算符优先级的错误。[]比投()运营商更高的优先级。

只是折腾是整个代码出来,使用这个:

#include <stdio.h> 
#include <stdlib.h> 

int main(void){ 
    void* data; 
    data = malloc(sizeof(int[2])); 
    ((int*)data)[0] = 5; 
    ((int*)data)[1] = 10; 
    printf("%d\n", *(int*)data); 
    printf("%d\n", *((int*)data+1)); 
    free(data); 
    return 0; 
} 
+1

'数据'不是void *,它是一个无效**,算术完美定义 – chqrlie

+0

啊好吧我虽然-pedantic-errors和-Wall就足够了停止这一点。并感谢您让我知道运营商优先级错误。然而,我一直在使用'void **'的原因是因为我一直在研究动态数组是如何完成的,而且我多次看到人们说'void **'超过'void *'。我有点困惑,为什么人们会建议'void **'是否有利用它只是一个空指针? – zee

+0

@chqrlie好的,总结是原始代码很奇怪,并没有做OP的想法。 – Lundin

0

你的两个例子都不正确。

void** data = malloc(sizeof(int)*2); 

被分配2个int整数,但如果data类型void**的。如果你希望仍然可以使用这个,这是不推荐的,你需要分配2个void*指针。那么这将是:

void** data = malloc(sizeof(void*)*2); 

话虽如此,在这里使用不需要void**。正如@ Lundin的文章所指出的那样,您可以使用void*。如果您使用int *data代替,您的代码将是最佳的,因为在这里使用void*指针没有意义。如果你决定这样做,你的代码可以只是:

#include <stdio.h> 
#include <stdlib.h> 

int main(void){ 
    int *data; 
    data = malloc(sizeof(int)*2); 
    data[0] = 5; 
    data[1] = 10; 
    printf("%d\n", data[0]); 
    printf("%d\n", data[1]); 
    free(data); 
    return 0; 
} 

哪个更直接,跳过void*指针在代码带来的并发症。

注意:您必须始终检查退回malloc(),因为它可以在失败时返回NULL

+0

好的,谢谢,我以为我应该使用sizeof的那个指针分配是要去指向。至于使用int * im只给这个代码作为例子,所以这不是实际使用它的方式,我主要试图理解指针和通用指针以及数组和动态数组是如何工作的。 – zee