该男子有代码
#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 *类型?我可以看到这是一个错误,当我更改此代码并且不引导它时,为什么?
答案 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转换为特定的已知类型,然后进行算术运算。
希望这会有所帮助。