C语言中的难点——指针
1.概念:变量的指针就是变量的地址,存放变量地址的变量是指针变量。为了表示指针变量和它所指向的变量之间的关系,在程序中用“*”符号表示“指向”,例如,i_pointer代表指针变量,而*i_pointer是i_pointer所指向的变量。
2.定义指针变量:
int *p1;
//p1是指向整型变量的指针变量
float *p2;
//p2是指向浮点变量的指针变量
char *p3;
//p3是指向字符变量的指针变量
【注意】一个指针变量只能指向同类型的变量。
3.指针变量引用:
设有指向整型变量的指针变量p,如要把整型变量a 的地址赋予p可以有以下两种方式:
(1)指针变量初始化的方法
int a;
int
*p=&a;
(2)赋值语句的方法
int
a;
int
*p;
p=&a;
【注意】不允许把一个数赋予指针变量,int *p;p=1000;这样赋值是错误的。被赋值的指针变量前不能再加“*”说明符,如写为*p=&a
也是错误的。
此时,*p相当于变量a。x=*p;<=>
x=a;
另外,指针变量和一般变量一样,存放在它们之中的值是可以改变的,也就是说可以改变它们的指向,假设
int i,j,*p1,*p2;
i='a';
j='b';
p1=&i; //p1指向对象i
p2=&j; //p2指向对象j
p2=p1;
//p2改变指向指向对象i,此时*p2=i
如果是*p2=*p1;
//将p1指向的内容‘a’赋予p2所指的区域。此时j='a';
问:&*p1 表示什么含义?*&i
表示什么含义? 答:*和&会相互抵消,&*p1就是p1。同理*&i就是i。
4.指针变量作为函数参数
函数的参数不仅可以是整型、实型、字符型等数据,还可以是指针类型。它的作用是将一个变量的地址传送到另一个函数中。在函数调用时,将实参变量的值传递给形参变量。采取的依然是“值传递”方式。因此最终指针形参的值就变成了实参变量的值。而反过来,不能企图通过改变指针形参的值而使指针实参的值改变。函数调用结束后,形参指针变量不复存在(已释放)。
swap(int *p1,int
*p2)
{int
temp;
temp=*p1;
*p1=*p2;
*p2=temp;
}
main()
{
int a,b;
int *pointer_1,*pointer_2;
scanf("%d,%d",&a,&b);
pointer_1=&a;pointer_2=&b;
if(a
swap(pointer_1,pointer_2);
printf("n%d,%dn",a,b);
}
5.指针变量的运算:它只能进行赋值运算和部分算术运算及关系运算(有限)。
①指针变量初始化赋值,前面已作介绍。
②把一个变量的地址赋予指向相同数据类型的指针变量。
例如:
int a,*pa;
pa=&a;
③把一个指针变量的值赋予指向相同类型变量的另一个指针变量。
如:
int a,*pa=&a,*pb;
pb=pa;
由于pa,pb均为指向整型变量的指针变量,因此可以相互赋值。
④把数组的首地址赋予指向数组的指针变量。
例如:
int a[5],*pa;
pa=a;
(数组名表示数组的首地址,故可赋予指向数组的指针变量pa)
也可写为:
pa=&a[0];
当然也可采取初始化赋值的方法:
int a[5],*pa=a;
⑤把字符串的首地址赋予指向字符类型的指针变量。
例如:
char *pc;
pc="C Language";
或用初始化赋值的方法写为:
char *pc="C Language";
这里应说明的是并不是把整个字符串装入指针变量,而是把存放该字符串的字符数组的首地址装入指针变量。在后面还将详细介绍。
⑥把函数的入口地址赋予指向函数的指针变量。
例如:
int (*pf)();
pf=f;
【注意】指针运算符*和指针变量说明中的指针说明符*不是一回事。在指针变量说明中,“*”是类型说明符,表示其后的变量是指针类型。而表达式中出现的“*”则是一个运算符用以表示指针变量所指的变量。
main(){
int
a=5,*p=&a;
printf
("%d",*p);
}
*p=&a表示指针变量p取得了整型变量a的地址。printf("%d",*p)语句表示输出变量a的值。
6.指向多维数组的指针和指针变量:
设有整型二维数组a[3][4]如下:
a[0] 0 1 2 3
a[1] 4 5 6 7
a[2] 8 9 10 11
7.函数指针变量:
类型说明符 (*指针变量名)();
如:int (*pf)();表示pf是一个指向函数入口的指针变量,该函数的返回值(函数值)是整型。
8.指针型函数:
int *ap(int x,int y)
{
......
}
exit是一个库函数,exit(1)表示发生错误后退出程序,exit(0)表示正常退出。
9.指针数组:
类型说明符
*数组名[数组长度]
如:int *pa[3] 表示pa是一个指针数组,它有三个数组元素,每个元素值都是一个指针,指向整型变量。
10.怎样定义一个指向指针型数据的指针变量呢?如下:
char **p;
定义
含 义
int i;
定义整型变量i
int *p
p为指向整型数据的指针变量
int a[n];
定义整型数组a,它有n个元素
int *p[n];
定义指针数组p,它由n个指向整型数据的指针元素组成
int (*p)[n];
p为指向含n个元素的一维数组的指针变量
int f();
f为带回整型函数值的函数
int *p();
p为带回一个指针的函数,该指针指向整型数据
int (*p)();
p为指向函数的指针,该函数返回一个整型值
int **p;
P是一个指针变量,它指向一个指向整型数据的指针变量
现把全部指针运算列出如下:
1) 指针变量加(减)一个整数:
例如:p++、p--、p+i、p-i、p+=i、p-=i
一个指针变量加(减)一个整数并不是简单地将原值加(减)一个整数,而是将该指针变量的原值(是一个地址)和它指向的变量所占用的内存单元字节数加(减)。
2) 指针变量赋值:将一个变量的地址赋给一个指针变量。
p=&a; (将变量a的地址赋给p)
p=array; (将数组array的首地址赋给p)
p=&array[i]; (将数组array第i个元素的地址赋给p)
p=max; (max为已定义的函数,将max的入口地址赋给p)
p1=p2; (p1和p2都是指针变量,将p2的值赋给p1)
注意:不能如下:
p=1000;
3) 指针变量可以有空值,即该指针变量不指向任何变量:
p=NULL;
4) 两个指针变量可以相减:如果两个指针变量指向同一个数组的元素,则两个指针变量值之差是两个指针之间的元素个数。
5) 两个指针变量比较:如果两个指针变量指向同一个数组的元素,则两个指针变量可以进行比较。指向前面的元素的指针变量“小于”
指向后面的元素的指针变量。