本专栏目的
前言
思维导图如下
C语言和C++语言都提供了枚举类型,两者是有一定区别。
有如下定义:
enum SHAPE {CIRCLE,RECT,LINE,POINT};
enum WEEK {MON,TUE,WED,THI,FIR,SAT,SUN};
允许非枚举值赋值给枚举类型,允许其他枚举类型的值赋值给另一个枚举类型
enum WEEK today = 3; //正确
today = CIRCLE; //正确
枚举具有外层作用域,容易造成名字冲突(在不同作用域不会冲突,但是遵循就近原则,访问不到外层作用域的枚举)
enum OTHER { RECT };//error C2365: “RECT”: 重定义;以前的定义是“枚举数”
int RECT = 12; //同上
if (CIRCLE == MON)
{
printf("oh.yes");
}
enum WEEK today = 3; //错误 error C2440: “初始化”: 无法从“int”转换为“main::WEEK”
today = CIRCLE; //错误 error C2440: “=”: 无法从“main::SHAPE”转换为“main::WEEK”
enum OTHER { RECT }; //错误 error C2365: “RECT”: 重定义;以前的定义是“枚举数”
int RECT = 12; //错误同上 但是可以通过枚举名访问指定的枚举属性
OTHER::RECT; //正确
if (CIRCLE == MON)
{
cout<<"oh.yes";
}
enum class SHAPE {CIRCLE,RECT,LINE,POINT};
enum class WEEK {MON,TUE,WED,THI,FIR,SAT,SUN};
cout<<SHAPCE::RECT<<endl; //输出 1
if (SHAPE::CIRCLE == WEEK::MON) //error C2676: 二进制“==”:“main::SHAPE”不定义该运算符或到预定义运算符可接收的类型的转换
{
cout<<"oh.yes";
}
在 C++11 之前的版本中,定义变量或者声明变量之前都必须指明它的类型
,比如 int、char 等,这个其实很不方便,尤其是在复杂项目的时候,有多个命名空间,如:Boost::asio::ip::tcp
等等,而在其他语言,如js,就只需要用关键字var
或者let
定义变量就行,到C++11后,auto
诞生了,可以在编译的时候制动推导替换类型。
注意:auto 仅仅是一个占位符,在编译器期间它会被真正的类型所替代。或者说,C++ 中的变量必须是有明确类型的,只是这个类型是由编译器自己推导出来的。
必须
马上初始化不能在函数的参数
中使用(但是
能作为函数的返回值)非静态成员变量
(也就是没有 static 关键字修饰的成员变量)中对于一个有范围的集合而言,由程序员来说明循环的范围是多余的,有时候还会容易犯错误,因此C++大叔给我们提供了一个简单的方法,如下:
int arr[]={1,2,3,4,5,6,7};
//一般用法
for(int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
{
cout<<arr[i]<<" ";
}
//新用法
for(int i:arr)
{
cout<<i<<" ";
}
特点:
typeid 是一个运算符,用来获取一个表达式的类型信息。
typeid 的操作对象既可以是表达式,也可以是数据类型,下面是它的两种使用方法:
typeid( dataType )
typeid( expression )
typeid 会把获取到的类型信息保存到一个 type_info 类型的对象里面,并返回该对象的常引用;当需要具体的类型信息时,可以通过成员函数来提取,本质是一个类,封装了大量的API,如下:
//获取一个普通变量的类型信息
int n = 100;
const type_info& nInfo = typeid(n);
cout << nInfo.name() << " | " << nInfo.raw_name() << " | " << nInfo.hash_code() << endl;
//获取一个字面量的类型信息
const type_info& dInfo = typeid(25.65);
cout << dInfo.name() << " | " << dInfo.raw_name() << " | " << dInfo.hash_code() << endl;
//获取一个普通类型的类型信息
const type_info& charInfo = typeid(char);
cout << charInfo.name() << " | " << charInfo.raw_name() << " | " << charInfo.hash_code() << endl;
//获取一个表达式的类型信息
const type_info& expInfo = typeid(20 * 45 / 4.5);
cout << expInfo.name() << " | " << expInfo.raw_name() << " | " << expInfo.hash_code() << endl;
其中:
除此之外,还可以用 == 比较两个类型是否相等,如下:
char *str;
int a = 2;
int b = 10;
float f;
类型判断结果为:
类型比较 | 结果 | 类型比较 | 结果 |
---|---|---|---|
typeid(int) == typeid(int) | true | typeid(int) == typeid(char) | false |
typeid(char*) == typeid(char) | false | typeid(str) == typeid(char*) | true |
typeid(a) == typeid(int) | true | typeid(b) == typeid(int) | true |
typeid(a) == typeid(a) | true | typeid(a) == typeid(b) | true |
typeid(a) == typeid(f) | false | typeid(a/b) == typeid(int) | true |
建议:内容很多,这个其实也并不常用,可以留个映像,到后面用到的时候查询即可。
// 使用:
inline int add(int a, int b) {
return a + b;
}
为什么使用内联函数?
内联函数没有普通函数调用时的额外开销(压栈,跳转,返回)
注意:
因此一些函数即使没有inline声明,也可能被编译器内联编译
定义函数时可以给形参指定一个默认的值,这样调用函数时如果没有给这个形参赋值(没有对应的实参),那么就使用这个默认的值。
void showX(int x = 666)
{
cout<<"x:"<<x<<endl;
}
showX();
showX(6);
小结:
int add(int a,int b = 5);
int add(int a,int b)
{
return a+b;
}
int foo(int a, int b = 2, int c = 3); // 正确
int foo1(int a, int b = 2, int c); // 错误, i3未指定默认值
int foo2(int a = 1, int b, int c = 3); // 错误, i2未指定默认值
定义函数时,还可以给函数提供占位参数
void func(int a,int = 0)
{
cout<<a<<endl;
}
func(2);
不知道在C语言写函数的时候会不会遇到这种情况,想函数名难想(不想直接拼音),而如果想实现以下功能:
int add(int a, int b) {
return a + b;
}
int add(double a, double b) {
return a + b;
}
想实现以上功能的时候,好像名字都可以用add
,故在C++的时候,引入了一个新的概念,函数重载。(当然上面的实现还可以更加简介,他可用模板,这个后面会更新)。
函数重载是指:在同一作用域
内,可以有一组具有相同函数名
,不同参数列表
的函数,这组函数被称为重载函数。
来个例子体会一下,比较不同类型的两个变量的大小
int maxmum(int a, int b)
{
return a > b?a:b;
}
long maxmum(long int a, long int b)
{
return a > b ? a : b;
}
char maxmum(char a, char b)
{
return a > b ? a : b;
}
double maxmum(double a, double b)
{
return a > b ? a : b;
}
const char* maxmum(const char* str1,const char* str2)
{
return strcmp(str1, str2)==1?str1:str2;
}
char* maxmum(char* str1, char* str2)
{
return strcmp(str1, str2) == 1 ? str1 : str2;
}
int main()
{
cout << maxmum(2, 6) << endl;
cout << maxmum(2L, 6L) << endl;
cout << maxmum('A', 'C') << endl;
cout << maxmum("maye", "MAYE") << endl;
char str1[] = "hello";
char str2[] = "hello";
cout << maxmum(str1, str2) << endl;
return 0;
}
函数重载可以根据具体的参数去决定调用哪一个函数。
如果在给重载函数的时候指定默认参数时,这个时候很容易造成函数冲突,如下:
void fun(int a)
{
cout << "fun(int a) " << a << endl;
}
void fun(int a, int b = 8)
{
cout << "fun(int,int =8) " << a <<" "<< b << endl;
}
int main()
{
//fun(5); //error C2668: “fun”: 对重载函数的调用不明确
fun(5, 6);//正确
return 0;
}