当前位置 : 主页 > 编程语言 > c++ >

关于在通用函数中进行转换的一些误解

来源:互联网 收集:自由互联 发布时间:2021-06-23
我对班上的教程有一些误解.有一个名为print_Arr()的函数,它是泛型函数,它获取指向double或整数数组的指针并打印它. 这是代码: int main() { int a[] = { 2,7,6,4,1 }; double b[] = { 12.5,2.7,3.0,5.5,5.9
我对班上的教程有一些误解.有一个名为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);
}

为什么我必须在此行中转换为(char *):

print_func((char*)a + m*i);

我发送给print_Arr()泛型函数两种类型的数组整数或双精度数,
因此逻辑上将a转换为int *或double *.

但为什么它会变成char *?我错过了什么?

首先,要说明为什么需要演员:

指针算术利用所指向类型的大小. void是一个永远不完整的类型,无法完成,因此无法在指向void类型的指针上进行指针运算.

要为加法运算符添加引用C11,章节§6.5.6,约束:

For addition, either both operands shall have arithmetic type, or one operand shall be a
pointer to a complete object type and the other shall have integer type.

并且,从第6.2.5章开始,

The void type comprises an empty set of values; it is an incomplete object type that
cannot be completed.

那说,为什么演员阵容是char *:

指针算术使用指向的类型.再次引用规范

[…] if the expression P points to
the i-th element of an array object, the expressions (P)+N (equivalently, N+(P)) and
(P)-N (where N has the value n) point to, respectively, the i+n-th and i−n-th elements of
the array object, provided they exist.

在这里,看看你的构造:

((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 *并访问它的主题:

[…] When a pointer to an object is converted to a pointer to a character type, the result points to the lowest addressed byte of the object. Successive increments of the result, up to the size of the object, yield pointers to the remaining bytes of the object. [….]

网友评论