C 有人能解释吗?

C 有人能解释吗?,c,printf,sizeof,C,Printf,Sizeof,我真的不明白。也许有人能给我解释一下。 我想知道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 这是错误的格式说明符: printf("

我真的不明白。也许有人能给我解释一下。 我想知道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

这是错误的格式说明符:

printf("%i and %i",sizeof(*dataInput)/sizeof(float),dataSize);
        ^^
sizeof
返回未签名的
size\u t
类型在Visual Studio中正确的格式说明符是
%zu
%Iu


使用错误的格式说明符调用,但这似乎无法解释
dataSize
10
输出,这没有意义,因为
sizeof(*dataInput)
将是一个
float
的大小。因此,我们期望
sizeof(*dataInput)/sizeof(float)
1
,正如Macattack所说,SSCCE应该有助于解析该输出。

当将数组传递给函数时,它将衰减为指针。无法计算指针的大小,因此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);
}
编辑:
输出
10
可能是格式说明符的错误用法,或者输出可能是从其他地方打印的“0”的“1”。因为他没有在printf的末尾添加换行符,所以我们无法保证最后一个
0
与此printf关联。

这可能是64位平台的问题,该平台使用32位
int
和64位
size\t
sizeof
的结果类型)

在这种情况下

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 - http://stackoverflow.com/a/21266299/12711

// 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

Plesae的可能副本在第二个值后打印一个换行符,这样我们就可以排除输出与我们预期的一样,只是在其他地方加了一个伪
0
。(不太可能,但仍然是。)运行了您的代码,无法再现您的输出。我得到了
1和
。我的第一个猜测是@MOehm所建议的,一个
0
打印在其他地方。包括编译/运行并演示错误的。请,给你的问题一个适当的标题,概括问题主题。好奇你是否尝试在printf中添加一个
\n
,看看这是否会将输出从
10
更改为
1
。10来自何处?@herohuyongtao这可能是格式说明符的错误用法,也可能是从其他地方打印出来的,因为他并没有在
printf
的末尾添加换行符。我认为这可能是一种解释,但我无法使用
gcc
clang
重现适合这种情况的字符,虽然我们曾经讨论过未定义的行为,但这并不意味着什么。@ShafikYaghmour:我也很难再现精确的输出,但在这种情况下,get的输出可能取决于堆栈上某个内存位置上发生了什么,或者在另一个未显式设置为0(或其他什么)的寄存器中发生了什么。我认为,一旦
printf()
被修复,OP将获得预期的输出。
printf("%i and %i",(int) (sizeof(*dataInput)/sizeof(float)),dataSize);  // cast size_t type to int


// as mentioned by Shafik Yaghmour in his answer - http://stackoverflow.com/a/21266299/12711

// 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