void * type to char * type leadng

时间:2016-04-22 03:31:42

标签: c

该男子有代码

#include <conio.h>
#include <stdio.h>

void dbleInt(void *a) {
    *((int*) a) *= 2;
}

void deleteEvenInt(void* a) {
    int tmp = *((int*) a);
    if (tmp % 2 == 0) {
        *((int*) a) = 0;
    }
}

void dbleDouble(void *a) {
    *((double*) a) *= 2.0;
}

void deleteEvenDouble(void* a) {
    int tmp = *((double*) a);
    if (tmp % 2 == 0) {
        *((double*) a) = 0;
    }
}

// Function takes an array, its size, the size of one element and a function //pointer,
// Which is then applied to all the elements of an array
void map(void *arr, unsigned num, size_t size, void (*fun)(void *)) {
    unsigned i;
    char *ptr = (char*) arr;
    for (i = 0; i < num; i++) {
        fun((void*) (ptr + i*size));
    }
}

为什么他将void * type引向char *类型?我可以看到这是一个错误,当我更改此代码并且不引导它时,为什么?

2 个答案:

答案 0 :(得分:2)

您不能对C中的void指针执行算术运算。因此以下代码是非法的:

void *foo = whatever;
foo + 1;

通过将foo转换为char *,她可以对指针执行算术运算。

答案 1 :(得分:0)

我的评论是为什么void *ptr,一个人无法执行地址算术。警告,漫长的漫步:)。

总的来说 当你做像

这样的ptr算术时
ptr  = ptr + N ; 

C的解释是执行以下等效整数运算(事实上编译器将生成相当于以下整数运算的汇编代码)

ptr = ptr + N * sizeof(typeof(* N));

因此编译器必须知道它的类型(* N)才能生成代码。 typeof(* N)这里的意思是变量的类型&#34; ptr&#34;指着。 (typeof不是标准的c构造,仅仅为了解释而在这里购买)。

拿一个例如

int x ;  // Assume x is at addesss 1000
int *ptr =  &x ; // ptr has a value of 1000

然后 ptr = ptr + 1;
在运行时将ptr设为1004(假设int的大小为4字节)

解释-1:上述语句表示ptr应该包含ptr之后的下一个整数变量的地址。由于ptr指向x,即地址1000,1000之后的下一个整数变量将是1004.所以ptr将是1004.

解释-2这也与ptr = ptr的解释同步+ N相当于整数算术

ptr = ptr + N* sizeof (typeof(*N)) ; // typeof (*N)->int
           //  => 1000 + 1 *sizeof (typeof (int))
                               //  => 1004

总结对于ptr算术

ptr = ptr  + N ;

编译器生成等效的汇编代码

ptr = ptr + N * sizeof(typeof(* N))//编译器需要typeof(* N)

因此编译器需要知道ptr指向的数据类型是什么

现在考虑

void foo (int type, void *ptr) {

    ptr = ptr + 2 ;
}
f2() {
int x ;
char c ;
f1(&x) ;
f1(&c);
} 

void * ptr是指向地址的通用ptr。当用f1(&amp; x)调用时,ptr指向一个整数的地址,当用f1(&amp; c)调用时,它指向一个字符的地址。所以在编译时,编译器无法确定typeof(* ptr)是什么。 (在一种情况下,它是整数,另一种是字符)。因此,编译器无法为其生成代码     ptr = ptr + n;

所以你必须将ptr转换为特定的已知类型,然后进行算术运算。

希望这会有所帮助。