网站建设管理系统,做的网站如何被百度搜到,模板网站更改,做哪个视频网站赚钱的一#xff1a;命名空间#xff1a;namespace
#xff08;一#xff09;#xff1a;命名空间的定义
注#xff1a;命名空间只能定义在全局#xff0c;不能定义在函数内部。
#xff08;1#xff09;类似于C语言的结构体#xff0c;C语言的命名空间定义为#xff1…一命名空间namespace
一命名空间的定义
注命名空间只能定义在全局不能定义在函数内部。
1类似于C语言的结构体C语言的命名空间定义为
namespace name{ // name是命名空间的名字
//
}
2命名空间里成员可以是变量/函数/自定义类型变量/类等。
namespace xs {int age;char name[10];int ID;struct xs{int height;char* hobies;};void swap(int* num1,int*num2){int tmp *num1;*num1 *num2;*num2 tmp;}
};
3命名空间可以嵌套定义
namespace xs {int age;char name[10];int ID;struct xs{int height;char* hobies;};void swap(int* num1,int*num2){int tmp *num1;*num1 *num2;*num2 tmp;}// 嵌套一个老师的命名空间namespace teacher {char* subject;int work_year;char* name;}
};
4在不同文件中定义同一个名字相同的命名空间会被编译器识别为同一个命名空间
例如同一个项目中分别有两个.cpp文件两个文件都有xs这命名空间在编译的时候不会报错编译器会将他们识别为同一个命名空间。
5C的标准库的命名空间是std(standard). 二命名空间的使用
我们在命名空间中定义了变量函数类或者结构体等如果我们没有解析命名空间像C语言一样使用命名空间的对象和方法时会报错
namespace xs {int age;char name[10];int ID;struct xs{int height;char* hobies;};void swap(int* num1,int*num2){int tmp *num1;*num1 *num2;*num2 tmp;}namespace teacher {char* subject;int work_year;char* name;}
};int main()
{int a 1;int b 2;swap(a, b);return 0;
}在使用命名空间域内定义的变量的时候有以下几种方法
1指定命名空间访问
:: 符号被称为作用域解析运算符
#include stdio.hnamespace xs {int age;char name[10];int ID;struct xs{int height;char* hobies;};void swap(int* num1,int*num2){int tmp *num1;*num1 *num2;*num2 tmp;}namespace teacher {char* subject;int work_year;char* name;}
};int main()
{int a 1;int b 2;// 这里指定xs这个命名空间域xs::swap(a, b);printf(a %d \nb %d, a, b);return 0;
}
2使用using关键字将命名空间中的某个成员展开
#include stdio.hnamespace xs {int age;char name[10];int ID;struct xs{int height;char* hobies;};void swap(int* num1,int*num2){int tmp *num1;*num1 *num2;*num2 tmp;}namespace teacher {char* subject;int work_year;char* name;}
};// 展开xs中的swap函数
using xs::swap;
int main()
{int a 1;int b 2;// 这里我们去掉xs::不会报错swap(a, b);printf(a %d \nb %d, a, b);return 0;
}3使用using关键字展开命名空间中的全部成员这种方式容易产生命名冲突等问题
#include stdio.hnamespace xs {int age 10;char name[10] 小明;int ID;struct _xs{int height;char* hobies;};void swap(int* num1,int*num2){int tmp *num1;*num1 *num2;*num2 tmp;}namespace _teacher {char* subject;int work_year;char* name;}
};// 展开命名空间中的全部成员,可以不用域解析::就可以随便访问命名空间内的所有成员了
using namespace xs;
int main()
{printf(age:%d\n name:%s, age, name);return 0;
}三为什么要使用命名空间
1.解决C语言命名冲突问题
2.命名空间的本质是开出一个独立的域空间C中域有函数局部域全局域命名空间域类域域影响的是编译时语法查找⼀个变量/函数/类型出处(声明或定义)的逻辑所以有了域隔离名字冲突就解决了。局部域和全局域除了会影响编译查找逻辑还会影响变量的⽣命周期命名空间域和类域不影响变量⽣命周期。
二输入输出cout / cin
说明cout和cin是c的标准输入输出类的对象他们是标准库iostream中定义的用于窄字符narrowcharacters(oftypechar)的输入输出。
1同C语言相比cout和cin不需要格式化他们支持任意类型的输入输出会自动将其他类型转换成字符串类型
2cout/cin/换行endl等都被定义于C标准库iostream因为C标准库都放在std(standard)的命名空间中所以使用的时候要解析命名空间。
3有些编译器iostream会间接包含printf和scanf函数也就是说不包含stdio.h头文件也可以使用这两函数。
#include iostreamusing namespace std;int main()
{int age;char name[10];cin age name;// 这里没有包含stdio.hprintf也可以正常使用printf(age:%d\tname:%s\n, age, name);cout age endl;cout name endl;return 0;
}
三缺省参数
定义在定义函数的时候给予参数一个默认的缺省值。
1半缺省全缺省。
半缺省部分形参给予默认值。C规定半缺省参数必须从右往左依次连续缺省不能间隔跳跃给缺省值。
全缺省全部形参给予默认值。
2带缺省参数的函数调⽤C规定必须从左到右依次给实参不能跳跃给实参。
3含缺省参数的函数调用的时候没有传参使用默认值传参使用传递值。
#include iostream// 半缺省
int Add1(int b, int c, int a 0)
{return a b c;
}// 全缺省
int Add2(int a 0, int b 0)
{return a b;
}using namespace std;int main()
{int n1 2;int n2 3;cout Add1(n1,n2) endl;// 全缺省的cout Add2() endl;return 0;
}
4函数声明和定义分离时缺省参数不能在函数声明和定义中同时出现规定必须函数声明给缺省值。
我们将.c文件的两个函数声明放到,h文件.c文件依然给缺省值 编译器报错 所以应该将.c文件中的缺省参数去掉
四内联函数inline
使用inline关键字修饰的函数被调用时会在调用处将函数定义展开
1加上inline的函数如果函数代码较多或者是递归编译器会忽视不展开代码。
2使用inline的本质是替换函数调用提高程序执行的效率因为函数调用需要建立函数栈帧开辟空间等消耗可以平替C语言的宏。
3inline不建议声明和定义分离到两个⽂件分离会导致链接错误。因为inline被展开就没有函数地址链接时会出现报错
使用inline直接在函数的前面加个inline就可以了。
inline int add(int a, int b)
{return a b;
}
五函数重载
函数重载即同名函数提现了类的多态行为。
满足函数重载的条件
1.函数的形参不同
2.函数的参数个数不同
3.形参的类型不同
4.形参类型顺序不同
// 函数的形参不同以及形参个数不同
int add(int a, int b,int c 1)
{return a b;
}
double add(double a, double b, int c 1)
{return a b c;
}// 形参不同和形参类型顺序不同
void func(char c, int n)
{cout c n endl;printf(形参不同\n);}void func(int n, char c)
{cout c n endl;printf(形参类型顺序不同\n);
}int main()
{// 名字一样调用的是两个函数func(a, 4);func(4, a);cout add(1, 2) endl;cout add(1.0, 2.0, 3) endl;return 0;
} 但是返回值不同不可以 六引用
一引用的定义和特性
1引用就是给一个对象起别名不开辟内存空间。
其基本格式为类型 引⽤别名 引⽤对象; 这里的不是取地址
#include iostream
using namespace std;int main()
{int a 0;int c 5;int ra a;int rc c;// 对引用进行ra;rc;cout ra后a: a endl;cout rc后c: c endl;cout ra的地址为 ra endl;cout a的地址为 a endl;cout rc的地址为 rc endl;cout c的地址为 c endl;return 0;
} 2引用定义的时候必须要初始化看吧。 3⼀个变量可以有多个引⽤跟一个人有多个绰号差不多
#include iostream
using namespace std;int main()
{int a 0;int c 5;int ra a;int rra a;int rc c;return 0;
}
4引⽤⼀旦引⽤⼀个实体再不能引⽤其他实体
5引用可以引用引用;
int a 0;int ra a;// 这样是可以的
int rra ra;
二引用的使用
1引⽤在实践中主要是于引⽤传参和引⽤做返回值中减少拷⻉提⾼效率和改变引⽤对象时同时改变被引⽤对象
例如在函数传参的时候
void fun(int x)
{x;
}int main()
{int a 0;fun(a);// 这里相当于将a取了一个别名然后函数里面根据这个别名找到对应的对象进行运算cout a endl;return 0;
}
三const修饰引用
1const修饰引用可以使权限缩小但是不能使权限放大当然const修饰的应用对象是不能被修改的。
// 定义一个变量
const int a 8;// 权限放大不允许会报错的
int ra a;// 权限平替这样可以
const int ra a;int b 0;
// 权限缩小
int rb b;
// 不允许
rb;
// 允许
b;// 权限缩小只是缩小引用的权限缩小而不会影响引用的对象的权限。2引用可以引用临时对象
临时对象在程序运行中产生的用于转换的值或者其他对象例如类型转换函数传参函数传参是临时拷贝传地址就不会产生临时对象。这期间就会产生临时对象。
临时对象具有常性
void fun(int x)
{x;
}void fun2(int x)
{int rx x;x;cout rx endl; // 这输出3
}int main()
{int a 0;fun(a);// 这里相当于将a取了一个别名然后函数里面根据这个别名找到对应的对象进行运算cout a endl;const int n 2;int rn n;n; // 这里不允许// 这里int向double转换的时候产生了临时变量权限被放大了。const double rm n * 3;// n是const修饰的变量传递给函数传递的是它的一份临时拷贝fun2(n);cout rm endl; // 这里输出6return 0;
}
四指针和引用的区别
1指针需要开辟空间指针变量存储的是空间的地址。引用不需要开空间他是所引用对象的另一个别名。 2引用定义的时候就必须要初始化指针可以不用
int r;// 指针不初始化没问题编译器不会初始化但是这样就成了野指针不建议这样搞
int* ptr;
3指针容易出现空指针和野指针引用不容易出现空引用引用比指针更安全。
空引用 4引⽤可以直接访问指向对象指针需要解引⽤才是访问指向对象。
5引⽤在初始化时引⽤⼀个对象后就不能再引⽤其他对象⽽指针可以在不断地改变指向对象。
int main()
{int a 0;int b a;int d 5;b d;int* p a;cout p endl;p d;cout p endl;cout a和b的地址 endl;cout a endl;cout b endl;return 0;
} 6sizeof中含义不同引⽤结果为引⽤类型的⼤⼩但指针始终是地址空间所占字节个数(32位平台下占4个字节64位下是8byte)
七nullptr和NULL的区别
NULL在C中被定义为了宏0容易导致和整型的0混淆使用而nullptr不会出现这种情况C语言支持NULL不支持nullptr。C都支持。
int main()
{// 这里明着给int类型的a赋值指针但是没报错int a NULL;printf(%d, a);return 0;
}