C++语法基础(二)

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);//1
    const char* cc;//3
    foo(cc,s);
    int i;double d;
    foo(d,i);//4
    foo(i,d);//2
    return 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);//3
    return 0;
}

重载解析

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

//重载解析优先级
#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方式编译函数,即不做换名

原函数
  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.a

cal.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.a

cal.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;
}

  • 12
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值