C++复合类型
结构体
1. C++的结构,定义结构体类型的变量时,可以省略struct关键字
2. 可以定义成员函数,在结构体中的成员函数内部可以直接访问本结构体的成员,无需通过“.”或“->”
联合
1. C++的联合,定义联合体类型的变量时,可以省略union关键字
2. 支持匿名联合3. 重点:共用一块内存空间
枚举
1. C++的枚举,定义枚举型的变量时,可以省略enum关键字
2. 独立的类型,和整型之间不能隐式转换.
代码演示
#include<iostream>
#include<cstring>
using namespace std;void testStruct(){struct Student{int m_age;char m_name[128];void getInfo(){cout << m_name << ":" << m_age << endl;}};/*struct*/ Student s1;s1.m_age = 18;strcpy(s1.m_name, "林枫");s1.getInfo();cout << "姓名:" << s1.m_name << ", 年龄:" << s1.m_age << endl;
}
void testUnion(){union /*A*/{//匿名联合主要想体现 成员的内存排布方式(共用同一块内存空间)int i;char c[4];};//Union A a; //C语言写法//A a; //C++写法i = 0x12345678;//cout << c[0] << ' ' << c[1] << ' ' << c[2] // << ' ' << c[3] << endl;//输出对应字符cout << hex << (int)c[0] << ' ' << (int)c[1] << ' ' << (int)c[2]<< ' ' << (int)c[3] << endl;
}
void testEnum(){enum Color{ red,green,blue };//C语言写法//enum Color c = red// 0-err//枚举类型不支持隐式转换//C++写法Color c = red;Color d = green;Color e = blue;cout << "c = " << c << endl;cout << "d = " << d << endl;cout << "e = " << e << endl;
}
void testBool(){bool a = true;//"";"fddgd"bool b = false;"0.0000";"123";NULL;cout << "a = " << a << ", b = " << b << endl;cout << boolalpha << "a = " << a << ", b = " << b << endl;
}
int main(){testStruct();testUnion();testEnum();testBool();return 0;
}
布尔类型
表示布尔量的数据类型
-->bool
布尔类型的字面值常量
-->true表示真 -->false表示假布尔类型的本质 - 单字节整数
用1和0表示真和假
任何基本类型都可以被隐式转换为布尔类型
非0即真,0即假
代码演示
#include<iostream>
using namespace std;void testBool(){bool a = true;//"";"fddgd"bool b = false;"0.0000";"123";NULL;cout << "a = " << a << ", b = " << b << endl;cout << boolalpha << "a = " << a << ", b = " << b << endl;
}
int main(){testBool();return 0;
}
函数关系--重载
重载关系
-->同一作用域内,函数名相同,参数表不同-->根据实参类型和形参的类型进行匹配,调用最匹配的函数
-->只有同一作用域内的同名函数才涉及重载的关系,不同作用域的同名函数涉及的是隐藏关系。
重载解析
-->完全匹配>常量转换>升级转换>标准转换>自定义转换>省略号匹配
-->函数指针的类型决定其调用的重载函数的版本
重载关系
代码演示(重载匹配)
//重载关系: 1.同一作用域内 2.函数名相同 3.参数列表不同
//形参表是否相同,与参数名无关,与形参个数, 以及,每一个对应的参数类型有关
#include <iostream>
using namespace std;
void foo(char* c,short s){cout << "1.foo" << endl;
}
void foo(int i,double d){cout << "2.foo" << endl;
}
void foo(const char* c,short s){cout << "3.foo" << endl;
}
void foo(double d,int i){cout << "4.foo" << endl;
}//int foo(double i,int d){} //错误,形参表相同,是否构成重载关系与返回值类型无关
int main(){char* c;short s;foo(c,s);//1const char* cc;//3foo(cc,s);int i;double d;foo(d,i);//4foo(i,d);//2return 0;
}
代码演示(不同作用域下的重载关系)
//不同作用域的同名函数涉及的是隐藏关系
#include <iostream>
using namespace std;
namespace ns1{void foo(char* c,short s){cout << "1.foo" << endl;}void foo(int i,double d){cout << "2.foo" << endl;}
}
namespace ns2{void foo(const char* c,short s){cout << "3.foo" << endl;}void foo(double d,int i){cout << "4.foo" << endl;}
}int main(){using namespace ns1;//ns1中foo出现在可见表中using ns2::foo;//ns2中foo出现在定义表中char* c;short s;foo(c,s);//3return 0;
}
重载解析
代码演示(重载解析优先级)
//重载解析优先级
#include<iostream>
using namespace std;void foo(char* c, short s){ //完全匹配 _Z3fooPcscout << "1.foo" << endl;
}
void foo(const char*, short s){ //常量转换 _Z3fooPKcscout << "2.foo" << endl;
}
void foo(char* c, int s){cout << "3.foo" << endl; //升级转换 _Z3fooPci
}
void foo(char* c, char s){ //标准转换 _Z3fooPcccout << "4.foo" << endl;
}
void foo(...){ //省略匹配 _Z3foozcout << "5.foo" << endl;
}int main(){char* c;short s;foo(c,s);//普通方式调用,由实参和形参的匹配度来决定调用哪个foo函数void(*pfunc)(const char* c,short s) = foo;//_Z3fooPKcspfunc(c,s);//函数指针方式调用,由函数指针本身的类型决定调用哪个foo函数return 0;
}
重载的本质--“换名机制”
Z --表示自定函数系统默认前缀
P --表示指针
c --char类型
s --short类型
K --const类型
z --表示可变长参数
屏蔽C++“换名机制”--extern “C”
通过extern “C”可以要求C++编译器按照C方式编译函数,即不做换名
原函数
int sum(int a,int b){return a + b;}int sub(int a, int b){return a - b;}
查看符号表
tern$vi cal.cpp
11_extern$g++ -c cal.cpp
11_extern$ls
a.out cal.cpp cal.o libcal.a main.c main.o
11_extern$ar -r libcal.a cal.o
11_extern$nm libcal.acal.o:
0000000000000014 T _Z3subii
0000000000000000 T _Z3sumii
使用extern ”C“
extern "C"{int sum(int a,int b){return a + b;}int sub(int a, int b){return a - b;}
}
查看符号表
11_extern$g++ -c cal.cpp
11_extern$ls
a.out cal.cpp cal.o main.c main.o
11_extern$ar -r libcal.a cal.o
ar: 正在创建 libcal.a
11_extern$ls
a.out cal.cpp cal.o libcal.a main.c main.o
11_extern$nm libcal.acal.o:
0000000000000014 T sub
0000000000000000 T sum
11_extern$
缺省参数
1. 可以为函数的形参指定缺省(默认)值,当调用该函数时若未指定实参,则使用形参的缺省(默认)值。
2. 如果函数的某一个形参具有缺省(默认)值,那么该形参后面的所有形参必须都具有缺省(默认)值
3. 尽量避免因为使用缺省参数而导致重载匹配歧义
4. 函数形参的缺省(默认)值只能在函数声明中指定
//缺省(默认)参数:带默认值的形参
//默认值不是初始值
#include<iostream>
using namespace std;
void foo(int a, double b=3.14, float c=2.0, short d=1, char e = 'A');
void foo(int a){
}
void foo(int a, double b, float c, short d, char e) {// 函数实现cout << "e = " << e << endl;
}
int main(){foo(1,2,3.0,4);foo(1,2,3.0,4,'B');//foo(10);//造成重载匹配歧义return 0;
}