C++(1)语法,命名空间,函数,引用,重载

278 阅读6分钟

C++的编译开发环境

在虚拟机Ubuntu上使用g++

g++是Linux中C++的编译器,需要安装,g++的使用方法和gcc一样

测试系统是否有g++
    g++ -v

安装:
    sudo apt-get update
    sudo apt-get install g++

使用vscode

编译需要安装minGW

使用Qt Creator

Qt Creator是Qt的集成开发环境,可以编译和运行C++程序,安装包可以直接从官网下载。

download.qt.io/archive/qt/…

image-20220717210508875

安装注意事项:

(1)如果安装时需要填Qt的ID和密码,没有直接在下方直接用邮箱注册一个使用(填入邮箱和密码)

(2)安装时除了默认内容外,只需要选择MinGW编译器即可

image-20220717210521428

C++简介

历史

上世纪80年代初,本.贾尼

83年,正式命名为C++,87年,GNU C++92年,微软 C++,98年,ANSI C++

ISO C++98 ,ISO C++03 ,ISO C++11 ,ISO C++14,ISO C++17,ISO C++20

C++和C的关系

C是C++的基础,C++是C的扩展

扩展的内容:

  • 1.面向对象(以类的方式组织代码) 2.运算符的重载(一种特殊的函数形式) 3.异常(一种全新的错误处理方法) 4.泛型编程(类型通用的实现)

C++的类型检查比C严格,C++完全兼容C


#include <iostream>
#include <string>
#include <list>
//#include <stdio.h>  //c里面的写法
#include <cstdio>    //写成这样比较好

int main()
{
	printf("第一个C++程序!\n");

	return 0;
}

C++的基础语法

源代码的保存

C++的源代码保存在后缀为.cpp的文件中,头文件的后缀是.h(.hpp)

.cc .C .cxx .c++

C++的头文件

C++包含自定义的头文件时不再以.h作为结尾

#include <iostream>//支持输入输出的头文件
#include <string>
#include <list>
//...

C语言的标准头文件任然可用

#include <stdio.h>
#include <stdlib.h>
//但是C++推荐使用以下语法
#include <cstdio>
#include <cstdlib>
//非标准头文件不支持该语法
#include <pthread.h>
//#include <cpthread>//错误

自定义头文件的语法和C语言没有区别

命名(名字)空间

命名空间的作用就是进行代码划分,防止命名冲突

image-20220717210534994

定义一个命名空间

namespace 空间名{
    变量的声明和定义;
    函数的声明和定义;
    .....    
};

命名空间的访问

1.直接在访问内容前加上命名空间名
    命名空间名::内容;
2.使用using声明在接下来的代码中使用某个命名空间中的数据
    using 命名空间名::内容; 
    //防止冲突
3.使用using对命名空间的内容进行整体使用
    using namespace 命名空间名;
    //防止冲突

匿名命名空间(不要这样使用)

如果一个数据不属于任何命名空间,C++编译器就会将其加入到匿名命名空间,可以使用以下语法来访问匿名命名空间中的内容

::内容;

也可以直接定义匿名命名空间

namespace{
    内容;
}

命名空间的嵌套

命名空间中还有命名空间

namespace ns1{
    xxx;
    namespace ns2{
        yyy;
        namespace ns3{
            zzz;
        }
    }    
};

如何访问:
    ns1::xxx;
    ns1::ns2::yyy;
    ns1::ns2::ns3::zzz;

练习:

设计三个命名空间,每个命名空间中包含一个add函数,分别计算两个整数,两个浮点数和两个字符串的加法,返回加法的结果,分别调用它们。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>

namespace ns1{
	int add(int a,int b)
	{
		return a+b;
	}
}

namespace ns2{
	double add(double a,double b)
	{
		return a+b;
	}
}
/*
这段没怎么看懂
*/
namespace ns3{
	char *add(const char *s1,const char *s2)
	{
		char *s = (char *)malloc(strlen(s1)+strlen(s2)+1);
        //这里为什么要加一 :固定要加一,拼接字符串
        
		if(s){
			strcpy(s,s1);
			strcat(s,s2);
		}

		return s;
	}
}


int main()
{
	printf("10+2 = %d\n", ns1::add(10,2));
	printf("3.14+2.68 = %lg\n", ns2::add(3.14,2.68));
	
	char *str = ns3::add("hello ","GZFX2108");
	printf("%s\n", str);
	free(str);

	return 0;
}

字符串的加法用拼接

使用Qt创建C++的工程

1.设置字符编码和系统一致
    工具 ===> 选项 ===> 文本编辑器 ===> 行为 ===> 编码改为system
2.建立工程
        文件 ===> 新建文件或项目 ===> Non-Qt Project ===> Plain C++ Application
        设置工程名和保存路径 ===> 完成

C++的输入和输出

C++d的标注输入输出定义在std的命名空间中。

C++中所哟预定义的类和函数(包括输入输入出)都是保存在std的命名空间。

using namespace std;

使用输入输出还要包括iostream的头文件

标准输出 ---------- cout<<
    cout<<可以输出任何非自定义的数据,加endl换行
    可以使用cout<<xxx<<yyy<<zzz.....进行连续输出
    
标准输入 ---------- cin>>
    cin>>代表空间的内容(变量/地址);
    可以使用cin>>xxx>>yyy>>zzz....进行连续输入

C++的内存分配

C语言堆内存的管理

malloc/free
calloc ----------- 分配的内存会自动初始化为0
realloc ---------- 调整分配的堆内存的大小

C++堆内存的管理

new/delete -------- 分配和释放单个内存
new[]/delete[] ---- 分配和释放多个连续内存

语法:

申请一个类型大小的空间
    类型名 *指针变量名 = new 类型;
    类型名 *指针变量名 = new 类型(值);//分配同时初始化
释放一个类型大小的空间 
    delete  指针变量名; 
    
申请的多个同类型大小的连续空间
    类型名 *指针变量名 = new 类型[n];//n表示该类型大小的个数
释放多个同类型大小的连续空间
    delete[] 指针变量名;

注意:new/delete和malloc/free的区别在于申请和释放对象内存时,在C++中不使用malloc/free,而使用new/delete。

引用(reference)

引用就是别名的意思

机器猫     小叮当  哆啦A梦
龙血武姬    龙女   希瓦娜

引用的语法

类型名& 引用名 = .....;//引用必须初始化
//以上的代码就是相当于给等号右边的内容起一个别名

引用既可以指向变量,也可以指向常量
    int num = 1;
    int& r_num = num;//num的应用
    const int& cr = 10;//常量的引用

引用一旦初始化,引用的对象不能改变,终身为其服务,常量的应用题必须用const修饰。

引用作为函数的参数和返回值

作为函数参数

普通变量作为函数的参数只能实现值的单向传递

引用作为函数参数可以实现值的双向传递

作为函数的返回值

一般函数的返回值只能作为右值

int x = xxx(...);

如果希望函数的返回值作为左值就可以使用后引用类型

不能返回局部变量和形参的引用
可以返回静态变量 全局 堆 引用参数的引用

指针的引用和数组的引用

指针的引用

引用的地址就是原数据的地址
指针的引用就是指针的别名,通常就是用来代替二级指针
语法:
    int *p = NULL;
    int *&rp = p;//指针的引用

数组的引用

int arr[5];
int (&r_arr)[5] = arr;//数组的引用   数组长度应该一样

//数组的引用作为函数参数可以保留数组的特性
//同时丧失了数组传参的灵活性,基本不使用

void set_arr(int (&r_arr)[5])
{
    sizeof(r_arr) ===> 20
}

void set_arr(int a[],int n)
{
    sizeof(a) ===> 8
}

函数重载

C++编译器和C编译器对函数的处理有区别

1.C++中参数列表为()表示没有参数,等同于(void)
2.C++不支持隐式声明,必须前置声明
3.C++的函数不再默认返回int,必须指定返回值类型
4.C++的函数调用匹配不但匹配函数名,还匹配参数列表