C++之路道阻且长TAT

前言

C++项目的组成:

cpp文件,h/hpp文件,外部库文件(dll,lib,exe等),资源文件(rc,res),数据文件(数据库、XML、dat等),其他
利用make工具等编译生成可执行文件(exe,dll等)
Windows的静态库文件扩展名是 .lib,动态库文件扩展名是 .dll (Dynamic-Link Libraries)
相应的,有静态编译和动态编译

C++项目编译过程

概述:
mycpp.prj{file01.cpp,file02.cpp,…,xx.rc}–预编译过程–>{file01.cpp’,file02.cpp’,…}–编译过程(compile)–>{file01.obj,file02.obj,…,xx.res}–链接过程(link)–>mycpp.exe

.prj:工程文件,统领若干cpp文件和其他一些文件
.rc:一些资源文件
.cpp’:预编译后得到的副本文件
.obj:目标文件
cpp文件是独立编译的,是最小编译单元,一个cpp文件和其他cpp文件没有关系,只在最后的链接过程产生联系

1.预编译过程:预处理源代码中的带有#号的语句,生成编译程序可处理的文本文件,对某个cpp文件将头文件进行展开插入,并且放在内存中,提高编译速度
2.编译过程:对每个预处理后源程序,编译并生成相应的的二进制目标文件(object文件)
此过程中,要求编译器能够识别每个标识符,知道其各自的类型、含义,但不要求知道存放位置
3.链接过程:用到一些库(.lib,.dll),对在整个程序范围内,确定各标识符所代表的地址,如变量、函数入口,生成可执行文件
此过程中,要求编译器能够确定每个标识符所对应的含义或地址
这里的地址指变量或函数在文件中的具体位置

这三步统称编译过程,这里的错误称为语法错误,这里必须会自己掌握
相应的,成功生成可执行文件后的错误是逻辑错误

make工具说明

通过比对源文件和要生成的文件的时间戳,选择并决定编译哪些文件,提高编译速度

入口函数(main函数)

返回值:int或void,缺省为int(C++17(C++1z)要求int)

命令行参数:
int argc,char *argv[ ]

头文件

扩展名:.h,.hpp,无扩展名
.h是C中的,.hpp是C++中的(,h是最常用的),无扩展名通常是系统的头文件

标准库:系统预定义的文件,其可执行代码通常存在于操作系统,或者随编译器一同发布,属于标准C++的一部分
< >:在系统目录中查找相应的头文件(system目录或者编译器提供的目录)
“ “:先在本地(当前工程)的目录中查找相应的头文件;若找不到,再到系统目录中查找相应的头文件
括号或引号里可以写成绝对路径或相对路径的形式

#include和#include<xx.h>
前者是C++的风格
大体上:#include相当于(是相当于,不是等价)

namespace std{
    #include"xx.h"
}

书写风格:一般是把尖括号(< >)放在前面(注意#include “stdafx.h”这个东西的存在),自己写的.h文件(” “)放在后面
不然可能会造成报错信息产生在尖括号的include那一行,让你百思不得其解

前置声明:告诉编译器,一个标识符所代表的类型,含义等,但不必告知其具体位置

在C++中可以使用类的前置声明
类似函数声明
如定义了类class A

class A{
...
};

想要在定义之前使用class A,就需要前置声明

class A;   //对于结构体struct也可以使用class xxx来前置声明,结构体本身就是默认类型为public的类,但是不能使用struct xxx,struct并没有自己的前置声明

注意:
前置声明只能作为指针或引用,不能定义类的对象,自然也就不能调用对象中的方法。
详见:https://www.cnblogs.com/fwycmengsoft/p/4061989.html

条件编译

1.if格式

#if 表达式
     语句序列①
[#else
     语句序列②]
#endif

功能:当表达式的值为真时,编译语句序列①,否则编译语句序列②。其中,#else和语句序列②可有可无。

2.ifdef格式

#ifdef     标识符
     语句序列①
[#else
     语句序列②]
#endif

功能:当标识符已被定义时(用#define定义),编译语句序列①,否则编译语句序列②。其中#else和语句序列②可有可无。

3.ifndef格式

#ifndef     标识符
     语句序列①
[#else
     语句序列②]
#endif

功能:该格式功能与ifdef相反。

在头文件中常用条件编译语句实现包含警戒,常见格式如下:

//example.h
#ifndef EXAMPLEH
#def EXAMPLEH
...
(头文件具体代码)
...
#endif

全新的运算符

先介绍 newdelete 两个运算符,他们取代了malloc和free函数
用法:

float *pai=new float(3.14); //开辟一个单精度数的空间,地址赋给指针变量pai,同时给该空间赋值3.14,失败返回NULL
int *p=new int[10]; //开辟一个int数组,new数组时不能赋初值
class people *iptr=new people; //new一个类空间
iptr->height=123;

delete []p; //去除int[10]数组的空间
delete pai; //去除一个float变量的空间

引用

单变量引用

对以下代码:

int a=1;
const int &temp=a;

temp是a的引用,但是无法被赋值从而改变a的值,但是可以对a赋值

对一个函数声明的形参中用const

对以下代码:

int sum(const int ar[],int n)
{
int i,total=0;
for(i=0;i<n;i++)
total+=ar[i];
return total;
}

这里const的作用是要求函数在处理数组ar时将其视作常量,不可更改,这样可以保护数组的数据不被修改。
一旦发生修改,编译器会产生错误并提示。
传参时直接传int型的数组没有问题。
如果需要修改数组的内容,则不加const。

C++的灵魂是面向对象的程序设计,最重要的就是的掌握

定义对象(类似结构体)

1.class 类名 对象名
也可以把class省略 直接“类名 对象名”
C++中结构体定义变量可以省略strcut

2.声明类的同时定义对象

class XXX{
...
}xxx1,xxx2;

也可以不带XXX(不推荐)

类的指针

类似结构体,定义指针变量可以

wchar_t(宽字符类型)主要用于存储东亚地区的字符