總結一下遇到的關於char *p、char p[]和字符串的題目:
例一:(指針的指針)
1 void getmemory(char **p) 2 { 3 p = (char *)malloc(100); //p應該是*p,因為這里是對傳入的二重指針所指向的內容分配空間,而不是二重指針的地址, 4 //所以應該為 *p = (char*)malloc(100); 5 } 6 7 int main() 8 { 9 char *str = NULL; 10 getmemory(str); //這里應該傳入&str,所以應該為 getmemory(&str); 11 strcpy(str, "hello world!"); 12 printf("%s\n", str); 13 free(str); 14 while (1); 15 return 0; 16 }
例二:(局部指針傳到外面)
1 char *getstring() 2 { 3 char p[] = "hello world"; 4 return p; 5 } 6 7 int main() 8 { 9 char *str = NULL; 10 str = getstring(); //用str接收getstring()函數返回的局部變量, 11 printf("%s\n", str); //但是在getstring()函數執行完時,p的內存空間就被系統回收了,也就是str所指向的空間被回收了,所以這里無法打印出hello world 12 13 while (1); 14 return 0; 15 }
例三:
1 int main() 2 { 3 char a[4]; 4 //char a; 5 char *str = &a; //這里指針級別不同,但是仍然能輸出"hello",最好改為*str = a; 6 strcpy(str, "hello"); 7 printf("%s\n", str); 8 9 while (1); 10 return 0; 11 }
說明:除了改變第9行的&a為a之外,按照代碼中第8行和第9行的寫法也可以正確輸出"hello";這里a不會出現越界的問題。
不妨修改一下main():
1 int main() 2 { 3 char a[4]; 4 strcpy(a, "hello"); 5 printf("%s\n", a); 6 7 while (1); 8 return 0; 9 }
說明:這里a也不會出現越界的問題,最后可以輸出"hello";但是如果我們把char a[4]換成char *a; 來看看會發生什么:
1 int main() 2 { 3 char *a; 4 strcpy(a, "hello"); 5 printf("%s\n", a); 6 7 while (1); 8 return 0; 9 }
輸出error:main.c(4): error C4700: 使用了未初始化的局部變量“a”;
說明:char *a;是在聲明一個變量,是沒有分配內存的,所以這里不能strcpy的;
strcpy需要復制到一個有效的,能存儲字符串的空間,而a只是一個地址,能存的也是一個地址。
例四:
1 int main() 2 { 3 char *src = "123456789"; 4 int len = strlen(src); 5 6 char *dest = (char*)malloc(len); 7 char *d = dest; 8 char *s = src[len]; 9 10 while (len--) 11 { 12 d++ = s--; 13 14 } 15 printf("%s\n", dest); 16 17 while (1); 18 return 0; 19 }
上面代碼一堆錯誤,太坑了。自己不妨先看看如何改正。
錯誤的地方:
第8行:char *s = &src[len-1];
第12行:這里=左邊的d“左操作數必須為左值”;改為d = s--; 對應15行dest改為d。
修改后源碼:
1 int main() 2 { 3 char *src = "123456789"; 4 int len = strlen(src); 5 6 char *dest = (char*)malloc(len); 7 char *d = dest; 8 char *s = &src[len-1]; 9 10 while (len--) 11 { 12 d = s--; 13 } 14 printf("%s\n", d); 15 16 while (1); 17 return 0; 18 }
例五:
1 int main() 2 { 3 char *s = "12345"; 4 strcpy(s, "67890"); 5 return 0; 6 }
說明:第3行相當於 const char *s = "12345"; 所以在第4行對s進行修改時,程序會中斷。第3行改為char s[] = "12345";即可。
再看一個類似的例子:
1 int main() 2 { 3 char s[] = "12345"; 4 char *s2 = "12345"; 5 const char *s3 = "12345"; 6 7 strcpy(s, "67890"); 8 9 printf("%s\n", s); 10 11 while (1); 12 return 0; 13 }
變量地址:
圖中可以看出來:s2和s3的地址都是0x007c56e8,為常量存儲區;s一個臨時變量,屬於棧區,所以s指向的內容可以修改,而s2,s3指向的內容則不能修改。
例六:
1 int main() 2 { 3 char *p = "linux"; 4 *p = 'L'; 5 printf("\n [%s] \n", p); 6 7 while (1); 8 return 0; 9 }
這個和上面的是相同的問題。第3行改為char p[] = "linux";即可。
個人總結不一定全對,歡迎指正~