前一段时间遇到一个很容易的犯的错误,这段程序很值得借鉴,下面是源程序,因为是错误的,所以我给注释了。
// #include <string.h>
// #include <stdlib.h>
// strReverse()
// {
// char *src = "cdata";
// char *dest = NULL;
// int len = strlen(src);
// dest = (char*)malloc(len);
// char *d = dest;
// char *s = src[len];
// while(len--!=0)
// *d++=*s--;;
// printf("%s\n",dest );
// return 0;
// }
真的是很考验基本功的程序,下面是正确的程序。
#include <string.h>
#include <stdlib.h>
#include <stdio.h> //缺少一个头文件
int main()
{
char *src = "cdata";
char *dest = NULL;
int len = strlen(src); //len是5 ,但是字符串是从0开始的。所以下面len-1,以及分配多一个内存。
dest = (char*)malloc(len+1);
char *d = dest;
char *s = &src[len-1]; //-1个,因为数组是从0开始的。
while(len--!=0)
*(d++)=*(s--); //应该是里面的内容,试想一下就可以了。
*d = '\0'; //加上结束符。
printf("%s\n",dest );
getchar();
return 0;
}
还有关于指针的,确实头晕,但是记住就好。
代码段1:
void GetMemeory(char *p){
p=(char*)malloc(100);
}
void Test()
{
char *str=NULL;
GetMemory(str);
strcpy(str,”helloworld”);
printf(str);
}
运行Test函数会有什么结果?
代码段2:
char *GetMemory(void){
char p[]="helloworld";
return p;
}
void Test(void)
{
char *str=NULL;
str=GetMemory();
printf(str);
}
运行Test函数会有什么结果?
代码段3:
void GetMemory(char **p,int num)
{
*p=(char*)malloc(num);
}
void Test(void)
{
char *str=NULL;
GetMemory(&str,100);
strcpy(str,"hello");
printf(str);
}
运行Test函数会有什么结果?
代码段1:出错。
原因:Test在调用GetMemory时,会把指针str复制一份,作为p传递给GetMemory。也就是说Test里的str和GetMemory里的p是两个不同的指针,对p做的任何操作都不影响str,str一直是空指针。然后再向空指针调用strcpy就会出错。
代码段2:输出一段乱码。
原因:这个结果和堆栈有关。Test调用GetMemory函数时,会在内存堆栈区中给GetMemory函数开辟一块新的空间(下称“区域A”),然后GetMemory的参数、局部变量等都在区域A里,于是GetMemory里面的局部变量char p[]也指向区域A里的字符串"helloworld"(注1)。问题在于GetMemory函数结束后,区域A会被释放,里面的一切内容失去意义,变成不可预测的随机值。GetMemory把p作为返回值返回给Test中的指针str,GetMemory结束后,str仍然指向区域A中的某位置,但这个位置的值已经变成随机值,所以printf会打印出随机字符,即乱码。
注1:这里我不是很确定。根据我以前的知识,常量字符串"helloworld"应该不在堆栈区里,不会随着函数的执行与结束而变化,代码段2理应输出"helloworld",但执行结果还确实是乱码,我目前只能想到上述解释。
代码段3:输出hello。
原因:由于Test和GetMemory之间传递的是指针的指针,所以和代码段1不同,这次两者修改的是同一个指针。GetMemory结束后,Test中的str指向堆里一个100字节的区域,然后再用strcpy向其中复制一个字符串'hello",所以输出结果也就是"hello"。