C++语法基础(二)

C++复合类型

结构体

  1. C++的结构,定义结构体类型的变量时,可以省略struct关键字

  2. 可以定义成员函数,在结构体中的成员函数内部可以直接访问本结构体的成员,无需通过"."或"->"

联合

  1. C++的联合,定义联合体类型的变量时,可以省略union关键字

  2. 支持匿名联合

  3. 重点:共用一块内存空间

枚举

  1. C++的枚举,定义枚举型的变量时,可以省略enum关键字

  2. 独立的类型,和整型之间不能隐式转换.

代码演示

cpp 复制代码
#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即假

代码演示

cpp 复制代码
#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;
}

函数关系--重载

重载关系

-->同一作用域内,函数名相同,参数表不同

-->根据实参类型和形参的类型进行匹配,调用最匹配的函数

-->只有同一作用域内的同名函数才涉及重载的关系,不同作用域的同名函数涉及的是隐藏关系。

重载解析

-->完全匹配>常量转换>升级转换>标准转换>自定义转换>省略号匹配

-->函数指针的类型决定其调用的重载函数的版本

重载关系

代码演示(重载匹配)

cpp 复制代码
//重载关系: 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);//1
    const char* cc;//3
    foo(cc,s);
    int i;double d;
    foo(d,i);//4
    foo(i,d);//2
    return 0;
}

代码演示(不同作用域下的重载关系)

cpp 复制代码
//不同作用域的同名函数涉及的是隐藏关系
#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);//3
    return 0;
}

重载解析

代码演示(重载解析优先级)

cpp 复制代码
//重载解析优先级
#include<iostream>
using namespace std;

void foo(char* c, short s){  //完全匹配 _Z3fooPcs
    cout << "1.foo" << endl;
}
void foo(const char*, short s){  //常量转换 _Z3fooPKcs
    cout << "2.foo" << endl;
}
void foo(char* c, int s){
    cout << "3.foo" << endl;  //升级转换 _Z3fooPci
}
void foo(char* c, char s){    //标准转换 _Z3fooPcc
    cout << "4.foo" << endl;
}
void foo(...){  //省略匹配  _Z3fooz
    cout << "5.foo" << endl;
}

int main(){
    char* c;
    short s;
    foo(c,s);//普通方式调用,由实参和形参的匹配度来决定调用哪个foo函数
    void(*pfunc)(const char* c,short s) = foo;//_Z3fooPKcs
    pfunc(c,s);//函数指针方式调用,由函数指针本身的类型决定调用哪个foo函数
    return 0;
}

重载的本质--"换名机制"

Z --表示自定函数系统默认前缀

P --表示指针

c --char类型

s --short类型

K --const类型

z --表示可变长参数

屏蔽C++"换名机制"--extern "C"

通过****extern "C"可以要求C++编译器按照C方式编译函数,即不做换名

原函数
cpp 复制代码
  int sum(int a,int b){
        return a + b;
    }

    int sub(int a, int b){
        return a - b;
    }
查看符号表
bash 复制代码
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.a

cal.o:
0000000000000014 T _Z3subii
0000000000000000 T _Z3sumii
使用extern "C"
cpp 复制代码
extern "C"{
    int sum(int a,int b){
        return a + b;
    }

    int sub(int a, int b){
        return a - b;
    }
}
查看符号表
bash 复制代码
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.a

cal.o:
0000000000000014 T sub
0000000000000000 T sum
11_extern$

缺省参数

1. 可以为函数的形参指定缺省(默认)值,当调用该函数时若未指定实参,则使用形参的缺省(默认)值。
2. 如果函数的某一个形参具有缺省(默认)值,那么该形参后面的所有形参必须都具有缺省(默认)值
3. 尽量避免因为使用缺省参数而导致重载匹配歧义
4. 函数形参的缺省(默认)值只能在函数声明中指定

cpp 复制代码
//缺省(默认)参数:带默认值的形参
//默认值不是初始值
#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;
}
相关推荐
TeYiToKu5 分钟前
笔记整理—linux驱动开发部分(9)framebuffer驱动框架
linux·c语言·arm开发·驱动开发·笔记·嵌入式硬件·arm
互联网打工人no112 分钟前
每日一题——第一百二十四题
c语言
爱吃生蚝的于勒15 分钟前
深入学习指针(5)!!!!!!!!!!!!!!!
c语言·开发语言·数据结构·学习·计算机网络·算法
羊小猪~~18 分钟前
数据结构C语言描述2(图文结合)--有头单链表,无头单链表(两种方法),链表反转、有序链表构建、排序等操作,考研可看
c语言·数据结构·c++·考研·算法·链表·visual studio
洋24039 分钟前
C语言常用标准库函数
c语言·开发语言
脉牛杂德1 小时前
多项式加法——C语言
数据结构·c++·算法
legend_jz1 小时前
STL--哈希
c++·算法·哈希算法
CSUC1 小时前
【C++】父类参数有默认值时子类构造函数列表中可以省略该参数
c++
Vanranrr1 小时前
C++ QT
java·c++·qt
徐嵌1 小时前
STM32项目---畜牧定位器
c语言·stm32·单片机·物联网·iot