十四种名词分别是:
A、变量指针 B、指针变量 C、常量指针 D、指针常量 E、数组指针 F、指针数组 G、函数指针 H、指针函数 I、行指针 J、列指针 K、二级指针 L、空指针 M、野指针 N、NULL指针
A 变量指针:
每个变量在内存中占有一定得储存单元,变量的地址指出了变量的储存单元在内存中的具体位置,所谓的变量指针指变量在内存所占的储存单元的起始地址;
eg: int a; &a表示取a的地址,也就是变量a的指针
B 指针变量:
指针变量是指专门存放某类对象的地址的变量
eg: int *pa,int a ;pa是一个指针变量,用它可以指向整型数据的变量,即存放整型变量的地址,如pa=&a,此时pa指向变量a。
总结:两者的区别只从概念上区分是容易的,但实际使用时要区分并不容易,需要注意的是,并不一定要定义一个指针变量才可以使用变量的指针,而指针变量也只有指向一具体的变量时,它才真正有意义,它提供一种间接访问变量的一种方式。
C 常量指针:
常量指针表示指向常量的指针,顾名思义,指针指向的是一个常量,既然是常量,即不能通过指针来修改常量的值,但是常量的值可以通过重新赋值或者自增自减改变;
eg:int age = 39;
const int * pt =&age;
这里不能通过pt来修改age的值,*pt += 1(这种操作是错误的);不能通过指针改变,但是可以通过其他放式改变age的值,例如对age重新赋值 age=18,age++,对了还有重要的一点忘了讲,对于常量指针,虽然不能通过指针来改变值,但是指针的指向可以改变
eg: 接上面的代码此处省略
intsage = 18;
pt =&asge;但是仍不能通过pt来改变sage(此时为18)的值
D 指针常量:
指针常量表示指针指向的地址不可以重新赋值,但内容可以改变,地址和指针永久绑定
eg: int age = 18;
int sage = 39;
int *const pt = &age;
此时可以通过pt改变age的值,例如*pt = 39;但不能改变pt 的指向。例如pt=&sage是不被允许的;
总结:对于指针常量和常量指针两个名字特别容易混淆,找了一种记忆方法:* (指针)和 const(常量) 谁在前先读谁;
E 数组指针:
指向一个一维数组的指针,也称为行指针;例如int (*p)[n]; ()优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长。也就是说执行p+1时,p要跨过n个整型数据的长度。这里大家可以考虑一下数字指针为什么是 int (*p)[n]而不是 int *p[n];
eg: int (*p)[4];
int a[3][4] = {{0,1,2,3},{4,5,6,7},{8,9,10,11}};
p = a 或者 p = a+1;//对指针赋值只能赋行地址
p = a[0]//error, 不能给数组指针赋列地址;
F 指针数组:
若一个数组的所有元素都是指针类型,这样的数组叫做指针数组。
eg: int *p[3]; //定义一个长度为3,类型为int*的指针数组
int i = 1 , j = 2 , k = 3;
p[0] = &i; p[1] = &j; p[2] = &k;
总结:对于数组指针和指针数组,数字指针的落脚点在指针,所以数组指针是一个指针;指针数组的落脚点是数组,所以指针数组是一个数组;
G 函数指针:
函数指针,也叫做指向函数的指针,函数的目标代码在内存中占用一段连续的存储空间,该存储空间的首地址叫做函数的入口地址。将函数的入口地址赋给一个指针变量,该指针叫做函数指针。一般格式为: 函数类型 (*指针变量名) (形参类型列表) 函数类型与要指向的函数的返回值类型保持一致
eg: void (*p)()//定义一个没有返回值的函数指针;
p = fun;//void fun(){}; fun为函数名,将函数的地址赋给指针
(*p)();//函数调用;
H 指针函数:
指针函数,也叫作返回指针的函数;除了返回int,char等基本类型外,函数还可以返回指针类型的数据。定义返回指针的函数时,只需在函数名前加一个“ * ”即可;
eg:int * fun()
{ int *a, i = 0;
a = &i
return a;//返回类型为指针类型
}
I 行指针:
详见E 数组指针,只是换了种名称而已;
J 列指针:
列指针,指向一个二维数组中一行中的一列,定义列指针的方法和定义普通指针的方法相同,对列指针的赋值只能赋列地址
eg:
int *p;
int a[3][4] = {{0,1,2,3},{4,5,6,7},{8,9,10,11}};
p = a[0] 或者p = a[0]+1 或者p = a[1];//对指针赋值只能赋行地址
p = a// error, 不能给列指针赋行地址;
K 二级指针:
二级指针,即指向指针的指针,普通指针中储存变量的地址,二级指针中储存的是普通指针的地址;
eg:
int i = 10;
int *p = &i;//p 中储存变量i的地址;
int **q = &p;//q中储存指针p的地址;
ps:q的值为p的地址值 假设q=&p=1310584
*q的值为i的地址值 也是p中储存的值 *q = p = &i = 1310588
**q的值为i的值 **q = *p = i = 10
L 空指针:
如果一个空指针常量赋值一个有类型的指针常量,那么这个指针就是空指针,空指针不指向任何函数或者对象;这里解释一下什么是空指针常量:一个表示0值的整数常量或常量表达式,0,0L,3-3都表示整数常量;所以进行:p = 0; p = 0L; p = '\0'; p = 3-3等其中一种p为空指针;
M UNLL指针:
NULL是一个标准规定的宏定义,用来表示空指针常量。因此,除了上面的各种赋值方式之外,还可以用 p = NULL; 来使 p 成为一个空指针。
N 野指针:
野指针不是空指针,是指向垃圾内存的指针。
形成原因
1.任何指针变量被刚创建时不会被自动初始化为NULL指针,它的缺省值是随机的。所以,指针变量在创建的同时应当被初始化,要么将指针设置为NULL,要么让它指向合法的内存。
2.指针被free或者delete之后,没有设置为NULL,让人误以为这是一个合法指针。free和delete只是把指针所指向的内存给释放掉,但并没有把指针本身给清理掉。这时候的指针依然指向原来的位置,只不过这个位置的内存数据已经被毁尸灭迹,此时的这个指针指向的内存就是一个垃圾内存。
3.由于C/C++中指针有++操作,因而在执行该操作的时候,稍有不慎,就容易指针访问越界,访问了一个不该访问的内存,结果程序崩溃;另一种情况是指针指向一个临时变量的引用,当该变量被释放时,此时的指针就变成了一个野指针。
以上内容仅供参考,笔者水平有限,错误或者有争议的地方请j及时指出QAQ.