C语言的学习,比较难的是指针的用法,指针搞不明白,那说明没有学好C语言。
下面将举例说明指针的一些用法,包括指针数组、数组指针、指针函数、函数指针和函数指针数组。
1. 指针
通常说所的指针是指针变量的简称,指针变量存放的是内存单元的地址,在32位处理器中地址是32位的,所以所有类型的指针都占32位即4字节。
一级指针存放非指针变量的地址,二级指针存放一级指针变量的地址。
下面来看一段程序:
#include <stdio.h> int main(void) { int a[5] = {1, 2 ,3, 4, 5}; int i; for(i = 0; i < 5; i++) printf("a[%d] = %d %d %d %d\n", i, a[i], *(a+i), *(i+a), i[a]); return 0; }
数组名a代表&a[0],是一个地址常量,对数组的操作本质是对指针的操作。i[a]这种写法也是可以的,i[a]等价于*(i+a),即*(a+i)。
2.指针数组
我们来看一个程序
#include <stdio.h> int main(void) { int a[5] = {1, 2, 3, 4, 5}; int *p[5], i; for(i = 0; i < 5; i++) p[i] = &a[i]; for(i = 0; i < 5; i++) printf("*p[%d]=%d\n", i, *p[i]); return 0; }
数组a和数组p的区别在于数组a的每个元素都是整型变量,而数组p的每个元素都是整型指针变量。
给元素赋值:
for(i = 0; i < 5; i++) p[i] = &a[i];
数组p的每个元素存放数组a的元素的地址。
编译运行程序的结果是:
*p[0]=1 *p[1]=2 *p[2]=3 *p[3]=4 *p[4]=5
3. 数组指针
先看一个程序
#include <stdio.h> int main(void) { int a[5] = {1, 2, 3, 4, 5}; int (*p)[5], i; p = &a; for(i = 0; i < 5; i++) printf("a[%d]=%d \n", i, *(*p+i)); return 0; }
这里p是数组指针,p指向的对象是具有10个元素的一维数组。注意p指向的对象一维数组,因此存放的必须是一维数组整体的地址,程序中的“p = &a”不能改为“p = a”,数组名代表首元素的地址,即a等价于&a[0]。
程序运行结果:
a[0]=1 a[1]=2 a[2]=3 a[3]=4 a[4]=5
现在我们来看看另外一个程序。
#include <stdio.h> int main(void) { int a[2][3] = {{1, 2, 3}, {4, 5, 6}}; int (*p)[3], i, j; p = a; for(i = 0; i < 2; i++) for(j = 0; j < 3; j++) printf("a[i][j]=%d %d %d %d %d %d\n", a[i][j], *(a[i]+j), *(*(a+i)+j), p[i][j], *(p[i] +j), *(*(p+i)+j)); return 0; }
指针p指向的是一维数组,因此要把一维数组的地址赋给p,赋值语句“p=a”把二维数组a的首元素地址&a[0]赋值给p,a[0]是一维数组,这是正确的。可以把p等价于a使用,最后用6种方式输出二维数组a的所有元素,结果如下:
a[i][j]=1 1 1 1 1 1 a[i][j]=2 2 2 2 2 2 a[i][j]=3 3 3 3 3 3 a[i][j]=4 4 4 4 4 4 a[i][j]=5 5 5 5 5 5 a[i][j]=6 6 6 6 6 6
4. 指针函数
指针函数是指返回值是地址的函数,例如:
int * fun(int a. int b);
函数fun的返回值是整型指针。
5. 函数指针
函数指针是指向函数的指针,下面看一个程序。
#include <stdio.h> int fun(int x, int y) { return x + y; } int main(void) { int a = 5, b = 4, c; int (*p)(int x, int y); //函数指针 p = fun; c = p(a, b); printf("%d + %d = %d\n", a, b, c); return 0; }
定义语句“int (*p)(int x, int y)”定义了p是指向具有两个整型参数,并且返回值是整型的函数的指针。然后把具有两个整型参数,并且返回值是整型的函数fun赋给p,这样p就指向函数fun的入口地址,使用时传入相应的参数。
这个程序的运行结果如下:
5 + 4 = 9
6. 函数指针数组
函数指针数组是多个相同类型函数指针的集合,下面看一个程序。
#include <stdio.h> int fun1(int x, int y) { return x + y; } int fun2(int x, int y) { return x - y; } int main(void) { int a = 5, b = 4, c, d; int (*p[2])(int x, int y); p[0] = fun1; p[1] = fun2; c = p[0](a, b); d = p[1](a, b); printf("%d + %d = %d\n", a, b, c); printf("%d - %d = %d\n", a, b, d); return 0; }
定义语句“ int (*p[2])(int x, int y);”定义了一个函数指针数组,数据p有两个元素,p[0]是一个指向具有两个整型参数,并且返回值是整型的函数的指针。然后把具有两个整型参数,并且返回值是整型的函数fun1赋给p[0],这样p[0]就指向函数fun1的入口地址,使用时传入相应的参数。
指针、函数和数组