局部变量和全局变量初始化区别:
局部变量,在未初始化情况下,初值为随机值。C规范对该初值并没有做规定,具体实现由编译器决定。如VC/VS等编译器,会将初始值值为0xCCCCCCCC, 而GCC等编译器则是不可预知的随机值。
全局变量和静态局部变量(带static修饰的局部变量)。即定义在函数外,不属于任何一个函数的变量。这两种默认初值为0.
指针:指针其实是一个地址。
指针赋值:一个地址的赋值。
空指针:即 int *p=NULL ; //等于NULL
野指针:即 int *p; //只声明,不定义(赋值)
指针变量:int *p =&a; //*p称为指针变量,无论是声明时候什么类型,指针变量只占有4个字节。
&:取地址符号
*:指针符号,指向一个储存空间,也可以取出存储空间的值
数字名:数组名是一个地址(首地址),是一个常量,不允许重新赋值 //第一个元素的地址。
对一级指针,二级指针进行操作:
其实:&与*是一个反运算符
一级指针:*p
(*p)++:括号优先级大,所以直接执行(*p)操作,取出该指针所对应的值,然后对值进行加1操作。
*p++:++与*优先级相同,从右往左操作:先执行p++,由于是“++”号是后加加号,所以会在整条语句执行完后再对P自加1,所以先输出*p,然后指针再+1。
*(p+1):括号优先级大,与*p++类似。
*p:直接取出指针所对应的数值。
*++p:++与*优先级相同,从右往左操作:先执行++操作,再执行*。++p先把指针+1,然后再取加1后的值。
*(++p):括号优先级大,与*++p类似。
#include<stdio.h> int main(void){ int a[]={1,2,3,4,5}; int *p=a; printf("++(*p):%d \n",++(*p));//2 printf("(*p)++:%d \n",(*p)++);//2 printf("a[0]:%d\n",a[0]);//3 printf("*p++:%d \n",*p++);//3 printf("*(p++):%d \n",*(p++));//2 printf("*p:%d \n",*p);//3 p=a;//a指针重新回到a[0] printf("a[0]:%d\n",a[0]);//3 printf("*++p:%d \n",*++p);//2 printf("*(++p):%d \n",*(++p));//3 return 0; }
二级指针:**p2
#include<stdio.h> int main(void){ int a=10; int *p=&a; int **pp; pp=&p; printf("&a:%p\n",&a);//000000000062FE4C printf("&p:%p\n",&p);//000000000062FE40 printf("&pp:%p\n",&pp);//000000000062FE38 printf("p:%p *p:%d\n",p,*p);//000000000062FE4C 10 printf("pp:%p **p:%d %d\n",pp,**pp,*(*pp));//000000000062FE40 10 10 printf("pp:%p &p:%p \n",pp,&p);//000000000062FE40 000000000062FE40 printf("*pp:%p p:%p \n",*pp,p);//000000000062FE4C 000000000062FE4C printf("**pp:%d *p:%d\n",**pp,*p);//10 10 return 0; }
由图所示:
p: p里面存储的是a的地址。
*pp二级指针: 取一级指针的数值,也就是&a,但是&a是一个地址,所以取出来的是一个地址。
**pp二级指针:可以看成*(*pp),先取*p里面的值,取出来之后是&a,接着就是*(&a),结果10。
常量指针:int const *p;
1.通过该指针不可以修改它所指向的存储单元里面的值【只有读的权限,没有修改,如果要修改存储单元里面的值,需要用一个指针去修改】
2.指针指向地址可以被修改【指向地址】
#include<stdio.h> int main(void){ int a=10; int b=9; int const *p =&a; *p=11;//常量指针报错,指向的存储单元的值,不可以被修改 p=&b; printf("p:%d",*p) ; return 0; }
指针常量:int * const p
1.指针本身即地址不可以被修改。【用二级指针修改存储单元里面的值】
2.通过该指针可以修改它所指向的存储单元的值。
【与常量指针相反】
#include<stdio.h> int main(void){ int a=10; int b=9; int *const p=&a; *p=11; p=&b;//报错,地址不能修改 printf("p:%d",*p); return 0; }
指向常量的指针常量:int const * const p
1.指针本身即地址不可以被修改。
2.通过该指针不可以修改他所指向的存储单元的值。
段的错误(常见问题):
a.操作了空指针
b.对野指针进行赋值(操作受保护的内存),也就是已经被占用的内存。
c.指针指向一个错误的内存(或者说是不存在的内存)。
d.修改常量区的内容。