C++指针

前言

指针是C和C++中一个重要的概念。正确而灵活地运用它,可以使程序简洁、紧凑、高效。

每一个学习、使用C和C++语言的人,都应该深入地学习和掌握指针。

学习 C++ 的指针既简单又有趣。通过指针,可以简化一些 C++ 编程任务的执行,还有一些任务,如动态内存分配,没有指针是无法执行的。

每一个变量都有一个内存位置,每一个内存位置都定义了可使用连字号(&)运算符访问的地址,它表示了在内存中的一个地址。

两个与指针变量有关的运算符:

(1)& 取地址运算符

(2)* 指针运算符(或称间接访问运算符)

请看下面的实例,它将输出定义的变量地址:

实例:

#include <iostream>

using namespace std;

int main()
{
	int  var1;
	char var2[10];

	cout << "var1 变量的地址: ";
	cout << &var1 << endl;

	cout << "var2 变量的地址: ";
	cout << &var2 << endl;

	return 0;
}
执行结果:

什么是指针?

指针是一个 变量它的值是另一个变量的地址,也就是,内存位置的直接地址。就像其它的常量或者变量一样,在使用指针存储其他变量地址之前, 必须对其声明。指针变量声明的一般形式为:

有效的C++基本数据类型   *指针变量名
其中,*号指定一个变量是指针。

以下是有效的指针声明:

int    *ip;    /* 一个整型的指针 */
double *dp;    /* 一个 double 型的指针 */
float  *fp;    /* 一个浮点型的指针 */
char   *ch;    /* 一个字符型的指针 */
所有指针的值的实际数据类型,不管是整型、浮点型、字符型,还是其他的数据类型 ,都是一样的都是一个代表内存地址的长的十六进制数。不同数据类型的指针之间 唯一的不同是,指针所指向的 变量或常量的数据类型不同

C++中使用指针

使用指针时会频繁进行以下几个操作: 定义一个指针变量、把变量地址赋值给指针、访问指针变量中可用地址的值。这些是通过使用一元运算符 * 来返回位于操作数所指定地址的变量的值。下面的实例涉及到了这些操作:

实例:

#include <iostream>

using namespace std;

int main()
{
	int  var = 20;   // 实际变量的声明
	int  *ip;        // 指针变量的声明

	ip = &var;       // 在指针变量中存储 var 的地址

	cout << "Value of var variable: ";
	cout << var << endl;

	// 输出在指针变量中存储的地址
	cout << "Address stored in ip variable: ";
	cout << ip << endl;

	// 访问指针中地址的值
	cout << "Value of *ip variable: ";
	cout << *ip << endl;

	return 0;
}
执行结果:

C++指针详解

C++ 中,有很多指针相关的概念,这些 概念都很简单,但是都很重要。下面列出了 C++ 程序员必须清楚的一些与指针相关的重要概念:

C++ Null指针

C++ 支持空指针。NULL 指针是一个定义在标准库中的值为零的常量。
在变量声明的时候,如果没有确切的地址可以赋值,为指针变量赋一个 NULL 值是一个 良好的编程习惯。赋为 NULL 值的指针被称为 空指针
NULL 指针是一个定义在标准库中的值为零的常量。请看下面的程序:
#include <iostream>
using namespace std;

int main()
{
	int  *ptr = NULL;
	cout << "ptr 的值是 " << ptr;
	return 0;
}
执行结果:
ptr 的值是 00000000
在大多数的操作系统上,程序不允许访问地址为 0 的内存,因为该内存是操作系统保留的。然而,内存地址 0 有特别重要的意义,它表明该指针不指向一个可访问的内存位置。但按照惯例,如果指针包含空值(零值),则假定它不指向任何东西。
因此,如果所有 未使用的指针都被赋予空值,同时避免使用空指针,就可以防止误用一个未初始化的指针。很多时候,未初始化的变量存有一些垃圾值,导致程序难以调试。

C++ 指针的算术运算

可以对指针进行四种算术运算:++、--、+、-。

C++ 指针和数组

指针和数组之间有着密切的关系。
实例:
#include <iostream>

using namespace std;

int main()
{
	int Array[4] = {0,1,2,3};//定义一个数组
	int *p = Array;//将数组的起始值赋值给指针p
	for (int i = 0; i < 4; i++)
	{ 
		cout << *p << endl;//输出指针上的数据
		cout << p  << endl;//输出指针指向的地址
		*p++; //对指针进行加运算,使其指向数组中的下一个值
	}
}
执行结果:
0
0019F7E8
1
0019F7EC
2
0019F7F0
3
0019F7F4

C++ 指针数组

可以定义用来存储指针的数组。

C++ 指向指针的指针

C++ 允许指向指针的指针。

C++ 传递指针给函数

通过引用或地址传递参数,使传递的参数在调用函数中被改变。
#include <iostream>
using namespace std;
void f(int *p1,int *p2)
{
int t=*p1;
*p1 = *p2;
*p2 = t;
}
int main()
{
int x=4,y=5;
cout<<"交换前"<<endl;
cout<<"x ="<<x<<','<<"y="<<y<<endl;
f(&x,&y);
cout<<"交换后"<<endl;
cout<<"x ="<<x<<','<<"y="<<y<<endl;
return 0;
}
执行结果:
交换前
x =4,y=5
交换后
x =5,y=4

C++ 从函数返回指针

C++ 允许函数返回指针到局部变量、静态变量和动态内存分配。

关于值传递,指针传递,引用传递的说明

值传递:

形参是实参的拷贝,改变形参的值并不会影响外部实参的值。从被调用函数的角度来说,值传递是单向的(实参->形参),参数的值只能传入,不能传出。当函数内部需要修改参数,并且不希望这个改变影响调用者时,采用值传递。

指针传递:

形参为指向实参地址的指针,当对形参的指向操作时,就相当于对实参本身进行的操作。

引用传递:

形参相当于是实参的"别名",对形参的操作其实就是对实参的操作,在引用传递过程中,被调函数的形式参数虽然也作为局部变量在栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址。被调函数对形参的任何操作都被处理成间接寻址,即通过栈中存放的地址访问主调函数中的实参变量。正因为如此,被调函数对形参做的任何操作都影响了主调函数中的实参变量。

实例:

#include<iostream>
using namespace std;

//值传递 4  
void change1(int n)//显示的是拷贝的地址而不是源地址  6   n++;
{
	cout << "值传递--函数操作地址" << &n << endl;        
}

 //引用传递10 
void change2(int & n)
{
	cout << "引用传递--函数操作地址" << &n << endl;
	n++;
}

 //指针传递15 
void change3(int *n)
{
	cout << "指针传递--函数操作地址 " << n << endl;
	*n = *n + 1;
}
int main()
{
	int n = 10;
	cout << "实参的地址" << &n << endl;
	change1(n);
	cout << "after change1() n=" << n << endl;
	change2(n);
	cout << "after change2() n=" << n << endl;
	change3(&n);
	cout << "after change3() n=" << n << endl;
	return true;
 }
执行结果:



  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

软件测试李同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值