从void指针传输值

时间:2011-04-21 23:28:38

标签: c pointers char void memcpy

有人可以告诉我这段代码有什么问题吗?

base是指向一堆floats的无效指针 i是值>1
size是类型的大小(在这种情况下为float - 4

char *a = (char *)base;
char *temp = (char *)a + size * (i/2);
printf("%d: %d = ", i, temp);
memcpy(a + size * i , temp , size);
printf("%d\n", a + size * i);

这是输出:

2:136724 = 136728
3:136724 = 136732
4:136728 = 136736
6:136732 = 136744
7:136732 = 136748
8:136736 = 136752

3 个答案:

答案 0 :(得分:1)

如果avoid*,编译器将不允许您编写a + size*i(您不能使用不完整类型的指针算法)。可能这种类型不是你想象的那样。

但为什么你认为有问题呢?左侧列的前进速度是右侧列的一半,这是预期的,因为您将除以2。

您确实意识到您正在打印地址,而不是正在复制的值,对吗?

答案 1 :(得分:1)

char *a = (char *)base;
char *temp = (char *)a + size * (i/2);
printf("%d: %f = ", i, *(float *)temp);
memcpy(a + size * i , temp , size);
printf("%f\n", *(float *)(a + size * i));

我所做的更改是正确地取消引用指针(并将它们转换为正确的类型)并将%d更改为%f,因为您指定base是一个浮点数组。 %d用于整数,%f用于浮点数。

您的代码无效的原因是您打印的是地址而不是值。

答案 2 :(得分:0)

请您告诉我们您要完成的工作?好像是一个 作业问题,对吗?

C语言允许您将任何指针转换为void *,然后将其强制转换 返回原始指针类型,不会丢失任何信息。什么 否则你使用void指针是一个坏主意,虽然有些库函数 (例如memcpy)由于历史原因仍然有空*。这也是原因 你不需要显式转换来从任何指针类型转到void *。

你无法看到虚拟*指向的东西,直到你把它扔回去 正确的指针类型。当你这样做时要小心!

#include <stdio.h>
#include <memory.h>

/* It's a bad idea to pass Base as a void pointer,
   but that's what you said you have. */
void silly_function(void*base, int i, int size) {
    /* Using a char* that points to float, is an even worse idea!
        char *a = (char *)base;
        char *temp = (char *)a + size * (i/2);
        printf("%d: %d = ", i, temp);
        memcpy(a + size * i , temp , size);
        printf("%d\n", a + size * i); 
    **/

    /** Probably ought to have a big SWITCH statement here, based
        on the data type. sizeof() isn't a good way to do this...
        On many computers, sizeof(float)==sizeof(long), but that
        doesn't mean that a float* is the same as a long* !!!
        For now, I'm going to assume (as you did) that base points
        to an array of float. */

    /* I think you're trying to copy the first half of the array
       into the second half of the array! But that's easy. */
    float*firsthalf = (float*)base; 
    float*secondhalf = firsthalf + (i/2);

    /* Show some starting values. */
    printf("Before: %x --> %f, %x --> %f\n",
        firsthalf, *firsthalf, secondhalf, *secondhalf);

    /* Now do the copy */
    memcpy(secondhalf, firsthalf, (i/2)*(sizeof(float)));

    /* Now prove that it's been copied? */
    printf("After:  %x --> %f, %x --> %f\n",
        firsthalf, *firsthalf, secondhalf, *secondhalf);
}

int main() {
    /* This drives the test */
    float ary[10] = {
        1.1f, 2.2f, 3.3f, 4.4f, 5.5f,
        0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
    silly_function(ary, 10, sizeof(ary[0]));
    return 0;
}

在我的系统上,输出是

Before: 12ff38 --> 1.100000, 12ff4c --> 0.000000
After:  12ff38 --> 1.100000, 12ff4c --> 1.100000

我希望这会有所帮助。