跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

C++ 初步学习(需 C 语言基础)

综述由AI生成对比了 C 与 C++ 在基本框架、头文件、输入输出、数据类型、强弱类型、const 修饰、三元运算符、引用、函数参数、重载、命名空间、结构体、字符串处理、swap 函数、运算符重载及排序函数等方面的区别。重点介绍了 C++ 中引用的使用、const 常量的特性以及 string 类的基本操作,适合有 C 语言基础的初学者入门。

板砖工程师发布于 2026/3/25更新于 2026/6/132 浏览

基本框架

#include <iostream>
using namespace std;
int main() {
    return 0;
}

头文件

在 C++ 中,头文件通常使用尖括号引用,例如 <cmath>。

输入和输出

int num = -1;
char c = 'a';
cin >> num >> c;
cout << num << c << endl; // endl 为换行

无需额外说明输入输出格式。

基本数据类型

C 语言和 C++ 的基本数据类型几乎相同。bool 类型在 C++ 中不需要头文件,可以使用 boolalpha 打印 true 和 false。

bool compare(int a, int b) { return a > b; }
cout << boolalpha << compare(2, 3) << endl; // 输出 false

强弱类型

C 语言:强类型,弱检查

void* p = NULL;
int* p1 = p; // 类型不符,但不会报错
int* p2 = NULL;
void* p3 = p2;

该程序不会报错。

C++:强类型,弱检查

void* p = NULL;
int* p1 = p; // 类型不符,void 无法直接转为其他类型,必须强制转换
p = (int*)p; // 正确
int* p1_null = NULL;
void* p2 = p1_null; // 任意类型的均可以转化为 void 类型

NULL 在 C 语言里面打印出来是 0,但是 nullptr 会编译错误(类型不符),更加安全。

const

const 在 C 语言里只是表示 const 修饰的变量为只读变量,并不是一个常量,但是在 C++ 里面是常量。

C 语言 (const 修饰的变量被放在栈区)

const int n = 18;
int arr[n]; // 此处编译器会报错,const 不是常量
int* p1 = &n;
*p1 = 20;
printf("%d", n); // 此处 n 的值被间接修改为 20

C++ (const 是常量,被放在堆区)

const int n = 90;
int arr[n]; // 可以正常编译
int* p1 = (const int*)&n;
*p1 = 20;
cout << n << *p1 << endl; // 此处 n 还是等于 90,但是*p1 是 20
// p1 指向的是 n 的数据赋值在栈区的地址,不会去改变 n 原本的值,但是为了和 C 语言兼容,他会隐藏拷贝过来的地址,显示的是堆区的地址,因此&n 和 p1 的地址是一样的。

同样的道理对于字符串字面量,在 C++ 里面 char *str="你好" 是错误的,必须用 const char *。

三元运算符

在 C 语言里面三元运算符返回的是一个数值,不是一个可以修改的左值,但是 C++ 里面返回可以是一个左值,变量。

C 语言

int a = 6;
int b = 5;
int c = (a > b ? a : b); // 正确
(a > b ? a : b) = 20; // 这种写法在 C 语言里面具有语法错误

C++

int a = 6;
int b = 5;
int c = (a > b ? a : b); // 正确
(a > b ? a : b) = 20; // 这种写法在 C++ 里面同样正确

引用

C 语言里面函数里面改变参数的值要用到指针。

void swap(int* a, int* b) {
    int t = *a;
    *a = *b;
    *b = t;
}
int x = 1, y = 2;
swap(&x, &y);

C++ 里面引入引用的概念。

int x = 10;
int& r = x; /*r 是 x 的别名,r 和 x 指向同一块内存,对 r 的操作 = 对 x 的操作*/
r = 20;
printf("%d\n", x); // 20

函数参数

C 语言

void inc(int* x) { (*x)++; }
inc(&a); // 调用

C++

void inc(int& x) { x++; }
inc(a); // 调用直接传入值但是起到了指针的效果

函数返回值的区别

C 语言

int* f() {
    static int x = 10;
    return &x;
} // 改函数返回的是一个指针

C++

int& f() {
    static int x = 10;
    return x;
}
f() = 100; // 直接修改 x

函数重载

一般情况下 int 和 double 类型的加法运算要写两个名字不同的函数。

int IntAdd(int a, int b) { return a + b; }
double DoubleAdd(double a, double b) { return a + b; }

函数重载可以让两个函数的名字相同(在同一个作用域内,函数名相同,但参数列表不同,编译器可以根据调用时传入的参数来判断到底调用哪一个函数)。

int add(int a, int b) { return a + b; }
double add(double a, double b) { return a + b; }
int main() {
    int a, b;
    cin >> a >> b;
    int x = add(a, b);
    double c, d;
    cin >> c >> d;
    double y = add(c, d);
    return 0;
}

C++ 里面 namespace 的应用

避免名字冲突。

#include <iostream>
using namespace std;
namespace A {
    int x = 10;
    void func1();
}
void A::func1() {
    cout << "hello" << ' ';
}
namespace B {
    int x = 20;
    void func2();
}
void B::func2() {
    cout << "winter vocation" << endl;
}
int main() {
    cout << A::x << ' ' << B::x << endl;
    A::func1();
    B::func2();
    return 0;
}

结构体定义的区别

#include <iostream>
#include <string>
using namespace std;
struct Student {
    string name;
    int age;
    int score[3];
    void setName(string name1) { name = name1; }
    void setAge(int age1) { age = age1; }
    void output() {
        cout << "name: " << name << endl;
        cout << "age: " << age << endl;
    }
    void setScore(int score1[3]) {
        for (int i = 0; i < 3; i++) {
            score[i] = score1[i];
        }
    }
    void outputScore() {
        cout << "chushiscore: ";
        for (int i = 0; i < 3; i++) {
            cout << score[i] << ' ';
        }
        cout << endl;
    }
    void paixu() {
        for (int i = 0; i < 2; i++) {
            for (int j = 0; j < 2 - i; j++) {
                if (score[j] > score[j + 1]) {
                    int temp = score[j];
                    score[j] = score[j + 1];
                    score[j + 1] = temp;
                }
            }
        }
        for (int i = 0; i < 3; i++) {
            cout << score[i] << ' ';
        }
    }
};
int main() {
    Student st;
    st.setName("zhangsan");
    st.setAge(18);
    st.output();
    int arr[3] = {90, 80, 70};
    st.setScore(arr);
    st.outputScore();
    st.paixu();
    return 0;
}

C++ 可以将函数定义在结构体里面,初始化一般都用函数来实现,定义变量的时候可以不加 struct。

string 字符串及其相关函数

  • string 创建字符串,末尾没有'/0'结尾
string s("hello world");
string s1("nihao");
s = s1; // 可以直接进行复制
  • 用 getline 来读取字符串与 fgets 类似,都是以'\n'结尾,可以读取空格但是 getline 可以指定结束条件
string s1, s2;
getline(cin, s1);
getline(cin, s2, 'a');
  • 用 size 计算字符串长度
string s1 = "hello";
string s2 = "world ";
cout << s1.size() << ' ' << s2.size() << endl;
  • 迭代器类似于 C 语言里面对一个字符串设置 start 和 end 指针。begin() 获得指向第一个字符的指针,end() 获得指向最后一个字符的后一个指针
// 用迭代器实现对字符串的遍历
string s1 = "hello";
string::iterator it1 = s1.begin();
string::iterator it2 = s1.end();
cout << it2 - it1 << endl;
while (it1 < it2) {
    cout << *it1;
    it1++;
}
return 0;
  • push_back() 在字符串末尾插入一个字符
string s1 = "hello";
cout << s1 << endl;
s1.push_back(' ');
s1.push_back('w');
s1.push_back('o');
s1.push_back('r');
s1.push_back('l');
s1.push_back('d');
cout << s1 << endl;
return 0;
  • string 类型的字符串可以直接加法运算
string s1("hello");
string s2("world");
s1 += s2;
cout << s1 << endl;
s2 = "hello" + s2;
cout << s2 << endl;
return 0;
  • pop_back 删除末尾字符
string s1("hello");
while (s1.size() >= 1) {
    s1.pop_back();
}
cout << s1 << endl;
return 0;
  • insert 在指定位置插入字符串
string s("hello");
cout << s << endl;
s.insert(1, "xxx");
cout << s << endl;
s.insert(2, 3, 'm');
cout << s << endl;
return 0;
  • find() 返回子串在字符串中第一次出现的起始下标值,未找到返回整数值 npos=18446744073709551615
// find 函数的几种常见用法
string s1 = "hello nihao l lo niidgllhasyudcllo";
string s2("llo");
// size_t n = s1.find(s2); // cout<<n<<endl; //2
// size_t n = s1.find(s2, 6); // cout<<n<<endl; //12
size_t n = s1.find("llo", 6, 2);
cout << n << endl; // 22
  • substr() 截取字符串中指定位置字串的长度,通常和 find 函数一起用
string s1 = "hello nihao";
size_t n = s1.find("ni");
string s3 = s1.substr(n, 2);
cout << s3; // ni
  • string 关系运算 (至少有一个 string 类型的字符串才可以比较)类似于 strcmp 比较 ASCII 码
string s1("hello");
string s2 = " world";
string s3("hello world");
if (s1 == s2) {
    cout << "no" << endl;
}
if (s3 == s1 + s2) {
    cout << "yes" << endl;
}
return 0;

swap 函数

// 数组的交换
int arr1[5] = {1, 2, 3, 4, 5};
int arr2[5] = {6, 7, 8, 9, 10};
swap(arr1, arr2);
for (int e : arr1) {
    cout << e << ' '; // '从 arr1 中依次取出每一个元素,赋值给变量 e',经常用于数组和 for 循环
}

运算符的重载

struct Student {
    string name;
    int age;
    int score[3];
};
ostream& operator<<(ostream &os, const Student &st) {
    os << st.name << endl;
    os << st.age << endl;
    return os;
}
istream& operator>>(istream &is, Student &st) {
    is >> st.name;
    is >> st.age;
    return is;
}
int main() {
    Student st;
    cin >> st;
    cout << st << endl;
    return 0;
}

sort 函数 (类似于 qsort 函数)

#include <iostream>
#include <algorithm>
#include <string>
using namespace std;

// 设计比较函数
bool cmp(int x, int y) { return x > y; }

// 设计仿函数
struct CMP {
    bool operator()(int x, int y) { return x > y; }
} cmp1;

struct Student {
    string name;
    int age;
};

// 结构体排序函数
bool cmp_name(Student s1, Student s2) { return s1.name < s2.name; };

int main() {
    int arr[5] = {3, 1, 4, 5, 2};
    sort(arr, arr + 5);
    for (int i = 0; i < 5; i++) {
        cout << arr[i] << ' ';
    }
    sort(arr, arr + 5, cmp);
    cout << endl;
    for (int i = 0; i < 5; i++) {
        cout << arr[i] << ' ';
    }
    cout << endl;
    string s("treltrhujhbxbghfdshauihiubvhd");
    sort(s.begin(), s.end(), cmp1);
    cout << s << endl;
    Student arrs[3] = {{"zhangsan", 18}, {"lisi", 17}, {"wangwu", 19}};
    sort(arrs, arrs + 3, cmp_name);
    for (int i = 0; i < 3; i++) {
        cout << arrs[i].name << ' ' << arrs[i].age << endl;
    }
    return 0;
}

sort 函数可以比较已经定义的几种数据类型(默认为从小到大排序),如果要按照其他顺序去排序要自定义比较函数或者仿函数。要比较类似于结构体类型的数据也要给他传入一个自定义的比较函数。

目录

  1. 基本框架
  2. 头文件
  3. 输入和输出
  4. 基本数据类型
  5. 强弱类型
  6. const
  7. 三元运算符
  8. 引用
  9. 函数参数
  10. 函数重载
  11. C++ 里面 namespace 的应用
  12. 结构体定义的区别
  13. string 字符串及其相关函数
  14. swap 函数
  15. 运算符的重载
  16. sort 函数 (类似于 qsort 函数)
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 如何入行成为 AI 产品经理?附腾讯、蚂蚁、商汤等大厂面试题
  • 普通程序员学习大模型(LLM)路线与知识体系指南
  • 大语言模型微调概念解析与实战流程指南
  • GitHub Copilot 专业版国内支付升级指南
  • 学生成绩管理系统:Spring Boot 全栈开发实战与优化
  • 宇树 G1 机器人开发入门:有线与无线连接配置
  • 前端三基石:从后端视角理解 HTML、CSS 与 JavaScript
  • ROS2 + Gazebo + PX4 环境搭建与仿真飞行实战
  • Windows 下通过虚拟机安装 macOS 全流程指南
  • AI 科学家系列论文阅读笔记:搜索推理与多智能体工作流
  • Spring Boot 微服务架构设计与实现
  • IDEA 配置 Maven 详细教程
  • Z-Image-Turbo 对比 Stable Diffusion:速度、质量与部署优势详解
  • Stable Diffusion 实现人脸一致的技术方案与实践
  • 前端虚拟列表深度拆解
  • C++ Qt 网络编程:QUdpSocket、QTcpSocket 与 Http 实战
  • 大模型 LangChain 框架基础与使用示例
  • Java 二分查找算法题目实战与解析
  • 哈希算法核心解析:原理、特性与实战应用
  • 极客大挑战 2025 Web 安全题目复现

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online