C++入门(上)--《Hello C++ World!》(1)(C/C++)
文章目录
- 前言
- 命名空间
- 域
- 命名空间的用法
- C++的输入和输出
- 缺省参数
- 函数重载
- auto关键字(C++11)
- 范围for
前言
C++不是C#
C++兼容大部分C的东西,但不是完全(98%的样子,除非遇到了不兼容的,那就记一下,不然就认为自己在C里面写的那些可以写到C++里(不兼容编译器也会提醒))
C++标准库的头文件都没有.h,这些都需要std这个命名空间才能用;C的库在CPP上也能用(不会用一般),但是不需要std;比如cstdio要std stdio.h就不用
学完C++的继承和多态之后建议看一下《Effective C++》,然后C++ Primer可以当做是一本语法字典,
把C++全部学完之后还建议看一下STL源码剖析
第一本和第三本应该来说是要必看的,看和不看差别很大
命名空间
域
域的优先级:如果有指定访问哪个域的话,先是去这里面找,找不到就报错
没有指定访问的话才是局部域里面找,最后才是全局域
不同域里面可以定义相同的变量
展开命名空间域的话要看是在哪展开的,在全局展开就当全局变量用(但不是"真"全局变量),在局部展开就当局部变量用(eg:在全局展开,就不能跟全局变量重名,不然会报错)
注意:局部变量之间可能也是不同域,看局部是不是在同一局部
命名空间的展开和头文件的展开要区分一下: 头文件展开类似拷贝,命名空间展开类似拆墙来让他们可以访问这里
命名空间的用法
一般开发中是用项目名字做命名空间名
命名空间的性质:
1.命名空间中可以定义变量/函数/类型(比如结构体,typedef关键词)
2.命名空间可以嵌套
3.同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。
(但是要注意会重名,可以用嵌套来解决)
命名空间的定义: namespace renshen { }//注意,这里没有分号 嵌套: namespace N1 { int a; int b; int Add(int left, int right) { return left + right; } namespace N2 { int a; int b; int Sub(int left, int right) { return left - right; } } } 这种嵌套这的使用为: eg: N1::N2::a; N1::a;
命名空间的使用 1.全局展开命名空间 --建议项目里不要这么去展开,建议日常可以这么搞;项目建议要选择指定访问,不能轻易展开命名空间 eg: using namespace std; 2.部分展开命名空间--在实际中常把常用的展开 eg: using std:cout; 3.加命名空间名称及作用域限定符(::前面没有东西的话,默认是全局访问,先访问"真"全局变量) --也就是指定访问 eg:N1::N2::a; N1::a;
C++的输入和输出
是流提取运算符
用cin cout不方便的时候就去用printf,scanf;虽然cout也能控制输出格式,但是没必要,不用学;printf和cout的应用场景具体见蓝桥杯C++小结篇
缺省参数
应用:比如像给函数提供默认选项
分为两类:全缺省参数和半缺省参数
函数有声明的话,函数的缺省参数只能在声明中给出;如果没有声明的话,才能在定义中写
全缺省参数: eg:void Func(int a = 10, int b = 20, int c = 30) 半缺省参数:(有至少一个没给默认值,有至少一个有默认值) eg:void Func(int a, int b = 10, int c = 20) 缺省规则:参数的默认值必须要从右到左依次给出(也就是从左边开始空,还不能跳着空,要连续) eg:void Func(int a, int b = 10, int c )--这样不行
在使用缺省参数的时候,对实参的要求: 从左到右必须依次给出(也就是从右边开始空,还不能跳着空,要连续) 不能eg:Func(1,,2);
函数有声明的话,函数的缺省参数只能在声明中给出 的原因:
1.避免声明和定义重复给缺省参数–害怕出现两个给的缺省参数不同的情况
2.因为声明一般被放在头文件中,而函数定义一般在源文件里面。在编译的时候,C++采用的是分离编译–编译器在编译每个源文件时仅能看到当前文件的内容 ,所以只有缺省参数放在声明里才行。
函数重载
函数重载就是让同名函数(一般功能类似)能够共存
函数重载的几种情况:(单单返回值不同的话不算函数重载) --这里的举例的话就只展示函数头 1.参数类型不同 int Add(int left, int right) 和 double Add(double left, double right) 2.参数个数不同 void f() 和 void f(int a) 3.参数类型的顺序的不同(形参的名不同没啥用) void f(int a, char b) 和 void f(char b, int a) 注意:void f(int a, char b) 和 void f(int b, char a)不算函数重载,这俩就是同一个函数 int f(int a, char b) 和 void f(double b, char a)算函数重载,就算返回值类型不一样
C语言不支持重载,但是CPP支持重载的原因:
1.编译链接过程:C语言的符号表里面对同名的函数时一样的,而C++不是
2.函数名修饰规则:重载的话C语言编译时就会报错,防止汇编时规则不支持(因为他不会把参数类型啥的带进来) 但是C++对函数名的修饰会把参数的类型啥的带进来
拓展一下编译链接的过程: 比如现在有三个文件 list.h list.cpp text.cpp 1.预处理:这个过程会进行头文件展开/宏替换/条件编译/去掉注释…… 生成 list.i text.i 2.编译:这个过程会检查语法(包括歧义,比如:调用歧义),生成汇编代码 生成文件:list.s text.s 3.汇编:将汇编代码转换成2二进制机器码(通过符号表-里面存的是函数名和地址的映射关系,具体啥样要看编译器) 生成文件:list.o text.o 4.链接:(在这一步,list.cpp和text.cpp才会"会师") 生成可执行程序: xxx.exe/a.out()//Linux不指定的话就会生成a.out() 对函数来说,如果有声明的话,声明就相当于是承诺(只要代码跟声明是匹配的就行)在链接那个过程才需要找定义 (该文件只有声明,没有对应的那个定义的才有此)
auto关键字(C++11)
auto用来自动推导出变量的类型
应用:很长的类型eg:迭代器 范围for等
auto的使用规则:
1.用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&
比如: int a = 1; auto& x = a;
2.在同一行(以;划时)定义多个变量时不能用auto
比如: auto a,b;
3.auto不能用在函数形参和返回值上,但是C++14可以做返回值了
4.auto不能用来声明数组
eg: auto a[2] = {0,1};//不能这样
引申出一个点:(知道有这个东西就行了) 求变量类型的方法:typeid().name() eg: auto d = 2+3.14; cout