1.C++兼容C的语法
//C++兼容C的语法 //C语言版本hello world #include<stdio.h> int main() { printf("hello world\n"); return 0; } //C++版本hello world #include<iostream> using namespace std; int main() { cout << "hello world" << endl; return 0; }
2.using namespace std的作用:解决C语言中变量命名冲突的问题
2-1namespace的由来
#include<stdio.h> int main() { int scanf = 10;//对 int strlen = 20;//对 //C语言中标识符命名的两个点:1.不能以数字,下划线开头 2.不能和关键字名字一样(但可以是函数名) printf("%d", scanf);//对 printf("%d\n", strlen);//对 scanf("%d", &scanf);//错 //本意是第一个scanf用stdio.h里的库函数,第二个scanf用int类型的变量 //但是C语言的局部优先原则,这里的两个scanf都是int类型的变量,所以出错 //小结:如果我就是想要达成我的本意的这个目的,C语言明显做不到(有命名冲突的问题),所以C++就使用namespace命名空间域来完善C }
这是将int scanf=10;放在了局部,定义int scanf的时候还是可以的,但是在使用scanf("%d",&scanf);时出现错误;
但是如果将scanf放在全局,连定义 都不被允许。namespace的使用:
2-2namespace的使用:
#include<iostream> //定义的是一个命名空间域:(变量和函数构成) namespace song { //变量 int scanf = 1; int strlen = 2; //函数 int add(int a, int b) { return a + b; } } int main() { //默认访问的是先局部后全局(局部没有则采用局部的) printf("%x\n", scanf); printf("%x\n", strlen); //指定访问song命名空间域 printf("%x\n", song::scanf); printf("%x\n", song::strlen); printf("%d\n", song::add(10,20)); }
::是域作用限定符,限定是属于哪一个域的变量或者函数
常见的域有:局部域,全局域,命名空间域,类域
#include<iostream> //全局域 int a = 10; //命名空间域可以嵌套 namespace song { int a = 20; namespace huang { int a = 30; } namespace chen { int a = 40; } } //类域 class stu { public: int a = 50; }; int main() { printf("默认先局部后全局(局部没有,全局有):a=%d\n", a); printf("指定song命名空间域:a=%d\n", song::a); printf("指定song命名空间域里的haung命名空间域:%d\n", song::huang::a); printf("指定song命名空间域里的chen命名空间域:%d\n", song::chen::a); stu s; printf("类域:%d\n", s.a); return 0; }
备注:
- 同一个项目的不同文件里 可以使用相同名称的命名空间域,编译链接时会自动合并
- 但是在同一个域中不能定义相同的标识符
3.使用标准库或自己定义的命名空间里的东西的三种方式:
#include<iostream> int main() { //要使用标准库里的东西,有三种方式: //方式1:每一个都指定命名空间 //麻烦但是最标准 std::cout << "hello world1" << std::endl; //方式2:整个东西都在全局展开,一夜回到解放前 //方便,但是当我们自己定义的和标准库里的东西名字相同,发生命名冲突的时候就没办法解决了 using namespace std; cout << "hello world2" << endl; //方式3:折中办法,对于标准库中的部分常用进行展开 using std::cout; using std::endl; cout << "hello world3" << endl; return 0; }
给大家看看使用自己定义的东西也是有三种方式 :
4.C++中的输入和输出
cout现在讲不清楚,我们的储备知识还不够,先记住使用即可
//ostream 类型全局对象 cout //istream 类型全局变量 cin //endl 全局的换行符号 #include<iostream> using namespace std; int main() { int a = 0; cin >> a; //自动识别类型:原理就是函数重载和运算符重载 cout << a<< endl<< &a << endl; return 0; }
5.缺省参数(缺省==不省==写上==默认)
缺省参数是指在声明和定义函数的时候为函数的参数设定一个默认值,在函数调用的时候,如果没有指定实参则采用该默认值.(备胎)
5-1缺省参数的分类
#include<iostream> using namespace std; //缺省参数的分类 //1:全缺省 void test1(int a=10, int b=20, int c=30) { cout << a << endl; cout << b << endl; cout << c << endl << endl; } //2:半缺省 //部分缺省-必须从右往左连续缺省 void test2(int a , int b , int c =10) { cout << a << endl; cout << b << endl; cout << c << endl; } int main() { test1(1, 2, 3); test2(1, 2);//实参个数>=没缺省的参数个数 return 0; }
#include<iostream> typedef struct Stack { int* a; int size; int capacity; }Stack; //老版本: //void InitStack(Stack* ps) //{ // ps->a = (int*)malloc(sizeof(int) * 4); // ps->size = 0; // ps->capacity = 4; //} //新版本: void InitStack(Stack* ps, int capacity=4) { ps->a = (int*)malloc(sizeof(int) * capacity); ps->size = 0; ps->capacity = capacity; } int main() { //假设我知道栈内至少需要存100个数据 //如果现在将上面的capacity写成100,下面我ST2就没办法使用了 //如果现在将上面的capacity写成10,在这里就要扩容,扩容是有时间成本的 Stack ST1; //老版本:InitStack(&ST1); //新版本: InitStack(&ST1, 100);//传了,使用传的100 //假设我知道栈内至少需要存10个数据 Stack ST2; //老版本:InitStack(&ST2); InitStack(&ST2, 10);//传了,使用传的10 //假设我不知道栈内至少需要存多少个数据 Stack ST3; InitStack(&ST3);//不传,使用备用的4 return 0; }
备注: 缺省参数不能在函数声明和定义中同时出现,否则就会报错
最好是在声明时写缺省,也就是下面这样
void InitStack(Stack* ps, int capacity = 4);//声明缺省 int main() { //业务需求; return 0; } //新版本: void InitStack(Stack* ps, int capacity)//定义不缺省 { ps->a = (int*)malloc(sizeof(int) * capacity); ps->size = 0; ps->capacity = capacity; }
6. 函数重载
函数重载的定义:C++中支持两个函数名相同,但是函数的参数(参数的个数或者类型)要不同
- C语言中一个项目中不允许出现同名函数
- C++中的函数重载允许一个项目中出现同名函数
#include<iostream> using namespace std; int Add(int a, int b) { return a + b; } char Add(char a, char b) { return a + b; } double Add(double a, double b) { return a + b; } float Add(float a, float b) { return a + b; } int Add(int a, int b, int c) { return a + b + c; } int main() { cout << Add(1, 1) << endl; cout << Add('1', '1') << endl;//函数参数的类型构成重载 cout << Add(1.1, 1.1)<< endl;//函数参数的类型构成重载//!!!备注:如果没强转或者备注,1.1默认就是double类型 cout << Add((float)1.1, (float)1.1)<< endl;//函数参数的类型构成重载//强转 //cout << Add(1.1f, 1.1f)<< endl;//函数参数的类型构成重载//备注 cout << Add(1, 1, 1) << endl;//函数参数的个数构成重载 return 0; }
这样写简直是为难编译器了!!哈哈🐼
思考:难怪C语言为什么不写交换函数和排序函数的库函数,那是因为C语言不支持函数重载,要还得像qsort一样,一个一个字节地交换,但是这样很不方便。