带参数的宏

时间:2016-08-23 05:47:32

标签: c pointers macros

在下面的代码中,我不断收到错误。如何修改第三行?为什么会一直这样?怎么了?

#include <stdio.h> 
#include "stdlib.h"
#define ARRAY_IDX(type, array, i) ((type *)(array+i)) // you can only modify this line!

int main(int argc, const char * argv[]) {
    void *ptr = malloc(10*sizeof(int));
#ifdef ARRAY_IDX
    for (int i = 0; i < 10; i++) {
        ARRAY_IDX(int, ptr, i) = i * 2;
    }

    for (int i = 0; i < 10; i++) {
        printf("%d ", ARRAY_IDX(int, ptr, i));
    }
    free(ptr);
#else
    printf("Implement ARRAY_IDX first");
#endif
}

2 个答案:

答案 0 :(得分:4)

看着

ARRAY_IDX(int, ptr, i) = i * 2;

printf("%d ", ARRAY_IDX(int, ptr, i));

显示表达式

ARRAY_IDX(int, whatever, whatever)

应扩展为int类型的表达式(和左值,以便我们可以分配给它)。

首先使用void *开始need to change (cast) it to a pointer that allows indexing,并且由于您要索引该数组的元素(而不是其单个字节,这将违反别名),您需要进行先int *

(int *)(ptr)

现在你有一个指向整数的指针(数组,希望如此)。增加它:

(int *)(ptr) + (idx)

最后,您需要一个左值int表达式。取消引用指针以获取:

(*((int *)(ptr) + (idx)))

将其转换为预处理器宏是应该可行的,所以我将其留给您。

请注意,无论谁给你这些代码都是 - 恕我直言 - 不是你应该信任的老师。这不会教你很多关于正确的C.它可能教你一些关于预处理器的东西。但是不要写这样的代码。只是不要。尽可能使用正确的类型。检查malloc的失败。

答案 1 :(得分:-2)

向void指针添加int没有任何问题。多年来,编译器设计人员认为这是标准行为,并且它是如此实现的。它与匿名结构和工会一样标准,编译器已有近20年的历史,最近才在C11中添加。实际上,所有编译器都会编译它,没有任何警告或错误,也不需要使用任何特殊的编译器标志。

正如我所指出的,你的问题是你正在为指针赋值。你需要在演员表之后取消引用它。

#define ARRAY_IDX(type, array, i) ((type *)array)[i]