Sirius' blog Sirius' blog
首页
  • 学习笔记

    • 《C++》
    • 《MATLAB》
    • 《Python》
  • 学习笔记

    • 《Git》
    • 《CMake》
  • 技术文档
  • 博客搭建
  • 学习
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Sirius0v0

怕什么真理无穷,进一寸有一寸的欢喜
首页
  • 学习笔记

    • 《C++》
    • 《MATLAB》
    • 《Python》
  • 学习笔记

    • 《Git》
    • 《CMake》
  • 技术文档
  • 博客搭建
  • 学习
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 基础

    • 程序的内存模型
    • CC++指针
    • CC++引用
    • CC++类与对象
    • CC++运算符重载
    • CC++继承
    • CC++多态
    • CC++文件操作
  • Cpp小记
    • Cpp输入与输出
      • 格式化输出
    • 函数
      • 默认参数
      • 函数重载
      • 函数模板
    • 字符串
      • 字符串处理函数
      • 字符串类 #include <string>
    • 引用
      • 引用作为函数形参
      • 引用作为函数返回值
    • 指针
      • 函数指针用法举例
    • 动态分配内存
      • 应用动态分配的数组
    • 自定义数据类型
      • 定义与使用
      • 结构体
      • 共用体
      • 枚举类型
    • 链表
      • 结点
      • 创建链表的常用方法
      • 销毁链表DestroyList(&L)
      • 链表的运算
  • C++学习笔记-220705-V1
  • 进阶

  • 奇思妙用

  • 库的使用

  • 《C++》学习笔记
Sirius0v0
2021-02-19
目录

Cpp小记

# C++

# Cpp输入与输出

# 格式化输出

// 需要#include<iomanip>

bool v;
int a, m, n;
double x, y, z, p, f;
float f1;

cin >> boolalpha >> v;
cin >> oct >> a >> hex >> m >> dec >> n;
cin >> p >> f >> f1 >> x >> y >> z;
cout << v << ' ' << boolalpha << v << ' ' << noboolalpha << v;
cout << a << ' ' << p << ' ' << a*p;
cout << hex << m << ' ' << oct << m << ' ' << dec << m;
cout << showbase << hex << m << ' ' << oct << m << ' ' << dec << m;
cout.precision(5);
cout << x << ' ' << y << ' ' << z;
cout << fixed << x << ' ' << y << ' ' << z;
cout << scientific << x << ' ' << y << ' ' << z;
cout << left << setw(6) << n;
cout.width(6);
cout << right << n;
cout << setw(10) << 77 << ' ' << setfill('0') << setw(10) << 77;
cout << fixed << setprecision(5) << f << ' ' << setprecision(9) << f;
cout << showpos << 1 << ' ' << 0 << ' ' << -1;
cout << noshowpos << 1 << ' ' << 0 << ' ' << -1;
return 0;

# 函数

# 默认参数

int add(int x = 1, int y = 2)
{
    return x + y
}

int main()
{
    add(5,5)	// 5+5=10
	add(4)		// 4+2=6
    add()		// 1+2=3
}

  • 声明函数及定义函数中 择其一进行设置缺省值

  • 设置缺省值应从右向左设置

# 函数重载

当函数名相同,函数参数列表、参数个数、参数类型不同时则进行重载

# 函数模板

// 函数模板定义语法
template <typename T>
T abs(T x)
{
    return x<0?-x:x;
}

# 字符串

# 字符串处理函数<string.h>

// 输入输出
gets();
puts();
    
// 复制
strcpy(str1,str2); //复制2到1
strcpy(str1,str2,4);	//复制2的前四个到1
    
// 连接
strcat(str1,str2);
strncat(str1,str2,4);    

// 比较
strcmp(str1, str2);

// 计算长度
strlen(str);
    
// 字符串转换为数值
f = atof("123.456");	// f = 123.456
i = atoi("-123");	// i = -123

# 字符串类 #include <string>

string str1 = "ABCDEFGHIJKLMN";
str1.c_str();	// string转换为C风格的字符串,返回char指针
str1.copy(S1, n, pos);	// 把str1中pos开始的n个字符复制到S1字符数组
str1.assign(S1, n);	// 将C风格的S1前n个字符赋值给str1

// 计算长度
str1.size();
str1.length();

// 检查字符串是否为空
str1.empty();

// 获得子字符串
str1.substr(2,4);	// 从下标2往后4个字符串 "CDEF"

// 查找字符串
str1.find("DEF", pos);	// 从pos开始查找,返回第一个字符下标位置

// 删除字符
str1.erase(3,5); 	// 从3开始删5个

// 增加字符
str1.append("12345",1,3);	// 在str1后添加"12345"从1开始后三个字符"234"

// 替换和插入
str1.replace(p0.n0,S1,n);	// 将p0开始的n0个字符换为S1前n个字符
str1.replace(p0,n0,str2,pos,n);	// 将p0开始的n0个字符替换为str2从pos开始的n个字符
str1.insert(p0,S1,n);	//在p0插入S1前n个字符
str1.insert(p0,str2,pos,n);	// 在p0插入str2从pos开始n个字符

# 引用

  • 引用的同时进行初始化;

    int x;
    int &r = x;	// 给x起个别名r
    
  • 引用主要把它作为函数形参使用,如此使用直观简单方便;

# 引用作为函数形参

void swap(int &a, int &b)
{
    int t;
    t = a, a = b, b = t;
}

int main(){
    int x = 10,y = 20;
    swap(x,y);
    cout << x << ',' << y;
    return 0;
}

# 引用作为函数返回值

  • 三种返回对比

    • 返回数值

      int max(int a, int b){
          return (a>b?a:b);
      }
      int main(){
          int x = 10, y = 20,z;
          z = max(x,y);
          cout << z;
          return 0;
      }
      
    • 返回指针

      int* max(int a, int b){
          return (a>b?&a:&b);
      }
      int main(){
          int x = 10, y = 20,z;
          z = max(x,y);
          cout << *z;
          return 0;
      }
      
    • 返回引用

      int& max(int &a, int &b){
          return (a>b?a:b);
      }
      int main(){
          int x = 10, y = 20,z;
          z = max(x,y);
          cout << z;
          return 0;
      }
      

# 指针

# 函数指针用法举例

求解

#include <iostream>
#include <cmath>

double integral(double a, double b, double (*f)(double x)){
    // 求解定积分
    int n = 1000, i ;
    double h, x, s = 0.0;
    h = (b - a)/n;
    for(i = 1; i <= n ; i++){
        x = a + (i-1)*h;
        s = s + (f(x) + f(x+h))*h/2;
    }
    return s;
}

double f1(double x){
    return 1+x;
}

double f2(double x){
    return x*x*x;
}

int main(){
    double a, b;
    std::cin >> a >> b;
    std::cout << (integral(a, b, f1) + integral(a, b, f2)) << std::endl;
    return 0;
}

# 动态分配内存

int *p1, *p2;
char *pz1, *pz2;
p1 = new int;		// 分配整型空间
p2 = new int(10);	// 分配整型空间,且幅初值10
pz1 = new char[80];
pz2 = new char[5][80];

delete p1;
delete [] pz1;

# 应用动态分配的数组

// 计算N*N二维数组的元素平均值
#include <iostream>

double AVE(double *A, int N){
    int i, j, sum = 0;
    for (i = 0; i < N ; i++){
        for (j = 0; j < N ; j++){
            sum += *(A+i*N+j);
        }
    }
    return sum/(N*N);
}
int main(){
    int i, j, n = 4;
    std::cin >> n;
    double *A = new double[n*n];
    for ( i = 0; i < n; i++){
        for ( j = 0; j < n; j++){
            std::cin >> *(A+i*n+j);
        }
    }
    std::cout << "detA = " << AVE(A,n);
    delete [] A;
    return 0;
}

# 自定义数据类型

# 定义与使用

(以结构体为例)

struct STUDENT{
    int no;
    char name[21];
    char sex;
    int age;
    char qq[11];
    double score;
};				// 定义结构体

STUDENT LiHua, XiaoMing;	// 实例化1
struct DATE{
    int year,month,day;
} d1, d2;					// 在定义时实例化

# 结构体

# 一维结构体数组

struct POINT{
    int x,y;
};

POINT points[100];

# 共用体

union GONGYONG{
    int m,n;
    char a,b;
};
  • 共用体内存长度是所有成员内存长度的最大值
  • 结构体内存长度是所有成员内存长度之和
/*在初始化只能初始化一个(因为成员共用一个存储空间)*/
GONGYONG x = {678};
GONGYONG y = {6,7,8,9}	// 错误!

# 枚举类型

enum DAYS {MON, TUE, WED, THU, FRI, SAT, SUN};
  • 默认第一个值为0, 后一个值为前一个值加一

  • 可指定值

    enum COLORS {RED = 10, GREEN = 8, BLUE, BLACK, PINK};
    // BLUE = 9, BLACK = 10, PINK = 11;
    

# 链表

# 结点

struct LNode{
    // 单链表结点类型
    ElemType data;
    LNode *next;
};
typedef LNode* LinkList;	// LinkList为单链表指针类型

头结点 -> 开始结点 -> ...... -> 尾结点

  • 可分为如下几类:
    • 单链表:指向下一个结点地址
    • 双链表:一个指向前一个结点地址,一个指向下一个结点地址;
    • 循环单链表:尾结点指向头结点
    • 循环双链表:尾结点一个指向头结点,头结点一个指向尾结点。

# 创建链表的常用方法

# 头插法CreateLinkF(&L, n, input())

#include <iostream>

typedef int ElemType;

struct LNode{
    // 单链表结点类型
    ElemType data;
    LNode *next;
};
typedef LNode* LinkList;	// LinkList为单链表指针类型

void input(ElemType *ep){
    std::cin >> *ep;
}

void CreateLinkF(LinkList *L, int n, void (*input)(ElemType*)){
    LinkList s;
    *L = new LNode;	// 创建头结点
    (*L)->next = NULL;	// 初始时为空表
    for (; n > 0; n--){// 创建n个结点列表
    	s = new LNode;	// 创建新结点
        input(&s->data);
        /*总让头结点指向新生成的结点*/
        s->next = (*L)->next;
        (*L)->next = s;
    }
    
}

int main(){
    LinkList L;
    int n;
    std::cin >> n;
    CreateLinkF(&L, n, input);
    return 0;
}

# 尾插法CreateLinkR(&L, n, input())

#include <iostream>

typedef int ElemType;

struct LNode{
    // 单链表结点类型
    ElemType data;
    LNode *next;
};
typedef LNode* LinkList;	// LinkList为单链表指针类型

void input(ElemType *ep){
    std::cin >> *ep;
}

void CreateLinkR(LinkList *L, int n, void (*input)(ElemType*)){
    LinkList p, s;
    p = *L = new LNode;	// 创建头结点
    for (; n > 0; n--){// 创建n个结点列表
    	s = new LNode;	// 创建新结点
        input(&s->data);
        /*p总指向新生成的s结点*/
        p->next = s;
        p = s;
    }
    p->next = NULL;
    
}

int main(){
    LinkList L;
    int n;
    std::cin >> n;
    CreateLinkF(&L, n, input);
    return 0;
}

# 销毁链表DestroyList(&L)

void Destroy(LinkList *L){
    LinkList q, p = *L;
    while(p != NULL){
        q = p->next;
        delete p;
        p = q;
    }
    *L = NULL;
}

# 链表的运算

# 遍历

void ListTraverse(LinkList L, void (*visit)(ElemType*)){
    LinkList p = L->next;
    while(p != NULL){
        visit(&(p->next));
        p = p->next;
    }
}

void visit(ElemType *ep){
    std::cout << *ep << " ";
}

# 查找结点

int LocateElem(LinkList L, ElemType e, int (*compare)(ElemType*, ElemType*)){
    // 返回L中第一个与e满足关系compare()的元素位置
    int i = 0;
    LinkList p = L->next;
    while(p != NULL){
        i++;
        if (compare(&(p->data), &e)){
            return i;
        }
        p = p->next;
    }
    return 0;
}

int compare(ElemType *ep1, ElemType *ep2){
    if(*ep1 == *ep2){
        return 1;
    }
    return 0;
}

# 插入结点

int ListInsert(LinkList *L, int i, ElemType e){
    LinkList s, p = *L;
    while(p != NULL && i > 1){// 寻找第i-1个结点
        p = p->next;
        i--;
    }
    if (p == NULL || i < 1){// i过大或过小(不合法)
        return 0;
    }
    s = new LNode;
    s->data = e;
    s->next = p->next;
    p->next = s;
    return 1;
}

# 删除结点

int ListDelete(LinkList *L, int i, ElemType *ep){
    // 删除第i个结点并返回其值
    LinkList p = NULL, q = *L;
    while(q != NULL && i >= 1){
        p = q;
        q = q->next;
        i--;
    }
    // p是i-1, q是i
    if (p == NULL || q == NULL){
        return 0;
    }
    p->next = q->next;
    if(ep != NULL){
        *ep = q->data;
    }
    delete q;
    return 1;
}
编辑 (opens new window)
#Cpp
上次更新: 2023/08/09, 13:21:24
CC++文件操作
C++学习笔记-220705-V1

← CC++文件操作 C++学习笔记-220705-V1→

最近更新
01
ipopt优化库配置及使用
07-21
02
ubuntu离线安装包的方法
07-21
03
其它控件的使用
03-05
更多文章>
Theme by Vdoing | Copyright © 2020-2024 Sirius0v0 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式