C++ 十分钟看指针

指针,用来遍历数组。是数组的迭代器,用来指向数组的一个元素。指针用于指向对象,与迭代器不同的是,指针用于指向单个对象,而迭代器只能用于访问容内的元素。

string s("By:Sayln_wu");
string *sp  =&s;

上面的定义个一个指向string类型的指针sp,&是取地址操作符。

1、指针的初始化

C++语音使用*符号把一个标示符声明为指针:

int *p1,*p2;
string *ps;
double *pd;

在声明语句中,符号*可用在指定类型的对象列表的任意位置。

int i1,*i2;

还有一种风格,如下:

int* p1;   //和int *p1; 是一样的。

千万不要把int*当做是一种数据类型。

不过,语句:

int* pi1,pi2;    //pi1为指针,而pi2则是为int类型。
int *pi1,*pi2;   //pi1,pi2为指针

注意以上的类型即可。

2、指针的赋值

int i;
int zero = 0;
const int c_i = 0;

int *pi = i;		//因为i没有赋值,所以此语句错误!
    pi = zero;		//不能把变量zero赋值给指针,所以此语句错误!
    pi = c_i;		//可以把const int 型的c_i赋值给指针pi
    pi  = 0;		// 0值常量表达式可以。

赋值只能使用以下4种类型的值。

* 0值常量表达式

* 类型匹配的对象的地址

* 另一对象之后的下一个地址

* 同类型的另一个有效指针

3、空指针    void*指针

viod*指针只支持几种有效的操作:与另一个指针进行比较;向函数传递void*指针或从函数返回void*指针;给另一个void*指针赋值。

不允许使用void*指针操纵它所指的对象。

4、指针操作

#include <IOSTREAM>
#include <STRING>
using namespace std;
int main()
{
	string s("BY:sayln_wu");
	string *ps = &s;
	cout<<*ps<<endl;	//输出:BY:sayln_wu
	cout<<ps<<endl;		//输出:0018FF2C  ,即ps的地址。
	*ps = "欢迎光临Sayln_wu博客";
	cout<<endl<<" s的值为:" << s <<"\n *ps的值为:"<<*ps<<"\n ps的地址为:"<<ps<<endl;
	return 0;
}

输出截图如下:

可以看出ps的地址是不变的。即s的地址。而*ps的改变使得s也发生了改变。

5、指针和引用的比较

引用(reference)和指针都可以间接的访问另一个值,但是他们有着重要区别。

第一个区别:引用总是指向某个对象,就是定义引用时没有初始化是错误的。而指针可以赋空值。

第二个区别:赋值行为的差异。下面写两个程序段来看一下赋值差异。

	cout<<"By:sayln_wu  "<<endl<<endl;
	cout<<"指针赋值:"<<endl;
	int i1=25;int i2=50;
	int *pi=&i1,*pi2=&i2;
	cout<<"i1为"<<i1<<"  i2为"<<i2<<endl;
	cout<<"*pi为"<<*pi<<"  *pi2为"<<*pi2<<endl;
	pi = pi2;
	cout<<"after:"<<endl;
	cout<<"i1为"<<i1<<"  i2为"<<i2<<endl;
	cout<<"*pi为"<<*pi<<"  *pi2为"<<*pi2<<endl<<endl;
	
	cout<<"引用赋值:"<<endl;
	int a=25;int b=50;
	int &ra=a,&rb=b;
	cout<<"a为"<<a<<"  b为"<<b<<endl;
	cout<<"ra为"<<ra<<"  rb为"<<rb<<endl;
	ra = rb;
	cout<<"after:"<<endl;
	cout<<"a为"<<a<<"  b为"<<b<<endl;
	cout<<"ra为"<<ra<<"  rb为"<<rb<<endl;

截图如下:

可以看到指针是修改了指向的地址,i1不变。而引用是ra即a的值,故a变为rb的值,也就是b的值。

6、指针的算术操作

通常,在指针上加上(或减去)一个整型数值n等效于获得一个新指针,该新指针指向指针原来指向的元素之后(或之前)的第n个元素。

 

int ia[] = {0,1,2,3,4}; 	
int *ip = ia; 			//ip指向ia[0]
int *ip2 = ip+4;		//ip2指向ia[4]
int *ip3 = ip+10;		//错误,溢出。

当然指针还支持相减,

ptrdiff_t n  = ip2 -ip;                          //结果为4
两种指针减法操作的结果是标准库类型ptrdiff_t的数据。需要加入<cstddef>头文件。ptrdiff_t是一个signed整形。

 

7、综合

请分析代码并参考截图:

// 
// int i;
// int zero = 0;
// const int c_i = 0;
// 
// int *pi = i;		//因为i没有赋值,所以此语句错误!
//     pi = zero;		//不能把变量zero赋值给指针,所以此语句错误!
// 	pi = c_i;		//可以把const int 型的c_i赋值给指针pi
// 	pi  = 0;		// 0值常量表达式可以。
#include <IOSTREAM>
#include <STRING>


using namespace std;
int main()
{
	string s("BY:sayln_wu");
	string *ps = &s;
	cout<<*ps<<endl;	//输出:BY:sayln_wu
	cout<<ps<<endl;		//输出:0018FF2C  ,即ps的地址。
	*ps = "欢迎光临Sayln_wu博客";
	cout<<endl<<" s的值为:" << s <<"\n *ps的值为:"<<*ps<<"\n ps的地址为:"<<ps<<endl<<endl;
	//上面一条输出为:
// 		s的值为:欢迎光临Sayln_wu博客
// 		*ps的值为:欢迎光临Sayln_wu博客
// 		ps的地址为:0018FF2C
//  可以看出ps的地址是不变的。即s的地址。而*ps的改变使得s也发生了改变。
	cout<<"By:sayln_wu  "<<endl<<endl;
	cout<<"指针赋值:"<<endl;
	int i1=25;int i2=50;
	int *pi=&i1,*pi2=&i2;
	cout<<"i1为"<<i1<<"  i2为"<<i2<<endl;
	cout<<"*pi为"<<*pi<<"  *pi2为"<<*pi2<<endl;
	pi = pi2;
	cout<<"after:"<<endl;
	cout<<"i1为"<<i1<<"  i2为"<<i2<<endl;
	cout<<"*pi为"<<*pi<<"  *pi2为"<<*pi2<<endl<<endl;
	
	cout<<"引用赋值:"<<endl;
	int a=25;int b=50;
	int &ra=a,&rb=b;
	cout<<"a为"<<a<<"  b为"<<b<<endl;
	cout<<"ra为"<<ra<<"  rb为"<<rb<<endl;
	ra = rb;
	cout<<"after:"<<endl;
	cout<<"a为"<<a<<"  b为"<<b<<endl;
	cout<<"ra为"<<ra<<"  rb为"<<rb<<endl;

	//指针输出数组元素
	cout<<endl<<"指针输出数组元素"<<endl;
	const size_t NUM = 5;
	int arr_num[NUM] = {0,1,2,3,4};
	for (int *pbegin=arr_num,*pend=arr_num+NUM;pbegin!=pend;++pbegin)
	{
		cout<<*pbegin<<" ";
	}
	cout<<endl<<endl;
	cout<<"指向const对象的指针"<<endl;
	const double pq=3.14222;
/*	double *ptr = π   //error*/
	const double *cptr = &pq;
	cout<<pq<<endl;
// 	不能使用void*指针保存const对象的地址,而必须使用const void*类型的指针保存const对象的地址;
// 	允许把非const对象的地址赋给指向const对象的指针。
	cout<<endl<<"const指针"<<endl;
	cout<<"const指针--本身的值不能修改"<<endl;
	int errNum = 10;
	int *const curErr =&errNum;
	cout<<"errNum:"<<errNum<<endl<<endl;
	if (*curErr)
	{
		*curErr = 5;
	}
	cout<<"errNum:"<<errNum<<endl<<endl;
	int errNum2 = 20;
/*	*curErr = &errNum2;   //error,const指针--本身的值不能修改 */
	
	cout<<"指向const对象的const指针"<<endl;
	const double pi3 = 3.1415;
	const double *const p_pi3 = &pi3;
	cout<<"既不能修改p_pi3所指向对象的值,也不能修改p_pi3所指向的地址。"<<endl<<endl;

	cout<<"指针和typedef"<<endl;
	typedef string *pstring;
	const pstring cstr=NULL;
//	上面等价于:
//	string *const cstr;
//	而不等价:
//	const string *cstr;
	return 0;
}


 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 内容概要 《计算机试卷1》是一份综合性的计算机基础和应用测试卷,涵盖了计算机硬件、软件、操作系统、网络、多媒体技术等多个领域的知识点。试卷包括单选题和操作应用两大类,单选题部分测试学生对计算机基础知识的掌握,操作应用部分则评估学生对计算机应用软件的实际操作能力。 ### 适用人群 本试卷适用于: - 计算机专业或信息技术相关专业的学生,用于课程学习或考试复习。 - 准备计算机等级考试或职业资格认证的人士,作为实战演练材料。 - 对计算机操作有兴趣的自学者,用于提升个人计算机应用技能。 - 计算机基础教育工作者,作为教学资源或出题参考。 ### 使用场景及目标 1. **学习评估**:作为学校或教育机构对学生计算机基础知识和应用技能的评估工具。 2. **自学测试**:供个人自学者检验自己对计算机知识的掌握程度和操作熟练度。 3. **职业发展**:帮助职场人士通过实际操作练习,提升计算机应用能力,增强工作竞争力。 4. **教学资源**:教师可以用于课堂教学,作为教学内容的补充或学生的课后练习。 5. **竞赛准备**:适合准备计算机相关竞赛的学生,作为强化训练和技能检测的材料。 试卷的目标是通过系统性的题目设计,帮助学生全面复习和巩固计算机基础知识,同时通过实际操作题目,提高学生解决实际问题的能力。通过本试卷的学习与练习,学生将能够更加深入地理解计算机的工作原理,掌握常用软件的使用方法,为未来的学术或职业生涯打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值