24.6.29学习目录
一.作用域
::用于解决归属问题
1.1 可用于全局和局部名字冲突时
using namespace std;
int a = 10;
void main()
{
int a = 20;
cout<<a<<endl;//局部变量20
cout<<::a;//访问的时全局变量10
}
1.2 用于表示标识符的归属
namespace A
{
int a = 10;
}
namespace B
{
int a = 20;
}
void test()
{
cout<<A::a<<endl;//10
cout<<B::a;//20
}
二.命名空间
命名空间用于解决标识符命名的冲突,控制其作用域:关键词为namespace
1.命名空间的使用语法
1.1 命名空间定义在全局范围
namespace A
{
int a = 10;
}
namespace B
{
int a = 20;
}
void test()
{
}
1.2 命名空间可以嵌套
namespace A
{
int a = 10;
namespace B
{
int a = 20;
}
}
void test()
{
cout<<A::a<<endl;//10
cout<<A::B::a;//20
}
1.3 命名空间可以随时添加成员
namespace A
{
int a = 10;
}
namespace A
{
void func()
{
cout<<"hello"<<endl;
}
}
void test()
{
cout<<A::a<<endl;
A::func();
}
1.4 声明和实现可以分离
但在实现时必须要把方法归属的命名空间写上
namespace Myspace
{
void func1();
void func2();
}
void Myspace::func1(){
cout<<"func1"<<endl;
}
void Myspace::func2(){
cout<<"func2"<<endl;
}
1.5 无名的命名空间
表示命名空间中的标识符只能在本文件内访问,相当于给标识符加上了static,使其可以作为内部连接
namespace
{
int a = 10;
void func1(){cout<<"func1"<<endl;};
}
void test(){
cout<<a<<endl;
func();
}
1.6 命名空间起别名
namespace LongName
{
int a = 10;
void func1(){cout<<"func1"<<endl;};
}
void test(){
namespace shortName = LongName;
cout<<shortName::a<<endl;//10
LongName::func1();
}
2.using声明
2.1 声明命名空间中的成员
namespace A
{
int a = 10;
int b = 20;
void func1(){cout<<"func1"<<endl;};
void func2(){cout<<"func2"<<endl;};
}
void test(){
using A::a;
using A::func1;
cout<<a<<endl;//10
func1();
//func2()//没有声明不可以直接访问
}
2.2 当成员函数有重载
using声明了所有的重载的函数
namespace A
{
void func1(){};
void func1(int x){};
void func1(int x,int y){};
}
void test()
{
using A::func1;
func1();
func1(10);
func1(10,20);
}
2.3 用using声明整个命名空间
namespace A
{
int a = 10;
int b = 20;
void func1(){cout<<"func1"<<endl;};
void func2(){cout<<"func2"<<endl;};
}
void test()
{
using namespace A;//只是阐述可用在命名空间A中寻找
a;
b;
func1();
func2();
int a = 20;//不会产生冲突
}
三.引用
相当于给变量取别名
- 变量一定要初始化
- 且不会对引用开辟新的空间
1.基本使用
1.1 变量的引用
void test()
{
int a = 10;
int &b = a;//&b和&a的地址指向同一个地方
}
1.2 数组的引用
int arr[5] = {1,2,3,4,5};
int (&myArr)[5] = arr;
1.3 指针变量的引用
int a = 10;
int *p = &a;
int* &myp = p;
1.4 函数的引用
void func(){
cout<<"func"<<endl;
}
void (&myfunc)() = func;
myfunc();
1.5 引用作为函数的参数
引用的常用方法,可用简化指针作为参数的方法
void func(int &x,int &y){
int tmp = x;
x = y;
y = tmp;
}
int main(){
int a = 10;
int b = 20;
func(a,b);
}
1.6 引用作为函数的返回值
不要返回局部变量,这会产生错误
int& func(int a){
a++;
return a;
}
int main(){
int a = 10;
int &b = func(a);
}
1.7 引用完成链式操作
struct A{
A& func(A &ob,int value){
cout<<value<<" ";
return ob;
}
};
void main(){
A ob1;
ob1.func(ob1,100).ob1.func(ob1,200).ob1.func(ob1,300)//100 200 300
}
1.8 常引用
当给常量取别名时,要加上const,因为常量是不可以改变的
const int &a = 10;
//int &a = 10;//这是错误的,常量是固定的,不会发生改变
作为函数的参数:防止函数内部改变外部的值
void printint(const int &a){
cout<<a;
}
四.内联函数
1.内联函数编写
内联函数在定义时需要添加上inline关键词,声明时不用添加关键词
int A(int x,int y);
int main(){
cout<<A(10,20);
}
inline int A(int x,int y){
return x + y;
}
内联函数:在编译阶段,将内联函数调用处替换为函数体,减少函数的开销。
2.宏函数和内联函数的联系与区别
- 宏函数在预处理阶段展开;内联函数是在编译阶段进行展开。都避免了函数调用的开销
- 宏函数的参数没有类型,不能保证参数的完整性;内联函数有参数的类型,保证参数的完整性。
- 宏函数没有作用域的限制;内联函数有作用域的限制,能作为命名空间、结构体、类和成员
3.注意事项
-
类中的成员函数默认都是内联函数(不加inline也是)
-
有时加上inline也不一定是内联函数(内联函数的条件)
- 不能存在任何形式的循环语句
- 不能存在过多的条件判断语句
- 函数体不能过于庞大
- 不能对函数取地址
-
内不内联是由编译器决定
五.extern “C”
c函数编译后和c++函数编译后函数名字不一样,当c++工程中需要调用c语言的函数时,编译时就会寻找不到。
为了防止这防止这种情况,就使用了extern "C"来保证函数名编译后相同。
工程中将其添加到头文件中
#include<stdio.h>
#if __cplusplus //判断是否为C++工程
extern "C"{
#endif
extern void func1();
extern int func2(int a);
#if __cplusplus
}
#endif