指针变量的定义
C语言有两种变量:
普通变量存储内容值
指针变量存储地址值
指针变量
定义的格式:类型名指针变量名;
1、定义变量(普通变量、指针变量)都必须在前面有类型名
2、在定义指针变量时,指针变量名前的”
“表示现定义的是一个指针类型的变量
*并不是指针变量名的一部分,只是一个标志
3、指针变量专门用来存地址,禁止将一个整型值直接赋给一个指针变量

一、指针变量的引用

“&”取地址运算符,通过&运算符可以取出普通变量的地址
“指针运算符,可以取出指针变量所指向的普通变量的值
(间接引用普通变量)
指针变量名
例如:
int a,b=20,c=30,d=40,
p;
p=&d;
a=p; a=40 b=20 c=30 d=40
1、可以通过赋值给一个指针变量”指向”某一普通变量(指针变量=&普通变量)
例如:
int a=10;
int
p;
p=&a;
2、在C语言中正确的做法是先让指针变量指向一个确定的存储单元后,
再通过该指针变量引用它所指向的存储单元
如:
intp;
p=100;警告!
3、变量名(普通变量、指针变量)都表示其存储单元内的值
4、若指针变量p指向变量a,即将变量的地址赋给了指针变量p
如:int a=20,p=&a;
则有下列结果:
(1)
p<=>a
(2)p<=>&a
(3)&p<=>&a<=>p
(4)
&a<=>p<=>a
(5)(
p)++ a++都是给变量a的值加1
5、所有的指针变量在内存中分配的字节数相同。sizeof()

二、一维数组指针

int fun(int a[10])
<=>int fun(int a)
<=>int fun(int a[ ])
若数组做为形参,则将数组名做指针变量来处理
指向数组元素的指针变量
由于数组元素与普通一样,所以定义指向数组元素的指针变量与定义
指向普通变量的指针变量完全一样
如:
int s[10],a,b;
int b[3][6];
int
p;
p=&a;
p=&s[2];
p=&b[2][4];
1、在C语言中规定:数组名代表数组的首地址,而且是一个地址常量
如:
int a[10];
intp;
P=a;<=>P=&a[0];
2、当指针变量指向数组中的某一个元素时,指针变量加1后指向数组的下一个元素,
指针变量减1指向数组中的前一个元素
如:
float a[10];float
p;
p=&a[4];则p-3的指向为a[1]
3、若两个指针变量指向同一数组,则这两个指针变量可以进行大小比较
char s[8];
charp1=s+3,p2=&s[7];
则:
p1>p2=>0 p11
p1-p2=>-4 p2-p1=>4
4、在形参中的数组实际上是一个指针变量,并不是真正的数组,
因为该”数组名”的值是可以改变的,而真正的数组名的值是不能改变的。
5、若形参是数组或指针变量,则在函数中可以通过该形参改变实参的值。

int a[N],p=a;
p+i a+i &a[i]
(p+i)(a+i)a[i]<=>p[i]
当指针变量指向数组时,下标运算([ ])用于数组也可用于指针变量后
(p+i) (a+i) a[i] p[i]
p++ ++p p+=1 p=p+1
p— —p p-=1 p=p-1
p++ (p++) p— (p—)
++p (++p) —p (—p)
(
p)++ ++(p) ++p
(p)— —(p) —*p

若有定义:int b[5]={10,30,20,15,40};
intq=b+2;
则:
q++表达式的值为2,同时q的指向为15
++q表达式的值为15,同时q的指向为15
(
q)++表达式的值为20,同时q的指向为20
++(*q)表达式的值为21,同时q的指向为20

三、指向多维数组的指针变量

如:int a[3][4];
a+1是跳过一行。因为二维数组是行指针,加1是跳过一行不是一个元素
注意:
1、只有列指针才是”真正”指向元素。即指向某一个元素的存储单元。
2、一维数组名表示的是列指针;二维数组名表示的是行指针。
若a是一个二维数组,则有:
1、a+i是行指针,即指向的是一整行。若对它加1则指向下一行。
2、(a+i)和a[i]一样,都是一个列指针即指向的是一个元素。
3、
(a+i)+j和a[i]+j一样,都表示元素a[i][j]的地址。即与&a[i][j]等价。
4、((a+i)+j) (a[i]+j)[j]和a[i][j]一样 都表示元素a[i][j]
指向多维数组元素的指针变量
int a[3][4];
int
p=&a[0][3];
则:
p+1指向元素a[1][0]
p+4指向元素a[1][3]
p-2指向元素a[0][1]
常用与取二维数组a元素地址的方式:
&a[i][j] a[i]+j (a+i)+j
指向由m个元素组成的一维数组的指针变量
定义指向由m个元素组成的一维数组的指针变量的格式
类型(
指针变量名)[m];
如:
int a[5][7];
int(p)[7];
p=a;
char b[10][80];
char (
r)[80];
r=b+5;

四、指向字符串的指针变量

字符串常量:C语言对字符串常量是按首地址处理字符串常量
1、char str[]=”China”;
2、char*p=”China”;
3、str=”Chinese”; 错误 复制号的左边不能放常量
4、p=”Chinese”; 正确 p是地址变量

五、指向函数的指针变量

函数名与数组名一样,是起始地址,而且是一个地址常量
定义指向函数的指针变量的方式:
类型名(*指针变量名) ();

类型名(指针变量名)(); 指向函数的指针变量
类型名 普通变量名; 内容变量
类型名 数组名[]; 数组
类型名
指针变量名; 普通地址变量
类型名 函数名() 函数的定义
{…}
类型名 (*指针变量名)[m]; 指向m个元素的一维数组的指针变量

1、在定义指向函数的指针变量时,要注意有两个小括号必须要有。
2、单独的函数名代表该函数的首地址(函数的入口地址)。
3、函数的指针变量只能指向函数的入口处(函数的首地址),不能指向函数中的某条指令
(另对指向函数的指针变量加1是没有意义的)。
4、给指向函数的指针变量赋值时,只写函数名即可。

六、返回指针的函数

返回指针的函数
类型名 函数名(形参)
{ }
返回指针的函数的定义方式为:
类型名*函数名(形参列表){ }

int fun(int x); 普通函数的定义
int fun(int x); 返回指针类型的函数
int (
fun)(int x); 指向函数的指针变量

七、指针数组和指向指针的指针变量

指针数组和指向指针的指针变量
若一个数组的所有元素均为指针类型(地址),则称为指针数组。
格式:
类型名数组名[常量表达式];
例1:类型名
数组名[常量表达式];
ints[10];
例2:类型名
指针变量名
intp;
例3:类型名 数组名[常量表达式];
int s[10];
1、要注意它与定义指向由m个元素组成的一维数组的指针变量之间的区别
**类型名
数组名[常量表达式];
类型名(指针名)[常量表达式m];**
2、它的每个元素都是一个指针类型(地址),即它的每个元素都相当于一个指针变量。
int
a[10]; 指针数组
int a[10]; 一维数组
int a[10][10]; 二维数组

八、指向指针的指针变量

用来存放指针变量地址的指针变量称为指向指针的指针变量。
定义格式:
类型名指针变量名;
如:
int a=3;
int *p=&a;
int
k=&p;
则:k得到变量p(变量a的地址)
*
k得到变量a的值(a的数据3)

九、空指针

变量可以有空值,即指针变量不指向任何变量,不指向任何有用的存储单元
在系统中已将NULL定义为0,即NULL的值为0
int a,b,c*p=NULL;
此时p的值为空指针,即p不指向任何有用的存储单元。尽管NULL的值为0,
但我们不能认为p指向了地址为0的存储单元。
1、当一个指针变量的值为空指针时,我们不能引用它所指向的存储单元。
2、若某指针(地址)的类型为void型,则有引用时应进行相应的强制类型置换。