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()',也可以由調用者來分配它並將函數傳遞給指針。 –