指针
指针与指针变量
指针:地址
指针变量:存放变量的地址
实例
int i = 2000; int *p; p = &i; printf("%d\n", *p);
定义指针变量三点注意
-
指针变量前面的"*",表示该变量的类型为指针型变量。其一般形式为:类型说明符 *变量名;
-
“*”表示这是一个指针变量,变量名即为定义的指针变量名,类型说明符表示本指针变量所指向的变量的数据类型
例如:float *p; 指针变量名是p
-
指针变量可以有空值,即该指针变量不指向任何变量,可以这样表示:p=NULL;
*与&
*:取值操作符
&:取址操作符
思考
-
如果执行了语句 p = &a; 那么&*p的含义是什么?
-
*与&两个运算符的优先级别相同,但按自右向左方向结合,因此先执行 *p的运算,它就是变量a,再执行&运算
-
因此,&*p与&a相同,即变量a的地址
-
*&a的含义是什么?
-
先进行&a运算,得a的地址,再进行*运算。即&a所指向的变量,也就是变量a
-
*&a和 *p的作用是一样的,它们都等价于a。即 *&a与a等价
指针与数组
引用一个数组元素:
-
下标法:如:a[i]形式;
-
指针法:如:*(a+i) 或 *(p+i)
注意:
-
其中a是数组名,p是指向数组元素的指针变量,其初值 p = a
2. 数组名即**数组中第一个元素的地址**
数组做参数
形式:
-
如 void add(int arry[]);
-
调用时add(a);//int a[3] = {1,2,3};
注意:当用数组名作为函数参数时,由于数组名代表的是数组首元素地址,因此传递的值是地址,所以要求形参是指针变量
二维数组与指针
表示形式 | 含义 |
---|---|
a | 二维数组名,指向一维数组a[0], 即0行首地址 |
a[0] , * (a+0) , * a | 0行0列元素地址 |
a+1 , &a[1] | 1行首地址 |
a[1] , *(a+1) | 1行0列元素a [1] [0] 的地址 |
a[1] + 2 , *(a+1)+2 , &a [ 1 ] [ 2 ] | 1行2列元素a [1] [2] 的地址 |
*(a [1] + 2) , * ( * (a+1)+2) , a [1] [2] | 1行2列元素a [1] [2] 的地址 |
二维数组指针变量可定义为:类型说明符 ( * 指针变量名) [长度] 如:int ( * p) [4]
-
他表示p是一个指针变量,它是指向包含4个元素的一维数组。
-
p + i 则指向一维数组a[i]
-
*(p+i)+j是二维数组i行j列的元素的地址,而 *( * (p+i)+j)则是i行j列的值。
void main() { int a[3][4]={0,1,2,3,4,5,6,7,8,9,10,11}; int (*p)[4]; int i,j; p = a; for(i = 0; i<3; i++) { for(j = 0; j<4; j++) { printf("%2d",*(*(P+i)+j)); } } }
指针数组
概念:一个数组,若其元素均为指针类型数据,称为指针数组,也就是说,指针数组中的每一个元素都相当于一个指针变量。一维指针数组的定义形式为类型名 * 数组名 [数组长度]如;int *name[4];
字符串与指针
除了字符数组,C语言还支持另外一种表示字符串的方法,就是直接使用一个指针指向字符串,例如:
char *str = "http://c.biancheng.net"; printf("%s",str);
char str[] = "http://c.biancheng.net"; printf("%s",str);
注意:以上两种字符串表示形式的原理不一样。
实例:
将字符串a复制到字符串b中
法一:
#include <stdio.h> void main() { char a[]="I Love China!", b[40],*p1, *p2; p1 = a; p2 = b; for(; *p1 != "\0"; p1++ ,p2++) { *p2 = *p1; } *p2 = '\0'; }
法二:
#include <stdio.h> void main() { char a[]="I Love China!", b[40],i; for(i=0; *(a+i) != "\0"; i++) { *(b+i) = *(a+i); } *(b+i)='\0'; }
字符指针变量和字符数组的讨论
-
字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的是地址(字符串第一个字符的地址),绝不是将字符串放到字符指针变量中。
-
赋值方式。
-
对字符数组只能对各个元素赋值,不能用以下办法对字符数组赋值。char str[20]; str="I love China!";
-
而对字符指针变量,可以采用下面方法赋值:char *a; a="I Love China1";但注意赋给a的不是字符,而是字符串第一个元素的地址
-
-
赋初值。
-
对字符指针变量初始化:char *a="I Love China!";等价于char *a; a="I Love China";
-
对数组初始化:char str[20]=" I Love China!";不等价char str[20]; str[]="I Love China!";
-
-
内存单元分配。
-
如果定义了一个字符数组,在编译时为它分配内存单元,它有确定的地址。
-
而定义一个字符指针变量时,给指针变量分配内存单元,在其中可以放一个字符变量的的地址。也就是说,该指针变量可以指向一个字符型数据,但如果未对它赋予一个地址值,则它并未具体指向一个确定的字符数据。
实例:
-
char str[10];scanf("%s",str);完全可以
-
char *a; scanf("%s",a);虽然一般可以运行,但这种方法是危险的
-
返回指针值的函数
一般定义形式:类型名 * 函数名(参数列表)
如:int *a(int x, int y);
区别
一个函数可以带回一个整型值、字符值、实型值等,也可以带回指针型的数据,即地址。其概念与以前类似,只是带回的值的类型是指针类型而已
指针函数与函数指针
-
指针函数:是指带指针的函数,即:本质是一个函数
-
函数指针:是指向函数的指针变量,因而函数指针本身首先应是指针变量,只不过该指针变量指向函数。
小结:
定义 | 含义 |
---|---|
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是一个指针变量,它指向一个指向整型数据的指针变量 |