目录
引用
C++ 引用 vs 指针
C++ 中创建引用
把引用作为参数
把引用作为返回值
日期 & 时间
当前日期和时间
基本的输入输出
I/O 库头文件
标准输出流(cout)
扩展知识
标准输入流(cin)
标准错误流(cerr)
标准日志流(clog)
引用很容易与指针混淆,它们之间有三个主要的不同:
需要注意的是,在某些情况下,指针可能更加灵活和有用。例如,当需要动态分配内存或者在函数中返回指向局部变量的指针时,指针是更好的选择。
总之,引用和指针在C++中都是重要的工具,但它们在某些方面有明显的区别。
在 C++ 中,可以使用“&”符号来声明一个引用。引用是一个变量的别名,它提供了一种简化并改善代码可读性的方式,使得代码更易于理解。以下是创建引用的示例:
#include
int main() {
int num = 10;
int& ref = num;
std::cout << num << std::endl; // 输出:10
std::cout << ref << std::endl; // 输出:10
ref++; // 修改引用也会修改原始变量
std::cout << num << std::endl; // 输出:11
std::cout << ref << std::endl; // 输出:11
return 0;
}
在此示例中,我们首先声明了一个整型变量 num 并将其初始化为10。然后,我们声明了一个引用 ref,它被绑定到 num 变量上。这意味着 ref 现在是 num 的别名,并且两者引用同一块内存地址。
然后,我们使用 ref 来更改变量值,这也会更改 num 的值,因为它们指向相同的变量。最后,我们输出了 num 和 ref 的值,以验证它们确实相同。
需要注意的是,引用必须在声明时初始化,并且不能重新绑定到其他变量。这保证了引用的安全性和稳定性,以避免产生未定义行为。除此之外,在使用引用时,我们无需特别地解引用或使用指针运算符,而是直接像使用变量一样使用它。
引用通常用于函数参数列表和函数返回值。下面列出了 C++ 程序员必须清楚的两个与 C++ 引用相关的重要概念:
在 C++ 中,可以将引用作为函数的参数传递,这样可以实现对传入参数的直接修改或访问。使用引用作为参数可以避免拷贝大的对象,提高程序的效率。以下是使用引用作为参数的示例:
#include
void increment(int& num) {
num++;
}
int main() {
int num = 10;
std::cout << "Before increment: " << num << std::endl; // 输出:Before increment: 10
increment(num);
std::cout << "After increment: " << num << std::endl; // 输出:After increment: 11
return 0;
}
在上面的示例中,我们定义了一个名为 increment 的函数,该函数接受一个整型引用作为参数。在函数内部,我们通过引用直接修改传入的参数值。然后,在 main 函数中,我们声明一个整型变量 num 并初始化为 10。我们调用 increment 函数并将 num 作为参数传递。由于传递的是引用,函数中对参数的修改会直接影响到原始变量 num。
最后,我们输出两次 num 的值,分别是递增前和递增后的值。可以看到,通过引用作为参数传递后,函数中的修改对原始变量产生了影响。
需要注意的是,使用引用作为参数传递时,函数内部对参数的修改会直接反映到原始变量上,因此应谨慎使用。此外,传递引用作为参数时,函数的声明和定义中都需要显式地指定参数为引用类型。
在 C++ 中,可以将引用作为函数的返回值。返回引用可以使函数返回一个别名,以便于对函数返回的对象进行修改或访问。这在一些情况下可以提高代码的效率和可读性。以下是使用引用作为返回值的示例:
#include
int& getLargest(int& num1, int& num2) {
if (num1 > num2) {
return num1;
}
else {
return num2;
}
}
int main() {
int num1 = 10;
int num2 = 20;
int& largest = getLargest(num1, num2);
largest = 30;
std::cout << "Largest number: " << largest << std::endl; // 输出:Largest number: 30
std::cout << "num1: " << num1 << std::endl; // 输出:num1: 10
std::cout << "num2: " << num2 << std::endl; // 输出:num2: 30
return 0;
}
在上面的示例中,我们定义了一个名为 getLargest 的函数,该函数接受两个整型引用作为参数,并返回其中较大的那个引用。在函数内部,我们通过比较两个参数的大小确定要返回的引用。
然后,在 main 函数中,我们声明了两个整型变量 num1 和 num2,并将它们分别初始化为 10 和 20。我们调用 getLargest 函数,并将 num1 和 num2 作为参数传递。由于函数返回的是引用,我们可以将其赋值给一个引用变量 largest。
接下来,我们通过 largest 引用修改了其指向的变量的值,即将其修改为 30。由于 largest 引用和 num1 引用同一块内存地址,所以对 largest 的修改也会影响到 num1。
最后,我们输出了 largest 的值以及 num1 和 num2 的值,以验证它们的确发生了改变。
需要注意的是,当将引用作为返回值时,应确保返回的引用不会指向局部变量或临时对象,以避免产生未定义行为。同时,在使用返回引用的函数时,我们需要注意引用的生命周期,确保返回引用所引用的对象仍然有效。
C++ 标准库没有提供所谓的日期类型。C++ 继承了 C 语言用于日期和时间操作的结构和函数。为了使用日期和时间相关的函数和结构,需要在 C++ 程序中引用
有四个与时间相关的类型:clock_t、time_t、size_t 和 tm。类型 clock_t、size_t 和 time_t 能够把系统时间和日期表示为某种整数。
结构类型 tm 把日期和时间以 C 结构的形式保存,tm 结构的定义如下:
struct tm {
int tm_sec; // 秒 (0~60)
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),其中0代表周日
int tm_yday; // 当年的天数 (0~365)
int tm_isdst; // 夏令时标识符,正常为0,表示当前时区不使用夏令时
};
C++ 标准库提供了一些函数和结构来处理日期和时间操作。下面是一些常用的函数和结构:
tm 结构在 C/C++ 中处理日期和时间相关的操作时,显得尤为重要。tm 结构以 C 结构的形式保存日期和时间。大多数与时间相关的函数都使用了 tm 结构。
下面是一个使用 C++ 标准库来获取当前系统时间、本地时间和协调世界时(UTC)的例子:
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
using namespace std;
using namespace std::chrono;
int main()
{
// 获取当前系统时间
system_clock::time_point now = system_clock::now();
// 转换为 time_t 类型的本地时间和协调世界时(UTC)
time_t now_t = system_clock::to_time_t(now);
struct tm* local_tm = localtime(&now_t);
struct tm* utc_tm = gmtime(&now_t);
// 输出本地时间和协调世界时(UTC)
char buf[100];
strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", local_tm);
cout << "Local time: " << buf << endl;
strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", utc_tm);
cout << "UTC: " << buf << endl;
return 0;
}
输出结果为:
Local time: 2023-11-04 02:51:55
UTC: 2023-11-04 02:51:55
在这个例子中,我们首先使用 system_clock::now() 函数获取当前系统时间的时间点。然后,我们将该时间点转换为 time_t 类型的时间,并使用 localtime() 和 gmtime() 函数将其转换为本地时间和协调世界时(UTC)。最后,我们使用 strftime() 函数将时间格式化为指定的格式,并将其输出到控制台上。
在 strftime() 函数中,第一个参数 buf 是输出字符串的缓冲区,第二个参数 sizeof(buf) 是缓冲区的大小,第三个参数是输出字符串的格式,其中 %Y-%m-%d %H:%M:%S 表示输出年、月、日、小时、分钟和秒,各字段之间用 - 和 : 连接。
C++ 的 I/O 发生在流中,流是字节序列。如果字节流是从设备(如键盘、磁盘驱动器、网络连接等)流向内存,这叫做输入操作。如果字节流是从内存流向设备(如显示屏、打印机、磁盘驱动器、网络连接等),这叫做输出操作。
在C++编程中,以下头文件对于I/O操作是很重要的:
这些头文件是C++标准库提供的,可以在C++程序中使用它们来处理输入和输出。例如,可以使用cin对象从控制台读取用户输入,使用cout对象向控制台输出数据,使用fstream类来读写文件等。
下面是一个简单的示例,演示了如何使用这些头文件进行基本的输入和输出操作:
#include
#include
#include
#include
int main() {
// 输入输出到控制台
int num;
std::cout << "请输入一个整数: ";
std::cin >> num;
std::cout << "你输入的整数是: " << num << std::endl;
// 输入输出到文件
std::ofstream outputFile("output.txt");
if (outputFile.is_open()) {
outputFile << "这是一行文本" << std::endl;
outputFile.close();
}
std::ifstream inputFile("input.txt");
if (inputFile.is_open()) {
std::string line;
while (std::getline(inputFile, line)) {
std::cout << line << std::endl;
}
inputFile.close();
}
return 0;
}
在这个示例中,我们使用iostream头文件中的cin和cout对象来进行基本的控制台输入和输出。同时,我们使用fstream头文件中的ofstream和ifstream类来进行文件的写入和读取操作。
值得注意的是,要正确使用文件流,需要确保文件存在且可访问。上述示例中,我们假设存在名为output.txt和input.txt的文件。
这些头文件提供了丰富的工具和功能,可以满足各种输入和输出需求,使得C++编程中的I/O操作更加灵活和方便。
标准输出流 cout 是 C++ 标准库中最常用的流之一,它用于向控制台或终端输出数据。cout 是一个对象,属于 std 命名空间,定义在
使用 cout 可以将数据输出到标准输出。以下是一些使用 cout 的示例:
#include
int main() {
int number = 10;
std::cout << "Hello, world!" << std::endl; // 输出字符串:Hello, world!
std::cout << "The value of number is: " << number << std::endl; // 输出变量值:The value of number is : 10
double pi = 3.14159;
std::cout << "The value of pi is: " << pi << std::endl; // 输出浮点数:The value of pi is : 3.14159
return 0;
}
在上述示例中,我们使用 << 运算符将数据插入到 cout 流中,并使用 std::endl 操纵符来插入换行符。std::endl 可以实现换行并刷新输出缓冲区。
cout 对象还支持格式化输出,可以使用 std::setw() 和 std::setprecision() 等操纵器来设置输出字段的宽度和精度。例如:
#include
#include
int main() {
double pi = 3.14159;
std::cout << "Default precision: " << pi << std::endl; //输出结果:Default precision : 3.14159
std::cout << std::setprecision(4) << "Precision 4: " << pi << std::endl; //输出结果:Precision 4 : 3.142
std::cout << std::setprecision(2) << "Precision 2: " << pi << std::endl; //输出结果:Precision 2 : 3.1
int num = 25;
std::cout << "Default width: " << num << std::endl; //输出结果:Default width : 25
std::cout << std::setw(6) << "Width 6: " << num << std::endl; //输出结果:Width 6 : 25
std::cout << std::setw(2) << "Width 2: " << num << std::endl; //输出结果:Width 2 : 25
return 0;
}
在上述示例中,我们使用 std::setprecision() 设置浮点数的输出精度,使用 std::setw() 设置整数的输出宽度。
除了上述示例中的基本用法外,cout 还可以与其他流操纵符和 C++ 中的各种数据类型一起使用,以实现更复杂的输出需求。通过灵活使用 cout,可以方便地输出各种数据类型和格式的内容到控制台。
cout.setf 常见的标志:
标志 | 功能 |
---|---|
boolalpha | 可以使用单词”true”和”false”进行输入/输出的布尔值. |
oct | 用八进制格式显示数值. |
dec | 用十进制格式显示数值. |
hex | 用十六进制格式显示数值. |
left | 输出调整为左对齐. |
right | 输出调整为右对齐. |
scientific | 用科学记数法显示浮点数. |
fixed | 用正常的记数方法显示浮点数(与科学计数法相对应). |
showbase | 输出时显示所有数值的基数. |
showpoint | 显示小数点和额外的零,即使不需要. |
showpos | 在非负数值前面显示”+(正号)”. |
skipws | 当从一个流进行读取时,跳过空白字符(spaces, tabs, newlines). |
unitbuf | 在每次插入以后,清空缓冲区. |
internal | 将填充字符回到符号和数值之间. |
uppercase | 以大写的形式显示科学记数法中的”e”和十六进制格式的”x”. |
iostream 中定义的操作符:
操作符 | 描述 | 输入 | 输出 |
---|---|---|---|
boolalpha | 启用boolalpha标志 | √ | √ |
dec | 启用dec标志 | √ | √ |
endl | 输出换行标示,并清空缓冲区 | √ | |
ends | 输出空字符 | √ | |
fixed | 启用fixed标志 | √ | |
flush | 清空流 | √ | |
hex | 启用 hex 标志 | √ | √ |
internal | 启用 internal 标志 | √ | |
left | 启用 left 标志 | √ | |
noboolalpha | 关闭boolalpha 标志 | √ | √ |
noshowbase | 关闭showbase 标志 | √ | |
noshowpoint | 关闭showpoint 标志 | √ | |
noshowpos | 关闭showpos 标志 | √ | |
noskipws | 关闭skipws 标志 | √ | |
nounitbuf | 关闭unitbuf 标志 | √ | |
nouppercase | 关闭uppercase 标志 | √ | |
oct | 启用 oct 标志 | √ | √ |
right | 启用 right 标志 | √ | |
scientific | 启用 scientific 标志 | √ | |
showbase | 启用 showbase 标志 | √ | |
showpoint | 启用 showpoint 标志 | √ | |
showpos | 启用 showpos 标志 | √ | |
skipws | 启用 skipws 标志 | √ | |
unitbuf | 启用 unitbuf 标志 | √ | |
uppercase | 启用 uppercase 标志 | √ | |
ws | 跳过所有前导空白字符 | √ |
iomanip 中定义的操作符:
操作符 | 描述 | 输入 | 输出 |
---|---|---|---|
resetiosflags(long f) | 关闭被指定为f的标志 | √ | √ |
setbase(int base) | 设置数值的基本数为base | √ | |
setfill(int ch) | 设置填充字符为ch | √ | |
setiosflags(long f) | 启用指定为f的标志 | √ | √ |
setprecision(int p) | 设置数值的精度(四舍五入) | √ | |
setw(int w) | 设置域宽度为w | √ |
标准输入流(cin)是C++中用于从用户输入读取数据的输入流对象。它是iostream库中的一个对象,用于与键盘或其他输入设备进行交互。
使用cin对象可以接收不同类型的输入数据,如整数、浮点数、字符、字符串等。以下是一些常见的用法:
1、读取整数:
int num;
cin >> num;
2、读取浮点数:
float num;
cin >> num;
3、读取字符:
char ch;
cin >> ch;
4、读取字符串:
string str;
cin >> str;
需要注意的是,cin以空格、制表符或换行符作为数据的分隔符。当使用>>运算符读取数据时,它会自动忽略前导空白字符,并在遇到分隔符时停止读取。
此外,cin还提供了一些其他功能和成员函数,如判断是否达到文件末尾(eof())、清除错误状态(clear())、忽略指定数量的字符(ignore())等。
以下是一个示例,演示如何使用cin读取用户输入的整数并进行计算:
#include
int main() {
int num1, num2;
std::cout << "Enter the first number: ";
std::cin >> num1;
std::cout << "Enter the second number: ";
std::cin >> num2;
int sum = num1 + num2;
std::cout << "The sum is: " << sum << std::endl;
return 0;
}
以上代码将提示用户输入两个整数,并计算它们的和,最后输出结果。
总之,标准输入流(cin)是C++中用于从用户输入读取数据的对象。它的使用方式简单且灵活,可以方便地获取用户的输入并进行相应的处理。
标准错误流(cerr)是C++中用于输出错误信息的输出流对象。它是iostream库中的一个对象,用于将错误信息输出到屏幕或其他错误输出设备。
与标准输出流(cout)不同,标准错误流不受缓冲区的影响,即错误信息不会被缓存,而是立即输出到目标设备。这使得错误信息能够及时地显示给用户,而不会因为缓冲而产生延迟。
使用cerr对象输出错误信息非常简单,只需使用插入运算符(<<)将错误信息插入到cerr对象中即可。以下是一个示例:
#include
int main() {
int dividend = 10;
int divisor = 0;
if (divisor == 0) {
std::cerr << "Error: Division by zero!" << std::endl;
} else {
int result = dividend / divisor;
std::cout << "Result: " << result << std::endl;
}
return 0;
}
在上述示例中,当除数为0时,我们使用cerr对象输出错误信息"Error: Division by zero!"。该错误信息将会立即显示在屏幕上,不会被缓存。
除了使用cerr对象,还可以使用标准错误流的另一个对象——clog。clog与cerr类似,也是用于输出错误信息的对象,但与cerr不同的是,clog的输出可以被缓存。这意味着错误信息可以在一定条件下进行缓冲,然后一次性输出。这在某些情况下可能更有利于错误信息的处理。
总结起来,标准错误流(cerr)是C++中用于输出错误信息的对象,不受缓冲区影响,能够及时地将错误信息输出到目标设备。它与标准输出流(cout)一起提供了一种方便的方式来管理程序的输入和输出。
标准日志流(clog)是C++中的一个预定义对象,也是iostream库中的一个输出流对象。类似于标准错误流cerr,clog也用于输出程序的日志信息。不同的是,clog对象会缓存输出的日志信息,并在一定条件下进行刷新,以提高程序的效率。
使用clog对象输出日志信息与使用cerr对象非常类似,只需使用插入运算符(<<)将日志信息插入到clog对象中即可。以下是一个示例:
#include
int main() {
int x = 10;
int y = 20;
std::clog << "Starting calculation..." << std::endl;
//执行一些计算并输出中间结果
for (int i = 1; i <= 10; i++) {
int result = x * i + y;
std::clog << "Iteration " << i << ": Result = " << result << std::endl;
}
std::clog << "Calculation completed." << std::endl;
return 0;
}
在上述示例中,我们使用clog对象输出了程序的日志信息,包括开始计算、每次迭代的结果以及计算完成等。这些日志信息被缓存在clog对象中,并在程序执行完毕后一次性输出。
需要注意的是,clog对象的输出可以被缓存,但并不保证缓冲区满后就会立即输出。因此,在需要立即输出日志信息的场景下,建议使用cerr对象。
总之,标准日志流(clog)是C++中用于输出程序日志信息的对象。它与标准输出流(cout)和标准错误流(cerr)一起提供了一种方便的方式来管理程序的输入和输出。