namespace hello { int rand = 0; int time = 0; }
printf("%d\n",hello::rand);
using namespace hello;
把命名空间展开,相当于把这一层命名空间拿掉我们常常会看到这样一句代码using namespace std;
这句代码的意思是拿掉封C++库的命名空间
了解了命名空间之后,我们就要学习命名空间的运用,有以下代码,我们应该怎么使用他的命名空间呢?
namespace N
{
int a = 10;
int b = 20;
int Add(int left, int right)
{
return left + right;
}
int Sub(int left, int right)
{
return left - right;
}
}
int main()
{
printf("%d\n", a); // 该语句编译出错,无法识别a
return 0;
}
int main()
{
printf("%d\n", N::a);
return 0;
}
using N::b;
int main()
{
printf("%d\n", N::a);
printf("%d\n", b);
return 0;
}
using namespce N;
int main()
{
printf("%d\n", N::a);
printf("%d\n", b);
Add(10, 20);
return 0;
}
1、cin>> (流提取运算符) 相当于C语言的输入printf
2、cout<< (流插入运算符)相当于C语言的输出scanf
1、缺省参数是声明或定义函数时为函数的参数(形参位置)指定一个默认值。在调用该函数时,如果没有指定实参则采用该默认值,否则使用指定的实参
2、缺省分为全缺省和半缺省,半缺省必须从右往左缺省
//全缺省
void TestFunc(int a = 10, int b = 20, int c = 30)
{
cout<<"a = "<<a<<endl;
cout<<"b = "<<b<<endl;
cout<<"c = "<<c<<endl;
}
半缺省
void TestFunc(int a, int b = 10, int c = 20)
{
cout<<"a = "<<a<<endl;
cout<<"b = "<<b<<endl;
cout<<"c = "<<c<<endl;
}
3、缺省参数不能在声明和定义中同时出现,会产生歧义,只能在声明的时候给
C++支持同名函数,有两个前提
1、要求参数名相同
2、参数不同:参数个数 / 类型 / 顺序(顺序指的是不同类型的形参的顺序),至少有一个不同
3、返回值类型不同不构成重载,因为使用的时候无法区分要调用的是谁
4、C++重载时会进行函数名修饰:_Z+函数名长度+函数名+类型首字母
5、extern "C"的作用是告诉编译器,extern "C"声明的函数,是C语言的库,要用C语言的方式去调用链接
1、预处理:头文件展开、宏替换、条件编译(ifdef 等)、去掉注释、生成test.i文件
2、编译:检查语法,生成汇编代码(有语法错误就是在这一步检查出来的)、生成test.s文件
3、汇编:把汇编代码转换成二进制的机器码、生成test.o文件
4、链接:找调用函数的地址,链接对应上,合并到一起、生成a.out文件
1、引用就是给一个变量取另外一个名字,不会开辟新的内存空间
2、引用的写法
3、引用必须在定义的时候初始化
4、引用一旦引用了一个实体,就不能再有其他实体
5、取别名原则:对原引用变量,读写权限只能缩小,不能放大
int main()
{
int a = 10;
int& b = a;//b就是a的另外一个名字
//取别名原则:对原引用变量,权限只能缩小,不能放大
const int x = 20;
int&y = x;//权限放大
const int&y = x;//权限不变
int c = 10;
const int&d = c;//权限缩小
return 0;
}
6、const对引用的影响
int main()
{
int a = 10;
int& b = a;
const int& c = 20;
double d = 2.2;
int f = d;//不同类型的赋值会发生隐式类型转化,产生临时变量,临时变量具有常性
const int& e = d;//用const的修饰引用,表示此引用只有读权限没有写权限,权限不变
//所以const int& e可以变成double类型的d的别名
//这时候e不是d的别名,是 临时变量 的别名
return 0;
}
1、引用的第一个作用就是做参数,可以在函数的形参位置使用引用,这样的好处是方便理解,同时也能提高代码的效率:下面是传值参数和传引用参数效率的比较
1、引用概念上定义一个变量的别名,指针存储一个变量的地址
2、引用在定义的时候必须初始化,指针没有要求
3、引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以再任何时候指向任何一个同类型的实体
4、没有NULL引用,但是有NULL指针
5、在sizeof中含义不同:引用结果为“引用类型的大小”,但指针始终是地址空间所占字节个数(32位平台下占4个字节)
6、引用自加即引用的实体+1,指针自加即指针向后偏移一个类型的大小
7、有多级指针但是没有多级引用
8、访问实体方式不同,指针需要解引用,引用通过编译器自身处理
9、引用比指针使用起来相对更安全
10、注:从语法层面而言引用是取别名,没有开额外空间,指针是存储地址,开了4/8byte的空间;但从底层来看,他们是用一样的方式实现的,他们直接的差别就像耐克鞋子和莆田鞋子一样,其实都是一个厂子里生产出来的,本质上鞋的模样和品质都是一样的,但是一个就是有牌子,另一个就是假鞋
1、在反复使用的简短函数前面加上inline,就会使它变成内联函数
2、内联函数的作用是提高函数的使用效率,让函数能够直接展开,而不用反复构建函数栈帧,效果类似于宏
3、和宏定义相比,内联函数解决了宏函数晦涩难懂,容易写错的问题
4、内联函数比宏的优点更在于,内联函数支持调试,而宏不支持调试
1、验证自己的宏定义写的是否正确,最好的方法就是调用替换一下
#define ADD(X,Y) ((X)+(Y))
int main()
{
//下面是几种常见的宏替换的场景
ADD(1,2);//第一种
if(ADD(1,2))//第二种
{}
ADD(1 & 2,3 | 4);//第三种
ADD(1,2)*4;//第四种
}
#include
#include
#include
using namespace std;
int TestAuto()
{
return 10;
}
int main()
{
const int a = 10;
auto b = &a;//auto b的类型是编译器推导的右边变量的类型(这个auto的类型是const int*)
auto c = 'a';
auto d = TestAuto();
cout << typeid(c).name() << endl;//打印变量类型的函数typeid
cout << typeid(d).name() << endl;
return 0;
}
int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9};
TestFor(array);
for (int i = 0; i < sizeof(array) / sizeof(int); ++i)
{
array[i] *= 2;
}
for (int i = 0; i < sizeof(array) / sizeof(int); ++i)
{
cout << array[i] << " ";
}
cout << endl;
//范围for循环
// 依次自动取array中的数据,赋值给e,自动判断结束
for (auto& e : array)//加上引用,此时e就是array的别名,可以直接修改到array的元素
{
e /= 2;
}
for (auto x : array)//范围for,效果与上面int写的for循环作用相同,可以遍历array数组
{
cout << x << " ";
}
cout << endl;
return 0;
}