指针和引用
异同:
指针指向的的是一块内存,所以里面存储的是内存的地址,引用是地址的别名,所以他们本质上都是存着一块内存的地址去操作内存
但是有跟多不同的地方
1:指针可以有const类型,但是引用没有
2:指针式一个实体,引用只是一个别名
3:安全性问题:指针可以定义的时候不赋值,应用必须赋值,指针可以多次修改指向的内存,但是引用不可以。
4:操作的时候,指针需要加*,引用不需要加&
5:引用不可以为空,但是指针可以为空,表示什么都不指向
6:sizeof引用得到是指向的内存的大小,sizeof指针得到的是4字节
7:从内存分配上,指针可以分配内存,而引用是不需要分配内存的
程序1: void myMalloc(char *s) //我想在函数中分配内存,再返回 { s=(char *) malloc(100); } void main() { char *p=NULL; myMalloc(p); //这里的p实际还是NULL,p的值没有改变,为什么? if(p) free(p); } 程序2:void myMalloc(char **s) { *s=(char *) malloc(100); } void main() { char *p=NULL; myMalloc(&p); //这里的p可以得到正确的值了 if(p) free(p); } 程序3: #include void fun(int *p) { int b=100; p=&b; } main() { int a=10; int *q; q=&a; printf("%d\n",*q); fun(q); printf("%d\n",*q); return 0; } 结果为 10 10 程序4: #include void fun(int *p) { *p=100; } main() { int a=10; int *q; q=&a; printf("%d\n",*q); fun(q); printf("%d\n",*q); return 0; } 结果为 10 100 为什么?
毛病出在函数GetMemory中。编译器总是要为函数的每个参数制作临时副本,指针参数p的副本是 _p,
编译器使 _p = p。如果函数体 内的程序修改了_p的内容,就导致参数p的内容作相应的修改。这就
是指针可以用作输出参数的原因。在本例中,_p申请了新的内存,只是把 _p所指的内存地址改变了,但
是p丝毫未变。所以函数GetMemory并不能输出任何东西。事实上,每执行一次GetMemory就会泄露一块
内存,因 为没有用free释放内存。
myMalloc(&p);将p的地址传入函数,假设存储p变量的地址是0x5555,则0x5555这个地址存的是指针变
量p的值,也就是Ox5555指向p。 调用的时候同样分配一个临时变量char **s,此时s 的值是&p的值也就是0x5555,但是s所占的空间是
另外的空间,只不过它所指向的值是一个地址:Ox5555。 *s=(char *) malloc(100);这一句话的意思是将s所指向的值,也就是0x5555这个位置上的变量的
值赋为 (char *) malloc(100),而0x5555这个位置上存的是恰好是指针变量p,这样p的值就变成了
(char *) malloc(100)的值。即p的值是新分配的这块内存的起始地址。 这个问题理解起来有点绕,关键是理解变量作函数形参调用的时候都是要分配一个副本,不管是传值还是传址。
传入后就和形参没有关系了,它不会改变形参的值。 myMalloc(p)不会改变p的值,p的值当然是 NULL,
它只能改变p所指向的内存地址的值。但是myMalloc(&p)为什么就可以了,它不会改变(&p)的值也不可能改变,
但是 它可以改变(&p)所指向内存地址的值,即p的值。
*******************************************************************************************************************************************
两者的本质区别,第一种str的局部变量,存在栈区,第二种指针是一个全局变量,它对应的是内存中的全局区域,
或者通过static开辟一段静态存储空间,static和const联合进行使用