那个人有密码
#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));
}
}他为什么要把虚空*类型引向char*类型?我可以看到,这是一个错误,当我改变这段代码,而不是领导它,但为什么呢?
发布于 2016-04-22 03:34:26
不允许对C中的空指针执行算术,因此以下代码是非法的:
void *foo = whatever;
foo + 1;通过将foo转换为char *,她可以对指针执行算术。
发布于 2016-04-22 04:29:26
我的评论是为什么void *ptr不能执行地址算法。警告,长篇大论:)。
通常,当您执行ptr算法时,如下所示
ptr = ptr + N ; C的解释是执行以下等效整数算法(实际上编译器将生成与以下整数算法等效的汇编代码)
ptr = ptr + N* sizeof (*N) ;
因此,编译器必须知道类型(*N)才能生成代码。在这里,类型(*N)意味着变量"ptr“的类型指向。(typeof不是一个标准的c结构,它是在这里购买的,只是为了解释)。
拿一张。
int x ; // Assume x is at addesss 1000
int *ptr = &x ; // ptr has a value of 1000ptr = ptr +1;
将使ptr在运行时为1004 (假设int的大小为4个字节)
说明-1:上面的语句意味着ptr应该包含ptr之后的下一个整数变量的地址。由于ptr指向x,即地址1000,所以在1000之后的下一个整数变量将是1004。所以ptr应该是1004。
解释-2这也与解释ptr = ptr +N等价于整数算术c
ptr = ptr + N* sizeof (typeof(*N)) ; // typeof (*N)->int
// => 1000 + 1 *sizeof (typeof (int))
// => 1004ptr手术总结
ptr = ptr + N ;编译器生成等效的程序集代码,如
ptr = ptr + N*多少( typeof(*N) ) // Compiler需要类型(*N)
因此,编译器需要知道ptr指向的数据类型。
现在考虑一下
void foo (int type, void *ptr) {
ptr = ptr + 2 ;
}
f2() {
int x ;
char c ;
f1(&x) ;
f1(&c);
} void * ptr是指向一个地址的通用ptr。当用f1(&x)调用时,ptr指向整数的地址,当用f1(&c)调用时,它指向字符的地址。因此,在编译时,编译器无法确定什么是类型(*ptr)。(因为在一种情况下,它是整数,而另一种是字符)。因此编译器不可能为ptr = ptr +n生成代码;
因此,您必须将ptr转换为一个特定的已知类型,然后执行算术操作。
希望这能有所帮助。
https://stackoverflow.com/questions/36784322
复制相似问题