我总是想知道这两者在C
之间有什么区别char *str;
char str[50];
我有以下代码用于从用户输入读取字符串而不是使用gets。
int read_line(char *str, int n);
int main (int *argc, char *argv[])
{
char *str;
read_line(str, 50);
printf("%s", str);
return 0;
}
int read_line(char *str, int n)
{
int ch, i = 0;
while((ch = getchar()) != '\n')
{
if(i < n)
{
*str++ = ch;
i++;
}
}
*str = '\0';
return i;
}
编译工作正常,但我尝试运行时崩溃了。
然后我将参数更改为read_line()
函数,而不是char *str
我使用char str[50]
。
当使用char *str[50]
作为参数时,程序按预期运行。
有人可以解释为什么会这样吗?或者主要区别是什么
pointer to char
和character array
?
答案 0 :(得分:2)
数组ID或多或少像指针一样工作。
但是使用指针你总是需要手动完成3个步骤:
char str[50];
完成所有这三项,而char *str;
只创建一个未初始化的指针,你甚至不创建指向的缓冲区。
指针和数组ID之间的进一步区别:
sizeof array
返回数组大小,而sizeof ptr
返回存储地址所需的内存大小。答案 1 :(得分:1)
主要区别在于后者为50个字符分配内存(str是第一个元素的指针),而前者只是声明一个指针(除了指针变量本身的内存之外没有分配内存)。
答案 2 :(得分:1)
如果您将运行这个简单的程序
,将立即看到差异#include <stdio.h>
int main( void )
{
char *str1;
char str2[50];
printf( "%zu\n", sizeof( str1 ) );
printf( "%zu\n", sizeof( str2 ) );
}
程序输出可能看起来像
4
50
如您所见,数组str2
有足够的内存来存储最多50个字符的字符串,而指针只能存储某个内存的地址。
将数组传递给代码中的函数
read_line(str2, 50);
(其中str2声明为char str2[50];
),然后数组名称被隐式转换为指向其第一个元素的指针。因此,例如这些函数声明是等价的
int read_line(char *str, int n);
int read_line(char str[50], int n);
甚至喜欢
int read_line(char str[100], int n);
int read_line(char str[], int n);
并声明相同的一个函数,因为声明为array的参数被调整为指针。
因此,当您传递数组时,函数会获取指向已分配内存的数组的第一个元素的指针,因为已定义数组。
当您像在此主函数中那样传递指针时
int main (int *argc, char *argv[])
{
char *str;
read_line(str, 50);
printf("%s", str);
return 0;
}
然后它没有被初始化并且具有一些不确定的值。结果是程序行为未定义。指针应指向一些可以存储输入数据的已分配存储器。
例如,您可以通过以下方式执行此操作
int main (int *argc, char *argv[])
{
char *str1;
char str2[50];
str1 = str2;
read_line(str1, 50);
printf("%s", str1);
return 0;
}
或
int main (int *argc, char *argv[])
{
char *str = malloc( 50 * sizeof( char ) );
read_line(str, 50);
printf("%s", str);
free( str );
return 0;
}