C++基础(一)

news2024/11/15 1:49:45

目录

1.不同版本的hello word!

2.namespace和::域作用限定符以及using

2.1 namespace

 2.2::

2.3using用于展开域

3.C++输入和输出

4.缺省参数

 5.重载

6.引用

6.1引用介绍

6.2 引用的特性

注意:

 6.4 const 的引用

 6.5指针和引用的关系

 7.inline

 8.nullptr



1.不同版本的hello word!

还记得第一次写C语言的hello word吗

//text.c
#include<stdio.h>

int main()
{
	printf("hello word!\n");
	return 0;
}

 这是C++版的

//text.cpp
#include<iostream>
using namespace std;
int main()
{
	cout << "hello word! \n" << endl;
	return 0;
}

C++ 诞生于c之后,c++兼容了c,我们重点了解c++中不同于c的部分

2.namespace和::域作用限定符以及using

 定义命名空间,需要用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}中即为命名空间的成员。命名空间可以定义变量/函数/类型等。

2.1 namespace

namespace bit

{

//定义变量
int rand=10;

//定义函数

int Add ( int a , int b )

{

return a +b ;
}

//定义类型

 struct Node

{

struct Node* next;

int val;
};

}

 2.2::

调用域下面的变量/函数等

bit  ::rand

  • namespace本质是定义了一个域,这个域跟全局域各自独立,不同的域可以定义同名变量,所以下面的rand不存在冲突了
namespace text1 {
	int rand = 0;
}
namespace text2 {
	int rand = 10;
}

 C++中域有函数局部域,全局域,类域;域影响的是编译时语法查找一个变量/函数/类型出处(声明或定义)的逻辑,所以有了域隔离,名字冲突就解决了。局部域和全局域除了会影响编译查找逻辑,还会影响变量的声明周期,命名空间域和类域不影响变量声明周期。

//text.cpp
#include<iostream>
using namespace std;

namespace bit 
{
	int rand;
	int a = 2;
	int Fun(float c, float d)
	{
		return c * d;
	}
}
int Fun(int c ,int d )
{
	return c + d;
}
int a = 1;
int main()
{
	int a = 0;

	printf("%d\n", a);
	// a没有被域限定 代码从上往下走,main 函数下被重新赋值 a=0,所以输出0
	printf("%d\n", ::a);
	//a被::域限定符限定,但左边没有元素,默认为全局域,a=1所以输出1
	printf("%d\n", bit::a);
	//a被::域限定符限定,左边有域名,限定在自定义的域,在bit域中a=2,所以输出2
printf("%d\n",Fun(1,2));
// a没有被域限定 代码从上往下走,找到自定义函数Fun调用Fun实现相加,输出3
printf("%d\n", ::Fun(1, 2));
//a虽然有域限定符,但是并没有限定范围,还是全局域找到Fun实现相加,输出3
	printf("%d\n", bit::Fun(1,2));
	//a被::域限定符限定,左边有域名,限定在自定义的域,在bit域中找到Fun实现相乘,输出2

}

 验证答案

namespace只能定义在全局,当然他还可以嵌套定义

//text.cpp
#include<iostream>
using namespace std;

namespace bit 
{
	int rand;
	namespace aa
	{
		int rand=1;
	}
	namespace bb 
	{
		int rand=0;
	}
}

int a = 1;
int main()
{
	
	printf("%d\n", bit::aa::rand);
	printf("%d\n", bit::bb::rand);
	return 0;
}

项目工程中多个文件中定义的同名namespace会认为是一个namespace,不会冲突

C++标准库都放在一个叫std(stdndard)的命名空间中

2.3using用于展开域

using namespace std;
//展开std头文件
using namespace bit::rand;
//展开bit中的rand

 一般日常练习中我们可以using namespace std,世纪项目开发中不建议using namespace

3.C++输入和输出

  1.  <iostream>是Input Output Stream 的缩写,是标准的输入,输出流库,定义了标准的输入,输出对象
  2. std::cin是ostream类的对象,他主要面向窄字符(narrow character (of type char))的标准输入流
  3. std::cout是ostream类的对象,它主要面向窄字符的标准输出流
  4. std::endl 是一个函数,流插入输出流,相当于插入一个换行字符加刷新缓冲区
  5. <<是流插入运算符,>>是流提取运算符(c语言中的左移右移操作符)
  6. 使用C++输入输出更方便,不要像printf/scanf输入输出那样,需要手动指定格式,C++的输入输出可以自动识别变量类型(本质是痛过重载实现的),其实最重要的是C++的流能更好的支持只定义类型对象的输入和输出。
//text.cpp
#include<iostream>
using namespace std;

int main()
{
	int i = 123;
	int j = 234;
	int x;
	int y;
	cin >> x >> y;
	//控制台手动输入x,y
	cout << i << j << endl;
	//输出i和j并且最后换行
	return 0;
}

但是一对<<  <<内只能有一个变量,否则编译器报错

在c++中我们没有包含<stdio.h>,也可以使用printf和scanf,在包含<iostream>间接包含了。vs编译器是这样的,但其他编译器会报错

4.缺省参数

  • 缺省参数是声明或定义函数时为函数指定一个确实值,在调用该函数时,如果没有指定实参则采用改形式参数的缺省值,否则使用指定的实参,缺省参数分为全缺省和半缺省参数                                                                                                                                                                   全缺省就是全部形参给缺省值,半缺省就是部分形参给缺省值。C++规定半缺省必须从右往左依次连续缺省,不能间隔条约给缺省值
  • 函数声明和定义分离时,缺省参数不能在函数声明和定义中同时出现,规定必须函数声明给缺省值
//text.cpp
#include<iostream>
using namespace std;
//全缺省
void Fun1(int a=10,int b=20,int c=30)
{
	cout << "全缺省" << endl;
	cout << "a=" << a << endl;
	cout << "b=" << b << endl;
	cout << "c=" << c << endl;

}
//半缺省
void Fun2( int a ,int b=10 ,int c=20)
{
	cout << "半缺省" << endl;
	cout << "a=" << a << endl;
	cout << "b=" << b << endl;
	cout << "c=" << c << endl;
}

void Fun3(int a, int b, int c)
{
	cout << "普通" << endl;
	cout << "a=" << a << endl;
	cout << "b=" << b << endl;
	cout << "c=" << c << endl;
}
int main()
{
	Fun1();//没有传参时,使用参数的默认值
	Fun2(10);//传参时,使用的指定值
	Fun3(10,20,30);//传入指定值

	

	return 0;
}

 5.重载

C++支持在同一作用域中出现同名函数,但是要求这些同名函数的形参不同,可以是参数个数不同或则类型不同。这样C++函数调用就表现出了多态行为,使用更加灵活。C语言是不支持同一作用域中出现同名函数的。

//text.cpp
#include<iostream>
using namespace std;
//1.参数类型不同
int Add(int a, int b)
{
	cout << "int Add(int a, int b)" << endl;
	return a + b;
}
double Add(double a, double b)
{
	cout << "double Add(double a, double b)" << endl;
	return a + b;
}
//2.参数个数不同
int Add(int a)
{
	cout << "int Add(int a)" << endl;
	return a;
}
double Add(double a, double b)
{
	cout << "double Add(double a, double b)" << endl;
	return a + b;
}
//3.参数类型顺序不同
void  fun(int a, char b)
{
	cout << "void fun(int a, char b)" << endl;
	
}
void  fun(char b, int  a)
{
	cout << "void fun(char a, int b)" << endl;

}
int main()
{
	cout << "参数类型不同" << endl;
	cout << Add(3,5)<< endl;
	cout << Add(3.1,5.0) << endl;
	cout << "参数个数不同" << endl;
	cout << Add(3) << endl;
	cout << Add(3.1, 5.0) << endl;
	cout << "参数类型顺序不同" << endl;
	fun(3, 'x');
	fun('x', 5);

	return 0;
}

 注意:返回值不能作为判断是否重载的依据因为容易产生歧义,如下面的代码f()调用

//text.cpp
#include<iostream>
using namespace std;
void f()
{
cout<<"f()<<endl;
}
void f(int a=10)
{
cout<<"f(int a=20)"<<endl;
}


int main()
{

f();
return 0;
}

 

6.引用

6.1引用介绍

 引用不是新定义一个变量,而是给已存在变量去了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间

类型&引用别名=引用对象;

//text.cpp
#include<iostream>
using namespace std;


int main()
{
	int a = 0;
	//引用:b和c是a的别名
	cout << "a=" << a <<" " << &a << endl;
	int &b = a;
	cout << "b=" << b <<" " << &b << endl;
	int& c = a;
	cout << "c=" << c << " " << &c << endl;
	//也可以给b取别名,d还是相当于a的别名
	int& d = a;
	cout << "d=" << d<< " " << &d << endl;

	return 0;
}

 值一样,地址也一样

 只是取得“外号”罢了

 传统的交换函数

void Swap(int* x,int* y)
{
int tem=*x;
*y=*x;
*x=tem;
}

现在只要传引用就能解决

void Swap(int& rx,int&ry)
{
int tem=rx;
rx=ry;
ry=tem;

}

6.2 引用的特性

  1. 引用在定义时必须初始化
  2. 一个变量可以有多个引用
  3. 引用一旦引用一个实体,再不能引用其他实体
  4. 可以给引用取引用

//text.cpp
#include<iostream>
using namespace std;


int main()
{
	int a = 0;

	int ra&;
	//编译器报错,未给初始化引用


	//一个变量可以有多个别名
	int &b = a;
	//引用:b和c是a的别名

	int& c = a;
	//也可以给b取别名,d还是相当于a的别名

	int& d = a;
	//d是a的别名

//给别名取别名
	int& f = b;
	
	return 0;
}

 

注意:

  1. 引用在实践中主要是于引用传参和引用做返回值中减少拷贝提高效率和改变引用对象时改变被引用对象
  2. 引用传参跟指针传参功能类似,引用传参相对更加方便
  3. 引用返回值的场景相对比较复杂
  4. 引用和指针在实践中相辅相成,功能有重叠性,但是各有特点,互相不可替代。C++的引用跟其他语言的引用有很大差别,除了用法,最大的点,C++引用定义后不能改变指向,JAVA的引用可以改变指向

 6.4 const 的引用

  • 可以引用一个const对象,但是必须用const引用。const引用也可以引用普通对象,因为对象的访问权限在引用过程中可以缩小,但是不能放大

不需要注意的是类似于int& rb=a*3; double d=12.34 ; int & rd=d;这样一些场景下a*3的值结果保存在一个临时对象中,int& rd=d 也是类似,在类型转换中会产生临时对象存储中间值,也就是说,rb和rd引用的都是临时对象,而C++规定的临时对象具有常性,所以在这里就触发了权限放大,必须要用常引用才可以

所谓临时对象就是编译器需要一个空间暂存表达式的求值结果时临时创建的一个未命名的对象,C++把这个未命名对象叫做临时对象

//text.cpp
#include<iostream>
using namespace std;


int main()
{
	int a = 0; 
	//定义整型a=0
	const int b = 10;
	//定义整型常量b=10
	int& ra = a;
	//给ra引用a,权限一样,没问题
	const int& raa = a;
	//给raa引用a ,权限缩小,也没问题
	int& rb = b;
	//给rb引用b,有const修饰到没有const修饰,权限放大,编译器报错
    const int& rbb = b;
	//给rbb引用b,有const修饰到const修饰,权限一致,没问题
	 
	
	int& ab = (a + b);
	//编译器报错,表达式的结果存在临时对象里,临时对象具有常性

	const int& ab = (a + b);
	//编译通过

	int rd = b;
    int abb = a + b;
	//编译通过,表达式的结果虽然存在临时变量里,这里是将表达式的值拷贝一份给abb没有涉及权限的问题


	a++;
	ra++;
	//可以执行,没有const修饰
	
	rb++;
	//不存在
	
	rbb++;
    raa++;
	b++;
	//有const修饰,编译器报错

	double d = 12.34;
	int i = d;
	//隐式类型转换会产生临时变量,但是值得拷贝不影响

	int& ri = d; 
	//编译不通过,double转换为int类似,C++规定会产生临时对象,临时对象具有常性,所以这里不加const,权限缩小
	const int& rii = d;
	//编译通过
	return 0;
}

注意:临时对象只有短暂的生命周期,但是被引用后,生命周期会延长直到引用对象销毁

 6.5指针和引用的关系

C++中指针和引用就像两个性格迥异的亲兄弟,指针是哥哥,引用是弟弟,在实践中他们相辅相成,功能具有重叠性,但是各有自己的特点,互相不可替代

  • 语法概念上引用是一个变量的取别名不开空间,指针是存储一个变量的地址,要开空间
  • 引用在定义时引用一个对象后,就不能再引用其他对象;而指针可以不断得改变指向对象
  • 引用可以直接访问指向对象,指针需要解引用才能访问指向对象
  • sizeof中含义不同,引用结果为引用类型大小,但指针始终是地址空间所占字节个数(32位平台下占4个字节,64位平台下是8字节)
  • 指针很容易出现空指针和野指针的问题,引用很少出现,引用使用起来相对更安全一些

 

从汇编语言来看,引用本质就是指针 

 7.inline

  • 用inline修饰的函数叫做内敛函数,编译时C++编译器会在调用的地方展开内联函数,这样调用内敛函数就需要建立栈帧了,提高效率
//text.cpp
#include<iostream>
using namespace std;

inline int Add(int x, int y)
{
	int ret = x + y;
	
	ret += 1;
	ret += 1;
	ret += 1;
	ret += 1;
	ret += 1;

	return ret;
}
int main()
{
	int ret = Add(1, 2);
	cout << ret << endl;

	return 0;
}

看一下汇编语言 ,实现内敛了

  • inline对于编译器而言只是一个建议,也就是说,你加了inline编译器也可以选择在调用的地方不展示,不同的编译器关于inline什么情况展开各不相同,因为C++标准没有这个。inline适合用于频繁调用的短小函数,对于递归函数,代码相对较对一些的函数,加上inline也会被编译器忽略2

  • C语言实现宏函数也会在预处理时替换展开,但是宏函数实现很复杂很容易出错且不方便调试,C++设计了inline目的就是替代C的宏函数
  • VS编译器debug版本下面默认是不展开inline的,这样方便调试,debug版本想展开需要设置一下这两个地方

 

  • inline不建议声明和定义分离到两个文件,分离会导致链接错误。因为inline被展开,就没有函数地址,连接时会出现报错


 8.nullptr

NULL实际是一个宏,在传统的C头文件(stddef.h)中。C++中NULL可能被定义为字面常量0,或者C中被定义为无类型指针(void*)的常量,不论采取哪种定义。在使用指针时,都不可避免会遇到一些麻烦

C++11中引入nullptr,nullptr是一个特殊的关键字,nullptr是一种特殊类型的字面量,它可以转换成任意其他类型的指针类型。使用nullptr定义空指针可避免类型转换的问题,因为nullptr只能被隐式转换成指针类型,而不能被转换为整数类型

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

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

相关文章

基于CSS两种菜单创建方式

作者&#xff1a;私语茶馆 1.前言 HTML多种场景下需要菜单的实现&#xff0c;这里提供两种方式&#xff1a; &#xff08;1&#xff09;基于CSS的POPUP式菜单 特征&#xff1a;按需显示POPUP菜单&#xff0c;但布局是浮动的。 &#xff08;2&#xff09;覆盖式弹出菜单。 …

独家揭秘!五大内网穿透神器,访问你的私有服务

本文精心筛选了五款炙手可热的内网穿透工具&#xff0c;它们各怀绝技&#xff0c;无论您是企业用户、独立开发者&#xff0c;还是技术探索者&#xff0c;这篇文章都物有所值&#xff0c;废话不多说&#xff0c;主角们即将上场。 目录 1. 巴比达 - 安全至上的企业护航者 2. 花…

二次改写内容,ai智能写作软件最便捷

对于自媒体创作者&#xff0c;二次改写是获取内容的一个不错的方法&#xff0c;通过二次改写不仅能提高自媒体内容创作的效率问题&#xff0c;而且还解决了创作中因灵感缺失产不出内容的问题&#xff0c;但是二次改写内容也是需要讲究方法的&#xff0c;如果没有好的方法&#…

68种语言说爱你网页源码

浪漫至死不渝&#xff0c;68种语言说爱你网页源码&#xff0c;本地和上传服务器都可以用&#xff0c;无加密。 网页源码&#xff1a;68种语言说爱你单页.zip 下面是HTML代码CSS代码超过七百多行打包成文件了。 <!DOCTYPE html> <html lang"en"><h…

计算机体系结构和指令系统2

1.存储系统的层次结构 有的教材把安装在电脑内部的磁盘成为“辅存”&#xff0c;把U盘、光盘等成为外存&#xff0c;也有的教材把磁盘、U盘、光盘等统称为“辅存”或外存。 主存——辅存&#xff1a;实现虚拟存储系统&#xff0c;解决了主存容量不够&#xff0c;辅存速度不够的…

【密码学】实现消息认证或数字签名的几种方式

消息认证的目的是验证消息的完整性和确认消息的来源。数字签名的目的是不仅验证消息的完整性和来源&#xff0c;还提供了不可否认性。此外&#xff0c;数字签名还可以验证消息的创建时间&#xff0c;防止重放攻击。那么具体有哪些实现的方式呢&#xff1f; 一、仅提供消息认证…

2024年7月13日全国青少年信息素养大赛Python复赛小学高年级组真题

第一题 题目描述 握情况。他决定让每个人输入一个正整数 N (0≤N≤1000)&#xff0c;然后计算并输出(5*N)的值。请用 在一个神秘的王国里&#xff0c;国王希望通过一个简单的测试来评估他的子民对基 础数学运算的掌 Python 编写程序&#xff0c;程序执行后要求用户输入一个正…

【山东大学】web数据管理——复习笔记

写在前面 若有图片加载失败&#xff0c;请科学上网 。本文为对软件学院连老师的PPT课件总结所得的复习笔记&#xff0c;仅供参考。不保证对考点的全覆盖&#xff0c;以PPT为主。对往年考过的题相关知识点前面都标注了“考过”&#xff0c;并高亮&#xff0c;供参考。写的比较匆…

代码随想录第51天|单调栈

42. 接雨水 参考 思路1: 暴力解法 找每个柱子的左右高度超时 O(N^2) 思路2: 双指针优化 class Solution { public:int trap(vector<int>& height) {vector<int> lheight(height.size(), 0);vector<int> rheight(height.size(), 0);lheight[0] hei…

【超音速 专利 CN117576413A】基于全连接网络分类模型的AI涂布抓边处理方法及系统

申请号CN202311568976.4公开号&#xff08;公开&#xff09;CN117576413A申请日2023.11.22申请人&#xff08;公开&#xff09;超音速人工智能科技股份有限公司发明人&#xff08;公开&#xff09;张俊峰&#xff08;总&#xff09;; 杨培文&#xff08;总&#xff09;; 沈俊羽…

Python酷库之旅-第三方库Pandas(021)

目录 一、用法精讲 52、pandas.from_dummies函数 52-1、语法 52-2、参数 52-3、功能 52-4、返回值 52-5、说明 52-6、用法 52-6-1、数据准备 52-6-2、代码示例 52-6-3、结果输出 53、pandas.factorize函数 53-1、语法 53-2、参数 53-3、功能 53-4、返回值 53-…

网络割接方案通用模板

第一章 项目概述 1.1 编写目的 为规范“十三五”以来&#xff0c;随着移动互联新技术的发展以及我国政府职能的不断转变&#xff0c; 我国的政法网络进入新的发展阶段&#xff0c;跨地域、跨部门、跨系统的信息共享、业务 协同以及智慧政务等成为了各地电子政务的重点建设内容。…

【Django+Vue3 线上教育平台项目实战】构建高效线上教育平台之首页模块

文章目录 前言一、导航功能实现a.效果图&#xff1a;b.后端代码c.前端代码 二、轮播图功能实现a.效果图b.后端代码c.前端代码 三、标签栏功能实现a.效果图b.后端代码c.前端代码 四、侧边栏功能实现1.整体效果图2.侧边栏功能实现a.效果图b.后端代码c.前端代码 3.侧边栏展示分类及…

自动化故障排查与运维团队建设策略

在当前的运维领域&#xff0c;自动化故障排查已成为提高运维效率、保障系统稳定性的关键手段。为了进一步提升故障排查能力&#xff0c;并建立高效的运维团队&#xff0c;以下策略值得深入考虑和实施。 一、自动化故障排查流程与工具 标准化故障排查流程 建立一套标准化的故…

121. 小红的区间翻转(卡码网周赛第二十五期(23年B站笔试真题))

题目链接 121. 小红的区间翻转&#xff08;卡码网周赛第二十五期&#xff08;23年B站笔试真题&#xff09;&#xff09; 题目描述 小红拿到了两个长度为 n 的数组 a 和 b&#xff0c;她仅可以执行一次以下翻转操作&#xff1a;选择a数组中的一个区间[i, j]&#xff0c;&#x…

Nginx入门到精通五(动静分离)

下面内容整理自bilibili-尚硅谷-Nginx青铜到王者视频教程 Nginx相关文章 Nginx入门到精通一&#xff08;基本概念介绍&#xff09;-CSDN博客 Nginx入门到精通二&#xff08;安装配置&#xff09;-CSDN博客 Nginx入门到精通三&#xff08;Nginx实例1&#xff1a;反向代理&a…

全球生成式AI 产品分析报告

全球生成式AI 产品研究报告 时代背景 全球进入AI驱动的生产革命&#xff0c;生成式技术是时代际遇。中美在生成式AI产业展开科技竞争&#xff0c;全栈组合拳拉锯发展。‍ 技术变革 Transformer架构优化模型泛化的训推能力与理解生成的内容能力。文本模态达高应用成熟度&…

OpenCV图像处理——获取穿过圆的直线与圆相交的两个点

在OpenCV中&#xff0c;没有直接的函数来计算直线与圆的交点&#xff0c;但可以通过数学方法来实现这一功能。以下是计算直线与圆交点的步骤&#xff0c;以及相应的C代码示例&#xff1a; 确定直线方程&#xff1a;使用直线上的两个点 P 1 ( x 1 , y 1 ) P1(x1, y1) P1(x1,y1)和…

旷野之间17 - 适合所有人的 Transformer

最初出现在著名论文《Attention is all your need》中&#xff0c;基于Transformer的架构已成为大多数成功的人工智能模型中必不可少的。 然而&#xff0c;许多用户甚至基于人工智能的产品的创造者可能不了解Transformer是什么或它是如何工作的。 嗯&#xff0c;阅读研究论文…

MVC之 IHttpModule管道模型《二》

》》》注意&#xff1a;在http请求的处理过程中&#xff0c;只能调用一个HttpHandler&#xff0c;但可以调用多个HttpModule。 HTTP Modules ASP.NET请求处理过程是基于管道模型的&#xff0c;这个管道模型是由多个HttpModule和HttpHandler组成&#xff0c;当请求到达HttpMod…