c++学习笔记


c++

main函数

  • 入口函数,执行程序会从main函数开始
  • 一个程序只能有一个main函数
  • main函数一般返回整数,记录程序异常退出码,或无异常返回 0
  • void main(){ *** } void函数无返回值,但不建议使用
  • c语言关键字必须#include <iostream>之后使用,不需要名称空间
  • 格式:
int main()
{
    printf("hello world\n");
    system("pause");
    return 0;
}

基本组成

  1. 预处理编译指令:# include <filename> 导入头文件

    • 通常用 <filename> 来导入标准头文件,"filename" 来导入自定义头文件
  2. 主函数: int main(int argc, char* argv[])

    • 一个项目中必须有且只能有一个int main函数,

    • main函数为程序入口,执行时会从main函数开始执行

    • int定义返回值类型, int argc定义输入值数据类型

    • 不需要返回值是定义类型 void

  3. using namespace std 相当于 from std import * , 不推荐使用,

  4. using std::cout 相当于 from std import cout, 对于函数的单独调用,防止多余的函数散落在全局域中

  5. c++中标准库的名称空间都是std

  6. 强制类型转换

    int a = 10;
    int *ip = a;
    char *cp = (char *)ip;

编译过程

  1. 预处理

    • 处理#开头的语句
      • 将``#include`关联的文件复制到当前文本里(头文件展开)
      • if (0){code1}
      • /* */
      • //
    • 删除注释
    • 条件编译等
    • 生成 .i 文件
  2. 编译

    • 语法检查,转换成汇编代码
    • 生成 .s 文件
  3. 汇编

    • 汇编后转换成二进制
    • 生成 .o 文件
  4. 链接

    • 将依赖库链接到exe中
    • 生成启动代码调用 main 函数
    • 生成exe

常用关键字

  • system:执行CMD的命令

  • 输入 scanf,碰到换行、Tab、换行会结束

  • gets_s(s1, 128)

    ​ (_s后缀代表安全的)碰到换行或给定参数(这里是128)停止

  • 输出 printf

  • 对于int、char、double等,使用scanf需要取地址

变量(标识符)

定义域

  • 跨文件引用变量,先用extern声明

  • static限制在当前文件内使用的变量

  • 变量使用前必须定义类型,可同时赋值,如:int num = 5;

  • 声明变量并赋值的方法

    • int a = 12;
    • int a = { 12 };
    • int a(12);
    • int a{12};
  • 连续赋值语句顺序从右向左依次执行, a = b = 5;相当于b=5;a=b;

  • c++标准为首次使用变量时声明,c标准则将所有变量声明放在开头

  • 定义常量

    • #define 宏常量定义,全局,写在开头,属于c语言遗留语法

    • const常量限定符,将一个变量定义为常量 : const int Months = 12;

char 字符

  • 只占一个字节
  • 存储10进制的ASCII码
  • 0 - 9 < A - Z < a - z
  • 48 - 57 < 65 - 90 < 97 - 122
  • \n 010 \t 009 \\ 092
  • \0为终止符,字符串中, \0后面的部分会忽略掉

字符串

  • 以 ‘\0’ 结尾的字符数组

  • 字符串长度

    • strlen,需要导入<string.h>
      • size_z len = strlen(s1)
      • 如果一个字符串末尾没有’\0’,调用strlen会导致内存溢出
    • sizeof ,计算结果需要建议,因为末尾的 \0是不显示的,正常不应算入长度
  • 字符串拷贝

    • strcpy_s: 完整拷贝整个字符串,目标字符串必须必源字符串长
    • strncpy: 拷贝指定长度的部分
  • 字符串追加

    • strcat
    • strncat

格式化字符串

  • %s 输入字符串
  • %f 输入浮点数
  • %llu
  • %d

常量

定义常量

  • #define 宏常量定义,全局,写在开头

  • const 常量修饰符,将一个变量定义为变量

运算符

  • 三目运算符

    • <表达式1> ?<表达式2> :<表达式3>

    • 如果表达式1为真,返回表达式2的结果,如果为假则返回表达式3的结果

    • 三目运算符返回的是变量本身,可以继续赋值

      int a=10;
      int b=2;
      a>b?a:b == 100
      
      // Result:a=100, b=2
  • 除法与取模

    • 两个整数的除法运算结果仍为整数
    • 取模运算只能在整数间运算
  • 或:|| 与:&& 非:!

  • 前置递增(递减)与后置递增(递减)

逻辑机构

  • switch(表达式){case 结果 : break;}
    • 当case 语句执行后,后面如果没有break打断,则后面的case不再判断,直接执行
    • 为防止执行多个结果,每个case下都应有break打断循环
    • default默认结果
  • while{} 与do()while{}
  • for 循环
    • for each
    • for(int i=0; i<100;i++){}
  • goto FLAG FLAG:
    • 跳转到对应行数运行,不推荐使用,降低可读性

数组

  • 定义方式

    • 数据类型 数组名[数组长度];
    • 数据类型 数组名[数组长度] = {值1, 值2 … };未赋值的元素会用0或空字符填充
    • 数据类型 数组名[ ] = {值1, 值2 … };
  • 特点

    • 放在连续的内存空间中
  • 数组元素类型相同

  • 定义后未赋值的元素用随机数填充

  • 数组名用处

    • 统计数组在内存中的长度 sizeof(arr)

    • 求数组长度 sizeof(arr) / sizeof(0)

    • 获取数组在内存中的首地址 , 直接打印数组名,返回内存首地址,默认返回16进制.

      也可以去首元素地址, 取址&arr[0]

    • 数组名一个常量,不可赋值

    • 函数传参传入数组名,函数的形参会转换成数组第一个元素的指针(内存地址)

  • 二维数组

    • 定义方法同一维数组,定义元素数先行后列
    • 定义二维数组时赋值可以是平摊的元素,系统会根据行元素的元素数量分割
    • 行数可以省略,列数不可省略
    • 取值方式arr[行][列]
  • functions

    -

指针

  • 定义方式:<数据类型> * <指针名> = &<变量名>

  • 指针占用内存,4个字节,32位

  • 使用方式:*<指针名>; 数组需要用大括号括起来:int arr_new[] = { *P }; P为一个数组的指针

    • ```c++
      int a = 10;
      int* ip = &a;
      char* cp = (char *)ip; // 指针类型转换
      cout << *cp; // 返回指针的值
      
          
      
      - 空指针:初始化指针变量,空指针指向的内存是不可访问的
      
        - int * P = NULL 如果初始化时不指向NULL,指向的内存地址是不确定的
        - 0-255之间的内存地址是系统占用的,因此不可访问
      
      - 常量指针:const int *p = &a; 
      
        - 特点:指针的指向可以修改,但是指针指向的值不可以修改
      
      - 指针常量:int * const p = &a;
      
        - 特点:指针的指向不可以修改,但是指针指向的值(*p)可以修改
      
      - 无论指针常量还是常量指针都不影响指向同一内存地址的**变量**修改内存中的内容
      
      - 指针移动 p + 1 ,代表向后移动一个单位地址(根据数据类型移动字节数不同 )
      
        
      
      ## 指针与数组
      
      - 数组名是一个不可修改的指针,记录内存地址,
      
      - 将一个数组名作为参数传递给函数式,会被编译器转换为指针,指向数组的第一个值
      
      - 定义函数时,形参用参数  void print_array(int arr[])
      
      - \*(arr[0] + 1) 通过指针获取数组的元素,指针后加的数值代表后移多少个元素*
      
        - ```c++
          int a[] = {0,1,2,3,4,5,6};
          const int * p = a;
          cout << *p << endl << *(p+2) << endl;

引用

  1. &在此不是求地址运算,而是起标识作用。

  2. 类型标识符是指目标变量的类型。

  3. 声明引用时,必须同时对其进行初始化。

  4. 引用声明完毕后,相当于目标变量名有两个名称,即该目标原名称和引用名,且不能再把该引用名作为其他变量名的别名。

结构体创建

  • 结构体属于用户自定义的数据类型,允许用户存储不同的数据类型

  • 定义

    • struct 数据结构名 {结构体成员列表};
  • 创建结构体变量

    #include <iostream>
    #include string
    using namespace std;
    struct student {
        string name;
        int age;
        int score;
    };
    
    int main() {
        student s = { "张三", 20, 120 };
        student * p = &s;
        cout << p->name << endl;
    }
    
  • 嵌套结构体

    #include <iostream>
    #include <string>
    #include <vector>
    
    using namespace std;
    
    
    typedef struct Student {
    public:
        string name;
        int age;
        int score;
    }student;
    
    typedef struct Teacher
    {
    public:
        string name;
        student students[3];
        int num;
    }teacher;
    
    int main(void) {
    
        teacher _teacher = {.name = "aa", .students = {
                                [0] = {.name = "a", .age = 12, .score = 1},
                                [1] = {.name = "b", .age = 12, .score = 1},
                                [2] = {.name = "c", .age = 12, .score = 1}
                            },
                            .num = 3
                           };
    
        cout << _teacher.students[0].age << endl;
    }

    数据类型

    C++对基本类型进行分类,形成了若干个族。类型signed charshortintlong统称为符
    号整型;它们的无符号版本统称为无符号整型;C++11新增了long longboolchar
    wchar_t符号整数无符号整型统称为整型;C++11新增了char16_tchar32_tfloatdouble
    long double统称为浮点型。整数和浮点型统称算术(arithmetic)类型。

    内存的基本单位是位(bit), bit可以看做开关有0、1两种表示

    通常一个字节有8bit(不同的系统里也有可能是16/24/32/64),则一个字节可以表示0-255

    判断数据类型的方法

    #include <iostream>
    #include <typeinfo> 
    int main(){
     using namespace std;
     int v1 = 1;
     cout << typeid(v1).name() << endl;
     return 0;
    }

    bool

    布尔变量的值可以是true或false,在c++中与0/1可互换

    十进制 30, 8进制027, 16进制 0x27, 不同进制数字只是方便输入,在系统中存储都会转换为2进制,而cout时都是输出10进制

    整型

    • short 2字节(至少16位)
    • int 2字节
    • long 4字节
    • long long 4字节
    • 可以使用sizeof来获取占用字节数,climits类中定义常量CHAR_BIT来记录每个字节的位数
    • 可使用unsigned来定义无符号类型,
    • 数值超出范围不会报错,但会返回意料之外的结果,导致程序bug,要慎重选择数据类型
    • 当有大型整型数组或明确有节省内存的需求时才有必要使用short
    • 代码中的整数常量除非是数值过大不能存储为int或者使用后缀指定类型,否则在编译过程中都将会存储为int类型,后缀U表示无符号,L表示long,大小写与顺序不限
    • 十六进制由于常会用来表示内存地址,所以系统会优先尝试保存为unsigned int

    浮点数

    指数表示法: d.dddE+n指的是将小数点向右移n位,而d.dddE-n指的是将小数点向左移n位。之所以称为“浮点”,就是因为小数点可移动

    • float 至少允许32位有效数字
    • double 至少允许48位有效数字,且不少于float
    • long double 和double一致
    • 指数范围在+-37, 可以从头文件cfloatfloat.h中找到系统的限制
    • cout.setf(ios_base::fixed, ios_base::floatfield);使用这条命令可以打印小数点后多余的0
    • 常数默认存储为double类型
    • 浮点数相比整数而言,精度更低,运算更慢,但是表示的数值范围更大

    char 字符

    • 只占一个字节
    • 存储10进制的ASCII码
    • 0 - 9 < A - Z < a - z
    • 48 - 57 < 65 - 90 < 97 - 122
    • \n 010 \t 009 \\ 092
    • 可以使用cout.put()将一个整数输出为对应的字符
    • 对于中文等其他ASCII码无法表示的字符可以用wchar_t, char16_t, char32_t等表示

    强制类型转换

    int a = 10;
    float a = (float)a
    int *ip = a;
    char *cp = (char *)ip;

    运算符

    • 三目运算符

      • int a = <表达式1> ?<表达式2> :<表达式3>

      • 如果表达式1为真,返回表达式2的结果,如果为假则返回表达式3的结果

      • 三目运算符返回的是变量本身,可以继续赋值

      int a=10;
      int b=2;
      a>b?a:b == 100
      // (bool ? true_v : false_v)   
      //x = true_v if bool else false_v
      // Result:a=100, b=2
    • 除法与取模

      • 两个整数的除法运算结果仍为整数
      • 取模运算只能在整数间运算
    • 或:|| 与:&& 非:!

    • 前置递增(递减)与后置递增(递减)

    • & 获取变量指针

    • 位运算

    • 整型提升:

      1. 如果有一个操作数的类型是long double,则将另一个操作数
        转换为long double。
      2. 否则,如果有一个操作数的类型是double,则将另一个操作
        数转换为double。
      3. 否则,如果有一个操作数的类型是float,则将另一个操作数
        转换为float。
      4. 否则,说明操作数都是整型,因此执行整型提升。
      5. 在这种情况下,如果两个操作数都是有符号或无符号的,且
        其中一个操作数的级别比另一个低,则转换为级别高的类型。
      6. 如果一个操作数为有符号的,另一个操作数为无符号的,且
        无符号操作数的级别比有符号操作数高,则将有符号操作数转换为无符
        号操作数所属的类型。
      7. 否则,如果有符号类型可表示无符号类型的所有可能取值,
        则将无符号操作数转换为有符号操作数所属的类型。
      8. 否则,将两个操作数都转换为有符号类型的无符号版本。

    逻辑机构

    • switch(表达式){case 结果 : break;}
      • 当case 语句执行后,后面如果没有break打断,则后面的case不再判断,直接执行
      • 为防止执行多个结果,每个case下都应有break打断循环
      • default默认结果
    • while{} 与do()while{}
    • for 循环
      • for each
      • for(int i=0; i<100;i++){}
    • goto FLAG FLAG:
      • 跳转到对应行数运行,不推荐使用,降低可读性

    格式化字符串

    • %s 字符串

    • %d 整数

函数

  • c++中不可以嵌套定义函数
  • 函数传参
    • 值传递
    • 地址传递

分文件的编写

  1. 头文件(.h)中声明函数
  2. .cpp文件中定义函数
  3. 源文件中调用#include "***.h"

c语言关键字

关键字 说明
auto 声明自动变量
break 跳出当前循环
case 开关语句分支
char 声明字符型变量或函数返回值类型
const 定义常量,如果一个变量被 const 修饰,那么它的值就不能再被改变
continue 结束当前循环,开始下一轮循环
default 开关语句中的”其它”分支
do 循环语句的循环体
double 声明双精度浮点型变量或函数返回值类型
else 条件语句否定分支(与 if 连用)
enum 声明枚举类型
extern 声明变量或函数是在其它文件或本文件的其他位置定义
float 声明浮点型变量或函数返回值类型
for 一种循环语句
goto 无条件跳转语句
if 条件语句
int 声明整型变量或函数
long 声明长整型变量或函数返回值类型
register 声明寄存器变量
return 子程序返回语句(可以带参数,也可不带参数)
short 声明短整型变量或函数
signed 声明有符号类型变量或函数
sizeof 计算数据类型或变量长度(即所占字节数)
static 声明静态变量
struct 声明结构体类型
switch 用于开关语句
typedef 用以给数据类型取别名
unsigned 声明无符号类型变量或函数
union 声明共用体类型
void 声明函数无返回值或无参数,声明无类型指针
volatile 说明变量在程序执行中可被隐含地改变
while 循环语句的循环条件

常用库

c++标准库不像C语言一样需要带有后缀

  1. iostream, c语言对应stdio.h+ctype.h输入输出,字符类
    • cout << 插入到标准输出流对象, 可以连续使用<<插入, 建议分行书写同一条命令
    • cin >> 将数据输入到程序中
    • cin.get() 获取输入,按回车结束获取
    • cin >> x >> y 将数据输入到两个变量中
    • endl 换行; 强制刷新数据流
  2. string字符串类
  3. cstring,c语言对应string.h字符串处理函数
  4. cmath, c语言对应math.h`数学函数
  5. cstdlib, c语言对应stdlib.h内存动态分配函数
  6. std,标准库名称空间

跳转语句

goto Flag 跳转到 Flag:

  • 使用冒号定义标记

评论
  目录