char* str1="string";
这使得str1
是一个指针;它指向字符串文字的第一个字符。你应该把它定义为const
,因为你不允许修改字符串文字:
const char *str1 = "string";
...
char str2[7]="string";
这使得str2
的char
数组(不是指针),和将字符串文字的内容复制到其中。没有必要将其定义为const
;该阵列本身是可写的。还可以省略尺寸,让它通过初始化来确定:
char str2[] = "string";
然后sizeof str2 == 7
(6个字节为"string"
加1用于终止'\0'
)。
此:
char* str3=(char)malloc(sizeof(char)*7);
编写不当,它甚至不应该编译;至少,你应该从你的编译器得到警告。您正在将malloc()
的结果转换为char
。你应该将其转换为char*
:
char *str3 = (char*)malloc(sizeof(char) * 7);
但投是不必要的,可以掩盖在某些情况下的错误;参见问题7.7和在comp.lang.c FAQ如下:
char *str3 = malloc(sizeof(char) * 7);
但sizeof(char)
是1的定义,所以你可以这样写:
char *str3 = malloc(7);
malloc()
分配内存,但它并没有初始化,所以如果您尝试打印str3
指向的字符串,如果分配的空间不包含终止空字符'\0'
,则会得到垃圾 - 甚至是运行时崩溃。你可以用strcpy()
初始化它,例如:
char *str3 = malloc(7);
if (str3 == NULL) {
fprintf(stderr, "malloc failed\n");
exit(EXIT_FAILURE);
}
strcpy(str3, "string");
你必须要非常小心,你复制的数据是不超过所分配的空间更大。 (否,`strncpy() is not the answer to this problem。)
void main()
不正确;它应该是int main(void)
。如果你的教科书告诉你使用void main()
找到更好的教科书;它的作者不太了解C.
而你需要为你使用任何库函数适当#include
指令:<stdio.h>
为printf()
,<stdlib.h>
为exit()
和malloc()
,并<string.h>
为strcpy()
。每个函数的文档都应该告诉你要包含哪个头文件。
我知道这是很多吸收;不要指望马上理解它。
我提到了comp.lang.c FAQ;这是一个很好的资源,特别是第6节,讨论数组和指针以及它们之间经常令人困惑的关系。如果你的问题3,如何从C函数返回一个字符串,事实证明,由于C内存分配的方式(基本上它自己管理它),结果会非常复杂。你不能安全地返回一个指向局部变量的指针,因为当函数返回时该变量不再存在,使得调用者留下一个悬挂指针,因此返回str2
是危险的。返回一个字符串文字是可以的,因为它对应于整个执行程序时存在的匿名数组。你可以用static
声明一个数组并返回一个指针,或者你可以使用malloc()
(这是最灵活的方法,但它意味着调用者需要free()
内存),或者你可以要求调用者传入一个指针到你的函数将复制结果的缓冲区。
有些语言让你建立一个字符串值,并简单地从函数中返回它。正如你现在发现的那样,C不是这些语言之一。
感谢您的澄清。在这种情况下,如果我的函数必须返回一个任意长度的字符串,我在函数中使用了一个char [someLength]缓冲区,我怎样才能返回这个缓冲区作为输出? – turtlesoup
@ user1926344:首先,请注意您的“任意长度”字符串不能长于“someLength”字节。其次,你只需将它复制到调用者可以访问的某个内存区域 - 这意味着你可以直接跳过'char [someLength]'变量并将其复制到那里。该区域可以是'静态'(有一些缺点),或者它可以是'malloc()',也可以由调用者来分配它并将函数传递给指针。 –