C语言指针

来源:互联网 发布:java枚举类型有什么用 编辑:程序博客网 时间:2024/06/15 10:24

程序设计第10章:指 针 
一、指针的概念 
(1) 内存中每个字节有一个编号—–地址,编译或函数调用时为其分配内存单元 
(2)指针与指针变量 
指针:一个变量的地址 
指针变量:专门存放变量地址的变量叫指针变量 
(3)&与*运算符 
含义: 取变量的地址;单目运算符;优先级: 2;结合性:自右向左 
(4) 直接访问与间接访问 
直接访问:按变量地址存取变量值 
间接访问:通过存放变量地址的变量去访问变量 
二、变量的指针和指向变量的指针变量 
(1) 指针变量 
一般形式: [存储类型] 数据类型 *指针名; 
注意:指针变量只能指向定义时所规定类型的变量;指针变量定义后,变量值不确定,应用前必须先赋值 
(2)指针变量的初始化 
一般形式:[存储类型] 数据类型 *指针名=初始地址值(初始地址值赋给指针变量,不是赋给目标变量) 
注意:变量必须已说明过类型应一致;用已初始化指针变量作初值 
(3)指针变量作为函数参数——地址传递(特点:共享内存,“双向”传递) 
注意:函数的参数可以是各种类型的数据 
参数的传递是单向的,且只能返回一个函数值。若想在被调函数中改变主调函数中局部变量的值或从一个函数中返回多个值,可以法1—全局变量(但是破坏了模块的独立性)法2—指针作为函数的参数(地址传递) 
(a为调用前,b为调用时参数传递,c为调用时执行函数体*p1、*p2互换即a、b互换,d为调用后形参不再存在a、b值改变) 
三、 指针与数组 
(1)指针的运算 
指针变量的赋值运算:假设有 int a,array[10],*p,*p1;则: 
p=&a; (将变量a地址p) 
p=array; (将数组array首地址p) 
p=&array[i]; (将数组元素地址p) 
p1=p; (指针变量p值p1) 
不能把一个整数p,也不能把p的值整型变量并且指针变量与其指向的变量具有相同数据类型。 
2)指针的算术运算: 
pi实际地址 p id (i为整型数,d为p指向的变量所占字节数) 
p++, p–, p+i, p-i, p+=i, p-=i等 
若p1与p2指向同一数组,p1-p2=两指针间元素个数(p1-p2)/d 
p1+p2 无意义 
(2) 指针变量的关系运算 
1)若p1和p2指向同一数组,则:p1小于p2 表示p1指的元素在前 
p1>p2 表示p1指的元素在后 
p1==p2 表示p1与p2指向同一元素 
2)若p1与p2不指向同一数组,比较无意义 
p==NULL或p!=NULL 
其中NULL 是整数0,系统保证地址为0的单元不指向任何有效数据,当p= NULL,p的值为地址0,地址为0存储单元内存放的不是有效数据。故当p==NULL时代表p是一个空指针。 
(3) 一维数组及其指针变量在使用时的注意事项 
1) 指针变量可以实现使本身的值改变,即可以使用 
p++,p+=1等,但是指针变量的加减运算是使其值增加若干个相对移动量. 
2) 注意下面几种运算: 
y=p++与y=(p++) 等价 (*与++同优先等级,右结合性) 
y=(p++)与y=(++p)不等价 (前者访问当前,后者访问下一个) 
y=(p)++与y=(p++)不等价 (前者表示指针访问当前目标量给y,目标量再加1;后者表示指针访问当前目标量给y,指针再下移一个) 
(4) 数组名作函数参数 
数组名作函数参数,是地址传递 
数组名作函数参数,实参与形参的对应关系

实参形参数组名数组名数组名指针变量指针变量数组名指针变量指针变量

对于一维数组作形参的情况,系统是将形参按指针变量处理的;一维数组作实参时,只使用数组名。 
(5)一级指针变量与一维数组的关系 
int *p 与 int q[10] 
数组名是指针(地址)常量 
p=q; p+i 是q[i]的地址 
数组元素的表示方法:下标法和指针法, 即若p=q, 则 p[i]  q[i]  (p+i)  (q+i) 
形参数组实质上是指针变量,即int q[ ]  int *q 
在定义指针变量(不是形参)时,不能把int *p 写成int p[]; 
系统只给p分配能保存一个指针值的内存区(一般2字节);而给q分配2*10字节的内存区 
(6)指针与二维数组 
这里写图片描述 
(1)二维数组的指针变量 分为两类:指向列、指向行 
1)指向二维数组元素的指针变量(用列地址赋值) 
2)指向一维数组的指针变量(用行地址赋值) 
格式:类型名 (*指针变量名)[一维数组长度]; 
例如:int (*p)[4], a[3][4]; 
含义:p是指针变量,它指向含有4个元素的一维数组,每个元素的类型是int。 
一维数组指针变量维数和二维数组列数必须相同。 
p的值是一维数组的首地址,p是行指针 
注意:通过((p+i))[j]或者(*(p+i)+j)可以访问第i行第j个的元素 
(2)二维数组的指针作函数参数 
用指向变量的指针变量(列指针) 
用指向一维数组的指针变量(行指针) 
用二维数组名 
(3)二维数组与一维数组指针变量的关系 
如 int a[5][10] 与 int (*p)[10]; 
二维数组名是一个指向有10个元素的一维数组的指针常量 
p=a+i 使 p指向二维数组的第i行 
((p+i)+j)  a[i][j] 
二维数组形参实际上是一维数组指针变量,即 int x[ ][10]  int (*x)[10] 
变量定义(不是形参)时两者不等价 
系统只给p分配能保存一个指针值的内存区(一般2字节);而给数组a分配2*5*10字节的内存区 
四、 指针与字符串 
(1)字符串表示形式 
1)用字符指针实现 
字符指针初始化:把字符串首地址赋给string char *string; 
string=“I love China!”; 
2) 用字符数组实现 
3) (2)字符指针变量与字符数组 
char *cp; 与 char str[20]; 
数组str由若干元素组成,每个元素放一个字符;而cp中存放字符串首地址 
char str[20]; str=“I love China!”; () 
char *cp; cp=“I love China!”; () 
str是地址常量;cp是地址变量 
cp接受键入字符串时,必须先开辟存储空间 
字符串与数组关系 
1)字符串用一维字符数组存放 
2)字符数组具有一维数组的所有特点 
3)数组名是指向数组首地址的地址常量 
4)数组元素的引用方法可用指针法和下标法 
5)数组名作函数参数是地址传递等 
区别 
1)存储格式:字符串结束标志 
2)赋值方式与初始化 
3)输入输出方式:%s %c 
五、指针与函数 
函数指针:函数在编译时被分配的入口地址,用函数名表示;指针变量可指向整型变量、字符串、数组,也可以指向函数。 
(1)指向函数的指针变量 
定义形式: 数据类型 (*指针变量名)(函数参数列表);如 int (*p)(int,int); 
1)函数指针变量赋值:如p=max; 
2)函数调用形式: c=max(a,b);  c=(*p)(a,b); 
3)对函数指针变量pn, p++, p–无意义 
六、返回指针值的函数 
函数定义形式:类型标识符 *函数名(参数表);例 int *f(int x, int y) 
1) 函数返回值的数据类型是指针 
2) int (*p)(参数列表)与int *p(参数列表)不同 
七、指针数组和多级指针:用于处理二维数组或多个字符串 
(1) 指针数组 
定义:数组中的元素为指针变量 
定义形式:[存储类型] 数据类型 *数组名[数组长度说明];例 int *p[4]; 
(2) 二维数组与指针数组区别 
二维数组:存储空间固定 (name数组分配5*9字节);字符指针数组:相当于可变列长的二维数组;分配内存单元=数组维数*2=5*2(存放各字符串指针)。 另:各字符串长度根据需要分配,不计算在字符指针数组上。 
2、指针数组各元素:相当于二维数组的行名,但指针数组中元素是指针变量,二维数组的行名是地址常量。 
(2)多级指针(指向指针的指针) 
定义: 指向指针的指针 
一级指针:指针变量中存放目标变量的地址 
二级指针:指针变量中存放一级指针变量的地址 
定义形式:[存储类型] 数据类型 **指针名;(存储类型为: 指针本身的存储类型;数据类型为:最终目标变量的数据类型) 
(3) 二级指针与指针数组的关系 
int **p 与 int *q[10] 
指针数组名是二级指针常量 
p=q; p+i 是q[i]的地址 
指针数组作形参,int *q[ ]与int **q完全等价;但作为变量定义两者不同 
系统只给p分配能保存一个指针值的内存区;而给数组q分配10块内存区,每块可保存一个指针值 
这里写图片描述

0 0
原创粉丝点击