001 任务一 _ 从C到C++ (1)

116 阅读5分钟

提示:

  • 学习C++语言前,先学习C语言,因为C++是兼容C的。
  • 学习C++语言,个人感觉不像学其它语言哪些,可以快速前进,它需要每天一小步,逐个击破。

1. Hello C++

  • 与所有语言一样,都是从Hello World开始。
#include <iostream>

// 导入C语言的头文件 
#include <cstdio>

int main() {
	
    // 输出
    std::cout << "Hello C++!" << std::endl;

    int age = 0;
    double height = 0;

    std::cout << "请输入年龄: " << std::endl;
    std::cin >> age;

    std::cout << "请输入身高: " << std::endl;
    std::cin >> height;
    
    std::cout << "年龄: " << age << 
        ", 身高: " << height << std::endl;

    printf("C++是兼容C语言的!");
	
    return 0;	
}
  • 这里使用的是g++的编译器

  • 和C语言一样,C++的入口函数也是main

  • C++的源文件扩展名是: cpp

  • 头文件:#include 类似于 C语言中的 #include <stdio.h>

  • C++中常使用cin、 cout进行控制台的输入、输出。cin用的右移运算符>>, cout用的是左移运算符<< endl是换行的意思。所有标准类型、对象和函数都位于std名字空间中

  • C++也可以用scanf/printf

  • C++完全兼容C语言的语法

    2 命名空间 namespace

为什么要名字空间?

  • 划分逻辑单元
  • 避免名字冲突

命名空间不影响内存布局

其它语言有也有类似的名字空间,像OC的类前缀,Java的package

2.2.1 定义名字空间

使用namespace可以定义命名空间

namespace ICBC {
    int g_money = 0;

    void save(int money) {
        g_money += money;   
    }

    void pay(int money) {
        g_money -= money;   
    }
}

相同名称的名字空间定义的成员可以分开在不同的地方,也可以组合在一起。

namespace CCB {
    int g_money = 0;    
}

namespace CCB {
    void save(int money) {
        g_money += money;   
    }   
}
​
namespace CCB {
    void pay(int money);    
}

void CCB::pay(int money) {
    g_money -= money;   
}

2.2 使用名字空间

  1. 使用作用域限定符来访问成员, 访问的成员必须在前面使用名字空间和::修饰
ICBC::save(1000);
std::cout << "ICBC: " << ICBC::g_money << std::endl;
  1. 使用名字空间指令

    using 成员;

    通过名字空间指令声明的成员,可以直接像访问局部变量一样,直接使用。

    只针对成员有效。

using ICBC::save;
using ICBC::pay;
save(2000);
pay(2800);
std::cout << "ICBC: " << ICBC::g_money << std::endl;
std::cout << "CCB: " << CCB::g_money << std::endl;
  1. 名字空间声明

    using namespace 空间名称;

    通过名字空间会将所有成员,可以直接访问。

    针对空间内的所有成员有效。

using namespace CCB;
save(1000);
pay(200);
std::cout << "ICBC: " << ICBC::g_money << std::endl;
std::cout << "CCB: " << CCB::g_money << std::endl;

注意,同时使用名字间指令和名字空间声明会造成冲突,但不会编译报错,会出现小作用域隐藏大作用域的情况。

#include <iostream>

// 定义名字空间
namespace ICBC {
    int g_money = 0;

    void save(int money) {
        g_money += money;   
    }

    void pay(int money) {
        g_money -= money;   
    }
}

// 分开定义也是一样的
namespace CCB {
    int g_money = 0;    
}

namespace CCB {
    void save(int money) {
        g_money += money;   
    }   
}

namespace CCB {
    void pay(int money);    
}

void CCB::pay(int money) {
    g_money -= money;   
}

int main() {
    
    // 1. 作用域限定符访问 ::
    ICBC::save(1000);
    std::cout << "ICBC: " << ICBC::g_money << std::endl;
/*
    // 2. 名字空间指令
    using ICBC::save;
    using ICBC::pay;
    save(2000);
    pay(2800);
    std::cout << "ICBC: " << ICBC::g_money << std::endl;
    std::cout << "CCB: " << CCB::g_money << std::endl;
*/
    // 3. 名字空间声明 
    using namespace CCB;
    save(1000);
    pay(200);
    std::cout << "ICBC: " << ICBC::g_money << std::endl;
    std::cout << "CCB: " << CCB::g_money << std::endl;
​
    return 0;
}

2.3 匿名名字空间

没有声明在任何一个名字空间的成员如变量、函数、类等属于全局命名空间,使用::来访问。

::成员;

#include <iostream>
using namespace std;

int g_value = 10086;

namespace ns {
    int g_value = 95533;    
}

int main() {
    
    // 直接说全局
    cout << "g_value: " << g_value << endl;

    // 引入名字空间, 造成冲突
    using namespace ns;
    
    // cout << "g_value: " << g_value << endl;

    cout << "ns::g_value: " << ns::g_value << endl;
    
    cout << "::g_value: " << ::g_value << endl;

    return 0;   
}

2.4 名字空间嵌套与别名

名字空间可以一层一层往里套

内层标识符隐藏外层同名标识符 ​ 嵌套的名字空间需要逐层分解

namepace 别名 = 空间作用域;

#include <iostream>
using namespace std;
​
namespace ns1 {
    namespace ns2 {
        namespace ns3 {
            namespace ns4 {
                int value = 2020;
            }
        }
    }
}

int main() {

    // 逐层访问 
    cout << ns1::ns2::ns3::ns4::value << endl;

    // 使用别名
    namespace ns = ns1::ns2::ns3::ns4;
    cout << ns::value << endl;
    
    return 0;   
}

3. 结构体

  • 定义结构型变量时,可以省略struct关键字
  • 可以定义成员函数,在结构体中的成员函数中可以直接访问该结构体的成员变量,无需通过“.”或“->”
#include <iostream>
#include <cstring>
using namespace std;
​
struct Person {
​
    char name[30];
    int age;
​
    void show() {
        cout << "Person: " << name << ',' << age << endl;
    }
    
}; // 分号不要少int main() {
    
    Person person = {"jack", 20};
    person.show();
​
    strcpy(person.name, "rose");
    person.age = 18;
    person.show();
​
    Person *p = &person;
    strcpy(p -> name, "tom");
    p -> age = 35;
    p -> show();
    return 0;
}

4. 枚举

  • 定义枚举型变量时,可以省略enum关键字
  • 独立的类型,和整型之间不能隐式转换
    #include <iostream>
using namespace std;

enum Color {
	red,	
	green,
	blue = 100,
	white
};

int main() {
	
	Color color = red;
	cout << color << endl;

	color = white;
	cout << color << endl;
	
//	color = 100; // 错误, 不能隐式转换 
	color = Color(100); // 显式转换
	
	return 0;	
}

5. 联合

  • 定义联合型变量时,可以省略union关键字
  • 支持匿名联合
#include <iostream>
using namespace std;

int main() {

    union {
        int data;
        char ch[4];
    };


    // 匿名联合
    data = 0x12345678;
	
    if (ch[0] == 0x78) {
        cout << "小端系统" << endl;
    } else {
        cout << "大端系统" << endl;	
    }

    return 0;
}