C++ ———— 1 (C&C++差异及增强)

一、关于C++编译

编译过程:

预处理->编译->汇编->链接

1、预处理:展开头文件和宏替换 -E

2、编译:语法检查,将代码文件转换为汇编文件 S

3、汇编:将汇编文件转换为二进制文件 -C

4、链接:将程序所需的各种库文件进行连接,生成 可行了文件

二、编译工具 g++、minGW 1、安装g++编译工具 sudo apt install g++ 2、编译程序 g++ *.cpp 3、标准C++程序框架

#include <iostream>
using namespace std;
int main()
{
	cout << "hello world" << endl;
}

二、C++与C的语言增强和差异性

1.更为严格的类型检查

const int N = 10;
int *p = &N;		//错误,C++不允许将 const 指针 隐式转换为 非 const指针

2.const只读变量

//C:
    const int a = 13;
	int *p = &a;
	*p += 12;
	printf("a: %d\n", a);	==> a: 25
        
//CPP:
	const int N = 10;              //N为常量,也是只读变量,通过指针也不能修改
    int *p = (int *)&N;            //错误,C++不允许将 const 指针 隐式转换为 非 const指针
    *p += 12;

    cout << N << endl;	 ==> 10
    cout << *p << endl;  ==> 22    // 类型的强制转换,将常量区的空间 拷贝到栈区,p指针指向了栈区空间。

3.类型转换

C语言转换:

int *p = (int *)a;

C++转换:

double x,y;
int a = int(x);
int b = int(x+y);

4.引用(reference)

1.引用是一种新增的数据类型,用法和int等数据类型基本一致

2.实质:就是给变量取一个别名

3.特点

​ (1)引用变量必须定义初始化。

int a = 10;
int& b = a;
cout << a << " " << b << endl;
cout << &a << " " << &b << endl;		//地址结果都相同

​ (2)引用比指针更节约空间

​ 引用和变量使用同一片空间

​ (3)引用的绑定在初始化后,不能改变的。

  1. 指针和引用的区别

    (1) 引用:必须定义初始化,不能解引用,不占空间

    (2) 指针:定义可以不用初始化,初始化后可以更改指向,占用存储空间

  2. 左值和右值

    (1)左值:有名称,能出现在 =的左侧或者右侧

    (2)右值:临时变量(对象),只能出现在=的右侧

  3. 右值引用

    (1)给右值取别名(给常量、返回的局部变量)

    语法:

    ​ 数据类型 && 变量名;

    eg:

    ​ int&& a = 13; <==> const int &b = 13;

    ​ cout << a <<endl;

  4. 练习设计一个函数,实现两个数据的交换。

    /*===============================================
    *   文件名称:4_exchange.cpp
    *   创 建 者:青木莲华
    *   创建日期:2025年08月26日
    *   描    述:利用引用实现两个数据的交换
    ===============================================*/
    #include <iostream>
    using namespace std;
    
    void exchange(int& a,int& b)
    {
        a = a + b;
        b = a - b;
        a = a - b;
    
    }
    
    int main()
    {
        int a = 10, b = 20;
        
        int &ea = a,&eb = b;
    
        exchange(ea,eb);
        cout << "a = " << a << " b = " << b << endl;
    }
    
  5. 函数的参数传递:值传递、地址传递、引用传递

5.函数重载(overload)

函数重载

​ 1.函数名相同,返回值不考虑在内

​ 2.参数列表不同(类型或个数不同)

意义

​ 让具有相似功能的算法,使用同一个接口名

6.默认参数

重载中的默认参数

1.函数的声明时,形参可以设置初始值

2.函数某个形参设置默认值后,其后所有的形参都必须要设置默认值。

3.使用时,可以不给拥有默认值的形参传递实参。

4.默认参数+函数重载,使用时需小心,歧义问题

7.内联函数

1.内联函数又称为:内嵌函数(内置函数)

2.在编译阶段, 将函数体嵌入使用(调用)的地方

3.优点:提升了程序的运行效率

4.缺点:程序代码体积增大

5.限制条件:

​ (1) 必须是频繁使用。

​ (2)函数体代码量少(五句以下),结构简单

6.语法结构:函数声明时+inline关键字说明,定义不加inline

inline	数据类型	函数名(<形参列表>);

8.结构体

1.一种用户自定义的数据类型。使用关键字 struct

struct Student{
    int a;
};

2.差异性:

​ (1) 结构体变量的定义:

​ (2) 为了保护成员变量的安全性,引入3个权限限定符的概念

默认权限为public

public:		//公有的,结构体变量能直接用 .变量名 访问
protected:	//保护的,不能直接访问
private:	//私有的,不能直接访问

​ (3) 为了访问结构体的私有成员,引入成员函数的概念。

​ ①成员函数:函数声明在结构体{ }中就行,也可以定义在结构体内

​ ②成员函数声明在结构体中,定义在结构体外的语法规则:

数据类型	结构体名::函数名(<形参列表>)
{
	函数体
}

​ ③成员函数的使用:

​ 结构体变量名.函数名(<实参列表>);

​ ④结构统体的任何成员函数中,都可以访问结构体的其他任何成员

例子

struct Node
{
    public:
    	Node(){}
        Node(int a,int b)
        {
            this->a = a;
            this->b = b;
        }
        int get_a()
        {
            return this->a;
        }
        int get_b()
        {
            return this->b;
        }
    private:
        int a;
        int b;
};
int main()
{
    Node n(10,20); 
    cout << "n.a = " << n.get_a() << " n.b = " << n.get_b() << endl;
}

​ (4) 当成员变量 与 成员函数的形参同名,引入this 指针做区分


Node(int a,int b)
{
    this->a = a;	//this->a  是成员a || a是形参a
    this->b = b;
}

​ (5) 为了实现结构体变量的定义初始化,引入构造函数的概念。

​ ① 构造函数

​ 在定义结构体变量时,系统自动调用的函数,用来初始化结构体变量

​ 语法要求:不能有返回值,函数名必须与结构体名相同

​ 结构体名 (<形参列表>){ }

​ ② 当结构体中没有定义过任何函数,编译器会自动生成一个 无参构造函数

Node(){}				//无参构造
Node(int a,int b)		//有参构造
{
    this->a = a;
    this->b = b;
}
Node n1;				//系统调用无参构造
Node n2(1,2);			//有参构造

三、内存模型及名字空间

1.内存模型

1.作用域

​ 局部作用域、名字空间域、类域

2.链接性

​ 内部链接:名称仅仅能在一个文件中的函数共享。

​ 外部链接:是指名称可以在文件间共享。一个 C 文件引入另一个文件的全局变量 (或函数)。

3.链接关键字:extern

​ 主要用于:

​ 外部链接

​ 语言的链接:c++代码调用 c语言的库函数

extern "C" int add(int x, int y);

4.动态内存:

​ C语言中:malloc 和 free

​ C++:newdelete / new [ ] 和 delete [ ] 两个运算符

#include <iostream>
using namespace std;
int a = 11;
namespace myspace
{
    int b = 100;
}
namespace A
{
    int Aa = 111;
    int Ab = 112;
    namespace B
    {
        int ABa = 211;
        int ABb = 212;
    }
}

int main()
{
    int a = 10;
    //局部
    cout << a << endl;
    //全局
    cout << ::a << endl;    //xxx:: 作用域访问符 访问xxx名字空间
    //:: 前不加名字空间表示全作用域
    //名字空间
    cout << myspace::b << endl;
    cout << "Aa = " << A::Aa << " Ab = " << A::Ab << endl;
    cout << "ABa = " << A::B::ABa << " ABb = " << A::B::ABb << endl;
    return 0;
}

作业:

1.键盘输入一个值

2.输出该数值的十六进制 和 二进制

​ 输入:13

​ 输出:0xD(16)

​ 输出:0b1101(2)

源码

/*===============================================
*   文件名称:work.cpp
*   创 建 者:青木莲华
*   创建日期:2025年08月26日
*   描    述:自动转换16进制和2进制
================================================*/
#include <iostream>
#include <stack>
using namespace std;


//16进制字符数组
const char arr[16] = {'0','1','2','3',
                      '4','5','6','7',
                      '8','9','a','b',
                      'c','d','e','f'};
//十进制转十六进制
void DtoH(int num)
{   
    //栈
    std::stack<char> stk;
    int temp = 0;
    do
    {
        //从最低位开始
        temp = num % 16;
        //将低位入栈
        stk.push(arr[temp]);
    }while((num /= 16) > 0);


    stk.push('x');
    stk.push('0');

    //持续出栈,从高位输出到低位    
    while(!stk.empty())
    {
        //获取栈顶元素
        char temp = stk.top();
        cout << temp;
        //出栈
        stk.pop();
    }
    //换行
    cout << endl;
}

//转二进制
void DtoB(int num)
{
    int temp;
    std::stack<char> stk;
    do
    {   //从最低位开始判断
        temp = num % 2;
        temp == 1 ? stk.push('1') : stk.push('0');
    }while((num >>= 1));
    stk.push('b');
    stk.push('0');

    while(!stk.empty())
    {
        cout << stk.top();
        stk.pop();
    }
    cout << endl;
}
int main()
{
    unsigned int num = 0;
    cout << "input a nunber >: ";
    cin >> num;
    
    DtoH(num);
    DtoB(num);
}

运行截图

alt