总结一下遇到的关于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 ", 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 ", 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 ", 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 ", 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 ", 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 ", 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 ", 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 ", 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(" [%s] ", p); 6 7 while (1); 8 return 0; 9 }
这个和上面的是相同的问题。第3行改为char p[] = "linux";即可。
个人总结不一定全对,欢迎指正~