有人能解释一下这个吗?

5
我真的不理解这个。或许有人可以向我解释一下。 我想知道dataInput中有多少个元素。我在用C语言编程。
void Calibrate_data(float* dataInput)
{   
    int dataSize = sizeof(*dataInput)/sizeof(float);
    printf("%i and %i",sizeof(*dataInput)/sizeof(float),dataSize);
}

输出结果如下:
1 and 10

2
可能是 https://dev59.com/uFbUa4cB1Zd3GeqPDvyI 的重复问题。 - Jongware
4
请在第二个值之后打印一个换行符,这样我们就可以排除输出结果中出现了杂质的情况(虽然这种情况不太可能发生)。请注意不要改变原来的意思。 - M Oehm
4
运行了你的代码,无法复现你的输出结果。我得到了 1 and 1。我的第一个猜测是 @MOehm 所建议的,可能是在此之后某个地方打印了 0。请提供一个能够编译、运行并演示错误的 SSCCE 示例。 - Macattack
3
请给你的问题一个恰当的标题,概括问题主题。 - Jens Gustedt
想知道你是否尝试过在printf中添加\n,以查看输出是否从10更改为1 - Shafik Yaghmour
3个回答

4

这里使用了错误的格式说明符:

printf("%i and %i",sizeof(*dataInput)/sizeof(float),dataSize);
        ^^

sizeof返回size_t类型,它是无符号的。正确的格式说明符是%zu或在Visual Studio中使用%Iu

使用错误的格式说明符会引发未定义行为,但这似乎不能解释dataSize的输出为10,这是没有意义的,因为sizeof(*dataInput)将是float的大小。所以我们期望sizeof(*dataInput)/sizeof(float)1,正如Macattack所说,一个SSCCE应该有助于解决那个输出。


2
当将数组传递给函数时,它会衰减为指针。您无法计算指针的大小,因此sizeof将不会给出元素的数量。如果您想要,可以将数组大小作为参数传递给函数。
这里的*dataInput是第一个元素,它是float类型。所以sizeof(*dataInput)表示sizeof(float)。
sizeof(*dataInput)/sizeof(float) = 4/4 = 1;
示例代码:
#include<stdio.h>
void Calibrate_data(float* dataInput);
int main()
{
    float data[] = { 12.22, 15.15 };
    Calibrate_data(data);
    return 0;
}

void Calibrate_data(float *dataInput)
{   
    printf("float size : %zu %zu\n", sizeof(*dataInput), sizeof(float));
    int dataSize = sizeof(*dataInput)/sizeof(float);
    printf("%zu and %d\n",sizeof(*dataInput)/sizeof(float),dataSize);
}

输出:

float size : 4 4
1 and 1
编辑:输出10可能是格式说明符的错误使用,或者输出可能是由其他地方打印的“1”和“0”,因为他没有在printf结尾添加换行符,所以我们不能确定最后的0与此printf相关联。

1
10来自哪里? - herohuyongtao
@herohuyongtao,这可能是格式说明符的错误用法,或者它可能是从其他地方打印出来的,因为他没有在printf的末尾添加换行符。 - sujin

2
这可能是一个64位平台上的问题,该平台使用32位的 int 和 64位的 size_tsizeof 的结果类型)。
在这种情况下,
printf("%i and %i",sizeof(*dataInput)/sizeof(float),dataSize);
         ^      ^  -------------------------------- --------
         |      |                  ^                    ^
         |      |                  |                    +---- 32-bit operand
         |      |                  +--- 64-bit operand
         |      |
         |      +--- expects 32-bit operand
         |
         +--- expects 32-bit operand

转换说明符和操作数不匹配会导致未定义的行为。

以下解决方案之一应该可以解决问题:

printf("%i and %i",(int) (sizeof(*dataInput)/sizeof(float)),dataSize);  // cast size_t type to int


// as mentioned by Shafik Yaghmour in his answer - https://dev59.com/THvaa4cB1Zd3GeqPE5OE#21266299

// this might not be supported on compilers that don't claim C99 support, 
//  for example, MSVC docs indicate that "I" should be used instead of "z" for size_t types

printf("%zu and %i",sizeof(*dataInput)/sizeof(float),dataSize);  // C99 - use correct conversion spec
printf("%Iu and %i",sizeof(*dataInput)/sizeof(float),dataSize);  // MSVC - use 'correct' conversion spec

1
我认为这可能是一个解释,但是无论是使用gcc还是clangColiru上都无法重现这种情况,尽管我们正在谈论未定义的行为,但这并不意味着太多。 - Shafik Yaghmour
@ShafikYaghmour:我也有困难复现完全相同的输出,但在这种情况下,输出的内容可能取决于堆栈或寄存器中某个内存位置上的内容,或者是未明确设置为0(或其他值)的一半。我认为一旦修复了printf(),OP将会得到预期的输出。 - Michael Burr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接