c++入门你需要知道的知识点(上)

🪐🪐🪐欢迎来到程序员餐厅💫💫💫

         今日主菜:c++入门

                 主厨:邪王真眼

            所属专栏:c++专栏

              主厨的主页:Chef‘s blog


前言:

咱也是好久没有更新了,继c语言和数据结构之后,今天再开个新坑c++,学c++与C语言有个共同点,那就是要及时写博客,一方面是及时总结知识方便以后回顾复习,一方面也是检验自己当前的学习效果,欧克,那麽今天我们就要踏入c++的大门,今天先来初窥门径。

1. 本节要求

C++ 是在 C 的基础之上,容纳进去了面向对象编程思想,并增加了许多有用的库,以及编程范式
等。熟悉 C 语言对 C++ 学习有一定的帮助,
本节主要目标:
  • 1. C++是如何对C语言设计不合理的地方进行优化的,比如:作用 域方面、IO方面、函数方面、指针方面、宏方面等。
  • 2. 为后续类和对象学习打基础。

2. C++关键字(C++98)

C++ 总计 63 个关键字, C 语言 32 个关键字
我们现在只是看一下 C++ 有多少关键字,不对关键字进行具体的讲解。他们的具体作用后面我们学到一个讲一个。

3. 命名空间

C/C++ 中,变量、函数和后面要学到的类都是大量存在的,将这些变量、函数和类的名称将都存
在于全局作用域中,可能会导致很多命名冲突,比如不小心给两个函数起了一样的名字。c++是通过使用命名空间来解决这个问题的。
这里就要用namespace 关键字了。(打起精神,第一个关键字来了!!!)

3.1样例

C语言命名冲突如下:

#include <stdio.h>
#include <stdlib.h>
int rand = 10;
//我们知道C语言有个叫rand的函数,我们在这里又定义了一个叫rand的变量。
int main()
{printf("%d\n", rand);
return 0;
}
// 编译后后报错:error C2365: “rand”: 重定义;以前的定义是“函数”

3.2 命名空间定义

定义命名空间,需要使用到 namespace 关键字 ,后面跟 命名空间的名字 ,然 后接一对 {} 即可, {}
中即为命名空间的成员。
// sixflower是命名空间的名字。
// 1. 正常的命名空间定义
namespace sixflower
{// 命名空间中可以定义变量/函数/类型int rand = 10;int Add(int left, int right){return left + right;}
注意:一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中
 

3.3 命名空间使用

命名空间中成员该如何使用呢?比如:
namespace bit
{// 命名空间中可以定义变量/函数/类型int a = 0;int b = 1;int Add(int left, int right){return left + right;}struct Node{struct Node* next;int val;};
}
int main()
{// 编译报错:error C2065: “a”: 未声明的标识符printf("%d\n", a);
return 0;
}
命名空间的使用有三种方式:

3.3.1.加命名空间名称及作用域限定符

int main ()
{
printf ( "%d\n" , N::a );
return 0 ;    
}

3.3.2.使用using将命名空间中某个成员引入

using N::b ;
int main ()
{
printf ( "%d\n" , N::a );
printf ( "%d\n" , b );
return 0 ;    
}

3.3.3.使用using namespace 命名空间名称引入

using namespce N ;
int main ()
{
printf ( "%d\n" , N::a );
printf ( "%d\n" , b );
Add ( 10 , 20 );
return 0 ;    
}

3.4使用原理:

编辑器在找你写的变量,函数,类等时默认在当前域和全局变量中寻找,

对于方案一:其实就是告诉编译器这个a在N里,那么编译器就回去N这个域中找

对于方案二:也是告诉编译器这个b是在N里,与方案一的区别是在之后使用时不用再写为N::b的模式。

对于方案三:就是在默认的基础上,让编译器搜索范围又增加了N域

4. C++输入&输出

请看代码:

#include<iostream>
// std是C++标准库的命名空间名,C++将标准库的定义实现都放到这个命名空间中
using namespace std;
int main()
{
cout<<"Hello world!!!"<<endl;
return 0;
}

相信你也明白这就是c++的“hello world”,但为什么这样写还听我细细道来。

  • 1. 使用cout标准输出对象(控制台)和cin标准输入对象(键盘)时,必须包含< iostream >头文件
  • 以及按命名空间使用方法使用std。
  • 2. cout和cin是全局的流对象,cout作用类似于printf,cin作用类似于类似于scanf。endl是特殊的C++符号,现在可以将它看作‘\n’,他们都包含在包含<iostream >头文件中。
  • 3. <<是流插入运算符,>>是流提取运算符,
  • 4. 使用C++输入输出更方便,不需要像printf/scanf输入输出时那样,需要手动控制格式。 C++的输入输出可以自动识别变量类型。
  • 注意:早期标准库将所有功能在全局域中实现,声明在.h后缀的头文件中,使用时只需包含对应 头文件即可,后来将其实现在std命名空间下,为了和C头文件区分,也为了正确使用命名空间,规定C++头文件不带.h;旧编译器(vc 6.0)中还支持<iostream.h>格式,后续编译器已不支持,因此推荐使用<iostream>+std的方式。

ps:

现在搞不懂cout,cin,>>,<<是正常的,先知道它的作用就行,以后还会细讲。

#include <iostream>
using namespace std;
int main()
{int a;double b;char c;// 可以自动识别变量的类型cin>>a;cin>>b>>c;cout<<a<<endl;cout<<b<<" "<<c<<endl;return 0;
}
// ps:关于cout和cin还有很多更复杂的用法,比如控制浮点数输出精度,控制整形输出进制格式等
等。因为C++兼容C语言的用法,可以用c语言实现这些要求,这些又用得不是很多,我们这里就不展开学习了。后续如果有需要,我
们再配合文档学习。
std命名空间的使用惯例:
1. 在日常练习中,建议直接 using namespace std 即可,这样就很方便。
2. using namespace std 展开,标准库就全部暴露出来了,如果我们定义跟库重名的类型 /
/ 函数,就存在冲突问题。该问题在项目开发中代码较多、规模 大,就很容易出现。所以建议在项目开发中使用方案1,2.

5. 缺省参数

5.1 缺省参数概念

缺省参数是 声明或定义函数时 为函数的 参数指定一个缺省值 。在调用该函数时,如果没有指定实
参则采用该形参的缺省值,否则使用指定的实参。
void Func(int a = 0)
{cout<<a<<endl;
}
int main()
{Func();     // 没有传参时,使用参数的默认值Func(10);   // 传参时,使用指定的实参
return 0;
}

5.2 缺省参数分类

5.2.1全缺省参数

void Func(int a = 10, int b = 20, int c = 30){cout<<"a = "<<a<<endl;cout<<"b = "<<b<<endl;cout<<"c = "<<c<<endl;}

5.2.2半缺省参数

void Func(int a, int b = 10, int c = 20){cout<<"a = "<<a<<endl;cout<<"b = "<<b<<endl;cout<<"c = "<<c<<endl;}
1. 半缺省参数必须 从右往左依次 来给出,不能间隔着给
2. 声明与定义分开时 缺省参数不能在函数声明和定义中同时出现,只能在声明出现
 //a.hvoid Func(int a = 10);// a.cppvoid Func(int a = 20){}// 注意:如果生命与定义位置同时出现,恰巧两个位置提供的值不同,那编译器就无法确定到底该
用那个缺省值。
3. 缺省值必须是常量或者全局变量

5. 函数重载

自然语言中,一个词可以有多重含义,人们可以通过上下文来判断该词真实的含义,即该词被重
载了。
比如:以前有一个笑话,国有两个体育项目大家根本不用看,也不用担心。一个是乒乓球,一个
是男足。前者是 谁也赢不了! ,后者是 谁也赢不了!

5.1 函数重载概念

函数重载:是函数的一种特殊情况,C++ 允许在 同一作用域中 声明几个功能类似 的同名函数,这
些同名函数的形参列表 ( 参数个数 或 类型 或 类型顺序 ) 不同,常用来处理实现功能类似数据类型
不同的问题
#include<iostream>
using namespace std;
// 1、参数类型不同
int Add(int left, int right)
{cout << "int Add(int left, int right)" << endl;return left + right;
}
double Add(double left, double right)
{cout << "double Add(double left, double right)" << endl;return left + right;
}
// 2、参数个数不同
void f()
{cout << "f()" << endl;
}
void f(int a)
{cout << "f(int a)" << endl;
}
// 3、参数类型顺序不同
void f(int a, char b)
{cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{cout << "f(char b, int a)" << endl;
}
int main()
{Add(10, 20);Add(10.1, 20.2);f();f(10);f(10, 'a');f('a', 10);return 0;
}

5.2 C++支持函数重载的原理--名字修饰(name Mangling)

为什么 C++ 支持函数重载,而 C 语言不支持函数重载呢?
C/C++ 中,一个程序要运行起来,需要经历以下几个阶段: 预处理、编译、汇编、链接
这个知识忘了的可以看一下这篇博客:
编译与链接
1. 实际项目通常是由多个头文件和多个源文件构成,而通过 C 语言阶段学习的编译链接,我们
可以知道,【当前 a.cpp 中调用了 b.cpp 中定义的 Add 函数时】,编译后链接前, a.o 的目标
文件中没有 Add 的函数地址,因为 Add 是在 b.cpp 中定义的,所以 Add 的地址在 b.o 中。那么
怎么办呢?
2. 所以链接阶段就是专门处理这种问题, 链接器看到 a.o 调用 Add ,但是没有 Add 的地址,就
会到 b.o 的符号表中找 Add 的地址,然后链接到一起
3. 那么链接时,面对 Add 函数,链接接器会使用哪个名字去找呢?这里每个编译器都有自己的
函数名修饰规则。
4.  通过下面我们可以看出 gcc(也就是支持C语言) 的函数修饰后名字不变。而 g++(也就是支持c++) 的函数修饰后变成【 _Z+ 函数长度 + 函数名 + 类型首字母】。 采用 C 语言编译器编译后结果


 
5. 通过这里就理解了 C 语言没办法支持重载,因为同名函数没办法区分。而 C++ 是通过函数修
饰规则来区分,只要参数不同,修饰出来的名字就不一样,就支持了重载
结论:在linux下,采用g++编译完成后,函数名字的修饰发生改变,编译器将函数参
数类型信息添加到修改后的名字中。
注意: 如果两个函数函数名和参数是一样的,返回值不同是不构成重载的,因为调用时函数时编译器没办法直到返回值,所以无法进行区分。

结语:

事实上,这篇博客只完成了本节目标的一半,敬请期待c++入门你需要知道的知识点(下)

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

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

相关文章

「THUWC 2017」大葱的神力 - 题解

忠告&#xff1a;如果你想抄题解的&#xff0c;可以离开&#xff0c;这不是一时半会儿能解决的问题 前置知识&#xff1a; 学习笔记&#xff1a;费用流https://blog.csdn.net/weixin_44043668/article/details/108738212C动态规划详解https://blog.csdn.net/weixin_51951103/a…

GPT实战系列-LangChain的OutPutParser解析器

GPT实战系列-LangChain的OutPutParser解析器 LangChain GPT实战系列-LangChain如何构建基通义千问的多工具链 GPT实战系列-构建多参数的自定义LangChain工具 GPT实战系列-通过Basetool构建自定义LangChain工具方法 GPT实战系列-一种构建LangChain自定义Tool工具的简单方法…

MySQL gh-ost DDL 变更工具

文章目录 1. MDL 锁介绍2. 变更工具3. gh-ost 原理解析4. 安装部署5. 操作演示5.1. 重点参数介绍5.2. 执行变更5.3. 动态控制 6. 风险提示 1. MDL 锁介绍 MySQL 的锁可以分为四类&#xff1a;MDL 锁、表锁、行锁、GAP 锁&#xff0c;其中除了 MDL 锁是在 Server 层加的之外&am…

strcmp的模拟实现

一&#xff1a;strcmp函数的定义&#xff1a; strcmp函数功能的解释&#xff1a; 比较两个字符串的大小&#xff08;按照字符串中字符的ascll码值&#xff09;。 标准规定&#xff1a; 第一个字符串大于第二个字符串&#xff0c;则返回大于 0 的数字 第一个字符串等于第二个…

宠物食品药品小程序有哪些功能

现在很多人都喜欢养宠物&#xff0c;这带动了宠物相关产业链&#xff0c;例如宠物医院、宠物清理、宠物食品、宠物玩具、宠物药品等。那么今天就介绍宠物食品药品小程序有哪些功能&#xff0c;以帮助您更好地为宠物行业的客户提供服务。 1. **商品展示**&#xff1a;宠物食品小…

C++ 作业 24/3/14

1、成员函数版本实现算术运算符的重载&#xff1b;全局函数版本实现算术运算符的重载 #include <iostream>using namespace std;class Test {friend const Test operator-(const Test &L,const Test &R); private:int c;int n; public:Test(){}Test(int c,int n…

嵌入式面经-ARM体系架构-计算机基础

嵌入式系统分层 操作系统的作用&#xff1a;向下管理硬件&#xff0c;向上提供接口&#xff08;API&#xff09; 应用开发&#xff1a;使用操作系统提供的接口&#xff08;API&#xff09;&#xff0c;做上层的应用程序开发&#xff0c;基本不用去关内核操作硬件是怎么实现的 …

HarmonyOS 非线性容器特性及使用场景

非线性容器实现能快速查找的数据结构&#xff0c;其底层通过 hash 或者红黑树实现&#xff0c;包括 HashMap、HashSet、TreeMap、TreeSet、LightWeightMap、LightWeightSet、PlainArray 七种。非线性容器中的 key 及 value 的类型均满足 ECMA 标准。 HashMap HashMap 可用来存…

Linux——信号量

目录 POSIX信号量 信号量原理 信号量概念 信号量函数 基于环形队列的生产者消费者模型 生产者和消费者申请和释放资源 单生产者单消费者 多生产者多消费者 多生产者多消费者的意义 信号量的意义 POSIX信号量 信号量原理 如果仅用一个互斥锁对临界资源进行保护&#…

path模块

一、path模块作用 path模块提供了操作路径的功能 二、语法 (1) path.resolve 拼接规范的绝对路径 常用 (2) path.sep 获取操作系统的路径分隔符 (3) path.parse 解析路径并且返回对象 (4) path.basename 获取路径的基本名称 (5) path.dirname 获取路径的目录名 …

Android NDK入门:在应用中加入C和C++的力量

目录 ​编辑 引 NDK的设计目的 与Java/Kotlin的结合 使用场景 开发流程 设置项目以支持NDK 编写本地代码 使用JNI连接本地代码和Java/Kotlin代码 编译和运行你的应用 附 引 自诩方向是android方向的移动端开发工程师&#xff0c;却从来没有真正仔细了解过NDK&#…

【Unity】Tag、Layer、LayerMask

文章目录 层&#xff08;Layer&#xff09;什么是LayerLayer的应用场景Layer层的配置&#xff08;Tags & Layers&#xff09;Layer的数据结构LayerMaskLayer的选中和忽略Layer的管理&#xff08;架构思路&#xff09;层碰撞矩阵设置&#xff08;Layer Collision Matrix&…