从 void 指针传输值

发布于 2024-11-02 16:04:16 字数 532 浏览 6 评论 0原文

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

base 是一个指向一堆浮点数的空指针
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

Can someone tell me whats wrong with this code?

base is a void pointer to a bunch of floats
i is a value >1
size is the size of the type (in this case 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);

This is the output:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

弄潮 2024-11-09 16:04:16

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

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

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

If a was a void*, the compiler wouldn't allow you to write a + size*i (you can't do pointer arithmetic with incomplete types). Probably the type isn't what you think it is.

But why do you think there's a problem? The left-hand column advances half as fast as the right-hand column, and this is expected because you are dividing by 2.

You do realize that you're printing addresses, and not the values being copied, right?

挖鼻大婶 2024-11-09 16:04:16
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,因为您指定基数是浮点数组。 %d 用于整数,%f 用于浮点数。

您的代码不起作用的原因是您打印的是地址而不是值。

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));

The changes I have made are to dereference the pointers correctly (and casting them to the correct type) and to change %d to %f as you specified that base is an array of floats. %d is for ints and %f is for floats.

The reason your code did not work is that you were printing out the addresses and not the values.

夏日落 2024-11-09 16:04:16

您能告诉我们您想要实现什么目标吗?似乎是一个
作业有问题吧?

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

你无法查看 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

“我希望这有帮助”。

Would you please tell us what you're trying to accomplish? Seems like a
homework problem, right?

The C language allows you to cast any pointer to a void*, and then cast it
back to the original pointer type, without losing any information. Anything
else you do with a void pointer is a bad idea, although some library functions
(such as memcpy) still have void* for historical reasons. That's also why
you don't need an explicit cast to go from any pointer type to a void*.

You cannot look at what the void* points to, until you cast it back to the
correct pointer type. And be careful when you do!

#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;
}

On my system, the output is

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

I hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文