首页 > 代码库 > 8、C语言——指针

8、C语言——指针

指针

一、指针变量定义

   1、定义的格式:

        类型名 *指针变量名

此处的*是一种标志,指针变量的标志
指针变量名是符合用户的标识符
前类型后分号是定义语句,除此以外都是执行语句

 c语言有两种变量:

        变量(普通变量)存储内容值,常量都是内容值,只能存放在普通变量中;

        地址变量(指针变量)存储地址值;


注:
1)定义变量(普通变量、指针变量)都必须在前面有类型名
2)在定义指针变量时,指针变量名前的“*”表示现定义的是一个指针类型的恩,只是一个标志。变量。星号并不是指针变量名的
3)指针变量专门用存地址,禁止将一个整型值直接赋给一个指针变量


2、指针变量的引用
“&”取地址运算符,通过&运算符可以取出普通变量的地址
&内容变量=地址值
“*”指针运算符,*可以取出指针变量所指向的普通变量的值,(间接引用普通量)
*的三种用法:

标志
指针运算符
*地址变量 = 内容值
指针方法:*p放在赋值号左边是写操作,如果放在赋值号右边是读操作
注:
1)可以通过赋值使一个指针变量“指向”某一普通变量(指针变量=&普通变量)
2)在C语言中正确的做法是先让指针变量指向一个确定的存储单元后,再通过该指针变量引用它所指向的存储单元
int *p;
*p = 200;此操作很危险,指针变量定义且初始化后才可以使用
3)变量名(普通变量、指针变量)都表示其存储单元内的值
4)若指针变量p指向变量a,即将变量a的地址赋给了指针变量p
int a=20,*p=&a;
A、*p<=>a
B、p<=>&a
C、&*p<=>&a<=>p
D、*&a<=>*p<=>a
E、(*p)++ a++
(*p)-- a--
++(*p) ++a ++*p
--(*p) --a --*p

5)所有的指针变量在内存中分配的直接数相同.sizeof()

说明:
1)int fun(int a[10])<=>int fun(int *a)=int fun(int a[])
&与*互逆
*与[]等价
&与[]互逆
若数组做为形参,则将数组名做指针变量来处理
二、指向数组的指针变量
1、指向数组元素的指针变量
由于数组元素与普通一样,所以定义指向数组元素的指针变量预定义指向普通变量的指针变量完全一样
注:
1)在c语言中规定:数组名代表数组的首地址,而且是一个地址常量
2)当指针变量指向数组中的某一个元素时,指针变量加1后指向数组的下一个元素,指针变量减1时指向数组中前一个元素
2、指向一维数组的指针变量
int a[10];
int *p;
p=a;<=>p=&a[0]
注:
1)在c语言中规定:数组名代表数组的首地址,而且是一个地址常量
2)当指针变量指向数组中的某一元素时,指针变量加1指向数组的下一个元素,指针变量减1时指向数组中前一个元素
3)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指针没有移动,但是指针所指的内容值加1
(*p)--;--(*p) 等价--*p

4)若两个指针变量指向同一个数组,则这两个指针变量可以进行大小比较
5)在形参中的数组实际上是一个指针变量,并不是真正的数组,因为该“数组名”的值是可以改变的,而真正的数组名的值是不能改变的
6)若形参是数组或指针变量,则在函数中可以通过该形参改变实参的值
三、指向多维数组的指针变量
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]等价。*(a+i)+j、a[i]+j、a[i][j]
4)*(*(a+i)+j)、*(a[i]+j)、(*(a+i))[j]和a[i][j]一样,都表示元素a[i][j]
注意:
int w[2][3]
*(w+1)[2]是元素,先计算[]后计算(),而[]是施加在()==w[3][0]的值是可以改变的,而真正的数组名的值是不能改变的
行[]列[]元素
行*列*元素
2、指向由m个元素组成的一维数组的指针变量
定义指向由m个元素组成的一维数组的指针变量的格式:
基类型 (*指针变量名)[m];
int *p;列指针变量
int (*p)[m]行指针变量
元素是普通变量
一维数组名是首地址,是地址常量,a=&a[0]

四、指向字符串的指针变量
字符串常量:C语言对字符常量是按首地址处理字符串常量
char str[]="abcd"等价char str[]={"abcd"}
char *p="abcd"但是不等价char *p={"abcd"}
str="abcd"不合法,常量不能放于赋值号左边
p="abcd"

五、指向函数的指针变量
函数名与数组名一样,是起始地址,而且是一个地址常量

定义指向函数的指针变量的方式:
类型名 (*指针变量名)();

小总结:
类型名 (*指针变量名)();
类型名 普通变量名;
类型名 数组名[];
类型名 *指针变量名;
类型名 函数名()
{....}
类型名(*指针变量名)[M];

注:
1)在定义指向函数的指针变量时,要注意有两个小括号必须要有,不需要定义形参
2)单独的函数名代表该函数的首地址(函数的入口地址)
3)函数的指针变量只能指向函数的入口处(函数的首地址)
4)给指向函数的指针变量赋值时,只写函数名即可,不必写参数

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

七、指针数组和指向指针的指针变量
1、若一个数组的所有 元素均为指针类型(地址),则称为指针数组

格式:
类型名 *数组名[常量表达式]

注:1)要注意它和定义指向由m个元素组成的一维数组的指针变量之间的区别
类型名 *数组名[常量表达式];
类型名 (*指针名)[常量表达式m];
2)它的每个元素都是一个指针类型(地址),即它的每个元素都相当于一个指针变量
2、指向指针的指针变量
用来存放指针变量地址的指针变量称为指向指针变量
定义格式:
基类型名 **指针变量名

八、空指针
指针变量可以有空值,即指针变量不指向任何变量,不指向任何有用的存储单元
在系统中已将null定义为0,即null的值为0
int a, b, c, *p=null;
此时p的值为空指针,即p不指向任何有用的存储单元,尽管null的值为0,但我们不能认为p指向了地址为0的存储单元

注:1)当一个指针变量的值为空指针,我们不能

8、C语言——指针