第十二回合:指针
A: 指针的概念
内存存储单元按字节排序,每个字节编有序号,我们称之为地址。由于可以通过地址就可以找到所要的内存单元,所以我们把地址成为指针。指针是个特殊的变量,它里面存储的数值被解释为内存里的一个地址
作用:
(1) 指针可以有效地表示复杂数据结构,如队列、栈、链表等
(2) 指针可以像汇编一样处理内存地址,为动态内存分配提供支持
(3) 指针可以实现对数组和字符串的方便使用,提高程序的效率
B: 指针变量的定义
数据类型 * 指针变量;
如:
int *p2; /*p2是指向整型变量的指针变量*/
float *p3; /*p3是指向浮点变量的指针变量*/
char*p4; /*p4是指向字符变量的指针变量*/
说明:数据类型并不是指变量本身的类型,而是该变量所指向目标变量的类型。个指针变量只能指向同类型的变量。
C: 指针的赋值
(a) 使用地址运算符&:
如:int a =133;
int * p1;
p1= & a; //使用地址运算符把a的值赋值给指针p1
(b) 将一个已具有指向的指针变量赋值给另一个指针变量
如(接上面的): int* p2;
p2= p1; //p1和p2同时指向变量a
(c) 指针与数组的赋值
int a[5],*pa;
pa=a; //(数组名表示数组的首地址,故可赋予指向数组的指针变量pa)
也可写为:
pa=&a[0]; //数组第一个元素的地址也是整个数组的首地址,
当然也可采取初始化赋值的方法:
int a[5],*pa=a;
(d) 字符串与指针的赋值。
例如:
char *pc;
pc="C Language";
或用初始化赋值:
char *pc="C Language";
PS: 不允许把一个数赋予指针变量,故下面的赋值是错误的:
如:
int *p;
p=1000; //错误的操作
D: & 和 * 的使用
(a) 合法的使用取地址符可以得到一个变量的地址
如:
int a;
int score[5]= {80, 90, 97, 98, 63};
(1) &a, &score[0]; //该操作合法
(2) &(a+ 5); // 该操作非法
(3) &a= 123; //该操作非法
(4) &score; //该操作非法
(b) 使用* 运算符,间接存取指针所指向的目标标变量的值
itn a = 234;
int * p1;
p1=& a; //p1d的值为234
E: 指针与整数相加减
意义:表示指针的移动
如: p+n p-n p++ p-- ++p --p
PS:
(1) 其中的n为整数,地址移动不能为小数。
(2) 加法表示指针p向地址增大的方向移动。
(3) 减法表示指针p向地址减小的方向移动
(4) 至于移动的长度,是由计算机决定。
如:设p是指向type(类型的关键字)类型的指针,n为整型表达式,则p+(或—)n为一个新的地址。其值为p+(或-)n*sizeof(type)。
F: 指针与一维数组
由于数组中的各元素的存储单元是连续分配的,因此可以用指针来访问数组,数组名就是该数字的首个地址。
如: int score[100];
score 就是该数组的首个地址,等价于& score[0]
PS: 通过收地址,可以很快的、方便的访问数组中的其他元素,方法如下:
首地址+ 偏移量
第0个元素 score, &score[0] *score, *score[0], *(score+0), *(&score[0]+0)
第1个元素 score+1, &score[0]+1 *(score+1), *(&score[0]+1)
第2个元素 score+2, &score[0]+2 *(score+2), *(&score[0]+2)
第i 个元素 score+i, &score[0]+I *(score+i), *(&score[0]+i)
备注:指针与二维数组的关系也和一维的差不多
G: 指针与字符串
(a) 可以用指针的方式定义字符串
如:char * str=“china”; //定义了指针变量str,其值为“china”的首个地址
等价于:
char * str;
str=“china”;
H:指针数组
指针数组也是数组,但又不同。指针数组中的元素值全部是其他变量的内存单元地址,即指针。这些指针必须指向同一类型的变量。
定义:
数据类型 *数组名[数组长度]
如: char * p1[2];
I:指向指针的指针
由于指针变量本身就是个变量,因此可以创建指向指针的指针(双重指针变量),其值为一个指针变量的地址。
如:
int a= 123;
int *p1=&a; //p1是指向变量a的指针变量
int** p2= &p1; //p2是指向变量p1的指针变量
(复习做的笔记,还在整理中。。。。)