先看一个程序,其实这是我编的一个不算小的程序里面的片断,把曾经遇到的问题写出来:
#include<stdio.h>
int main(void)
{
char *a;
//a=(char *)malloc(20);
a=gets(a);
//scanf("%s",a);
//getchar();
puts(a);
getchar();
return 0;
}
这个是我在windows下面调试的一个程序,用的是dev c++ 4.9 ,编译是没有问题的,运行的时候就是直接出现windows特有的垃圾界面,“工程1.exe 遇到问题需要关闭。我们对此引起的不便表示抱歉。”,就是叫你关了他。
分析之:其实把这个程序拿到linux下面的gdb一下就可以晓得运行到gets的时候,就会告诉你segments fault,很简单程序所用的数据段出了问题,cplus里面其实也降到过,就是说没有初始化的指针不要赋值,段出现了覆盖的问题,因为指针在没有初始化的时候,他是没有一个明确的地址的,你要是直接赋值就会导致指针地址与其他的程序所占的地址的冲突,最后就会出现段错误。
解决方法:
把指针化成数组,*a改成a[],我不喜欢用数组,所以我用第二种方法,给指针分配地址:
malloc就可以轻松的解决这个问题。
今天再补充一点:
malloc是动态的分配,地址并不固定的,而数组在定义和初始化的时候就已经固定了,可以看一个程序:
#include <stdio.h>
#include <malloc.h>
int main(void)
{
char *p="asdfasdf";
char *q;
q=(char *)malloc(20);
q=p;
printf("%s/n",p);
}
p的地址还是可以赋给q的,即便没有malloc分配,初始化的时候就应该知道,指针的地址其实也算是动态的,比如这么定义和换地址:
#include <stdio.h>
#include <malloc.h>
int main(void)
{
char *p="asdfasdf";
char *q="ddddddddd";
//q=(char *)malloc(20);
p=q;
printf("%s/n",p);
}
仍然可以的。
但是数组就不可以了,因为他的地址开始申明和赋值的时候,就已经固定了,不可以变了的。
#include <stdio.h>
#include <malloc.h>
int main(void)
{
char p[20]="asdfasdf";
char q[20];
p=q;
printf("%s/n",p);
}
编译的时候会报错,D:/hehe/hehe/zhi/zhi.cpp(8) : error C2106: '=' : left operand must be l-value。
呵呵记得就行了。
但是有一点,char *p可以直接在定义的时候给值,比如char *p=“asdf”,或者char *p;p=“asdf”;这个其实是一种绑定的方法,动态的吧。
但是下面这样就不可以了,char *p;scanf("%s",p);因为p的位置不确定的,得在scanf("%s",p);之前malloc或者new一下。
char 型指针可以直接给字符串,但是int型的就不可以啊,比如int *p=123;就是不对了,这样吧,int *P;再malloc或者new一下一个确定的地址,然后就*p=123就可以了。
int赋值是给*p=123,而char型的就是给首地址p=“asdf”,呵呵。