C++基础(①入门教程)
基础
std::cout
:标准输出流
#include <iostream>int main() {int num = 100;std::cout << "Hello"; // 输出文本std::cout << " World"; // 继续输出,拼接在前一个内容后面std::cout << num; // 输出变量值return 0;
}
输出结果:Hello World100
std::endl
:换行并刷新缓冲区
#include <iostream>int main() {std::cout << "第一行" << std::endl;std::cout << "第二行";return 0;
}
输出结果:
第一行
第二行
指针
指针是 C++ 的核心特性之一,它存储了变量的内存地址。通过指针可以直接操作内存,这在系统级编程中非常重要。
指针的定义与使用
#include <iostream>int main() {int num = 10; // 定义一个整数变量int* ptr = # // 定义指针,存储num的地址(&是取地址符)std::cout << "num的值: " << num << std::endl; // 输出:10std::cout << "num的地址: " << &num << std::endl; // 输出:0x7ffd...(内存地址)std::cout << "指针ptr的值: " << ptr << std::endl; // 输出:与num的地址相同std::cout << "指针指向的值: " << *ptr << std::endl; // 输出:10(*是解引用符,获取指针指向的值)// 通过指针修改变量的值*ptr = 20;std::cout << "修改后num的值: " << num << std::endl; // 输出:20return 0;
}
这是因为 指针ptr
存储的是变量num
的内存地址,而*ptr
表示 “访问指针所指向的内存地址中的值”(即num
本身)。当你通过*ptr = 20
修改时,本质上是直接修改了num
所在内存地址中的数据,因此num
的值会随之改变。
当定义 int num = 10 时,系统会在内存中开辟一块空间存储10,假设这块空间的地址是 0x1234(实际地址由系统分配)。
定义 int* ptr = &num 时,&num 获取了num的内存地址(即0x1234),并将这个地址存到指针ptr中。此时ptr的值就是0x1234。
执行 *ptr = 20 时:
* 是 “解引用运算符”,表示 “找到ptr存储的地址(0x1234)对应的内存空间”。
然后将20写入这个内存空间 —— 而这个空间正是num所占用的空间。
因此,当你后续访问num时,它读取的就是0x1234中的新值20,所以输出会改变。
空指针与野指针
空指针:指向内存地址 0 的指针,表示不指向任何有效对象
int* p = nullptr; // C++11推荐的空指针表示方式(替代NULL)
动态内存管理
C++ 允许手动分配和释放内存,主要通过new
和delete
操作符实现。
动态分配单个变量
#include <iostream>int main() {// 动态分配一个int类型的内存,返回指向该内存的指针int* p = new int;*p = 100; // 给动态内存赋值std::cout << *p << std::endl; // 输出:100// 释放动态分配的内存(必须做,否则会内存泄漏)delete p;p = nullptr; // 释放后将指针置空,避免野指针return 0;
}
动态分配数组
#include <iostream>int main() {int n = 5;// 动态分配一个包含n个int的数组int* arr = new int[n];// 给数组赋值for (int i = 0; i < n; i++) {arr[i] = i * 10;}// 输出数组元素for (int i = 0; i < n; i++) {std::cout << arr[i] << " "; // 输出:0 10 20 30 40}// 释放动态数组(注意要加[])delete[] arr;arr = nullptr;return 0;
}
函数进阶
函数重载(Function Overloading)
允许定义同名函数,但参数列表(类型、个数或顺序)必须不同,编译器会根据调用时的参数自动匹配。
#include <iostream>// 重载函数:求和
int add(int a, int b) {return a + b;
}double add(double a, double b) {return a + b;
}int add(int a, int b, int c) {return a + b + c;
}int main() {std::cout << add(2, 3) << std::endl; // 调用int版本,输出5std::cout << add(2.5, 3.5) << std::endl; // 调用double版本,输出6std::cout << add(1, 2, 3) << std::endl; // 调用三参数版本,输出6return 0;
}
默认参数
函数参数可以指定默认值,调用时如果不传递该参数,则使用默认值。
#include <iostream>// 带默认参数的函数:计算矩形面积
int area(int length, int width = 5) { // width默认值为5return length * width;
}int main() {std::cout << area(10) << std::endl; // 只传length,width用默认值5,输出50std::cout << area(10, 8) << std::endl; // 传递两个参数,输出80return 0;
}
类与对象
访问控制(public, private, protected)
public:类内外均可访问(对外开放的接口)。
private:仅类内部可访问(封装的实现细节)。
protected:类内部和子类可访问(用于继承)。
#include <iostream>
#include <string>class Person {
private:// 私有成员:仅类内可访问int age;public:// 公有成员:外部可访问std::string name;// 构造函数:初始化对象Person(std::string n, int a) : name(n) {setAge(a); // 通过公有方法间接修改私有成员}// 公有方法:外部通过方法访问/修改私有成员void setAge(int a) {if (a > 0) { // 加入校验逻辑age = a;}}void showInfo() {std::cout << "姓名:" << name << ",年龄:" << age << std::endl;}
};int main() {Person p("张三", 20);p.name = "李四"; // 可直接修改公有成员p.setAge(25); // 通过方法修改私有成员(无法直接 p.age = 25)p.showInfo(); // 输出:姓名:李四,年龄:25return 0;
}
核心意义:通过 private
隐藏内部实现,仅暴露必要的 public
接口,实现 “封装”,保证数据安全性。
静态成员(static)
类的静态成员属于 “类本身”,而非某个对象,所有对象共享同一份静态成员。
#include <iostream>class Counter {
private:static int count; // 静态成员变量:所有对象共享public:Counter() {count++; // 每次创建对象,计数器加1}// 静态成员函数:无this指针,只能访问静态成员static int getCount() {return count;}
};// 静态成员变量必须在类外初始化
int Counter::count = 0;int main() {Counter c1, c2, c3;std::cout << "创建了" << Counter::getCount() << "个对象" << std::endl; // 输出:3return 0;
}
继承
继承允许创建新类(子类)复用已有类(父类)的属性和方法,并可以扩展新功能,实现 “代码复用”。
#include <iostream>
#include <string>// 父类(基类)
class Person {
protected: // 受保护成员:子类可访问std::string name;int age;public:Person(std::string n, int a) : name(n), age(a) {}void showBaseInfo() {std::cout << "姓名:" << name << ",年龄:" << age << std::endl;}
};// 子类(派生类):继承自Person
class Student : public Person {
private:int studentId; // 子类新增属性public:// 子类构造函数:必须先初始化父类Student(std::string n, int a, int id) : Person(n, a), studentId(id) {}// 子类新增方法void showStudentInfo() {showBaseInfo(); // 调用父类方法std::cout << "学号:" << studentId << std::endl;}
};int main() {Student s("王五", 18, 1001);s.showStudentInfo();// 输出:// 姓名:王五,年龄:18// 学号:1001return 0;
}
继承方式:public
继承(父类 public
成员仍为 public
,protected
仍为 protected
)、protected
继承、private
继承(较少用)。