我对班上的教程有些误解。有一个名为print_Arr()
的函数,它是泛型函数,它获取指向double或整数数组的指针并打印它。
以下是代码:
int main() {
int a[] = { 2,7,6,4,1 };
double b[] = { 12.5,2.7,3.0,5.5,5.9,1.0 };
print_Arr(a, sizeof(a)/sizeof(a[0]), sizeof(int), print_int);
print_Arr(b, sizeof(b)/sizeof(b[0]), sizeof(double), print_double);
}
void print_Arr(void* a, int size, int m, void (*print_func)(void* )) {
for (int i = 0; i <= size-1; i++)
{
print_func((char*)a + m*i);
}
}
void print_int(int* p) {
printf("%d\n", *p);
}
void print_double(double* num) {
printf("%f\n", *num);
}
为什么我必须在此行中将a
转换为(char*)
:
print_func((char*)a + m*i);
我向print_Arr()
泛型函数发送了两种类型的数组整数或双精度数,
因此逻辑上将a
投射到int *
或double*
。
但为什么它会投放到char*
?我错过了什么?
答案 0 :(得分:4)
首先,需要关于 为什么 的演员:
指针算法使用指向类型的大小。 void
是一个永远不完整的类型,无法完成,因此在指向void
类型的指针上无法进行指针运算。
为加法运算符添加引用C11
,章节§6.5.6,约束:
另外,两个操作数都应具有算术类型,或者一个操作数应为a 指向完整对象类型的指针,另一个应具有整数类型。
,并且,从章节§6.2.5,
void
类型包含一组空值;它是一个不完整的对象类型 无法完成。
那说,为什么演员要char*
:
指针算法使用指向的类型。再次引用规范
[...]如果表达式
P
指向 数组对象的i
- 元素,表达式(P)+N
(等效地,N+(P))
和(P)-N
(其中N
的值为n
)分别指向i+n
- 和i−n
- 元素 数组对象,只要它们存在。
在这里,看看你的构造:
((char*)a + m*i);
其中m
是实际参数指向的实际对象类型的大小。因此,如果将指针强制转换为实际类型,则计算错误。要进行比较,请说:
sizeof (char)
为1,由标准规定。sizeof (int)
== 4,在您的平台上说。因此,对于数组int arr[ ] = {1, 2, 3, 4}
,表达式
(char*)a + (sizeof(int)*1)
和(int*) a + 1
是等价的。
最后,触及将另一种指针转换为char*
并访问它的主题:
[...]当指向对象的指针转换为指向字符类型的指针时, 结果指向对象的最低寻址字节。连续增量 结果,直到对象的大小,产生指向对象剩余字节的指针。 [....]
答案 1 :(得分:3)
您需要char *
强制转换,因为您对指针执行指针运算,从头开始获取字节偏移量,但您不能在void *
上执行此操作。
答案 2 :(得分:0)
void指针没有类型大小,因此您无法使用它进行计算。
答案 3 :(得分:-1)
public:
int num=0;
int c;
int doubleToChar(double a){
while ((a-1)>=0){
num++;
}
c=a;
return a*10;
}/* int doubleToCharhundred(double a){
while ((a-1)>=0){
num++;
}
return a*100-c;
}*/
double a=12.12345;
char *tenDivide ;
char *intPart;
//u can add hundred or thousand by another char;
tenDivide =doubleToChar(a);
if(num<128)
intPart=num;
else{
while(num-1){
//same doubleToChar
}
}