目录
1.不同版本的hello word!
2.namespace和::域作用限定符以及using
2.1 namespace
2.2::
2.3using用于展开域
3.C++输入和输出
4.缺省参数
5.重载
6.引用
1.不同版本的hello word!
还记得第一次写C语言的hello word吗
//text.c
#include<stdio.h>
int main()
{
printf("hello word!\n");
return 0;
}
这是C++版的
//text.cpp
#include<iostream>
using namespace std;
int main()
{
cout << "hello word! \n" << endl;
return 0;
}
C++ 诞生于c之后,c++兼容了c,我们重点了解c++中不同于c的部分
2.namespace和::域作用限定符以及using
定义命名空间,需要用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}中即为命名空间的成员。命名空间可以定义变量/函数/类型等。
2.1 namespace
namespace bit
{
//定义变量
int rand=10;//定义函数
int Add ( int a , int b )
{
return a +b ;
}//定义类型
struct Node
{
struct Node* next;
int val;
};}
2.2::
调用域下面的变量/函数等
bit ::rand
- namespace本质是定义了一个域,这个域跟全局域各自独立,不同的域可以定义同名变量,所以下面的rand不存在冲突了
namespace text1 {
int rand = 0;
}
namespace text2 {
int rand = 10;
}
C++中域有函数局部域,全局域,类域;域影响的是编译时语法查找一个变量/函数/类型出处(声明或定义)的逻辑,所以有了域隔离,名字冲突就解决了。局部域和全局域除了会影响编译查找逻辑,还会影响变量的声明周期,命名空间域和类域不影响变量声明周期。
//text.cpp
#include<iostream>
using namespace std;
namespace bit
{
int rand;
int a = 2;
int Fun(float c, float d)
{
return c * d;
}
}
int Fun(int c ,int d )
{
return c + d;
}
int a = 1;
int main()
{
int a = 0;
printf("%d\n", a);
// a没有被域限定 代码从上往下走,main 函数下被重新赋值 a=0,所以输出0
printf("%d\n", ::a);
//a被::域限定符限定,但左边没有元素,默认为全局域,a=1所以输出1
printf("%d\n", bit::a);
//a被::域限定符限定,左边有域名,限定在自定义的域,在bit域中a=2,所以输出2
printf("%d\n",Fun(1,2));
// a没有被域限定 代码从上往下走,找到自定义函数Fun调用Fun实现相加,输出3
printf("%d\n", ::Fun(1, 2));
//a虽然有域限定符,但是并没有限定范围,还是全局域找到Fun实现相加,输出3
printf("%d\n", bit::Fun(1,2));
//a被::域限定符限定,左边有域名,限定在自定义的域,在bit域中找到Fun实现相乘,输出2
}
验证答案
namespace只能定义在全局,当然他还可以嵌套定义
//text.cpp
#include<iostream>
using namespace std;
namespace bit
{
int rand;
namespace aa
{
int rand=1;
}
namespace bb
{
int rand=0;
}
}
int a = 1;
int main()
{
printf("%d\n", bit::aa::rand);
printf("%d\n", bit::bb::rand);
return 0;
}
项目工程中多个文件中定义的同名namespace会认为是一个namespace,不会冲突
C++标准库都放在一个叫std(stdndard)的命名空间中
2.3using用于展开域
using namespace std;
//展开std头文件
using namespace bit::rand;
//展开bit中的rand
一般日常练习中我们可以using namespace std,世纪项目开发中不建议using namespace
3.C++输入和输出
- <iostream>是Input Output Stream 的缩写,是标准的输入,输出流库,定义了标准的输入,输出对象
- std::cin是ostream类的对象,他主要面向窄字符(narrow character (of type char))的标准输入流
- std::cout是ostream类的对象,它主要面向窄字符的标准输出流
- std::endl 是一个函数,流插入输出流,相当于插入一个换行字符加刷新缓冲区
- <<是流插入运算符,>>是流提取运算符(c语言中的左移右移操作符)
- 使用C++输入输出更方便,不要像printf/scanf输入输出那样,需要手动指定格式,C++的输入输出可以自动识别变量类型(本质是痛过重载实现的),其实最重要的是C++的流能更好的支持只定义类型对象的输入和输出。
//text.cpp
#include<iostream>
using namespace std;
int main()
{
int i = 123;
int j = 234;
int x;
int y;
cin >> x >> y;
//控制台手动输入x,y
cout << i << j << endl;
//输出i和j并且最后换行
return 0;
}
但是一对<< <<内只能有一个变量,否则编译器报错
在c++中我们没有包含<stdio.h>,也可以使用printf和scanf,在包含<iostream>间接包含了。vs编译器是这样的,但其他编译器会报错
4.缺省参数
- 缺省参数是声明或定义函数时为函数指定一个确实值,在调用该函数时,如果没有指定实参则采用改形式参数的缺省值,否则使用指定的实参,缺省参数分为全缺省和半缺省参数 全缺省就是全部形参给缺省值,半缺省就是部分形参给缺省值。C++规定半缺省必须从右往左依次连续缺省,不能间隔条约给缺省值
- 函数声明和定义分离时,缺省参数不能在函数声明和定义中同时出现,规定必须函数声明给缺省值
//text.cpp
#include<iostream>
using namespace std;
//全缺省
void Fun1(int a=10,int b=20,int c=30)
{
cout << "全缺省" << endl;
cout << "a=" << a << endl;
cout << "b=" << b << endl;
cout << "c=" << c << endl;
}
//半缺省
void Fun2( int a ,int b=10 ,int c=20)
{
cout << "半缺省" << endl;
cout << "a=" << a << endl;
cout << "b=" << b << endl;
cout << "c=" << c << endl;
}
void Fun3(int a, int b, int c)
{
cout << "普通" << endl;
cout << "a=" << a << endl;
cout << "b=" << b << endl;
cout << "c=" << c << endl;
}
int main()
{
Fun1();//没有传参时,使用参数的默认值
Fun2(10);//传参时,使用的指定值
Fun3(10,20,30);//传入指定值
return 0;
}
5.重载
C++支持在同一作用域中出现同名函数,但是要求这些同名函数的形参不同,可以是参数个数不同或则类型不同。这样C++函数调用就表现出了多态行为,使用更加灵活。C语言是不支持同一作用域中出现同名函数的。
//text.cpp
#include<iostream>
using namespace std;
//1.参数类型不同
int Add(int a, int b)
{
cout << "int Add(int a, int b)" << endl;
return a + b;
}
double Add(double a, double b)
{
cout << "double Add(double a, double b)" << endl;
return a + b;
}
//2.参数个数不同
int Add(int a)
{
cout << "int Add(int a)" << endl;
return a;
}
double Add(double a, double b)
{
cout << "double Add(double a, double b)" << endl;
return a + b;
}
//3.参数类型顺序不同
void fun(int a, char b)
{
cout << "void fun(int a, char b)" << endl;
}
void fun(char b, int a)
{
cout << "void fun(char a, int b)" << endl;
}
int main()
{
cout << "参数类型不同" << endl;
cout << Add(3,5)<< endl;
cout << Add(3.1,5.0) << endl;
cout << "参数个数不同" << endl;
cout << Add(3) << endl;
cout << Add(3.1, 5.0) << endl;
cout << "参数类型顺序不同" << endl;
fun(3, "x");
fun("x", 5);
return 0;
}
注意:返回值不能作为判断是否重载的依据因为容易产生歧义,如下面的代码f()调用
//text.cpp
#include<iostream>
using namespace std;
void f()
{
cout<<"f()<<endl;
}
void f(int a=10)
{
cout<<"f(int a=20)"<<endl;
}
int main()
{
f();
return 0;
}
6.引用
引用不是新定义一个变量,而是给已存在变量去了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间
类型&引用别名=引用对象;
//text.cpp
#include<iostream>
using namespace std;
int main()
{
int a = 0;
//引用:b和c是a的别名
cout << "a=" << a <<" " << &a << endl;
int &b = a;
cout << "b=" << b <<" " << &b << endl;
int& c = a;
cout << "c=" << c << " " << &c << endl;
//也可以给b取别名,d还是相当于a的别名
int& d = a;
cout << "d=" << d<< " " << &d << endl;
return 0;
}
值一样,地址也一样
传统的交换函数
void Swap(int* x,int* y)
{
int tem=x;
*y=*x;
*x=tem;
}
现在只要传引用就能解决
void Swap(int& rx,int&ry)
{
int tem=rx;
rx=ry;
ry=tem;
}