无法弄清楚为什么 "sizeof(msg) = 0"

Cannot Figure out Why "sizeof(msg) = 0"

我需要找到输入的消息的长度。我已将 msg 中的所有字符放入一个数组 msg[] 中,但是当我检查该数组的大小时,结果为零。 谢谢你的帮助。

#include <stdio.h>
#define SIZE ((int) (sizeof(msg)/sizeof(msg[0])))

int main(void){
    int i = 0,j = 0;
    char msg[i];
    char ch = ' ';
    printf("Please enter a msg you want traslated: ");
    while(ch != '\n'){
        scanf("%c",&ch);
        if(ch == '\n'){
            break;
        }
        i++;
        msg[j] = ch;
        j++;
    }
    printf("%d\n",SIZE);
    return 0;
}

那是因为你有 sizeof(char[0]).

您将可变长度数组 msg 声明为 char msg[0],然后您写入 non-allocated 内存位置(不更改 sizeof 的值,根据定义,它是to compute the number of elements in an array -- 引自 6.5.3.4p6)。编写 msg[somethinh] = 未定义的内容,您可能会在评估 sizeof 运算符之前崩溃。

但是,通常情况下,sizeof 会告诉您数组的大小,在您的情况下为 0,因为 i=0。

问题来了。

您正在定义一个包含零个元素的数组:

int i = 0,j = 0;
char msg[i];

如果你检查 sizeof(msg),你会得到零。

如果您检查 sizeof(msg[0]),您将得到 1(在数组的元素 0 处,char 是 1 个字节)。

所以你在程序末尾的数学是正确的:0 / 1 == 0

您需要做的是为数组分配一些 space,这将给 msg 一个大小。如果你这样做:

char msg[50]

那么 sizeof(msg) 将是 50。因为 char 是 1 个字节,而你想要其中的 50 个:50 * 1 == 50

我明白你的意思了。您想要计算用户输入了多少个元素。不幸的是,您不能使用这种方法。 msg 数组将始终为 50 个字节,无论您的循环需要多少次迭代。

但是,您已经走在了正确的道路上。每次有人添加内容时,您都会增加 ij。所以在程序结束时你可以这样做:

printf("User entered %d records\n", i);

你混淆的原因是你没有正确理解可变长度数组。

首先请注意,您不能声明大小等于 0 的可变长度数组。所以无论如何这个数组声明

int i = 0,j = 0;
char msg[i];

不正确。

要更改数组的大小msg,仅更改数组声明中使用的变量i 的值是不够的。要求程序的执行控制每次都要经过数组声明,得到一个新的值i.

这是一个演示程序。

#include <stdio.h>

int main(void) 
{
    int i = 1;
    
    L1:;
    char msg[i];

    printf( "The size of msg is %zu\n", sizeof( msg ) );
    
    if ( i++ < 10 ) goto L1;
}

程序输出为

The size of msg is 1
The size of msg is 2
The size of msg is 3
The size of msg is 4
The size of msg is 5
The size of msg is 6
The size of msg is 7
The size of msg is 8
The size of msg is 9
The size of msg is 10

如您所见,更改变量i后,控制权转移到标签L1。控件通过变量 i.

的值声明数组

但数组中早期存储的值将丢失。

根据 C 标准(6.2.4 对象的存储持续时间)

7 For such an object that does have a variable length array type, its lifetime extends from the declaration of the object until execution of the program leaves the scope of the declaration.35) If the scope is entered recursively, a new instance of the object is created each time. The initial value of the object is indeterminate.

因此要么使用固定大小的字符数组,要么使用标准函数在循环内动态重新分配数组 realloc

这是一个演示程序。

#include <stdio.h>
#include <stdlib.h>

int main(void) 
{
    char *msg = malloc( sizeof( char ) );
    size_t i = 0;
    
    printf( "Please enter a msg you want to translate: " );

    for ( char c; scanf( "%c", &c ) == 1 && c != '\n'; i++ )
    {
        char *tmp = realloc( msg, i + 1 );
        
        if ( tmp == NULL ) break;
        
        msg = tmp;
        msg[i] = c;
    }
    
    msg[i] = '[=13=]';
    
    printf( "You entered %zu characters: %s\n", i, msg );
    
    free( msg );
    
    return 0;
}

它的输出可能看起来像

Please enter a msg you want to translate: Humza Ahmed
You entered 11 characters: Humza Ahmed