数据类型 七种基本的 C++ 数据类型 类型 关键字 布尔型 bool 字符型 char 整型 int 浮点型 float 双浮点型 double 无类型 void 宽字符型 wchar_t 一些基本类型可以使用一个或多个类型修饰符进行修饰:
signed:表示变量可以存储负数。对于整型变量来说,signed 可以省略,因为整型变量默认为有符号类型 unsigned:表示变量不能存储负数。对于整型变量来说,unsigned 可以将变量范围扩大一倍 short:表示变量的范围比 int 更小。short int 可以缩写为 short long:表示变量的范围比 int 更大。long int 可以缩写为 long long long:表示变量的范围比 long 更大。C++11 中新增的数据类型修饰符 各数据类型的内存和范围 下表显示了各种数据类型在内存中存储值时需要占用的内存,以及该类型的变量所能存储的最大值和最小值
类型 位 范围
char 1 个字节 -128 到 127 或者 0 到 255
unsigned char 1 个字节 0 到 255
signed char 1 个字节 -128 到 127
int 4 个字节 -2147483648 到 2147483647
unsigned int 4 个字节 0 到 4294967295
signed int 4 个字节 -2147483648 到 2147483647
short int 2 个字节 -32768 到 32767
unsigned short int 2 个字节 0 到 65,535
signed short int 2 个字节 -32768 到 32767
long int 8 个字节 -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807
signed long int 8 个字节 -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807
unsigned long int 8 个字节 0 到 18,446,744,073,709,551,615
float 4 个字节 精度型占4个字节(32位)内存空间,+/- 3.4e +/- 38 (7 个数字)
double 8 个字节 双精度型占8 个字节(64位)内存空间,+/- 1.7e +/- 308 (15 个数字)
long double 16 个字节 长双精度型 16 个字节(128位)内存空间,可提供18-19位有效数字
wchar_t 2 或 4 个字节 1 个宽字符
数据类型的声明
cpp 体验AI代码助手 代码解读 复制代码 bool isRight = true; int age = 5; void sum() {
} auto 关键字:自动推导类型声明 auto 关键字在 C++11 中引入,用于自动类型推导。当使用 auto 关键字声明变量时,编译器会根据变量的初始值自动推导出变量的类型。这可以简化代码,避免显式地指定复杂类型
(类似于 C# 和 JavaScript 中的 var 关键字)
cpp 体验AI代码助手 代码解读 复制代码 int a = 42; auto b = a; // 类型推导为 int
unordered_map<int, int> hashtable; // 一个 int-int 的哈希表 auto item = hashtable.find(target - nums[i]); // 用 auto 关键字之后不需要显式的判断 item 的类型 auto 关键字在 C++ 中非常有用,可以用于简化变量声明,特别是在处理复杂类型(如迭代器、模板类型等)时。例如,当使用迭代器遍历容器时,可以使用 auto 关键字来简化迭代器的声明
枚举类型 例如,下面的代码定义了一个颜色枚举,变量 c 的类型为 color。最后,c 被赋值为 "blue"
cpp 体验AI代码助手 代码解读 复制代码 enum color { red, green, blue } c; c = blue; 类型判断 typeid 运算符:可以用于获取一个对象的类型信息,返回一个 type_info 对象(类型的首字母)。例如:
cpp 体验AI代码助手 代码解读 复制代码 int i = 42; float j = 42.5f; std::cout << typeid(i).name() << std::endl; // 输出:i std::cout << typeid(j).name() << std::endl; // 输出:f std::is_same 类型特征:可以用于检查两种类型是否相同。例如:
cpp 体验AI代码助手 代码解读 复制代码 std::cout << std::is_same<int, float>::value << std::endl; // 输出:0 std::cout << std::is_same<int, int>::value << std::endl; // 输出:1 std::is_integral 类型特征:可以用于检查一个类型是否为整型。例如:
cpp
体验AI代码助手
代码解读
复制代码
std::cout << std::is_integral
cpp
体验AI代码助手
代码解读
复制代码
std::cout << std::is_floating_point
cpp
体验AI代码助手
代码解读
复制代码
std::cout << std::is_pointer<int*>::value << std::endl; // 输出:1
std::cout << std::is_pointer
cpp
体验AI代码助手
代码解读
复制代码
std::cout << std::is_array<int[]>::value << std::endl; // 输出:1
std::cout << std::is_array
cpp
体验AI代码助手
代码解读
复制代码
std::cout << std::is_function<int(int)>::value << std::endl; // 输出:1
std::cout << std::is_function
类型转换 隐式类型转换 简单粗暴,但是存在问题。例如将一个 float 类型的值 42.5 转换为 int 类型,由于 int 类型不支持小数部分,因此在进行转换时,小数部分会被截断,只保留整数部分
cpp 体验AI代码助手 代码解读 复制代码 float f = 42.5f; int i = int(f); int i = (int)f; int i = f; 显式类型转换 C 风格的类型转换:使用括号将需要转换的类型括起来,并在前面添加需要转换的类型。例如:
cpp 体验AI代码助手 代码解读 复制代码 int i = 42; float f = (float)i; // C 风格的类型转换 C++ 风格的类型转换:使用 static_cast、dynamic_cast、const_cast 或 reinterpret_cast 进行类型转换。例如:
静态转换static_cast是将一种数据类型的值强制转换为另一种数据类型的值
cpp
体验AI代码助手
代码解读
复制代码
int i = 42;
float f = static_cast
cpp 体验AI代码助手 代码解读 复制代码 class Base {}; class Derived : public Base {}; Base* ptr_base = new Derived; Derived* ptr_derived = dynamic_cast<Derived*>(ptr_base); // 将基类指针转换为派生类指针 常量转换const_cast用于将 const 类型的对象转换为非 const 类型的对象
cpp 体验AI代码助手 代码解读 复制代码 const int i = 10; int& r = const_cast<int&>(i); // 常量转换,将const int转换为int 重新解释转换reinterpret_cast将一个数据类型的值重新解释为另一个数据类型的值,通常用于在不同的数据类型之间进行转换
cpp 体验AI代码助手 代码解读 复制代码 int i = 10; float f = reinterpret_cast<float&>(i); // 重新解释将int类型转换为float类型 数字和字符串互转 字符串转 int、float
cpp
体验AI代码助手
代码解读
复制代码
#include
int main() {
std::string str = "42";
int i = std::stoi(str);
std::cout << "The integer is: " << i << std::endl;
float f = std::stof(str);
std::cout << "The float is: " << f << std::endl;
}
这些函数都需要包含头文件
需要注意的是,这些函数只能将符合特定格式的字符串转换为数字类型。例如,对于 std::stoi,字符串必须以数字开头,可以包含正负号,但不能包含其他字符。对于 std::stof,字符串必须包含小数点和数字,可以包含正负号和指数符号,但不能包含其他字符
int、float 转字符串
cpp
体验AI代码助手
代码解读
复制代码
#include
int main() { int i = 42; float f = 3.14; std::string str1 = std::to_string(i); std::string str2 = std::to_string(f); std::cout << "The integer string is: " << str1 << std::endl; std::cout << "The float string is: " << str2 << std::endl; } 常量 在 C++ 中,有两种简单的定义常量的方式:
使用 #define 预处理器。 使用 const 关键字。 define 预处理器 下面是使用 #define 预处理器定义常量的形式:
cpp 体验AI代码助手 代码解读 复制代码 #define identifier value 具体请看下面的实例:
cpp
体验AI代码助手
代码解读
复制代码
#include
#define LENGTH 10
#define WIDTH 5
#define NEWLINE '\n'
int main() {
int area; area = LENGTH * WIDTH; cout << area; cout << NEWLINE; } const 关键字 您可以使用 const 前缀声明指定类型的常量,如下所示:
cpp 体验AI代码助手 代码解读 复制代码 const type variable = value; 具体请看下面的实例:
cpp
体验AI代码助手
代码解读
复制代码
#include
int main() { const int LENGTH = 10; const int WIDTH = 5; const char NEWLINE = '\n'; int area;
area = LENGTH * WIDTH; cout << area; cout << NEWLINE; } 类型限定符 类型限定符提供了变量的额外信息,用于在定义变量或函数时改变它们的默认行为的关键字。
限定符 含义 const const 定义常量,表示该变量的值不能被修改。。 volatile 修饰符 volatile 告诉该变量的值可能会被程序以外的因素改变,如硬件或其他线程 restrict 由 restrict 修饰的指针是唯一一种访问它所指向的对象的方式。只有 C99 增加了新的类型限定符 restrict mutable 表示类中的成员变量可以在 const 成员函数中被修改 static 用于定义静态变量,表示该变量的作用域仅限于当前文件或当前函数内,不会被其他文件或函数访问 register 用于定义寄存器变量,表示该变量被频繁使用,可以存储在CPU的寄存器中,以提高程序的运行效率。 const 实例
cpp 体验AI代码助手 代码解读 复制代码 const int NUM = 10; // 定义常量 NUM,其值不可修改 const int* ptr = &NUM; // 定义指向常量的指针,指针所指的值不可修改 int const* ptr2 = &NUM; // 和上面一行等价 volatile 实例
cpp 体验AI代码助手 代码解读 复制代码 volatile int num = 20; // 定义变量 num,其值可能会在未知的时间被改变 mutable 实例
cpp 体验AI代码助手 代码解读 复制代码 class Example { public: int get_value() const { return value_; // const 关键字表示该成员函数不会修改对象中的数据成员 } void set_value(int value) const { value_ = value; // mutable 关键字允许在 const 成员函数中修改成员变量 } private: mutable int value_; }; static 实例
cpp 体验AI代码助手 代码解读 复制代码 void example_function() { static int count = 0; // static 关键字使变量 count 存储在程序生命周期内都存在 count++; } register 实例
cpp 体验AI代码助手 代码解读 复制代码 void example_function(register int num) { // register 关键字建议编译器将变量 num 存储在寄存器中 // 以提高程序执行速度 // 但是实际上是否会存储在寄存器中由编译器决定 } 变量作用域 有三个地方可以定义变量:
在函数或一个代码块内部声明的变量,称为局部变量 在函数参数的定义中声明的变量,称为形式参数 在所有函数外部声明的变量,称为全局变量 局部变量和全局变量 例子:
cpp
体验AI代码助手
代码解读
复制代码
#include
int g; // 全局变量声明 int main () { int a, b; // 局部变量声明 // 实际初始化 a = 10; b = 20; g = a + b; cout << g; } 局部变量的值会覆盖全局变量的值,例子:
cpp
体验AI代码助手
代码解读
复制代码
#include
int g; // 全局变量声明 int main () { int g = 10; // 局部变量声明 cout << g; } 变量的作用域可以分为以下几种:
局部作用域:在函数内部声明的变量具有局部作用域,它们只能在函数内部访问。局部变量在函数每次被调用时被创建,在函数执行完后被销毁 全局作用域:在所有函数和代码块之外声明的变量具有全局作用域,它们可以被程序中的任何函数访问。全局变量在程序开始时被创建,在程序结束时被销毁 块作用域:在代码块内部声明的变量具有块作用域,它们只能在代码块内部访问。块作用域变量在代码块每次被执行时被创建,在代码块执行完后被销毁 类作用域:在类内部声明的变量具有类作用域,它们可以被类的所有成员函数访问。类作用域变量的生命周期与类的生命周期相同 块作用域
cpp
体验AI代码助手
代码解读
复制代码
#include
int main() { int a = 10; { int a = 20; // 块作用域变量 std::cout << "块变量: " << a << std::endl; } std::cout << "外部变量: " << a << std::endl; }
// 输出结果 块变量: 20 外部变量: 10 类作用域 可以使用类名和作用域解析运算符 :: 来访问这个变量
cpp
体验AI代码助手
代码解读
复制代码
#include
class MyClass { public: static int class_var; // 类作用域变量 }; int MyClass::class_var = 30; // 使用类名和作用域解析运算符 :: 来访问这个变量 int main() { std::cout << "类变量: " << MyClass::class_var << std::endl; } C++ 内存分区 全局区(Global) 全局区是存放全局变量和静态变量的内存区域,在程序启动时自动分配,在程序结束时自动释放。全局区的内存空间是连续的,由编译器自动管理。全局区的大小也是固定的,因此只能存放较小的数据
常量区(Const) 常量区是存放常量数据的内存区域,如字符串常量、全局常量等。常量区内存只读,不可修改。常量区的内存空间是连续的,由编译器自动管理
栈区(Stack) 栈区是由编译器自动分配和释放的内存区域,存放函数的参数值、局部变量等。栈区内存的分配和释放速度很快,因为它的内存空间是连续的,且由编译器自动管理。栈区的大小是固定的,一般只能存放较小的数据。当函数执行完毕后,栈区内存会自动释放,因此不需要手动释放栈区内存
堆区(Heap) 堆区是由程序员手动分配和释放的内存区域,存放程序运行期间动态分配的内存。堆区的内存空间是不连续的,因此内存分配和释放的速度较慢,但是堆区的内存空间较大,可以存放较大的数据。堆区内存的分配和释放需要使用 new 和 delete 或 malloc 和 free 等函数手动管理
代码区(Code) 代码区是存放程序的可执行代码的内存区域,由操作系统负责管理。代码区的内存空间是只读的,不可修改
运算符 算术运算符 下表显示了 C++ 支持的算术运算符。
假设变量 A 的值为 10,变量 B 的值为 21,则:
运算符 描述 实例
- 把两个操作数相加 A + B 将得到 31
- 从第一个操作数中减去第二个操作数 A - B 将得到 -11
- 把两个操作数相乘 A * B 将得到 210 / 取整 B / A 将得到 2 % 取余 B % A 将得到 1
- 自增运算符,整数值增加 1 A++ 将得到 11
- 自减运算符,整数值减少 1 A-- 将得到 9 关系运算符 下表显示了 C++ 支持的关系运算符。
假设变量 A 的值为 10,变量 B 的值为 20,则:
运算符 描述 实例 == 检查两个操作数的值是否相等,如果相等则条件为真。 (A == B) 不为真。 != 检查两个操作数的值是否相等,如果不相等则条件为真。 (A != B) 为真。 检查左操作数的值是否大于右操作数的值,如果是则条件为真。 (A > B) 不为真。 < 检查左操作数的值是否小于右操作数的值,如果是则条件为真。 (A < B) 为真。
= 检查左操作数的值是否大于或等于右操作数的值,如果是则条件为真。 (A >= B) 不为真。 <= 检查左操作数的值是否小于或等于右操作数的值,如果是则条件为真。 (A <= B) 为真。 逻辑运算符 下表显示了 C++ 支持的关系逻辑运算符。
假设变量 A 的值为 1,变量 B 的值为 0,则:
运算符 描述 实例 && 称为逻辑与运算符。如果两个操作数都 true,则条件为 true。 (A && B) 为 false。 || 称为逻辑或运算符。如果两个操作数中有任意一个 true,则条件为 true。 (A || B) 为 true。 ! 称为逻辑非运算符。用来逆转操作数的逻辑状态,如果条件为 true 则逻辑非运算符将使其为 false。 !(A && B) 为 true。 其他一些重要的运算符 运算符 描述 sizeof sizeof 运算符返回变量的大小。例如,sizeof(a) 将返回 4,其中 a 是整数。 Condition ? X : Y 条件运算符。如果 Condition 为真 ? 则值为 X : 否则值为 Y。 ,(逗号运算符) 逗号运算符会顺序执行一系列运算。整个逗号表达式的值是以逗号分隔的列表中的最后一个表达式的值。 .(点运算符)和 ->(箭头运算符) 成员运算符用于引用类、结构和共用体的成员 ::(双冒号运算符) 用于直接访问命名空间、类、结构体、共用体或枚举类型的成员或静态成员 Cast(强制转换运算符) 强制类型转换,把一种数据类型转换为另一种数据类型。例如,int(2.2000) 将返回 2 &(指针运算符) 指针运算符 & 由变量获取到它的地址。例如 &a 得到变量 a 的地址 *(指针运算符) 指针运算符 * 由地址获取到变量的值。例如 *ptr 得到地址 ptr 指向的变量 逗号运算符(,) 使用逗号运算符是为了把几个表达式放在一起 整个逗号表达式的值为系列中最后一个表达式的值 例子:
cpp
体验AI代码助手
代码解读
复制代码
#include
int main() { int i, j; j = 10; i = (j++, j+100, 999+j); cout << i; // 1010 } 成员运算符(. ->) 成员运算符用于引用类、结构和共用体的(public)成员
cpp 体验AI代码助手 代码解读 复制代码 class Point { public: int x; int y; void print() { std::cout << "(" << x << ", " << y << ")" << std::endl; } };
int main() { /** 点运算符 */ Point p; p.x = 5; // 访问成员变量 p.print(); // 访问成员函数
/* 箭头运算符 */
Point* pPtr = new Point();
pPtr->x = 5; // 访问成员变量
pPtr->print(); // 访问成员函数
delete pPtr;} 双冒号运算符(::) 双冒号运算符用于访问命名空间、枚举类型、类的成员
以下例子中演示访问命名空间 NS 中的成员变量 x,其实 std 也是一个命名空间,其包含了 C++ 标准库中的所有标识符,例如标准输入输出流、容器、算法等等
cpp 体验AI代码助手 代码解读 复制代码 /* 命名空间 / namespace NS { int x = 42; } / 类 / class MyClass { public: static int y; }; / 枚举类型 */ enum Color { RED, GREEN, BLUE };
int MyClass::y = 123; // 访问类的静态成员
int main() { std::cout << NS::x << std::endl; // 访问命名空间成员 std::cout << MyClass::y << std::endl; // 访问类的静态成员 std::cout << Color::RED << std::endl; // 访问枚举类型成员 } 基类也是类的一种,所以访问基类的成员也用双冒号运算符
cpp 体验AI代码助手 代码解读 复制代码 class Base { public: int x; void print() { std::cout << "Base::print()" << x << std::endl; } };
class Derived : public Base { public: void print() { Base::print(); // 调用基类的方法 std::cout << "Derived::print()" << Base::x << std::endl; // 访问基类的成员 } };
int main() { Derived d; d.x = 42; d.print(); } 指针运算符(& *)
cpp
体验AI代码助手
代码解读
复制代码
#include
int main () { int var; int *ptr; // * 运算符也可以用来表示一个指针 int val;
var = 3000;
ptr = &var; // 获取变量 var 的地址,赋值给 ptr val = *ptr; // 获取地址 ptr 指向的变量 var 的值 cout << "Value of var :" << var << endl; cout << "Value of ptr :" << ptr << endl; cout << "Value of val :" << val << endl;
return 0; } 注释 C++ 存在三种注释:
// 一般用于单行注释 /* ... */ 一般用于多行注释 #if 0 ... #endif 条件编译注释
cpp
体验AI代码助手
代码解读
复制代码
#include
int main() { // 这是单行注释
/* 这是注释 */
/*
* 可以多行注释
*/
cout << "Hello World!";
return 0;} 块注释用于程序调试,测试时使用 #if 1 来执行测试代码,发布后使用 #if 0 来屏蔽测试代码
cpp 体验AI代码助手 代码解读 复制代码 #if condition code1 #else code2 #endif 基本的输入和输出 I/O 库头文件 下列的头文件在 C++ 编程中很重要。
头文件 函数和描述
cpp
体验AI代码助手
代码解读
复制代码
#include
using namespace std;
int main( ) { char str[] = "Hello C++"; cout << "Value of str is : " << str << endl; } C++ 编译器根据要输出变量的数据类型,选择合适的流插入运算符来显示值。<< 运算符被重载来输出内置类型(整型、浮点型、double 型、字符串和指针)的数据项。
流插入运算符 << 在一个语句中可以多次使用,如上面实例中所示,endl 用于在行末添加一个换行符
标准输入流(cin)
cpp
体验AI代码助手
代码解读
复制代码
#include
int main( ) { char name[50]; cout << "请输入您的名称: "; cin >> name; cout << "您的名称是: " << name << endl; } 流提取运算符 >> 在一个语句中可以多次使用,如果要求输入多个数据,可以使用如下语句:
cpp 体验AI代码助手 代码解读 复制代码 cin >> name >> age; 这相当于下面两个语句:
cpp 体验AI代码助手 代码解读 复制代码 cin >> name; cin >> age; 标准错误流(cerr) 预定义的对象 cerr 是 iostream 类的一个实例。cerr 对象附属到标准输出设备,通常也是显示屏,但是 cerr 对象是非缓冲的,且每个流插入到 cerr 都会立即输出
cpp
体验AI代码助手
代码解读
复制代码
#include
using namespace std;
int main( ) { char str[] = "Unable to read...."; cerr << "Error message : " << str << endl; } 标准日志流(clog) 预定义的对象 clog 是 iostream 类的一个实例。clog 对象附属到标准输出设备,通常也是显示屏,但是 clog 对象是缓冲的。这意味着每个流插入到 clog 都会先存储在缓冲区,直到缓冲填满或者缓冲区刷新时才会输出
cpp
体验AI代码助手
代码解读
复制代码
#include
using namespace std;
int main( )
{
char str[] = "Unable to read....";
clog << "Error message : " << str << endl;
}
日期和时间
C++ 标准库没有提供所谓的日期类型。C++ 继承了 C 语言用于日期和时间操作的结构和函数。为了使用日期和时间相关的函数和结构,需要在 C++ 程序中引用
有四个与时间相关的类型:clock_t、time_t、size_t 和 tm。类型 clock_t、size_t 和 time_t 能够把系统时间和日期表示为某种整数。
结构类型 tm 把日期和时间以 C 结构的形式保存,tm 结构的定义如下:
cpp 体验AI代码助手 代码解读 复制代码 struct tm { int tm_sec; // 秒,正常范围从 0 到 59,但允许至 61 int tm_min; // 分,范围从 0 到 59 int tm_hour; // 小时,范围从 0 到 23 int tm_mday; // 一月中的第几天,范围从 1 到 31 int tm_mon; // 月,范围从 0 到 11 int tm_year; // 自 1900 年起的年数 int tm_wday; // 一周中的第几天,范围从 0 到 6,从星期日算起 int tm_yday; // 一年中的第几天,范围从 0 到 365,从 1 月 1 日算起 int tm_isdst; // 夏令时 }; 下面是 C/C++ 中关于日期和时间的重要函数。所有这些函数都是 C/C++ 标准库的组成部分,您可以在 C++ 标准库中查看一下各个函数的细节。
函数 描述 time_t time(time_t *time); 该函数返回系统的当前日历时间,自 1970 年 1 月 1 日以来经过的秒数。如果系统没有时间,则返回 -1 char *ctime(const time_t *time); 该返回一个表示当地时间的字符串指针,字符串形式 day month year hours:minutes:seconds year\n\0 struct tm *localtime(const time_t *time); 该函数返回一个指向表示本地时间的 tm 结构的指针 clock_t clock(void); 该函数返回程序执行起(一般为程序的开头),处理器时钟所使用的时间。如果时间不可用,则返回 -1 char * asctime ( const struct tm * time ); 该函数返回一个指向字符串的指针,字符串包含了 time 所指向结构中存储的信息,返回形式为:day month date hours:minutes:seconds year\n\0。 struct tm *gmtime(const time_t *time); 该函数返回一个指向 time 的指针,time 为 tm 结构,用协调世界时(UTC)也被称为格林尼治标准时间(GMT)表示 time_t mktime(struct tm *time); 该函数返回日历时间,相当于 time 所指向结构中存储的时间 double difftime ( time_t time2, time_t time1 ); 该函数返回 time1 和 time2 之间相差的秒数 size_t strftime(); 该函数可用于格式化日期和时间为指定的格式 当前日期和时间 下面的实例获取当前系统的日期和时间,包括本地时间和协调世界时(UTC)
cpp
体验AI代码助手
代码解读
复制代码
#include
int main() { // 基于当前系统的当前日期/时间 time_t now = time(0);
// 把 now 转换为字符串形式 char* dt = ctime(&now);
cout << "本地日期和时间:" << dt << endl;
// 把 now 转换为 tm 结构 tm *gmtm = gmtime(&now); dt = asctime(gmtm); cout << "UTC 日期和时间:"<< dt << endl; }
输出结果: 本地日期和时间:Fri Sep 15 06:44:51 2023 UTC 日期和时间:Fri Sep 15 06:44:51 2023 使用结构 tm 格式化时间 C 库函数 size_t strftime(char *str, size_t maxsize, const char *format, const struct tm *timeptr 根据 format 中定义的格式化规则,格式化结构 timeptr 表示的时间,并把它存储在 str 中。
下面是 strftime() 函数的声明
cpp 体验AI代码助手 代码解读 复制代码 size_t strftime(char *str, size_t maxsize, const char *format, const struct tm *timeptr) str -- 这是指向目标数组的指针,用来复制产生的 C 字符串。 maxsize -- 这是被复制到 str 的最大字符数。 format -- 这是 C 字符串,包含了普通字符和特殊格式说明符的任何组合。这些格式说明符由函数替换为表示 tm 中所指定时间的相对应值。格式说明符是:
cpp 体验AI代码助手 代码解读 复制代码 #include <stdio.h> #include <time.h>
int main () { time_t rawtime; struct tm *info; char buffer[80]; time( &rawtime ); info = localtime( &rawtime ); strftime(buffer, 80, "%Y-%m-%d %H:%M:%S", info); printf("格式化的日期 & 时间 : %s\n", buffer ); }
输出结果: 格式化的日期 & 时间 : 2023-09-15 06:45:54 判断 判断语句 C++ 编程语言提供了以下类型的判断语句。点击链接查看每个语句的细节。
语句 描述 if 语句 一个 if 语句 由一个布尔表达式后跟一个或多个语句组成 if...else 语句 一个 if 语句 后可跟一个可选的 else 语句,else 语句在布尔表达式为假时执行 嵌套 if 语句 您可以在一个 if 或 else if 语句内使用另一个 if 或 else if 语句 switch 语句 一个 switch 语句允许测试一个变量等于多个值时的情况 嵌套 switch 语句 您可以在一个 switch 语句内使用另一个 switch 语句 ? : 运算符 我们已经在前面的章节中讲解了 条件运算符 ? : ,可以用来替代 if...else 语句。它的一般形式如下:
cpp 体验AI代码助手 代码解读 复制代码 Exp1 ? Exp2 : Exp3; 其中,Exp1、Exp2 和 Exp3 是表达式。请注意,冒号的使用和位置
? 表达式的值是由 Exp1 决定的。如果 Exp1 为真,则计算 Exp2 的值,结果即为整个 ? 表达式的值。如果 Exp1 为假,则计算 Exp3 的值,结果即为整个 ? 表达式的值
循环 循环类型 C++ 编程语言提供了以下几种循环类型。点击链接查看每个类型的细节。
循环类型 描述 while 循环 当给定条件为真时,重复语句或语句组。它会在执行循环主体之前测试条件 for 循环 多次执行一个语句序列,简化管理循环变量的代码 do...while 循环 除了它是在循环主体结尾测试条件外,其他与 while 语句类似 嵌套循环 您可以在 while、for 或 do..while 循环内使用一个或多个循环 循环控制语句 循环控制语句更改执行的正常序列。当执行离开一个范围时,所有在该范围中创建的自动对象都会被销毁。
C++ 提供了下列的控制语句。点击链接查看每个语句的细节。
控制语句 描述
break 语句 终止 loop 或 switch 语句,程序流将继续执行紧接着 loop 或 switch 的下一条语句
continue 语句 引起循环跳过主体的剩余部分,立即重新开始测试条件
goto 语句 将控制转移到被标记的语句。但是不建议在程序中使用 goto 语句
字符串
C++ 标准库提供了 string 类类型,需要引入 #include
- 构造字符串
cpp 体验AI代码助手 代码解读 复制代码 string s1(); // si = "" string s2("Hello"); // s2 = "Hello" string s3(4, 'K'); // s3 = "KKKK" string s4("12345", 1, 3); //s4 = "234",即 "12345" 的从下标 1 开始,长度为 3 的子串 注意:string 类不接收一个整型参数或一个字符型参数的构造函数。下面的两种写法是错误的
cpp 体验AI代码助手 代码解读 复制代码 string s1('K'); // 不接收一个字符型参数 string s2(123); // 不接收一个整型参数 2. 求字符串长度
cpp 体验AI代码助手 代码解读 复制代码 string s1 = "hello world"; cout << s1.length() << endl; // 11 cout << s1.size() << endl; // 11 3. 字符串拼接 除了可以使用+和+=运算符对 string 对象执行字符串的连接操作外,string 类还有 append 成员函数,可以用来向字符串后面添加内容。append 成员函数返回对象自身的引用,会改变原字符串。例如:
cpp 体验AI代码助手 代码解读 复制代码 string s1("123"), s2("abc"); s1.append(s2); // s1 = "123abc" s1.append(s2, 1, 2); // s1 = "123abcbc" s1.append(3, 'K'); // s1 = "123abcbcKKK" s1.append("ABCDE", 2, 3); // s1 = "123abcbcKKKCDE",添加 "ABCDE" 的子串(2, 3) 补充见 c.biancheng.net/view/400.ht…
指针 什么是内存地址 每一个变量都有一个内存位置,每一个内存位置都定义了可使用连字号(&)运算符访问的地址,它表示这个变量在内存中的地址
cpp
体验AI代码助手
代码解读
复制代码
#include
using namespace std;
int main () { int var1; char var2[10];
cout << "var1 变量的地址: "; cout << &var1 << endl;
cout << "var2 变量的地址: "; cout << &var2 << endl;
return 0; } 运行结果:
体验AI代码助手 代码解读 复制代码 var1 变量的地址: 0xbfebd5c0 var2 变量的地址: 0xbfebd5b6 什么是指针 指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址。就像其他变量或常量一样,您必须在使用指针存储其他变量地址之前,对其进行声明。指针变量声明的一般形式为:
cpp 体验AI代码助手 代码解读 复制代码 type *var-name; 在这里,type 是指针的基类型,它必须是一个有效的 C++ 数据类型,var-name 是指针变量的名称。用来声明指针的星号 * 与乘法中使用的星号是相同的。但是,在这个语句中,星号是用来指定一个变量是指针。以下是有效的指针声明:
cpp 体验AI代码助手 代码解读 复制代码 int ip; / 一个整型的指针 / double *dp; / 一个 double 型的指针 / float *fp; / 一个浮点型的指针 / char *ch; / 一个字符型的指针 */ 所有指针的值的实际数据类型,不管是整型、浮点型、字符型,还是其他的数据类型,都是一样的,都是一个代表内存地址的长的十六进制数。不同数据类型的指针之间唯一的不同是,指针所指向的变量或常量的数据类型不同
指针的使用 指针的使用一般包括:
定义一个指针变量 把变量地址赋值给指针 访问指针变量中可用地址的值
cpp
体验AI代码助手
代码解读
复制代码
#include
using namespace std;
int main () { int var = 20; // 实际变量的声明 int *ip; // 指针变量的声明
ip = &var; // 在指针变量中存储 var 的地址
cout << "变量 var 的值是:"; cout << var << endl;
// 输出在指针变量中存储的地址 cout << "指针 ip 指向的地址是:"; cout << ip << endl;
// 访问指针中地址的值 cout << "指针 ip 指向的地址存的变量的值是:"; cout << *ip << endl;
return 0; } 运行结果:
cpp 体验AI代码助手 代码解读 复制代码 变量 var 的值是:20 指针 ip 指向的地址是:0xbfc601ac 指针 ip 指向的地址存的变量的值是:20 空指针 赋为 NULL 值的指针被称为空指针
cpp
体验AI代码助手
代码解读
复制代码
#include
using namespace std;
int main () { int *ptr = NULL; cout << "ptr 的值是 " << ptr ; return 0; } 运行结果:
cpp 体验AI代码助手 代码解读 复制代码 ptr 的值是 0 内存地址 0 有特别重要的意义,它表明该指针不指向一个可访问的内存位置。但按照惯例,如果指针包含空值(零值),则假定它不指向任何东西。
如需检查一个空指针,您可以使用 if 语句,如下所示:
cpp 体验AI代码助手 代码解读 复制代码 if(ptr) /* 如果 ptr 非空,则完成 / if(!ptr) / 如果 ptr 为空,则完成 */ 因此,如果所有未使用的指针都被赋予空值,同时避免使用空指针,就可以防止误用一个未初始化的指针。很多时候,未初始化的变量存有一些垃圾值,导致程序难以调试。
指针自增自减比较 指针自增自减比较通常用于数组
指针递增
cpp
体验AI代码助手
代码解读
复制代码
#include
using namespace std; const int MAX = 3;
int main () { int var[MAX] = {10, 100, 200}; int *ptr;
ptr = var; // 指针中的数组地址 // ptr = &var[MAX-1]; // 指针中最后一个元素的地址 for (int i = 0; i < MAX; i++) { cout << "Address of var[" << i << "] = "; cout << ptr << endl;
cout << "Value of var[" << i << "] = ";
cout << *ptr << endl;
ptr++; // 移动到下一个位置} return 0; } 运行结果:
cpp 体验AI代码助手 代码解读 复制代码 Address of var[0] = 0xbfa088b0 Value of var[0] = 10 Address of var[1] = 0xbfa088b4 Value of var[1] = 100 Address of var[2] = 0xbfa088b8 Value of var[2] = 200 指针比较
cpp
体验AI代码助手
代码解读
复制代码
#include
using namespace std; const int MAX = 3;
int main () { int var[MAX] = {10, 100, 200}; int *ptr;
ptr = var; // 指针中第一个元素的地址 int i = 0; while ( ptr <= &var[MAX - 1] ) // 指针指向是否在数组范围内 { cout << "Address of var[" << i << "] = "; cout << ptr << endl;
cout << "Value of var[" << i << "] = ";
cout << *ptr << endl;
// 指向上一个位置
ptr++;
i++;} return 0; } 运行结果:
cpp 体验AI代码助手 代码解读 复制代码 Address of var[0] = 0xbfce42d0 Value of var[0] = 10 Address of var[1] = 0xbfce42d4 Value of var[1] = 100 Address of var[2] = 0xbfce42d8 Value of var[2] = 200 指针数组 在这里,把 ptr 声明为一个数组,由 MAX 个整数指针组成。因此,ptr 中的每个元素,都是一个指向 int 值的指针。下面的实例用到了三个整数,它们将存储在一个指针数组中,如下所示:
cpp
体验AI代码助手
代码解读
复制代码
#include
using namespace std; const int MAX = 3;
int main () { int var[MAX] = {10, 100, 200}; int *ptr[MAX];
for (int i = 0; i < MAX; i++) { ptr[i] = &var[i]; // 赋值为整数的地址 } for (int i = 0; i < MAX; i++) { cout << "Value of var[" << i << "] = "; cout << *ptr[i] << endl; } return 0; } 运行结果:
cpp 体验AI代码助手 代码解读 复制代码 Value of var[0] = 10 Value of var[1] = 100 Value of var[2] = 200 也可以用一个指向字符的指针数组来存储一个字符串列表,如下:
cpp
体验AI代码助手
代码解读
复制代码
#include
using namespace std; const int MAX = 4;
int main () { const char *names[MAX] = { "Zara Ali", "Hina Ali", "Nuha Ali", "Sara Ali", };
for (int i = 0; i < MAX; i++) { cout << "Value of names[" << i << "] = "; cout << names[i] << endl; } return 0; } 运行结果:
cpp 体验AI代码助手 代码解读 复制代码 Value of names[0] = Zara Ali Value of names[1] = Hina Ali Value of names[2] = Nuha Ali Value of names[3] = Sara Ali 指向指针的指针(多级间接寻址) 指向指针的指针是一种多级间接寻址的形式,或者说是一个指针链
指针的指针就是将指针的地址存放在另一个指针里面
通常,一个指针包含一个变量的地址。当我们定义一个指向指针的指针时,第一个指针包含了第二个指针的地址,第二个指针指向包含实际值的位置
image.png
一个指向指针的指针变量必须如下声明,即在变量名前放置两个星号。例如,下面声明了一个指向 int 类型指针的指针:
cpp 体验AI代码助手 代码解读 复制代码 int **var; 当一个目标值被一个指针间接指向到另一个指针时,访问这个值需要使用两个星号运算符,如下面实例所示:
cpp
体验AI代码助手
代码解读
复制代码
#include
using namespace std;
int main () { int var; int ptr; int *pptr;
var = 3000;
// 获取 var 的地址
ptr = &var;
// 使用运算符 & 获取 ptr 的地址
pptr = &ptr;
// 使用 pptr 获取值
cout << "var 值为 :" << var << endl;
cout << "*ptr 值为:" << *ptr << endl;
cout << "**pptr 值为:" << **pptr << endl;
return 0;} 运行结果:
cpp 体验AI代码助手 代码解读 复制代码 var 值为 :3000 ptr 值为:3000 *pptr 值为:3000 多级间接寻址的应用场景 动态内存分配:使用多级指针可以实现动态内存分配,即分配一个指针数组,用于存储多个指针变量的地址,然后再分配每个指针变量所指向的内存空间。 多维数组:在多维数组中,可以使用多级指针来表示二维、三维等多维数组,以便在程序中动态地分配和访问多维数组。 数据结构:在数据结构中,可以使用多级指针来表示链表、树等数据结构,以便在程序中动态地添加、删除和修改节点。 函数指针:在函数指针中,可以使用多级指针来表示指向函数指针的指针,以便在程序中动态地管理函数指针 传递指针给函数 C++ 允许您传递指针给函数,只需要简单地声明函数参数为指针类型即可
下面的实例中,我们传递一个无符号的 long 型指针给函数,并在函数内改变这个值:
cpp
体验AI代码助手
代码解读
复制代码
#include
using namespace std;
// 在写函数时应习惯性的先声明函数,然后在定义函数 void getSeconds(unsigned long *par);
int main () { unsigned long sec; getSeconds( &sec ); cout << "Number of seconds :" << sec << endl // 输出实际值
return 0; }
void getSeconds(unsigned long *par) { *par = time( NULL ); // 获取当前的秒数 return; } 当上面的代码被编译和执行时,它会产生下列结果:
cpp 体验AI代码助手 代码解读 复制代码 Number of seconds : 1695175690 能接受指针作为参数的函数,也能接受数组作为参数,如下所示:
cpp
体验AI代码助手
代码解读
复制代码
#include
double getAverage(int *arr, int size); // 函数声明
int main () { // 带有 5 个元素的整型数组 int balance[5] = {1000, 2, 3, 17, 50}; double avg; avg = getAverage( balance, 5 ); // 传递一个指向数组的指针作为参数 cout << "Average value is: " << avg << endl; // 输出返回值
return 0; }
double getAverage(int *arr, int size)
{
int i, sum = 0;
double avg;
for (i = 0; i < size; ++i)
{
sum += arr[i];
}
avg = double(sum) / size;
return avg;
}
当上面的代码被编译和执行时,它会产生下列结果:
cpp 体验AI代码助手 代码解读 复制代码 Average value is: 214.4 从函数返回指针 C++ 只支持在函数外返回 static 类型的局部变量的地址(因为如果不是 static 类型的变量,函数执行结束后该地址指向的局部变量就被销毁了,返回出来的这个指针就没有意义了)
现在,让我们来看下面的函数,它会生成 10 个随机数,并使用表示指针的数组名(即第一个数组元素的地址)来返回它们,具体如下:
cpp
体验AI代码助手
代码解读
复制代码
#include
using namespace std;
// 要生成和返回随机数的函数 int * getRandom( ) { static int r[5];
srand( (unsigned)time( NULL ) ); // 设置种子 for (int i = 0; i < 5; ++i) { r[i] = rand(); cout << r[i] << endl; }
return r; }
// 要调用上面定义函数的主函数 int main () { int *p; // 一个指向整数的指针
p = getRandom(); for ( int i = 0; i < 5; i++ ) { cout << "*(p + " << i << ") : "; cout << *(p + i) << endl; }
return 0; } 运行结果:
cpp 体验AI代码助手 代码解读 复制代码 624723190 1468735695 807113585 976495677 613357504 *(p + 0) : 624723190 *(p + 1) : 1468735695 *(p + 2) : 807113585 *(p + 3) : 976495677 *(p + 4) : 613357504 引用 引用的本质是一个已存在变量的别名
创建引用
cpp 体验AI代码助手 代码解读 复制代码 int i = 17;
int& r = i; // 成功创建 i 的引用变量 r r 可以读作是"一个初始化为 i 的整型引用"
cpp
体验AI代码助手
代码解读
复制代码
#include
using namespace std;
int main () { // 声明简单的变量 int i; double d;
// 声明引用变量 int& r = i; double& s = d;
i = 5; cout << "Value of i : " << i << endl; cout << "Value of i reference : " << r << endl;
d = 11.7; cout << "Value of d : " << d << endl; cout << "Value of d reference : " << s << endl;
return 0; } 运行结果:
cpp 体验AI代码助手 代码解读 复制代码 Value of i : 5 Value of i reference : 5 Value of d : 11.7 Value of d reference : 11.7 把引用作为参数
cpp
体验AI代码助手
代码解读
复制代码
#include
// 函数声明 void swap(int& x, int& y);
int main () { // 局部变量声明 int a = 100; int b = 200;
cout << "交换前,a 的值:" << a << endl; cout << "交换前,b 的值:" << b << endl;
/* 调用函数来交换值 */ swap(a, b);
cout << "交换后,a 的值:" << a << endl; cout << "交换后,b 的值:" << b << endl;
return 0; }
// 函数定义 void swap(int& x, int& y) { int temp; temp = x; /* 保存地址 x 的值 / x = y; / 把 y 赋值给 x / y = temp; / 把 x 赋值给 y */
return; } 把引用作为返回值 通过使用引用来替代指针,会使 C++ 程序更容易阅读和维护。C++ 函数可以返回一个引用,方式与返回一个指针类似。
当函数返回一个引用时,则返回一个指向返回值的隐式指针。这样,函数就可以放在赋值语句的左边。例如,请看下面这个简单的程序:
cpp
体验AI代码助手
代码解读
复制代码
#include
using namespace std;
double vals[] = {10.1, 12.6, 33.1, 24.1, 50.0};
double& setValues(int i) {
double& ref = vals[i];
return ref; // 返回第 i 个元素的引用,ref 是一个引用变量,ref 引用 vals[i]
}
// 要调用上面定义函数的主函数 int main () {
cout << "改变前的值" << endl; for ( int i = 0; i < 5; i++ ) { cout << "vals[" << i << "] = "; cout << vals[i] << endl; }
setValues(1) = 20.23; // 改变第 2 个元素 setValues(3) = 70.8; // 改变第 4 个元素
cout << "改变后的值" << endl; for ( int i = 0; i < 5; i++ ) { cout << "vals[" << i << "] = "; cout << vals[i] << endl; } return 0; } 运行结果:
cpp 体验AI代码助手 代码解读 复制代码 改变前的值 vals[0] = 10.1 vals[1] = 12.6 vals[2] = 33.1 vals[3] = 24.1 vals[4] = 50 改变后的值 vals[0] = 10.1 vals[1] = 20.23 vals[2] = 33.1 vals[3] = 70.8 vals[4] = 50 当返回一个引用时,要注意被引用的对象不能超出作用域。所以返回一个对局部变量的引用是不合法的,但是,可以返回一个对静态变量的引用。
cpp 体验AI代码助手 代码解读 复制代码 int& func() { int q; //! return q; // 在编译时发生错误 static int x; return x; // 安全,x 在函数作用域外依然是有效的 } 引用和指针的区别 五个主要的不同:
初始化:引用必须在定义时进行初始化,指针可以在任何时候进行初始化 空值:引用不能为空,必须引用某个已经存在的变量,指针可以为空 重定义:引用不能被重新定义,即不能让引用引用另一个变量,指针可以被重新定义 运算符:引用没有自己的运算符,它使用被引用变量的运算符,指针有自己的运算符,如 * 和 -> 内存管理:引用不需要进行内存管理,它不会导致内存泄漏和野指针等问题,指针需要进行内存管理,需要手动分配和释放内存 引用和指针的应用场景 函数参数传递:在函数参数传递中,如果需要修改参数的值,则可以使用指针或引用类型来传递参数。如果参数可以为空,则可以使用指针类型。如果参数不能为空,则可以使用引用类型。例如:
cpp 体验AI代码助手 代码解读 复制代码 // 使用指针传递参数 void func(int* p) { if(p){ *p = 10; } }
// 使用引用传递参数 void func(int& r) { r = 10; } 动态内存分配:在动态内存分配中,需要使用指针类型来存储分配的内存地址,以便后续访问内存中的数据。例如:
cpp 体验AI代码助手 代码解读 复制代码 // 动态分配内存,返回指针 int* p = new int[10];
// 访问内存中的数据 p[0] = 1; 数据结构:在数据结构中,需要使用指针类型来表示数据结构中的节点,以便在程序中动态地添加、删除和修改节点。例如:
cpp 体验AI代码助手 代码解读 复制代码 // 定义链表节点 struct Node { int val; Node* next; };
// 动态分配节点,返回指针 Node* p = new Node;
// 修改节点的值和指针 p->val = 1; p->next = nullptr; 运算符重载:在运算符重载中,需要使用引用类型来实现运算符的重载,以便更加直观和安全地访问数据。例如:
cpp 体验AI代码助手 代码解读 复制代码 // 定义向量类 class Vector { public: // 重载下标运算符 int& operator[](int i) { return data[i]; }
private: int data[10]; };
// 使用引用访问向量元素 Vector v; v[0] = 1; 数组 数组声明 必须声明数组元素类型、数组变量名、数组大小
cpp 体验AI代码助手 代码解读 复制代码 type arrayName [ arraySize ];
如: double balance[10]; 数组初始化 采用花括号 {} 来包含数组
数组大小必须大于等于元素个数 数组大小不填则默认是元素个数
cpp 体验AI代码助手 代码解读 复制代码 double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0}; 数组元素访问
cpp 体验AI代码助手 代码解读 复制代码 double salary = balance[9]; 多维数组 初始化
cpp
体验AI代码助手
代码解读
复制代码
int a[3][4] = {
{0, 1, 2, 3} , /* 初始化索引号为 0 的行 /
{4, 5, 6, 7} , / 初始化索引号为 1 的行 /
{8, 9, 10, 11} / 初始化索引号为 2 的行 */
};
访问
cpp 体验AI代码助手 代码解读 复制代码 int val = a[2][3]; 指向数组的指针
cpp 体验AI代码助手 代码解读 复制代码 double *p; double runoobAarray[10];
p = runoobAarray; p = runoobAarray; 表示把第一个元素的地址存储在 p 中,接下来就可以使用 p、(p+1)、*(p+2) 等来访问数组元素
cpp
体验AI代码助手
代码解读
复制代码
#include
int main () { // 带有 5 个元素的双精度浮点型数组 double runoobAarray[5] = {1000.0, 2.0, 3.4, 17.0, 50.0}; double *p;
p = runoobAarray;
// 输出数组中每个元素的值 cout << "使用指针的数组值 " << endl; for ( int i = 0; i < 5; i++ ) { cout << "*(p + " << i << ") : "; cout << *(p + i) << endl; }
cout << "使用 runoobAarray 作为地址的数组值 " << endl; for ( int i = 0; i < 5; i++ ) { cout << "*(runoobAarray + " << i << ") : "; cout << *(runoobAarray + i) << endl; }
return 0; } 运行结果:
cpp 体验AI代码助手 代码解读 复制代码 使用指针的数组值 *(p + 0) : 1000 *(p + 1) : 2 *(p + 2) : 3.4 *(p + 3) : 17 *(p + 4) : 50 使用 runoobAarray 作为地址的数组值 *(runoobAarray + 0) : 1000 *(runoobAarray + 1) : 2 *(runoobAarray + 2) : 3.4 *(runoobAarray + 3) : 17 *(runoobAarray + 4) : 50 传递数组给函数 三种函数形式参数的声明方式:
cpp 体验AI代码助手 代码解读 复制代码 // 形式参数是一个指针: void myFunction(int *param) {
} // 形式参数是一个已定义大小的数组: void myFunction(int param[10]) {
} // 形式参数是一个未定义大小的数组: void myFunction(int param[]) {
} 例子:
cpp
体验AI代码助手
代码解读
复制代码
#include
double getAverage(int arr[], int size); // 函数声明
int main () { int balance[5] = {1000, 2, 3, 17, 50}; // 带有 5 个元素的整型数组 double avg; avg = getAverage( balance, 5 ); // 传递一个指向数组的指针作为参数 cout << "平均值是:" << avg << endl; // 输出返回值 return 0; }
double getAverage(int arr[], int size)
{
int i, sum = 0;
double avg;
for (i = 0; i < size; ++i)
{
sum += arr[i];
}
avg = double(sum) / size;
return avg;
}
从函数返回数组
由于在函数内部定义的数组属于局部变量,函数执行完后这个局部数组的内存会被释放,返回出来的指针指向的数组已经不存在了,所以不能用局部数组。只能选择用静态数组或动态分配数组:
静态数组 静态数组就是前面加个 static
使用静态数组需要在函数内部创建一个静态数组,并将其地址返回,例如:
cpp 体验AI代码助手 代码解读 复制代码 int* myFunction() { static int myArray[3] = {1, 2, 3}; return myArray; } 让我们来看下面的函数,它会生成 10 个随机数,并使用数组来返回它们
cpp
体验AI代码助手
代码解读
复制代码
#include
using namespace std;
// 要生成和返回随机数的函数 int * getRandom( ) { static int r[5];
// 设置种子 srand( (unsigned)time( NULL ) ); for (int i = 0; i < 5; ++i) { r[i] = rand(); cout << r[i] << endl; }
return r; }
// 要调用上面定义函数的主函数 int main () { // 一个指向整数的指针 int *p;
p = getRandom(); for ( int i = 0; i < 5; i++ ) { cout << "*(p + " << i << ") : "; cout << *(p + i) << endl; }
return 0; } 运行结果:
cpp 体验AI代码助手 代码解读 复制代码 624723190 1468735695 807113585 976495677 613357504 *(p + 0) : 624723190 *(p + 1) : 1468735695 *(p + 2) : 807113585 *(p + 3) : 976495677 *(p + 4) : 613357504 动态分配数组 在函数内部动态分配的数组在函数执行结束时不会自动释放,所以需要调用函数的代码负责释放返回的数组
cpp
体验AI代码助手
代码解读
复制代码
#include
int* createArray(int size) { int* arr = new int[size]; for (int i = 0; i < size; i++) { arr[i] = i + 1; } return arr; }
int main() { int* myArray = createArray(5); // 调用返回数组的函数,得到一个指向数组的指针 for (int i = 0; i < 5; i++) { cout << myArray[i] << " "; } cout << endl; delete[] myArray; // 释放内存 return 0; } 运行结果:
cpp 体验AI代码助手 代码解读 复制代码 1 2 3 4 5
列子: https://infogram.com/9862pdf-1h0n25opqj80z4p https://infogram.com/9862pdf-1h7v4pd0lqn584k https://infogram.com/9862pdf-1hnp27eqdj3yn4g https://infogram.com/9862pdf-1h984wv15g3md2p https://infogram.com/9862pdf-1h1749wqzjvlq2z https://infogram.com/9862pdf-1h0n25opqjyyl4p https://infogram.com/9862pdf-1h7v4pd0lqw9j4k https://infogram.com/9862pdf-1hxj48mqgjpr52v https://infogram.com/9862pdf-1h0r6rzwyqpkw4e https://infogram.com/9862pdf-1h1749wqzjv0l2z
