目录
目录
前言
C++和C语言的不同
・文件后缀
・C语言是面向过程编程,C++则是面向对象编程
・头文件
・新增命名空间
・输入输出
补充:输入时需要注意的
・新的数据类型
补充:关于C++中的const
・空指针的声明
・函数思想
参考资料:
前言
学习C++之前 建议先学习C语言的知识。因为C++看似很多功能,都是用C语言来实现的。
熟练C语言之后对C++的学习有很大助力,并且某些硬件比如 Arduion 也是由C语言进行控制的。
作为计算机专业的学生,在大一开始也是从C语言入门的。但是学校并没有C++的课程。
想系统学习C++的我,机缘巧合之下报了顿开教育的C++全栈课程。没想到也是由C语言先开始教学,再进入C++。
C++和C语言的不同
学习C++之前,先了解一下C++与C语言的不同之处。
・文件后缀
C语言源文件的后缀为.c,C++源文件的后缀为.cpp
・C语言是面向过程编程,C++则是面向对象编程
・头文件
1.包含自己的头文件时不变
#include "xxx.h"
2.包含C语言标准库时的两种方法
#include保持原来方法不变
#include去掉“.h ”在最前加上“c”
3.包含C++标准库时不需要“.h”
#includeC++标准输入输出头文件(Input/Output Stream)
・新增命名空间
在C语言中同一个作用域下不允许定义相同标识符(变量名,函数名等)
而C++中引入了命名空间之后可以重复使用同一标识符,从而增加了标识符的使用率
#include基本创建空间方法 namespace NameList1{ int varA=1; void print(){ printf("variable in NameList1:%dn",varA); } } namespace NameList2{ int varA=1; void print(){ printf("variable in NameList2:%dn",varA); } }
通过上面的代码就可以通过不同的空间创建拥有相同名字的变量和函数了(叫空间中的成员或空间中的数据)
并且可以通过作用域分辨符“::”来使用他们
#include//基本创建空间方法 namespace NameList1 { int varA; void print() { printf("variable in NameList1:%dn", varA); } } namespace NameList2 { int varA=2; void print() { printf("variable in NameList2:%dn", varA); } } int main() { NameList1::varA = 1; NameList1::print(); NameList2::print(); return 0; }
输出:
variable in NameList1:1
variable in NameList2:2
如此可见,名字虽然相同,但是所在的空间不同。可以通过 作用域分辨符“::”来区分并访问它们。
而作用域分辨符“::”还有另一个作用就是可以区分全局变量。
#includeint Var = 2; int main() { int Var = 1; printf("%dn", Var); printf("%dn",::Var); return 0; }
输出:
1
2
并且可以知道,在没有作用域分辨符“::”的时候,输出变量时采用就近原则。
另外,可以通过“using namespace”来指定某个空间名从而省略使用作用域分辨符
...
int main() {
using namespace NameList1;
printf("%dn", varA);
return 0;
}
但是使用两次 “using namespace”来指定两个不同空间名时会出现二义性问题,导致程序报错。
因为“using namespace”的作用域为此代码开始到所在函数结束,并不会被第二个“using namespace”断开。
错误代码:
...
int main() {
using namespace NameList1;
printf("%dn", varA);
using namespace NameList2;
printf("%dn", varA);
return 0;
}
错误代码
此时需要用 作用域分辨符“::” 来进行区分来避免二义性
正确代码:
...
int main() {
using namespace NameList1;
printf("%dn", varA);
printf("%dn", NameList2::varA);
return 0;
}
正确代码
此外,命名规则还能进行嵌套(剥洋葱)
...
namespace A {
int aa = 10;
namespace B {
int bb = 100;
}
}
int main() {
printf("%dn", A::aa);
printf("%dn", A::B::bb);
using namespace A::B;
printf("%dn", bb);
using namespace A;
printf("%dn", aa);
printf("%dn", B::bb);
printf("%dn", bb);
return 0;
}
输出:
10
100
100
10
100
100
・输入输出
使用
而需要强制类型转换时只需在变量名前加上括号或者给变量名加上括号进行。
"ednl" 用来进行换行
#includeint main(){ using namespace std; cout << "ILoveyoun"; char str[] = "ILoveyoun"; cout << str; int a = 1; float b = 1.1; cout << a; cout << b; cout << "n"; cout << a << "t" << (int)b << "n"; cout << a << "t" << int(b) << "n"; //即使是输入用变量也要有初始化的习惯 int iNum = 0; float fNum = 0.0f; //unsigned int uNum = 1u; //long int lNum = 1L; cout << "请输入一个整数,一个浮点数,一个字符串:"; cin >> iNum >> fNum >> str; cout << iNum << "t" << fNum << "t" << str << endl; return 0; }
在开头一遍会输入“using namespace std” ,因为cout 和 cin 在常用库内的命名空间std里有定义。
如果不使用,则需要 std::cout 和 std::cin 来访问
补充:输入时需要注意的
c++的“cin”和c的“sacnf”一样,会判断输入缓存区中是否有空格,空格为输入数据读取的结束。
接受空格的输入:
char str[10]=""; //C gets_s(str,10); //C++ cin.getline(str,10); cout.write(str,10);
另外缓冲区可以通过
while(getchar()!=n);
来清除
・新的数据类型
bool类型:占用一个字节
非零表示成立,0或者指针空表示不成立
#includeusing namespace std; void testBool() { bool bNum = 1234; cout << bNum << endl; bNum = -1; cout << bNum << endl; bNum = false; cout << bNum << endl; bNum = true; cout << bNum << endl; //boolalpha 用true和false方式打印bool类型 cout << boolalpha << bNum << endl; }
输出:
1
1
0
1
true
引用类型:给变量起别名,可以通过别名直接调用原变量
...
int main() {
int A = 1;
int B = 2;
int& quoteA = A;
int& quoteB = B;
cout << quoteA << quoteB << endl;
}
常见用法,两数交换时可以不用像麻烦的指针那样进行操作,形参变成了实参,可以直接对其进行更改
...
void swap(int& quoteA, int& quoteB) {
int c = quoteA;
quoteA = quoteB;
quoteB = c;
}
int main() {
int A = 1;
int B = 2;
cout << A << B << endl;
swap(A, B);
cout << A << B << endl;
}
输出:
12
21
常引用:需要const修饰,引用时无法通过别名对被引用对象进行修改
右值引用: 提供一个修改常量的接口(例如输入本金得到利息的计算结果)
...
void printRightValue(int&& a){
a+=11;
cout<
常引用和右值引用的区别:右值引用不能给左值起别名
int aa=1; const int& x=aa; int&& xx=aa;//错误
引用的用处
函数参数(防止拷贝产生)
函数返回值(增加左值使用),一般返回全局变量的引用,无法返回局部变量
auto类型:根据赋值的数据,自动推断其类型(需要赋值)
与C语言auto的区别:在C++中淘汰了C语言的用法,只有自动推断用法
补充:关于C++中的const
字符串常量传递给函数时,形参必须用const修饰
常量起别名时需要const来修饰
・空指针的声明
nullptr 而不是 NULL,其实都可以,但是建议用nullptr
int* p = nullptr; char* pc = NULL;
・函数思想
内联函数:
inline,短小精悍的函数可以为内联函数
inline int Max(int a,int b){
return a>b ? a : b;
}
在结构体中或者类中实现的函数默认内联
函数重载:
C++允许同名不同参数函数存在
不同参数的定义:参数数目不同,参数类型不同,参数顺序不同(前提类型不同)
void print(int a) //算
{
cout << a << endl;
}
void print(int a, int b) //算
{
cout << a + b << endl;
}
void print(int b, int a) //不算
{
cout << a + b << endl;
}
void print(int a, char b) //算
{
cout << "int,char" << endl;
cout << a + b << endl;
}
void print(char a, int b) //算
{
cout << a + b << endl;
}
重载优先调用类型一致的函数,若没有则优先左边参数匹配
...
void print(char a, int b);
void print(int a, int b);
int main() {
print(1,'A');
return 0;
}
void print(int a, int b)
{
cout << a + b << endl;
}
void print(char a, int b)
{
cout << "char,int" << endl;
cout << a + b << endl;
}
输出:
66
函数缺省:(重载的综合写法)
C++中允许给函数形参初始化
缺省顺序 必须从右往左缺省,缺省的参数中间不能存在没有缺省的
没有传入参数,使用的是默认值
传入参数必须从左往右满足
...
void printData(int a=1, int b=2, int c=3, int d=4)
{
cout << a + b + c + d << endl;
}
int main()
{
printData(); //a=1 b=2 c=3 d=4
printData(10); //a=10 b=2 c=3 d=4
printData(10, 20); //a=10 b=20 c=3 d=4
printData(10, 20, 30); //a=10 b=20 c=30 d=4
printData(10, 20, 30, 40);//a=10 b=20 c=3 d=40
return 0;
}
输出:
疑惑点:10
19
37
64
100
常引用的本质是什么
参考资料:
基于 顿开教育 莫影老师 C++课程第一课 笔记整理



