1.学习习惯。
在编写C语言程序时候,不要简单的printf成功就通过。要进行调试,观察成员变量的变化过程。了解每一个变量存放的位置。尤其实在学习指针的过程中。强大的编辑器可以让我们偷窥到内存中指针存放的位置,指向的变量内容.
2.指针变量,指针常量,常量指针。
(1)、指针常量是指定义的指针只能在定义的时候进行初始化,而且初始化后不能改变值,char * const p1; int * const p2;
const 位于* 的右侧,这说明声明的对象是个常量。所以第一句定义了一个只读的字符型指针p1,第二句定义了一个只读整形指针p2 常量指针值不能变,但指向的内容可以改变。
(2)、常量指针是指向常量的指针,因为指向的是常量,所以这个对象的值是不能改变的。 int const *p1; const int * p2;
3.在函数内部定义局部变量。
char * Func(void)
{
char str[30];
return str;
} //str是局部变量,位于占内存中,在Func结束时候就会被释放,所以返回str导致错误。
return不能返回指向“栈内存”,的指针,因为该内存在函数体借书的时候就会被自动销毁。
4.华为笔试题中的两道。
int main()
{
char *ptr;
if((ptr = (char *)malloc(0)) == NULL)
printf("this is null pointer\n");
else
printf("this is a valid pointer");
}
输出: this is a valid pointer.
void main()
{
char * str = (char )* malloc(100);
strcpy(str,"Hello");
free(str);
if(str != NULL)
{
strcpy(str,"world");
printf(str);
}
}
以上两段程序通过简单的程序调试就可以得出结论。free函数并不是把指针赋值为NULL而是切断指针与所指的内容之间的联系。
void GetMemory(char *p)//形参不能改变实参的值.
{
p = (char *) malloc(100);//C语言程序结束后对栈区进行清除工作。对堆与静态就不会清除。
}
void Test(void)
{
char *str = NULL;
GetMemory(str);
strcpy(str,"Hello World");//str仍是NULL。不可以给NULL赋值
printf(str);
}
char * GetMemory(void)
{
char p[] = "Hello world!!!";
return p;
}
void Test(void)
{
char *str =NULL;
str = GetMemory();//函数中的P是一个局部变量。在getmemory函数结束后 p就会被销毁,此内存会被其他程序段复用。所以读到的不一定是个什么东东。不可以对p所指的内存写,那是XJBX 。
printf(str);
}
char *p; // 此时p是一个指针,没有分配内存,指向内存区域,只读不能写。
char p[];//p是一个数组,内存已经分配好了。
ps:指针不能分配内存,指向的是系统的只读内存。数组是分配内存的就是将系统的只读内存里面的数据copy过去。
5. 野指针。
不是NULL指针,是指向被释放的或者访问受限的指针。(if语句很难判断一个指针式正常指针还是野指针)
成因:
(1).指针变量没有被初始化,任何指针变量刚被创建时候不会自动成为NULL,他的缺省值是随机的,所以指针变量在创建的同时应当被初始化。要么指向NULL,要么指向一个合法的内存。
(2).指针被free或者被delete后,没有置NULL,其实free与delete知识把指针所指的内存释放掉,被没有把指针本身干掉。此时指针指向垃圾内存。
(3).指针操作超越了变量的作用范围,比如不要返回指向栈内存的指针或者引用,因为栈内存在函数结束时候会被释放掉。
避免方法:
(1).指针变量一定要初始化为NULL,因为任何指向指针变量刚被创建时不会自动成NULL,值随机。
(2).当指针p指向的内存空间释放时候,没有设置指针p的值为NULL,delete 与 free知识啊把内存空间释放了,但是并没有将p设置成NULL
6.指针比较基础的知识。
char *p; // p是指向char型数据的指针,
char p[];//p是char数组的指针(近似指针)
char **p; //p是指向char型指针的指针
char pp[][];//pp 为二维数组的指针。
char (*p)[];//p指向一维char 数组的指针。
总结,指针是从右向左结合的。
*p[]说名p首先是个数组,数组元素才是指针。
(*p)[]说明p首先是个指针,指针指向的才是数组。
函数指针与函数返回值,
char (*p)(void,void)
char *p (void,void)
char (*(*p())[])();等同于char (*(*p(void))[])(void);
p返回值为指向一维数组的指针的函数,该一维数组由指向返回char类型的函数的指针组成。
void表示无,void* 表示任意类型的指针,原因在于,(C/c++语言特性)指针变量的内存空间全都相同。