C++基础02-C++对c的拓展

变量名实质上是一段连续存储空间的别名,是一个标号(门牌号)

通过变量来申请并命名内存空间.

通过变量的名字可以使用存储空间.

变量名,本身是一段内存的引用,即别名(alias). 引用可以看作一个已定义变量的别名。

引用的语法:Type& name = var;

int a=10;  //c编译器分配4个字节内存, a内存空间的别名

int &b=a;  //b就是a的引用

3.1.3 规则

1 引用没有定义,是一种关系型声明。声明它和原有某一变量(实体)的关系。故而类型与原类型保持一致,且不分配内存。与被引用的变量有相同的地址。

2 声明的时候必须初始化,一经声明,不可变更

3 可对引用,再次引用。多次引用的结果,是某一变量具有多个别名

4 &符号前有数据类型时,是引用。其它皆为取地址

 

const int a;

int const b;

//第⼀个第⼆个意思⼀样 代表⼀个常整形数

const int *c;

//第三个 c是⼀个指向常整形数的指针(所指向的内存数据不能被修改,但是本⾝可以修改)

int * const d;

//第四个 d 常指针(指针变量不能被修改,但是它所指向内存空间可以被修改)

const int * const e ;

//第五个 e⼀个指向常整形的常指针(指针和它所指向的内存空间,均不能被修改)

const 常量是由编译器处理的,提供类型检查和作用域检查

 #define 宏定义由预处理器处理,单纯的文本替换  

引用作为函数参数

       普通引用在声明时必须用其它的变量进行初始化,引用作为函数参数声 明时不进行初始化

引用作为函数的返回值(引用当左值)

I. 当函数返回值为引用时,

         若返回栈变量: 不能成为其它引用的初始值(不能作为左值使用)

         若返回静态变量或全局变量 可以成为其他引用的初始值(可作为右值使用,也可作为左值使用)

        如果返回值为引用可以当左值

        如果返回值为普通变量不可以当左值。

普通引用有自己的存储空间吗?

        1)引用在C++中的内部实现是一个常指针

               Type& name <===> Type* const name

        2)C++编译器在编译过程中使用常指针作为引用的内部实现,因此引用所占 用的空间大小与指针相同

        3)从使用的角度,引用会让人误会其只是一个别名,没有自己的存储空间。

这是C++为了实用性而做出的细节隐藏。

从右向左看,&或*哪个离变量近, 哪个便起主要作用。int*&a=p_a; 把int*看成类型

int  b=12;

int  &a=b;

int* p_a=&b;

int* &a=p_a;

const引用

const 引用有较多使用。它可以防止对象的值被随意修改。因而具有一 些特性。

(1)const 对象的引用必须是 const 的,将普通引用绑定到 const 对象是不 合法的。这个原因比较简单。既然对象是 const 的,表示不能被修改,引用当然 也不 能修改,必须使用 const 引用。实际上,

           const int a=1;

           int &b=a;

这种写法是不合法 的,编译不过。

(2)const 引用可使用相关类型的对象(常量,非同类型的变量或表达式)初 始化。这个是 const 引用与普通引用最大的区别。

          const int &a=2; 是合法的。

          double x=3.14;

          const int &b=a;

也是合法的。

//int &m = 41; //error , 普通引⽤ 引⽤⼀个字⾯量 请问字⾯量有没有内存地址

const int &m = 43; //c++编译器 会 分配内存空间

// int temp = 43

// const int &m = temp;

#include	<iostream>
using namespace	std;	
int	main(void)	
{	
//1>	⽤变量 初始化 常引⽤
int	x1	=	30;	
const int &y1=x1;	//⽤x1变量去初始化 常引⽤
//2>⽤字⾯量 初始化 常量引⽤
const int a	= 40;		//c++编译器把a放在符号表中
//int &m = 41;	//error	,	普通引⽤ 引⽤⼀个字⾯量 请问字⾯量有没有内存地址
26
const int &m = 43;		//c++编译器 会 分配内存空间
//	int	temp = 43
//	const int &m = temp;
return 0;	
}

 

const引用的原理

const 引用的目的是,禁止通过修改引用值来改变被引用的对象

结论:

1)const int & e 相当于 const int * const e

2)普通引用 相当于 int *const e

3)当使用常量(字面量)对const引用进行初始化时,C++编译器会为常量值

分配空间,并将引用名作为这段空间的别名

4)使用字面量对const引用初始化后,将生成一个只读变量

 

 

内存四区:

1引用的基本语法:

#if 1
#include<iostream>
using namespace std;
//1 引用没有定义, 是一种关系型声明。声明它和原有某一变量(实体)的关
//系。故 而类型与原类型保持一致, 且不分配内存。与被引用的变量有相同的地
//址。
//2 声明的时候必须初始化, 一经声明, 不可变更。
//3 可对引用, 再次引用。多次引用的结果, 是某一变量具有多个别名。
//4 & 符号前有数据类型时, 是引用。其它皆为取地址。
void test01() {int a = 10;int &b = a;cout << a << endl;  //10b = 20;cout << a << endl;   //20cout << b << endl;   //20a = 30;{int *p = &a; *p = 12;cout << *p << endl; //12cout << a << endl;  //12}cout << a << endl;   //12cout << b << endl;   //12}
void test02() {int a = 10;int *p = &a;*p = 12;cout << *p << endl; //12cout << a << endl;  //12
}void test03() {const int a = 10;int *p = (int *)&a;*p = 12;cout << *p << endl; //12cout << a << endl;  //10
}void test04() {int a = 10;int &b = a;int *p = &a;*p = 30;p = &b;*p = 20;int &re = a;re = 50;cout << a << endl;  //50cout << b << endl;  //50cout << re << endl;  //50int ff = 10;re = ff;cout << a << endl;  //10cout << b << endl;  //10cout << re << endl;  //10}void test05() {int	a=1, b=0;int	&r = a;r = b;	//错误,不可更改原有的引⽤关系//float &rr = b;	//错误,引⽤类型不匹配	cout<<&a<<&r<<endl;	//变量与引⽤具有相>同的地址。int	&ra = r;	//可对引⽤更次引⽤,表⽰	a	变量有两个别名,分别是	r	和	ra
}
void test06() {int a = 10;int &b = a;int c = 20;b = c;b = 50;cout << a << endl;  //50cout << b << endl;  //50cout << c << endl;  //20  b并不是c的引用}void test07() {int a = 10;int &b = a;b = 100;cout << a << endl;  //100cout << b << endl;  //100int c = 20;b = c;b = 200;cout << a << endl;  //200cout << b << endl;  //200cout << c << endl;  //20 c的值未更改 b并不是c的别名
}
int& test08() {int a;return a;   //返回的是a的别名,函数调用完释放a,那么a的引用将不知道指向何处,所以test08()值会乱码
}
int& test09() {int a=0;return a;   //返回的是a的别名,函数调用完释放a,那么a的引用将不知道指向何处,所以test08()值会乱码const int &a1 = 100;
}
int main() {//test01();//test02();//test03();//test04();//test05();//test06();//test07();int a = 100;test08() = a;//test08() = a  //修改局部变量的值 错误cout << test08() << endl; //-858993460cout << test09() << endl; //0   //不懂int a1= 100;test09() = a1;cout << test09() << endl; //0cout << a1 << endl;    //100return 0;
}
#endif

 2引用当函数参数

#if 1
#include<iostream>
using namespace std;
void change_value1(int c) { //int c=a; c是局部变量需要复制 重新开辟栈空间c = 100;
}
void change_value2(int *c) {//int *c=a; 指针c存放a的地址。改变*c就是改变a的值//不需要额外复制*c = 200;
}
void change_value3(int &c) { //int &c=a; 形参c是实参a的引用,不需要额外复制c = 300;
}void test01() {int a = 0;change_value1(a);cout << "change_value1:" << a << endl;  //0a = 0;change_value2(&a);cout << "change_value2:" << a << endl;  //200a = 0;change_value3(a);cout << "change_value3:" << a << endl;  //300
}struct student {int id;char name[64];
};
void PrintStudent1(student s) {   //不建议使用 值拷贝cout << s.id << "  " << s.name << endl;
}
void PrintStudent2(student *s) {cout << s->id << "  " << s->name << endl;
}
void PrintStudent3(student &s) {cout << s.id << "  " << s.name << endl;
}
void test02() {student s1 = { 10,"sdsd" };PrintStudent1(s1);  //不建议使用PrintStudent2(&s1);PrintStudent3(s1); 
}
int main() {//test01();test02();return 0;
}
#endif

3引用的本质

#if 1
#include<iostream>
using namespace std;//当研究引用时,可以将引用当做一个常指针研究
//当使用引用编程时,就把引用理解为变量的别名就OK了
struct typeA {int &a;
};
struct typeB {int *a;
};
//引用的所占用的大小 跟指针相等
void test01() {cout << "sizeof(struct typeA):" << sizeof(typeA) << endl;  //4 32位系统cout << "sizeof(struct typeB):" << sizeof(typeB) << endl;  //4 32位系统
}
struct student {int id;char name[64];
};
//引用声明时必须初始化 常量声明时也必须初始化 引用可能是常量
//引用可能是常指针 int * const p;
void modify1(int *const a) {  //int *const a=main::&a; 可以改变a的值但不能改变a指向*a = 300;//a++;   错误
}
void modify2(int &a) {  //int &a=main::a; //当我们将引用作为函数参数传递的时候,编译器会替我们将实参,取地址给引用a = 200;            //对一个引用操作 赋值时,编译器替我们隐藏*操作
}
void modifyStudent(int *const a) {  //int *const a 可以改变a的值但不能改变a指向*a = 300;//a++;   错误
}void test02() {int a = 10;int &re = a;int *const p = &a;
}
int main(){test01();return 0;
}
#endif

4常量指针

#if 1
#include<iostream>
using namespace std;
int main() {int const a = 0;  //在常量区int *const p1 = NULL; //在常量区//p1++; ERROR*p1 = 30;int const *p2 = NULL;  //在常量区p2++;//*p2 = 40; ERRORreturn 0;
}
#endif

5引用作为函数返回值

#if 1
#include<iostream>
using namespace std;int getA1() {int tempValue = 10;return tempValue;
}
void getA2(int *a) {*a = 20;
}int &getA3() {int a = 10;return a;  //int &temp=a;将temp传到外部 返回的是别名
}
int &getA4() {static int a = 10;return a;
}
char *getmen(int num) {char *p = NULL;p = (char *)malloc(num);return p;  //值拷贝
}int getmen2(char **pp, int num) {char *p = NULL;p = (char *)malloc(num);*pp = p;return 0;
}void test01() {int a = 0;a = getA1();  //将返回值10拷贝给了a。要是有多个结构体会很浪费空间char *pp = NULL;pp = getmen(10);int main_a = 0;main_a = getA3();  //main_a=temp; 值拷贝cout << main_a << endl;  //10cout << main_a << endl;  //10//引用作为返回值,不要返回局部变量的引用。否则可能会出错 getA3函数被回收(没有权限访问,之前的变量覆盖)//引用如果当函数返回值的话,函数可以当左值int &main_a_re = getA3();cout << main_a_re << endl; //10cout << main_a_re << endl;  //-858993460int &main_a_re1 = getA4(); cout << main_a_re1 << endl;  //10cout << main_a_re1 << endl;   //10cout << main_a_re1 << endl;   //10getA4() = 1000;
}int main() {test01();return 0;
}
#endif

6引用指针

#if 1
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;struct teacher {int id;char name[64];
};
int get_mem(struct teacher** tpp) {teacher *tp = NULL;tp = (teacher*)malloc(sizeof(teacher));if (tp == NULL) {return 0;}tp->id = 100;strcpy(tp->name, "li4");*tpp = tp;return 0;
}
void Free_teacher(struct teacher **tpp) {if (tpp == NULL) {return;}struct teacher *tp = *tpp;if (tp != NULL) {free(tp);*tpp = NULL;}
}
void test01() {struct teacher *tp = NULL;get_mem(&tp);cout << tp->id << " " << tp->name << endl;Free_teacher(&tp);}
int get_mem2(struct teacher * &tp) { //struct teacher *为整体相当于inttp = (struct teacher *)malloc(sizeof(struct teacher));if (tp == NULL) {return -1;}tp->id = 1000;strcpy(tp->name, "wangwu");return 0;}
void Free_teacher2(struct teacher * &tp) {if (tp != NULL) {free(tp);tp = NULL;}}
void test02() {struct teacher *tp = NULL;get_mem2(tp);cout << tp->id << " " << tp->name << endl;Free_teacher2(tp);
}
int main() {test01();test02();return 0;
}
#endif

7const引用

#if 1
#include<iostream>
using namespace std;
void test01() {//如果对一个常量进行引用,则必须是一个const引用//相反 如果一个普通变量,用一个const引用是可以的const int a = 10; //安全性较高//int &b = a;  //错误 将 "int &" 类型的引用绑定到 "const int" 类型的初始值设定项时,//限定符被丢弃	03C++对C的拓展const int &re = a;int b = 20;  //安全性较低const int &re2 = b;// ret2 = 200; 错误b = 30;cout << b << endl;    //30cout << re2 << endl;  //30 const引用的目的是,禁止通过修改引用值来改变被引用的对象。//但可以通过改变被引用的对象改变引用值}void test02() {//int &ref = 10; //错误 引用了不合法的内存 不可以const int &ref = 10; //加入const后,编译器处理方式为:int tmp=10;const int &ref=tmp;对临时变量的引用//ref =10;  //错误int *p = (int*)&ref;*p = 1000;cout << ref << endl;  //1000
}//引用使用场景:通常用来修饰形参
void showValue(int &val) {val += 1000;  //如果只是想显示内容 而不进行修改就使用const进行修饰cout << "value:" << val << endl;
}void showValue(const int &val) {//val += 1000;  //编译错误cout << "value:" << val << endl;
}void test03() {int a = 10;showValue(a);  //1010
}
int main() {test01();cout << "--------" << endl;test02();cout << "------------" << endl;test03();return 0;
}
#endif

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/567903.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php小程序onload,微信小程序 loading 组件实例详解

这篇文章主要介绍了微信小程序 loading 组件实例详解的相关资料,需要的朋友可以参考下loading通常使用在请求网络数据时的一种方式&#xff0c;通过hidden属性设置显示与否主要属性&#xff1a;wxml显示loading正在加载jsPage({data:{// text:"这是一个页面"hiddenLo…

C++基础04-类基础

一、类和对象 面向对象三大特点&#xff1a;封装、继承、多态。 struct 中所有行为和属性都是 public 的(默认)。C中的 class 可以指定行为和属性的访问方式。 封装,可以达到,对内开放数据,对外屏蔽数据,对外提供接口。达到了信息隐蔽的功能。 class 封装的本质,在于将数…

C++基础05-类构造函数与析构函数

总结&#xff1a; 1、类对象的作用域为两个{}之间。在遇到}后开始执行析构函数 2、当没有任何显式的构造函数&#xff08;无参&#xff0c;有参&#xff0c;拷贝构造&#xff09;时&#xff0c;默认构造函数才会发挥作用 一旦提供显式的构造函数&#xff0c;默认构造函数不复…

PHP网站配置项,Thinkphp5通用网站后台配置项的动态添加及更新

一、引入无论平时我们自己制作&#xff0c;还是浏览别人的网站&#xff0c;它都具有其相应的一些共用的、通用的属性&#xff0c;比如&#xff1a;网站的名字&#xff0c;关键字、备案号、分页数量、是否开启缓存等信息。一些网站可能将配置项写死在后台&#xff0c;无法动态更…

oracle 查询cpu 100%,Oracle 11g中查询CPU占有率高的SQL

oracle版本&#xff1a;oracle11g背景&#xff1a;今天在Linux中的oracle服务上&#xff0c;运用top命令发现许多进程的CPU占有率是100%。操作步骤&#xff1a;以进程PID:7851为例执行以下语句&#xff1a;方法一&#xff1a;(1)通过PID&#xff0c;查得相对应的系统进程对应的…

C++基础08-this指针-const修饰成员函数-函数返回引用/值

一、this指针 1、C类对象中的成员变量和成员函数是分开存储的。C语言中的内存四区模型仍然有效&#xff01; 2、C中类的普通成员函数都隐式包含一个指向当前对象的this指针。 3、静态成员函数、成员变量属于类 4、静态成员函数与普通成员函数的区别 静态成员函数不包含指…

C++基础09-货物售卖和MyArray实现

1、货物出货与进货 #if 0 #include<iostream> using namespace std; /* 某商店经销一种货物。货物购进和卖出时以箱为单位。各箱 的重量不一样&#xff0c;因此商店需要记录目前库存的总重量&#xff0c;现在用 C模拟商店货物购进和卖出的情况 */ class Goods { public:…

C++基础11-类和对象之操作符重载1

总结&#xff1a; 1、运算符重载的本质是函数重载 2、运算符重载可分为成员函数重载和全局函数重载(差一个参数) 3、运算符重载函数的参数至少有一个是类对象&#xff08;或类对象的引用&#xff09; 4、不可以被重载的操作符有&#xff1a;成员选择符(.) 成员对象选择符(.*) …

linux照片备份软件,Linux、Unix上5个惊艳开源备份软件

Linux和类Unix系统上5个惊艳的开源备份软件&#xff1a;Bacula、Amanda、Backupninja、Backuppc和UrBackup&#xff0c;这些都是既可以使用在Linux上也可以使用在Unix上面&#xff0c;他们的优点就是性能稳定&#xff0c;使用灵活。一个好的备份计划是非常必要的&#xff0c;这…

linux 添加重定向域名,Linux系统中Nginx的安装并进行域名认证和重定向

Linux系统中Nginx的安装并进行域名认证和重定向本文主要介绍Linux系统中Nginx的安装并进行域名认证和重定向&#xff0c;希望通过本知识点的讲解对大家今后的学习和工作有所帮助&#xff0c;下面进行具体介绍&#xff1a;12.6 Nginx安装cd /usr/local/srcwget http://nginx.org…

linux有读EC RAM的工具吗,Step to UEFI (179)Shell下 EC Ram 读取工具

最近工作需要在 UEFI Shell 下Check EC Ram 的设定&#xff0c;发现手上只有 Windows 下的读取工具(RW Everything)。于是研究了一下如何在Shell 读取 EC Ram。根据【参考1】读取的流程如下&#xff1a;Port 66 CommandsThere are also some EC commands that use ports 0x66 …

C++基础13-类和对象之继承1

在 C中可重用性(software reusability)是通过继承(inheritance)这一机制来实现的。 如果没有掌握继承性,就没有掌握类与对象的精华。 总结&#xff1a; 1、只要是父类中的private成员&#xff0c;不管是什么继承方式&#xff0c;儿子都访问不了&#xff0c;但它是存在在儿子之…

C++基础13-类和对象之继承2

总结&#xff1a; 1、子类对象可以当做父类对象使用 2、子类对象可以直接赋值给父类对象 3、子类对象能够直接初始化父类对象 4、父类指针可以直接指向子类对象 5、凡是继承过来的属性和函数都可以在子类中用this-> 进行访问 6、默认构造函数并不会初始化数据成员 7、如果…

C++基础14-类和对象之多继承与虚继承

多继承&#xff1a;一个类有多个直接基类的继承关系称为多继承 总结&#xff1a; 1、一般将具有菱形样式继承方式的某些类声明为虚继承 3、虚继承的主要目的是为了防止二义性 2、虚继承就是在继承方式前加virtual 如果一个派生类从多个基类派生&#xff0c;而这些基类又有一…

linux系统安装ntp,CentOS下NTP安装配置

安装yum install ntp配置文件 /etc/ntp.confrestrict default kod nomodifynotrap nopeer noqueryrestrict -6 default kod nomodify notrap nopeer noqueryrestrict 127.0.0.1restrict -6 ::1# 用restrict控管权限# nomodify - 用户端不能更改ntp服务器的时间参数# noquery - …

C++基础15-类和对象之多态

总结&#xff1a; 1、在父类中申明虚函数时&#xff0c;一般情况下在子类中也申明&#xff08;便于读代码&#xff09; 一、赋值兼容 赋值兼容规则是指在需要基类对象的任何地方都可以使用公有派生类的对象来替代。 赋值兼容是一种默认行为,不需要任何的显示的转化步骤。 …

傲云浏览器linux,Centos7安装部署zabbix监控软件

目录部署监控服务器部署监控服务器Zabbix ServerWeb页面验证设置部署监控服务器一、安装LNMP环境Zabbix监控管理控制台需要通过Web页面展示出来&#xff0c;并且还需要使用MySQL来存储数据&#xff0c;因此需要先为Zabbix准备基础LNMP环境。1. wget下载官网Nginxwget http://ng…

c语言环境变量的作用,C语言获取系统环境变量

C语言获取系统环境变量可以通过如下代码实现.#include #include char *platform(){//获取系统变量信息char *ret;extern char **environ;char **env environ;//打印系统变量信息/*while(*env){//puts(*env);env;}*/ret getenv("OS"); //for windows_ntif(NULL ! re…

mysql索引创建及使用注意事项

总结&#xff1a; 1、在使用索引时&#xff0c;一般情况下不建议使用like操作。如果使用&#xff0c;则%放在后面。否则不会使用索引。like ‘%abd%’不会使用索引,而like ‘aaa%’可以使用索引.&#xff08;最左缀原则&#xff09; 2、单列索引的使用&#xff1a; 《1》 只…

mulitpartfile怎么接收不到值_和平精英信号接收区和信号值是什么?信号值怎么恢复...

[闽南网]和平精英公测开启&#xff0c;和平精英与刺激战场有什么不同呢&#xff1f;今天小编就为大家带来了信号值详解&#xff01;各位玩家千万不要错过呀&#xff01;信号值详解信号接收区和信号值是什么&#xff0c;对选手有什么影响&#xff1f;在游戏战斗界面中&#xff0…