无法弄清楚为什么 "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 个字节,无论您的循环需要多少次迭代。
但是,您已经走在了正确的道路上。每次有人添加内容时,您都会增加 i
和 j
。所以在程序结束时你可以这样做:
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
我需要找到输入的消息的长度。我已将 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 个字节,无论您的循环需要多少次迭代。
但是,您已经走在了正确的道路上。每次有人添加内容时,您都会增加 i
和 j
。所以在程序结束时你可以这样做:
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