变量与指针
变量的指针就是变量的地址,用来存放变量地址的变量是指针变量。
指针变量是一种特殊的变量,它和以前学过的其它类型的变量的不同之处是,指针变量用来指向另一个变量。
为了表示指针变量和它所执行的变量之间的联系,在C++中用 * 符号表示指向。
如:i_pointer是一个指针变量,而 * i_pointer表示i_pointer所指向的变量。
定义指针变量
C++规定所有变量在使用前必须先定义,即指定其类型,在编译时按变量类型分配存储空间。对指针变量必须将它定义为指针类型。如:
int i, j; //定义整型变量i,j
int *pointer_1, *pointer_2; //定义指针变量pointer_1,pointer_2
指针变量前的int是指,所定义的指针变量是指向整型数据的指针变量,或者说,pointer_1,pointer_2中只能存放整形数据的地址,而不能存放浮点型或其它数据类型的地址。
也就是说,指针变量pointer_1,pointer_2只能用来指向整型数据,而不能指向浮点型变量。这个int就是指针变量的基类型。
指针变量的基类型就是该指针变量指向的变量的类型
定义指针变量的一般形式为
基类型 * 指针变量名;
需要注意的是 * 不是指针变量的一部分,在变量名前加一个 * 表示该变量为指针变量。
把被指向的变量的地址赋给指针变量,则指针变量就会指向另一个变量。如:
pointer_1=&i; //将变量i的地址存放到指针变量pointer_1中
pointer_2=&j; //将变量j的地址存放到指针变量pointer_2中
这样,pointer_1就指向了变量i,pointer_2就指向了变量j。
一般的C++编译系统为每一个指针变量分配4个字节的存储单元,用来存放变量的地址。
在定义指针变量时注意:
1、在定义指针变量时必须指定基类型。由于不同类型的数据在计算机系统中的存储方式和所占的字节数是不同的,因此,想通过指针引用一个变量,只知道地址是不够的,必须知道该数据的类型,才能按存储单元的长度以及数据的存储形式正确地去除该数据。
一个变量的指针包括两个方面的含义,一是以存储单元编号表示的地址(如编号为2000的字节),一是它指向的存储单元的数据类型(如int,char,float等),即基类型。指针变量是基本数据类型派生出来的类型,它不能离开基本类型而独立存在。
2、怎么表示指针类型。
基本类型可以用char,int,float等系统已定义的类型标识符来表示,指针类型应当明确指出其基类型。指向整型数据的指针类型表示为int *,读作指向int的指针或简称int指针。
3、不能用一个整数给一个指针变量赋值
4、一个指针变量只能指向同一个类型的变量
5、在说明变量类型时,不能一般地说a是一个指针变量,而应完整地说a是指向整型数据的指针变量。
引用指针变量
有两个与指针变量有关的运算符
(1)&:取地址运算符
(2)*:指针运算符(或称间接访问运算符)
例1:通过指针变量访问整型变量
#include <iostream>
using namespace std;
int main()
{
int a, b; //定义整型变量a,b
int * pointer_1, * pointer_2; //定义指针变量为int型变量
a = 100, b = 10; //赋值
pointer_1 = &a; //把变量地址赋给指针变量
pointer_2 = &b;
cout << a << " " << b << endl; //输出a,b的值
cout << *pointer_1 << " " << *pointer_2 << endl; //通过指针变量输出a,b的值
cout << pointer_1 << " " << pointer_2 << endl; //输出变量的地址
return 0;
}
结果如下:

对&和*运算符的说明
1、如果已执行了pointer_1=&a;语句,请问&*pointer_1的含义是什么?
&和*两个运算符的优先级别相同,但按自右向左方向结合,因此先进行*pointer_1的运算,它就是变量a,再执行&运算,因此,&*pointer_1与&a相同,即变量a的地址。
2、*&a的含义是什么?
先进行&a的运算,得到a的地址,即pointer_1,再进行*运算,即*pointer_1,*&a和*pointer_1的作用是一样的,它们等价于变量a。
例2:输入a和b两个整数,按先大后小的顺序输出a和b,用指针变量处理。
#include <iostream>
using namespace std;
int main()
{
int a, b, * p1, * p2, * p;
cout << "请输入两个整数:";
cin >> a >> b;
p1 = &a;
p2 = &b;
if (a < b)
{
p = p1;
p1 = p2;
p2 = p;
} //此法是交换两个指针变量的值,而非交换a和b的值
cout << "输出结果为:" << *p1 <<" " << *p2 << endl;
return 0;
}
结果如下:

用指针作函数参数
函数的参数不仅可以是整型、浮点型、字符型等数据,还可以是指针类型,它的作用是将一个变量的地址传送给被调用函数的形参。
例3:对输入的两个整数按大小顺序输出,用函数处理,并用指针类型的数据作函数参数。
#include <iostream>
using namespace std;
int main()
{
int a, b, * pointer_1, * pointer_2;
void swap(int* p1, int* p2);
cout << "请输入两个整数:";
cin >> a >> b;
pointer_1 = &a;
pointer_2 = &b;
if(a<b) swap(pointer_1, pointer_2);
cout << "输出结果为:" << a <<" " << b << endl;
return 0;
}
void swap(int* p1, int* p2) //函数的作用是将 * p1的值和 * p2的值互换
{
int temp;
temp = *p1;
*p1 = *p2;
*p2 = temp;
}
结果如下:

程序分析:
swap是用户定义的函数,它的作用是交换两个变量的值。swap函数的两个形参p1,p2是基类型为整型的指针变量。程序运行时,先执行main函数,输入a和b的值,然后将a和b的地址分别赋给指针变量pointer_1和pointer_2,使pointer_1指向a,pointer_2指向b。接着执行if语句,由于a<b,因此执行swap函数。
注意,实参pointer_1和pointer_2是指针变量,在函数调用时,将实参变量的值传送给形参变量,而现在实参变量的值是地址,通过虚实结合,形参p1得到实参pointer_1的值&a,形参p2得到实参pointer_2的值&b。这时p1和pointer_1都指向变量a。p2和pointer_2都指向变量b,接着执行swap函数,使*p1和*p2的值互换,也就是使a和b的值互换,最后输出a和b。
可以看到,在执行swap函数后,主函数中的变量a和b的值改变了,这个改变不是通过将形参值传回实参来实现的,而是用指针变量作为函数实参,在函数执行过程中使指针变量所指向的变量值发生变化,函数调用结束后,这些变量的变化依然保留下来,这样实现通过调用函数使变量的值发生变化,并在主调函数中使用这些改变了的值。
不能试图通过改变形参指针变量的值而使实参指针变量的值改变。
实参变量和形参变量之间的数据传递使单向的值传递方式,指针变量作函数参数也要遵循这一规则,调用函数时不会改变实参指针变量的值,但可以改变实参指针变量所指向的值。
函数的调用可以而且只可以得到一个返回值,而使用指针变量作函数参数,就可以通过指针变量改变主调函数中变量的值,相当于通过函数调用从被调用的函数中得到多个值。
C++中参数的传递方式
1、值传递
函数接收的是参数的副本,函数内对参数的修改不影响原始数据。
void increment(int x)
{
x++; // 修改副本,不影响原始值
}
int main()
{
int a = 5;
increment(a); // a 仍为 5
return 0;
}
2、引用传递
函数接收的是实参的引用,也叫别名,函数内修改直接影响原始数据。
void increment(int& x)
{
x++; // 直接修改原始值
}
int main()
{
int a = 5;
increment(a); // a 变为 6
return 0;
}
3、指针传递
函数接收的是实参的地址,通过解引用操作原始数据。
void increment(int* ptr)
{
(*ptr)++; // 解引用修改原始值
}
int main()
{
int a = 5;
increment(&a); // a 变为 6
return 0;
}
例4:输入a,b,c三个整数,按由大到小的顺序输出
#include <iostream>
using namespace std;
int main()
{
int a, b, c, * p1, * p2, * p3;
void exchange(int*, int*, int*);
cout << "请输入三个整数:";
cin >> a >> b >> c;
p1 = &a;
p2 = &b;
p3 = &c;
exchange(p1, p2, p3);
cout << "输出结果为:" << a << " " << b <<" "<< c << endl;
return 0;
}
void exchange(int *p1, int *p2,int *p3)
{
void swap(int* p1, int* p2);
if (*p1 < *p2) swap(p1, p2);
if (*p1 < *p3)swap(p1, p3);
if (*p2 < *p3)swap(p2, p3);
}
void swap(int* p1, int* p2)
{
int temp;
temp = *p1;
*p1 = *p2;
*p2 = temp;
}
结果如下:

C++第26天:变量与指针学习

被折叠的 条评论
为什么被折叠?



