C++入门知识
创始人
2024-04-03 13:18:50
0

目录

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

2. 命名空间

2.1 命名空间定义

2.2 命名空间使用

3.C++输入输出

4.缺省函数

缺省参数分类

5. 函数重载

5.1 函数重载概念

5.2 C++支持函数重载的原理

5.3 extern “C”


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

在讨论有多少关键字的时候,要说清楚在那个版本之下,在C++98中,C++总计63个关键字,C语言32个关键字,这里只是一个展示表,在后面的学习中慢慢掌握

C语言和C++源文件后缀是不同的

C++源文件的后缀是 .cpp。后缀不同工程不同,背后的使用的编译器是不一样的。

2. 命名空间

在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。     使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的
#include 
#include 
int rand = 10;int main()
{printf("%d\n", rand);return 0;
}
C语言没办法解决类似这样的命名冲突问题,所以C++提出了namespace来解决 编译后后报错:error C2365: “rand”: 重定义;以前的定义是“函数”

2.1 命名空间定义

定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}中即为命名空间的成员。 下面是最基本的命名空间定义
#include//之前在全局作用域中可以定义的内容,在命名空间内都可以定义
namespace zx
{//定义变量int a = 10;int b = 20;//定义函数int Add(int x, int y){return x + y;}//定义结构体struct BTNode{struct BTNode* left;struct BTNode* right;int data;};
}int a = 10;
int b = 20;
int Add(int x, int y)
{return x + y;
}
int main()
{return 0;
}

2.命名空间嵌套:一个命名空间中,可以包含其他的命名空间

类似于:学校可以看作一个命名空间,学校下包含各个学院,学院下又包含不同专业

namespace zx
{int a = 120;int b = 20;int Add(int x, int y){return x + y;}namespace zx2{int x = 10;int y = 20;}
}

3.同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。

ps:一个工程中的test.h和上面test.cpp中两个N1会被合并成一个

2.2 命名空间使用

1.加命名空间名称及作用域限定符
int a = 10;int main()
{int a = 30;printf("%d\n", a);return 0;
}

如上,直接打印出来a为30,要打印全局作用域中的a,就要使用作用域运算符

::作用域运算符

printf("%d\n", ::a);

这样编译器就会找全局作用域中的a ,找到了就打印,找不到会报错

以此类推,你要找上面 定义的 命名空间中的 a,加上名字即可
printf("%d\n", zx::a);

这样打出来就是120

2.使用using将命名空间中某个成员引入 使用using,相当于把b变成了当前文件中的全局变量,下面打印出来的结果相同的,但是如果你在文件全局作用域中再次定义一个b。就会报错
using N::b;
int main()
{printf("%d\n", N::a);printf("%d\n", b);return 0; 
}

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

把命名空间N中所有成员都定义为当前文件中的全局变量;

但是一般不推荐使用,容易冲突

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

命名空间嵌套时,内部命名空间中成员的使用方式

如下,打印出来结果为x的值

namespace zx
{int a = 110;int b = 20;namespace zx2{int x = 10;int y = 20;}
}
int main()
{printf("%d\n", zx::zx2::x);return 0;
}

3.C++输入输出

cin输入,cout输出

cin在接受输入时,不能接受空格 tab 回车,如要接受,使用getchar

1. 使用cout标准输出对象(控制台)cin标准输入对象(键盘)时,必须包含< iostream >头文件以及按命名空间使用方法使用std。 2. cout和cin是全局的流对象,endl是特殊的C++符号,表示换行输出,他们都包含在包含< iostream >头文件中。 3. <<是流插入运算符,>>是流提取运算符。 4. 使用C++输入输出更方便,不需要像printf/scanf输入输出时那样,需要手动控制格式。C++的输入输出可以自动识别变量类型。 5. 实际上cout和cin分别是ostream和istream类型的对象,>>和<<也涉及运算符重载等知识,这些知识我们我们后续才会学习,所以我们这里只是简单学习他们的使用。后面我们还有有一个章节更深入的学习IO流用法及原理。 写项目时推荐如下:
#include 
int main()
{std::cout << "12" << std::endl;return 0;
}

练习时可使用:

#include 
using namespace std;
int main()
{cout << "12" << endl;return 0;
}
std是C++标准库的命名空间,如何展开std使用更合理呢? 1. 在日常练习中,建议直接using namespace std即可,这样就很方便。 2. using namespace std展开,标准库就全部暴露出来了,如果我们定义跟库重名的类型/对象/函数,就存在冲突问题。该问题在日常练习中很少出现,但是项目开发中代码较多、规模大,就很容易出现。所以建议在项目开发中使用,像std::cout这样使用时指定命名空间 + using std::cout展开常用的库对象/类型等方式

4.缺省函数

声明或定义函数时,可以给函数的参数带上默认值,在调用函数时,如果用户没有指定实参,则使用默认值,如果用户指定了实参,则使用用户传递的实参
void Func(int a = 0)
{cout<

缺省参数分类

1.全缺省参数:所有的参数都有默认值
#include 
using namespace std;
void fun(int a = 1, int b = 2, int c = 3)
{cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl;cout << "------" << endl;
}
int main()
{fun();fun(10);fun(10, 20);fun(10, 20, 30);return 0;
}

大家对比结果可看出规律,当传入不全时,依次传参 

2.半缺省参数 部分参数带有默认值 a和b有默认值,c没有--》编译报错 a和c有默认值,b没有--》编译报错 b和c有默认值,a没有--》编译成功 注意事项: 1. 半缺省参数必须右往左依次来给出,不能间隔着给 2. 缺省参数不能在函数声明和定义中同时出现 假设声明和定义的位置可以同时给出,如果两个地方的默认值不一样,编译器就不能判断使用那个值。 一般情况下,如果缺省值放在函数定义的位置,用户就不知道函数的形参是否带默认值。所以一般放在函数声明的地方。 3. 缺省值必须是常量或者全局变量 4. C语言不支持(编译器不支持)

5. 函数重载

5.1 函数重载概念

函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同,常用来处理实现功能类似数据类型不同的问题
int Add(int left, int right)
{return left + right;
}
double Add(double left, double right)
{return left + right;
}int main()
{cout << Add(1, 2) << endl;cout << Add(1.2, 2.3) << endl;return 0;
}

5.2 C++支持函数重载的原理

在C/C++中,一个程序要运行起来,需要经历以下几个阶段:预处理、编译、汇编、链接 在上面程序中,编译阶段对形参类型进行推演:编译器确认实参的类型 上面首先 1,2都是int,两个形参都是int,最终就会调用 int 的ADD函数 后面double类型的同理 如果如此输入
cout << Add(1, 2.3) << endl;
此时,如果没有参数类型对应的函数,编译器会对实参进行隐式类型转换,如果转换之后有类型匹配的函数则调用,否则报错,如下,会把double型转换为int型,输出为都是3
int Add(int left, int right)
{return left + right;
}
int main()
{cout << Add(1, 2) << endl;cout << Add(1.2, 2.3) << endl;return 0;
}

一些注意的点: 1. 实际项目通常是由多个头文件和多个源文件构成,而通过C语言阶段学习的编译链接,我们可以知道, 【当前a.cpp中调用了b.cpp中定义的Add函数时】,编译后链接前,a.o的目标文件中没有Add的函数地 址,因为Add是在b.cpp中定义的 c语言编译器仅仅在函数名字前添加了下划线

 所以,下面两个函数在c语言中的名字最终被修饰为: _Add

虽然两个方法的原型不同,编译器认为这两函数为同一函数,导致重定义出错。

int Add(int left, int right)
{return left + right;
}
double Add(int left, int right)
{return left + right;
}
上面同样的代码,在C++中运行无报错 2. 所以链接阶段就是专门处理这种问题,链接器看到a.o调用Add,但是没有Add的地址,就会到b.o的符号表中找Add的地址,然后链接到一起。(老师要带同学们回顾一下) 3. 链接时,面对Add函数,这里每个编译器都有自己的函数名修饰规则。 4. 由于Windows下vs的修饰规则过于复杂,而Linux下g++的修饰规则简单易懂,下面我们使用了g++演示了这个修饰后的名字。 5. 通过下面我们可以看出gcc的函数修饰后名字不变。而g++的函数修饰后变成【_Z+函数长度+函数名+型首字母】。 6. C语言没办法支持重载,因为同名函数没办法区分。而C++是通过函数修饰规则来区分,只要参数不同,修饰出来的名字就不一样,就支持了重载

7. 如果两个函数函数名和参数是一样的,返回值不同是不构成重载的,因为调用时编译器没办法区分

5.3 extern “C”

由于C和C++编译器对函数名字修饰规则的不同,在有些场景下可能就会出问题,比如: 1. C++中调用C语言实现的静态库或者动态库,反之亦然 2. 多人协同开发时,有些人擅长用C语言,有些人擅长用C++ 在这种混合模式下开发,由于C和C++编译器对函数名字修饰规则不同,可能就会导致链接失败,在该种场景下,就需要使用extern "C"。在函数前加extern "C",意思是告诉编译器,将该函数按照C语言规则来编译 具体创建规则可以在网上查找

相关内容

热门资讯

贵州百灵纾困纠纷背后:新希望与... 近日,苗药龙头贵州百灵(002424)与华创证券之间的纾困纠纷一直是市场关注的重点,自2025年8月...
*ST南置(002305)披露... 截至2025年12月29日收盘,*ST南置(002305)报收于2.23元,较前一交易日上涨0.9%...
原创 普... 俄罗斯总统弗拉基米尔·普京签署法律,禁止在俄罗斯境内执行外国刑事法院和国际法院的裁决 相关文件已在俄...
盒马购得面包发馊变臭!商家“仅... 面包发馊发臭 近日,市民刘女士向“新民帮侬忙”反映,从盒马鲜生购入的日式面包,竟然发馊发臭!然而事发...
当年龄不再是“免罚金牌”,彰显... 文/九派新闻特约评论员 舒圣祥 明年1月1日起,新修订的《治安管理处罚法》即将正式施行。新法专门新增...
2026年1月1日起施行!“被... 2025年新修订的治安管理处罚法将于2026年1月1日起施行,针对新修订的内容中与市民生活息息相关的...
“车企起诉电池企业第一案”:2... 编者按: 极氪起诉欣旺达这场官司,无论最终迎来怎样的判决,都注定会为整个行业留下一笔深刻的警示财富。...
逃缴1.09亿美元关税!深圳货... 可以说2025是税务大年,卖家不仅要扛住国内申报的节奏,还得适应一件更现实的事:跨境这门生意,账目和...
青岛榜样|奋战公益诉讼一线,诠... “说是检察官,其实我们更像户外工作者,经常跋山涉水、穿梭于田野乡间,哪里有公益受损和群众需求,哪里就...
双星新材(002585)披露市... 截至2025年12月29日收盘,双星新材(002585)报收于6.82元,较前一交易日上涨1.04%...