前言:吼吼吼!终于学到了第八章得“指针”了!!

˙Ⱉ˙ฅ 种种定义

如果在程序中定义了一个变量,在对程序进行编译时,系统就会给这个变量分配内存单元。编译系统根据程序中定义的变量类型,分配一定长度的空间。内存区的每一个字节有一个编号,这就是“地址”。

由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元,将地址形象化地称为“指针”。

C语言中的地址包括位置信息(内存编号,或称纯地址)和它所指向的数据的类型信息,或者说它是“带类型的地址”。

存储单元的地址和存储单元的内容是两个不同的概念。

在程序中一般是通过变量名来引用变量的值。

直接按变量名进行的访问,称为“直接访问”方式。还可以采用另一种称为

“间接访问”的方式,即将变量的地址存放在另一变量(指针变量)中,

然后通过该指针变量来找到对应变量的地址,从而访问变量。

指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址。就像其他变量或常量一样,您必须在使用指针存储其他变量地址之前,对其进行声明。

指针变量声明的一般形式为:

1
2
type(类型名)*var-name(指针变量名);
//type 是指针的基类型(必须是一个有效的 C 数据类型);var-name 是指针变量的名称。

用来声明指针的星号 * 与乘法中使用的星号是相同的。但是,在这个语句中,星号是用来指定一个变量是指针。以下是有效的指针声明:

1
2
3
4
int    *ip;    /* 一个整型的指针 */
double *dp; /* 一个 double 型的指针 */
float *fp; /* 一个浮点型的指针 */
char *ch; /* 一个字符型的指针 */

左端的int是在定义指针变量时必须指定的“基类型”。指针变量的基类型用来指定此指针变量可以指向的变量的类型。

前面介绍过基本的数据类型(如int,char,float等),既然有这些类型的变量,就可以有指向这些类型变量的指针,因此,指针变量是基本数据类型派生出来的类型,它不能离开基本类型而独立存在。

1
2
3
4
5
在定义指针变量时要注: 
(1) 指针变量前面的“*”表示该变量为指针型变量。指针变量名则不包含“*”。
(2) 在定义指针变量时必须指定基类型。一个变量的指针的含义包括两个方面,一是以存储单元编号表示的纯地址(如编号为2000的字节),一是它指向的存储单元的数据类型(如int,char,float等)。
(3) 如何表示指针类型指向整型数据的指针类型表示为“int*”,读作“指向int的指针”或简称“int指针”。
(4) 指针变量中只能存放地址(指针),不要将一个整数赋给一个指针变量。
Tips:

所有实际数据类型,不管是整型、浮点型、字符型,还是其他的数据类型,对应指针的值的类型都是一样的,都是一个代表内存地址的长的十六进制数。
不同数据类型的指针之间唯一的不同是,指针所指向的变量或常量的数据类型不同。

˙Ⱉ˙ฅ 怎样引用指针变量

① 给指针变量赋值。

② 引用指针变量指向的变量。

③引用指针变量的值。

1
2
3
4
5
int a, *p;
p=&a; //把a的地址赋给指针变量p
printf("%d",*p); //以整数形式输出指针变量p所指向的变量的值,即a的值
*p=1; //将整数1赋给p当前所指向的变量,由于p指向变量a,相当于把1赋给a,即a=1
printf("%o",p); //以八进制形式输出指针变量p的值,由于p指向a,相当于输出a的地址,即&a ③
Tips:

要熟练掌握两个有关的运算符:

(1) &取地址运算符。&a是变量a的地址。

(2) ***** 指针运算符(或称“间接访问”运算符),*p代表指针变量p指向的对象。

˙Ⱉ˙ฅ 使用指针变量的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*[eg1]:通过指针变量访问整型变量。*/
#include <stdio.h>
int main()
{ int a=100,b=10;
//定义整型变量a,b,并初始化
int *pointer_1,*pointer_2;
//定义指向整型数据的指针变量pointer_1, pointer_2
pointer_1=&a; //把变量a的地址赋给指针变量pointer_1
pointer_2=&b; //把变量b的地址赋给指针变量pointer_2
printf("a=%d,b=%d\n",a,b); //输出变量a和b的值
printf("*pointer_1=%d,*pointer_2=%d\n",*pointer_1,*pointer_2);
//输出变量a和b的值
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*怎样引用指针变量
[eg2]:输入a和b两个整数,按先大后小的顺序输出a和b。
解题思路:不交换整型变量的值,而是交换两个指针变量的值(即a和b的地址)。
*/
#include <stdio.h>
int main()
{ int *p1,*p2,*p,a,b; //p1,p2的类型是int *类型
printf("please enter two integer numbers:");
scanf("%d,%d",&a,&b); //输入两个整数
p1=&a; //使p1指向变量a
p2=&b; //使p2指向变量b
if(a<b) //如果a<b
{ p=p1;p1=p2;p2=p;} //使p1与p2的值互换
printf("a=%d,b=%d\n",a,b); //输出a,b
printf("max=%d,min=%d\n",*p1,*p2); //输出p1和p2所指向的变量的值
return 0;
}
/*Tips:
a和b的值并未交换,它们仍保持原值,但p1和p2的值改变了。
实际上,第9行可以改为{p1=&b; p2=&a;}即直接对p1和p2赋以新值,这样可以不必定义中间变量p,使程序更加简练。
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/*指针变量作为函数参数
[eg3]:题目要求同例8.2,即对输入的两个整数按大小顺序输出。现用函数处理,而且用指针类型的数据作函数参数。*/
//Methods1
#include <stdio.h>
int main()
{ void swap(int *,int *p2); //对swap函数的声明
int a,b;
int *pointer_1,*pointer_2; //定义两个int *型的指针变量
printf("please enter a and b:");
scanf("%d,%d",&a,&b); //输入两个整数
pointer_1=&a; //使pointer_1指向a
pointer_2=&b; //使pointer_2指向b
if(a<b) swap(pointer_1,pointer_2); //如果a<b,调用swap函数
printf("max=%d,min=%d\n",a,b); //输出结果
return 0;
}

void swap(int *p1,int *p2) //定义swap函数
{ int temp;
temp=*p1; //使*p1和*p2互换
*p1=*p2;
*p2=temp;
} //本例交换a和b的值,而p1和p2的值不变。这恰和例8.2相反

//Methods2
#include <stdio.h>
int main()
{ void swap(int *,int *); //对swap函数的声明
int a,b;
//int *pointer_1,*pointer_2; //定义两个int *型的指针变量
printf("please enter a and b:");
scanf("%d,%d",&a,&b); //输入两个整数
//pointer_1=&a; //使pointer_1指向a
//pointer_2=&b; //使pointer_2指向b
if(a<b) swap(&a,&b); //如果a<b,调用swap函数
printf("max=%d,min=%d\n",a,b); //输出结果
return 0;
}

void swap(int *p1,int *p2) //定义swap函数
{ int temp;
temp=*p1; //使*p1和*p2互换
*p1=*p2;
*p2=temp;
}