(一)指针
指针是C语言中的一个重要概念,也是C语言的一个重要特色。正确而灵活的使用指针,可以使程序简洁,紧凑,高效。可以说,指针就是C语言的精华。指针的概念比较复杂,使用也比较灵活,因此初学时常常会出错,仔细,比较,思考,练习是学习指针的关键。
1.1 什么是指针
指针就可以简单的理解为地址。就是说,可以通过它找到以它为地址的内单元,即信息。
C语言中的地址包括位置信息(纯地址)和它所指向的数据的类型信息。
所以,指针得含义就包含两个方面:一是以存储单元编号表示的纯地址,二是它指向的存储单元的数据类型(int,char,float等)。
&a,一般称它为变量a的地址,但,确切的说,应该是【整形变量a的地址】;
C语言中,对变量的访问有两种方式。
(1)直接访问:按变量名进行访问,例:printf("%d",i);
(2)间接访问:通过地址进行访问,例:int *p; p=&a; *p=1;就是对a赋值为1;
打个比方:为了打开一个A宝箱,有两种方法。一种是将钥匙带在身上,想打开的时候直接打开。另外一种是用另外一个B宝箱放钥匙,想打开A宝箱的时,就需要先打开B宝箱,然后再打开A宝箱。前一种就是直接访问,后一种就是间接访问;
*P就是表示P指向的对象。
指向就是通过地址来体现的,假设p的值是变量a的地址(2000),这样,就建立起来a和p的一种联系,即通过p能知道a的地址,从而找到变量a的内存单元。
1.2 指针变量
在C语言中可以定义整型变量,浮点型变量,字符型变量,等,也可以定义一类特殊的变量,用来存放地址,即指针变量(地址变量);
注意:指针和指针变量是两个概念,指针是一个地址,指针变量是一个存放地址的变量
1.2.1 【如何定义一个指针变量】
看个代码:
使用指针给两个变量赋值;
#include<stdio.h>
int main()
{
int a, b;
int *p1, *p2;
p1 = &a;
p2 = &b;
*p1 = 1;
*p2 = 2;
printf("%d\n%d\n", a, b);
return 0;
}
int * p;
*p1表示指针变量p1所指向的变量,也就是a;
程序中出现了两次p1和p2,二者含义不同,第一次出现是表示定义两个整型指针变量,第二次出现则代表p1和p2分别指向的变量。
定义指针变量时,左侧必须有类型名。例如:int *p1;char *p2;float *p3;即:类型名 * 指针变量名;
1.2.2 【如何引用一个指针变量】
(1) 给指针变量赋值。
int *p;
p = &a; //把a的地址赋给指针变量p;
(2) 引用指针变量指向的变量。
如果已执行“p = &a;”,即指针变量p指向了变量a。
printf("%d", *p); //以整数形式输出指针变量指向的变量的值,即a的值;
(3)引用指针变量的值
printf("%o",p);//以八进制形式输出指针变量p的值,如果p指向a,即输出a的地址。
注意:两个运算符*和&
*:指针运算符,*p代表指针变量p指向的对象。
&:取地址运算符,&a是变量a的地址。
看个题:
输入a和b两个整数,使用指针操作使他们按大小顺序输出;
#include<iostream>
using namespace std; //使用指针交换两个数;
int main()
{
int a, b;
int *p1, *p2,*t;
cin >> a >> b;
p1 = &a; //对a取地址
p2 = &b;
if (a < b)
{
t = p1;
p1 = p2;
p2 = t;
}
cout << "a=" << a <<"\t"<< "b=" << b << endl;
cout << "max=" << *p1<<"\t"<< "min=" << *p2 << endl;
return 0;
}
程序分析:
a和b的值并没有改变,它们仍保持原来的值,但p1和p2的值改变了,p1原来指向a,现在指向b。p2类推。
1.3 指针作函数参数
函数的参数也可以是指针,它的作用是将一个变量的地址传递到另外一个函数中。
同样的题目:
输入a和b两个整数,使用指针操作使他们按大小顺序输出;并且使用函数;
#include<iostream>
using namespace std; //使用指针交换两个数;
void max(int *p1, int *p2)
{
int t;
t = *p1;
*p1 = *p2;
*p2 = t;
}
int main()
{
int a, b;
int *p1, *p2,*t;
cin >> a >> b;
p1 = &a; //对a取地址
p2 = &b;
if (a < b)
{
max(p1, p2);
}
cout << "a=" << a <<"\t"<< "b=" << b << endl;
cout << "max=" << *p1<<"\t"<< "min=" << *p2 << endl;
return 0;
}
在函数调用时,将实参变量的地址传递给形参变量,采取的方法依然是“值传递”的方式。,函数调用结束后,形参p1和p2不复存在。
这个程序采用的方法是交换a,b的值,和上一个程序恰恰相反。
看个程序:
void fun(int x, int y)
{
int t;
t = x;
x = y;
y = t;
}
这个只是在子函数里交换了形参的值,而主函数中的值并没有交换。在调用函数时,a的值传给了x,b的值传给了y,执行完fun函数时,x和y的值进行了交换,但并没有影响a和b的值。
注意:单向传递的值传递,形参的改变不能改变实参。为了使在函数中改变了的变量被main函数所用,就不能采取把要改变的值作为参数的方法,而应该使用指针变量作为函数参数。