1.什么是C++?
- C++是从C语言中生长出来的,C/C++不分家。
- C++是一种计算机高级程序设计语言,由C语言扩展升级而产生 ,最早于1979年由本贾尼·斯特劳斯特卢普(C++语言之父)在AT&T贝尔工作室研发。
- C++既可以进行C语言的过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行以继承和多态为特点的面向对象的程序设计。
- C++擅长面向对象程序设计的同时,还可以进行基于过程的程序设计。
- C++几乎可以创建任何类型的程序:游戏、设备驱动程序、HPC、云、桌面、嵌入式和移动应用等。
总的来说,c++是c语言的升级版,更加实用。在众多编程语言中,c++不是最简单的,但是确实数一数二的非常实用的。
2.如何学习C++?
以下引用自2010年8月号《程序员》刊登的拙文《C++强大背后》最后一段
- 第一个层次,C++基础 (平平常常)
挑选一本入门书籍,如《C++ Primer》、《C++大学教程》或Stroustrup撰写的经典《C++程序设计语言》或他一年半前的新作《C++程序设计原理与实践》,而一般C++课程也止于此,另外《C++ 标准程序库》《The C++ Standard Library Extensions》可供参考; - 第二个层次,正确高效的使用C++ (驾轻就熟)
此层次开始必须自修,阅读过《(More)Effective C++》、《(More)Exceptional C++》、《Effective STL》及《C++编程规范》等,才适宜踏入专业C++开发之路; - 第三个层次,深入解读C++ (出神入化)
关于全局问题可读《深入探索C++对象模型》、《Imperfect C++》、《C++沉思录》、《STL源码剖析》,要挑战智商,可看关于模版及模版元编程的书籍如《C++Templates》、《C++设计新思维》、《C++模版元编程》; - 第四个层次,研究C++ (返璞归真)
阅读《C++语言的设计和演化》、《编程的本质》(含STL设计背后的数学根基)、C++标准文件《ISO/IEC 14882:2003》、C++标准委员会的提案书和报告书、关于C++的学术文献。由于我主要是应用C++,大约只停留于第二、三个层次。然而,C++只是软件开发的一环而已,单凭语言并不能应付业务和工程上的问题。建议读者不要强求几年内“彻底学会C++的知
识”,到达第二层左右便从工作实战中汲取经验,有兴趣才慢慢继续学习更高层次的知识。
大部分的我们学到第二、三层次已经超级超级厉害了,胜任大部分工作没问题。只有像C语言之父、C++编译器这种佬才能胜任第四个层次,可以说自己可以开发语言了。
还是那句话:道阻且长,行则将至!!!
知识是枯燥乏味的,但我们的未来是光明的‘power’
书籍推荐
1.入门阶段,随便找一本简单的书快速入门,《高质量程序设计指南—C++/C语言》就挺适合的,可以简单快速了解C++的语法特性。
2.当C++学习过半之后,大概继承和多态学完,建议《Effective C++》,该书以建议的方式告诉你如何写出更好的C++程序,看和不看差别非常大。《C++ Prime》可以当成工具书对待,当字典使用,有不清楚的语法特性可以快速去查。
3.中后期:《STL源码剖析》将六大组件逐一剖析,看完之后对STL的设计框架以及内部实现原理有更深的认识,面试时可以游刃有余和面试官交锋。有一定难度,如果基础知识掌握不扎实,不建议看,强烈建议好好把基础知识打扎实。
3.C++关键字
ps:C++(C++98)总计63个关键字,C语言32个关键字。详细内容见博客
注意:false和true并不是C语言的关键字,是C++关键字。
4.命名空间
看如下代码,出现报错
报错原因:<stdlib.h>是C 标准库中的一个头文件,提供了许多通用工具函数,其中就包含了rand()函数且存在于全局作用域。这些变量、函数和类的名称有可能与我们自己对变量、函数和类的命名产生冲突。
同时,仅依靠C语言无法解决该问题,本贾尼·斯特劳斯特卢普就引入了C++中的namespace关键字。
使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染。
4.1命名空间定义
使用到namespace关键字,后面跟命名空间的名字(自定义),然后接一对{}即可,与结构体不同在于}后无;符号。{}中即为命名空间的成员。
注意:一个命名空间就定义了一个新的作用域叫做命名空间域,命名空间中的所有内容都局限于该命名空间中。在编译器查找时,先在局部域(自家菜地),接着到全局域(野地),默认不会到命名空间(张爷爷的菜地)去找。
这就需要自己限定作用域,引入 域作用限定符
namespace namee
{
// 命名空间中可以定义变量/函数/类型/命名空间(即可嵌套)
rand = 1; //调用时 namee::rand
int Add(int left, int right) //调用时 namee::Add()
{
return left + right;
}
struct Node //调用时 struct namee::Node node
{
struct Node* next;
int data;
};
namespace nameee
{
int printf = 1; //调用时 namee::nameee::printf
}
}
同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。
ps:一个工程中的test.h和test.cpp中两个相同名称的命名空间会被合并成一个
当然,如果这多个相同名称的命名空间内部命名冲突,解决办法一:人为修改。解决办法二:嵌套。
4.2命名空间的使用
namespace namee
{
// 命名空间中可以定义变量/函数/类型/命名空间
int a = 0;
int b = 1;
int Add(int left, int right)
{
return left + right;
}
struct Node
{
struct Node* next;
int data;
};
namespace nameee
{
int printf = 1;
}
}
- 加命名空间名称及作用域限定符
int main()
{
struct namee::Node N;
printf("%d\n", namee::a);
printf("%d\n", namee::Add(1,1));
printf("%d\n", namee::nameee::printf);
return 0;
}
- 使用using namespace 命名空间名称 展开
using namespce namee;
int main()
{
printf("%d\n", b);
Add(10, 20);
return 0;
}
这里的展开和头文件的展开不一样,这里是指在编译器默认查找时,先在局部域(自家菜地),接着到全局域(野地),后又会到命名空间域(张爷爷的菜地)去找。
这就有了展开命名空间的坏处------容易发生冲突,所以尽可能不要随意展开。
- 使用using将命名空间中某个成员引入
using namee::b;
//假设b经常被使用,a不经常使用
int main()
{
printf("%d\n", namee::a);
printf("%d\n", b);
printf("%d\n", b+1);
printf("%d\n", b+2);
return 0;
}
5.C++输入&输出
C++输入
#include<iostream>
using namespace std;
//要使用 cin 和 cout 就必须要加上以上两条语句
1.使用cout标准输出对象(控制台)和cin标准输入对象(键盘)时,必须包含< iostream >头文件以及按命名空间使用方法使用std。即+std的方式。
3.是<stdio.h>的进阶版,scanf和printf仍能使用。
4.<<是流插入运算符,>>是流提取运算符。可以简单理解为输出时使用<<,输入时使用>>。
5.endl是特殊的C++符号,表示换行输出,他们都包含在包含头文件中。换行还可以(‘\n’),且比endl快。
6.使用C++输入输出更方便,不需要像printf/scanf输入输出时那样,需要手动控制格式(%d、%c、%s)。C++的输入输出可以自动识别变量类型。
std命名空间的使用惯例:
std是C++标准库的命名空间,如何展开std使用更合理呢?
- 在日常练习中,建议直接using namespace std即可,这样就很方便。
- using namespace std展开,标准库就全部暴露出来了,如果我们定义跟库重名的类型/对
象/函数,就存在冲突问题。该问题在日常练习中很少出现,但是项目开发中代码较多、规模
大,就很容易出现。所以建议在项目开发中使用,像std::cout这样使用时指定命名空间 +
using std::cout展开常用的库对象/类型等方式。
1.cin >>
cin对空白字符的处理与scanf一致。即:跳过开头空白字符,遇到空白字符停止读取,且空白字符(包括换行符)残留在缓冲区。
不能用cin语句把空格字符和回车换行符作为字符输入给字符变量,它们将被跳过。
接受一个字符串,遇“空格”、“TAB”、“回车”都结束。
如果想将空格字符或回车换行符(或任何其他键盘上的字符)输入给字符变量,可以用一些函数,下面有讲。
一个cin语句可以分写成若干行。如 cin>>a>>b>>c>>d;
可以写成
cin>>a //注意行末尾无分号
>>b //这样写可能看起来清晰些
>>c
>>d;
也可以写成
cin>>a;
cin>>b;
cin>>c;
cin>>d;
以上3种情况均可以从键盘输入: 1(空格)2(空格)3(空格)4 ↙
也可以分多行输入数据:
1↙
2(空格)3↙
4↙
在用cin输入时,系统会根据变量的类型从输入流中提取相应长度的字节。
所以可以如下输入
char c1,c2;
int a;
float b;
cin>>c1>>c2>>a>>b;
在键盘上输入:1(空格)2(空格)34(空格)56.78↙
//cin >> a, b, c 这种写法错误
2.cin.get()
用法1: cin.get(字符变量名)可以用来接收字符
用法2:cin.get(字符数组名,接收字符数目)用来接收一行字符串(不能接收回车),可以接收空格
3.cin.getline() // 接受一个字符串,可以接收空格并输出
cin.getline()实际上有三个参数,cin.getline(接受字符串,接受个数,结束字符),当第三个参数省略时,系统默认为’\0’。当然,也可以是其他自定义字符。
4.getline() // 接受一个字符串,可以接收空格并输出,需包含string头文件
5.gets() // 接受一个字符串,可以接收空格并输出,需包含string头文件
6.getchar() //接受一个字符,需包含string头文件
getchar()是C语言的函数,C++也可以兼容,但是尽量不用或少用;
C++输出
一个cout语句可以分写成若干行。如 cout<<"This is a simple C++ program."<<endl;
可以写成
cout<<"This is " //注意行末尾无分号
<<"a C++ "
<<"program."
<<endl; //语句最后有分号
也可写成多个cout语句,即
cout<<"This is "; //语句末尾有分号
cout <<"a C++ ";
cout <<"program.";
cout<<endl;
以上3种情况的输出均为
This is a simple C++ program.
在用cout输出时,用户不必通知计算机按何种类型输出,系统会自动判别输出数据的类型,使输出的数据按相应的类型输出。
// cout << a,b,c;这种写法错误
进制输出
#include <iostream>
#include <iomanip>//新库
using namespace std;
int main(){
int i = 90;
cout << i << endl;
cout << dec << i << endl;//十进制(效果和默认一样)
cout << oct << i << endl;//八进制输出
cout << hex << i << endl;//十六进制输出(字母默认是小写字母)
cout << setiosflags(ios::uppercase);//将字母大写输出
cout << hex << i << endl;//十六进制输出(大写字母)
cout << setbase(8) << i << endl;
}
//结果:90 90 132 5a 5A 132
std::oct 、 std::dec 、 std::hex ,这三个控制符包含在库 < iostream > 中
setbase(n) 表示以 n 进制显示,包含在库 < iomanip > 中,n 只能取 8, 10, 16 三个值。
setiosflags(ios::uppercase) 表示将字母大写输出,包含在库 < iomanip > 中。
输出数字位数的控制
#include <iostream>
#include <iomanip>//新库
using namespace std;
int main(){
double i = 3333.1415926;
cout << i << endl;//3333.14(默认6位)
cout << setprecision(9) << i << endl;//3333.14159
cout << setiosflags(ios::fixed);
cout << i << endl;//3333.141592600这是因为double的精度比较高
cout << fixed << setprecision(3) << i << endl;//3333.142
cout << setprecision(9) << fixed << i << endl;//3333.141592600
}
可以看出,C++默认浮点数输出有效位数是 6 位
1.使用 setprecision(n) 即可设置浮点数输出的有效位数(若前面整数位数大于 n 位,使用科学计数法输出)
2.使用 setiosflags(ios::fixed) 或 fixed,表示对小数点后面数字的输出精度进行控制
所以,和 setprecision(n) 结合使用即可设置浮点数小数点后面数字的输出精度,位数不足的补零。
因为C++与C是兼容的,如果你感觉使用printf控制输出格式顺手的话没问题!
输入输出这里参考的博客:
https://blog.csdn.net/Dr_Myst/article/details/123164599
https://blog.csdn.net/qq_35481167/article/details/82792103(强制显示小数点和正负号、设置宽度和对齐方式)
https://www.cnblogs.com/shikamaru/p/5826117.html
6.缺省参数
6.1 缺省参数概念
缺省参数是声明或定义函数时为函数的参数指定一个缺省值(可以缺少、省略)。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。
void Func(int a = 0)
{
cout<<a<<endl;
}
int main()
{
Func(); // 没有传参时,使用参数的默认值
Func(10); // 传参时,使用指定的实参
return 0;
}
6.2 缺省参数分类
- 全缺省参数
void Func(int a = 10, int b = 20, int c = 30)
{
cout<<"a = "<<a<<endl;
cout<<"b = "<<b<<endl;
cout<<"c = "<<c<<endl;
}
int main()
{
Func(1,2,3);//1 2 3
Func(1,2);//1 2 30
Func(1);//1 20 30
Func();//10 20 30
Func(1, ,3)//这是错误的,必须顺序传,不能跳跃,与下面的半缺省参数必须从右往左依次来给出相协调、呼应。
}
- 半缺省参数
void Func(int a, int b = 10, int c = 20)
{
cout<<"a = "<<a<<endl;
cout<<"b = "<<b<<endl;
cout<<"c = "<<c<<endl;
}
- 半缺省参数必须从右往左依次来给出,不能间隔着给。就不能void Func(int a=10, int b = 10, int c )
- 缺省参数不能在函数声明和定义中同时出现。如果声明与定义位置同时出现,恰巧两个位置提供的值不同,那编译器就无法确定到底该用那个缺省值。
- 缺省值必须是常量或者全局变量
- C语言不支持(编译器不支持)
今天就到这了!
持续更新中…
有帮助的收藏一下吧!