C++
1. 基础程序
#include "iostream" // C++头文件
#include "stdio.h" // C 头文件
//using namespace std; // 命名空间
// main() 是程序开始执行的地方
int main() {
std::cout << "Hello, World!" << "\n";
return 0;
}
- C++ 语言定义了一些头文件,这些头文件包含了程序中必需的或有用的信息。上面这段程序中,包含了头文件 。
- 下一行 using namespace std; 告诉编译器使用 std 命名空间。命名空间是 C++ 中一个相对新的概念。
- 下一行 // main() 是程序开始执行的地方 是一个单行注释。单行注释以 // 开头,在行末结束。
- 下一行 int main() 是主函数,程序从这里开始执行。
- 下一行 cout << “Hello World”; 会在屏幕上显示消息 “Hello World”。
- 下一行 return 0; 终止 main( )函数,并向调用进程返回值 0。
2. C++ 标识符
C++ 标识符是用来标识变量、函数、类、模块,或任何其他用户自定义项目的名称。一个标识符以字母 A-Z 或 a-z 或下划线 _ 开始,后跟零个或多个字母、下划线和数字(0-9)。
C++ 标识符内不允许出现标点字符,比如 @、& 和 %。C++ 是区分大小写的编程语言。因此,在 C++ 中,Manpower 和 manpower 是两个不同的标识符。
下面列出几个有效的标识符:
mohd zara abc move_name a_123
myname50 _temp j a23b9 retVal
3. 高级编程语言和低级编程语言
高级编程语言和低级编程语言的主要区别在于它们的抽象级别,以及编程在编写和理解代码时必须关注的细节的数量。
高级编程语言更接近人类语言,抽象级别更高,更易于阅读和编写。它们提供了大量的功能,如内存管理,错误处理,和对象导向编程等。这些语言被设计为更容易理解和使用,尽管在一些情况下,它们可能不如低级语言那样高效。常见的高级编程语言包括 Python,Java,C#,Ruby,JavaScript等。
低级编程语言更接近硬件,更接近机器语言。它们的抽象级别较低,更难以阅读和编写。然而,它们提供了更高的控制程度,允许程序员更精细地控制如何使用硬件资源,如内存和处理器时间。常见的低级编程语言包括C,C++,汇编语言等。
注意,这是一个相对的概念:相对于汇编语言来说,C和C++可被视为高级语言;但相对于Python或Ruby,C和C++又被视为相对低级的语言。
低级编程语言一般分为两类:汇编语言和机器语言。这两种语言更接近计算机硬件,所以称为低级语言。
- 机器语言:这是最基本的编程语言,直接由二进制代码组成,可以直接被计算机硬件理解和执行。机器语言非常依赖特定的硬件架构,对于人类来说几乎是不可读的。
- 汇编语言:汇编语言是一种低级语言,它使用易于理解的符号代码(如 ADD、MOV、SUB 等)来代替二进制代码。每一种汇编指令对应一种机器语言指令。汇编语言也是依赖于特定的硬件架构,但相比机器语言,它的可读性和可编写性都有所提高。
再次强调,虽然 C 和 C++ 被认为是“高级语言”,但与 Java、Python、Ruby 等语言相比,它们也有一些“低级”特性。例如,它们允许程序员直接管理内存和访问硬件,这些在更高级的语言中通常不允许或不需要。
4. C++ 关键字
asm | else | new | this |
auto | enum | operator | throw |
bool | explicit | private | true |
break | export | protected | try |
case | extern | public | typedef |
catch | false | register | typeid |
char | float | reinterpret_cast | typename |
class | for | return | union |
const | friend | short | unsigned |
const_cast | goto | signed | using |
continue | if | sizeof | virtual |
default | inline | static | void |
delete | int | static_cast | volatile |
do | long | struct | wchar_t |
double | mutable | switch | while |
dynamic_cast | namespace | template |
不能当作变量名
5. C++ 中的空格
只包含空格的行,被称为空白行,可能带有注释,C++ 编译器会完全忽略它。
在 C++ 中,空格用于描述空白符、制表符、换行符和注释。空格分隔语句的各个部分,让编译器能识别语句中的某个元素(比如 int)在哪里结束,下一个元素在哪里开始。因此,在下面的语句中:
int age;
在这里,int 和 age 之间必须至少有一个空格字符(通常是一个空白符),这样编译器才能够区分它们。另一方面,在下面的语句中:
fruit = apples + oranges; // 获取水果的总数
fruit 和 =,或者 = 和 apples 之间的空格字符不是必需的,但是为了增强可读性,您可以根据需要适当增加一些空格。
6. C++ 注释
程序的注释是解释性语句,您可以在 C++ 代码中包含注释,这将提高源代码的可读性。所有的编程语言都允许某种形式的注释。
C++ 支持单行注释和多行注释。注释中的所有字符会被 C++ 编译器忽略。
C++ 注释一般有两种:
-
//
- 一般用于单行注释。 -
/* ... */
- 一般用于多行注释。
注释以 // 开始,直到行末为止。例如:
#include <iostream>
using namespace std;
int main() {
// 这是一个注释
cout << "Hello World!";
return 0;
}
也可以放在语句后面:
#include <iostream>
using namespace std;
int main()
{
cout << "Hello World!"; // 输出 Hello World!
return 0;
}
当上面的代码被编译时,编译器会忽略 //
这是一个注释 和 //
输出 Hello World!,最后会产生以下结果:
Hello World!
C++ 注释以 /*
开始,以 */
终止。例如:
#include <iostream>
using namespace std;
int main() {
/* 这是注释 */
/* C++ 注释也可以
* 跨行
*/
cout << "Hello World!";
return 0;
}
在 /*
和 */
注释内部,//
字符没有特殊的含义。在 //
注释内,/*
和 */
字符也没有特殊的含义。因此,您可以在一种注释内嵌套另一种注释。例如:
/* 用于输出 Hello World 的注释
cout << "Hello World"; // 输出 Hello World
*/
7. C++ 数据类型
使用编程语言进行编程时,需要用到各种变量来存储各种信息。变量保留的是它所存储的值的内存位置。这意味着,当您创建一个变量时,就会在内存中保留一些空间。
您可能需要存储各种数据类型(比如字符型、宽字符型、整型、浮点型、双浮点型、布尔型等)的信息,操作系统会根据变量的数据类型,来分配内存和决定在保留内存中存储什么。
7.1 基本的内置类型
C++ 为程序员提供了种类丰富的内置数据类型和用户自定义的数据类型。下表列出了七种基本的 C++ 数据类型:
类型 | 关键字 |
布尔型 | bool |
字符型 | char |
整型 | int |
浮点型 | float |
双浮点型 | double |
无类型 | void |
宽字符型 | wchar_t |
其实 wchar_t 是这样来的:
typedef short int wchar_t;
所以 wchar_t 实际上的空间是和 short int 一样。
一些基本类型可以使用一个或多个类型修饰符进行修饰:
- signed
- unsigned
- short
- long
下表显示了各种变量类型在内存中存储值时需要占用的内存,以及该类型的变量所能存储的最大值和最小值。
**注意:**不同系统会有所差异,一字节为 8 位。
**注意:**默认情况下,int、short、long都是带符号的,即 signed。
**注意:**long int 8 个字节,int 都是 4 个字节,早期的 C 编译器定义了 long int 占用 4 个字节,int 占用 2 个字节,新版的 C/C++ 标准兼容了早期的这一设定。
bool: 对错,例如 1 > 2 >>> false
类型 | 位 | 范围 |
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 个宽字符 |
从上表可得知,变量的大小会根据编译器和所使用的电脑而有所不同。
下面实例会输出您电脑上各种数据类型的大小。
#include<iostream>
#include <limits>
using namespace std;
int main()
{
cout << "type: \t\t" << "************size**************"<< endl;
cout << "bool: \t\t" << "所占字节数:" << sizeof(bool);
cout << "\t最大值:" << (numeric_limits<bool>::max)();
cout << "\t\t最小值:" << (numeric_limits<bool>::min)() << endl;
cout << "char: \t\t" << "所占字节数:" << sizeof(char);
cout << "\t最大值:" << (numeric_limits<char>::max)();
cout << "\t\t最小值:" << (numeric_limits<char>::min)() << endl;
cout << "signed char: \t" << "所占字节数:" << sizeof(signed char);
cout << "\t最大值:" << (numeric_limits<signed char>::max)();
cout << "\t\t最小值:" << (numeric_limits<signed char>::min)() << endl;
cout << "unsigned char: \t" << "所占字节数:" << sizeof(unsigned char);
cout << "\t最大值:" << (numeric_limits<unsigned char>::max)();
cout << "\t\t最小值:" << (numeric_limits<unsigned char>::min)() << endl;
cout << "wchar_t: \t" << "所占字节数:" << sizeof(wchar_t);
cout << "\t最大值:" << (numeric_limits<wchar_t>::max)();
cout << "\t\t最小值:" << (numeric_limits<wchar_t>::min)() << endl;
cout << "short: \t\t" << "所占字节数:" << sizeof(short);
cout << "\t最大值:" << (numeric_limits<short>::max)();
cout << "\t\t最小值:" << (numeric_limits<short>::min)() << endl;
cout << "int: \t\t" << "所占字节数:" << sizeof(int);
cout << "\t最大值:" << (numeric_limits<int>::max)();
cout << "\t最小值:" << (numeric_limits<int>::min)() << endl;
cout << "unsigned: \t" << "所占字节数:" << sizeof(unsigned);
cout << "\t最大值:" << (numeric_limits<unsigned>::max)();
cout << "\t最小值:" << (numeric_limits<unsigned>::min)() << endl;
cout << "long: \t\t" << "所占字节数:" << sizeof(long);
cout << "\t最大值:" << (numeric_limits<long>::max)();
cout << "\t最小值:" << (numeric_limits<long>::min)() << endl;
cout << "unsigned long: \t" << "所占字节数:" << sizeof(unsigned long);
cout << "\t最大值:" << (numeric_limits<unsigned long>::max)();
cout << "\t最小值:" << (numeric_limits<unsigned long>::min)() << endl;
cout << "double: \t" << "所占字节数:" << sizeof(double);
cout << "\t最大值:" << (numeric_limits<double>::max)();
cout << "\t最小值:" << (numeric_limits<double>::min)() << endl;
cout << "long double: \t" << "所占字节数:" << sizeof(long double);
cout << "\t最大值:" << (numeric_limits<long double>::max)();
cout << "\t最小值:" << (numeric_limits<long double>::min)() << endl;
cout << "float: \t\t" << "所占字节数:" << sizeof(float);
cout << "\t最大值:" << (numeric_limits<float>::max)();
cout << "\t最小值:" << (numeric_limits<float>::min)() << endl;
cout << "size_t: \t" << "所占字节数:" << sizeof(size_t);
cout << "\t最大值:" << (numeric_limits<size_t>::max)();
cout << "\t最小值:" << (numeric_limits<size_t>::min)() << endl;
cout << "string: \t" << "所占字节数:" << sizeof(string) << endl;
// << "\t最大值:" << (numeric_limits<string>::max)() << "\t最小值:" << (numeric_limits<string>::min)() << endl;
cout << "type: \t\t" << "************size**************"<< endl;
return 0;
}
本实例使用了 endl,这将在每一行后插入一个换行符,<<
运算符用于向屏幕传多个值,sizeof()
运算符用来获取各种数据类型的大小。
当上面的代码被编译和执行时,它会产生以下的结果,结果会根据所使用的计算机而有所不同:
type: ************size**************
bool: 所占字节数:1 最大值:1 最小值:0
char: 所占字节数:1 最大值: 最小值:?
signed char: 所占字节数:1 最大值: 最小值:?
unsigned char: 所占字节数:1 最大值:? 最小值:
wchar_t: 所占字节数:4 最大值:2147483647 最小值:-2147483648
short: 所占字节数:2 最大值:32767 最小值:-32768
int: 所占字节数:4 最大值:2147483647 最小值:-2147483648
unsigned: 所占字节数:4 最大值:4294967295 最小值:0
long: 所占字节数:8 最大值:9223372036854775807 最小值:-9223372036854775808
unsigned long: 所占字节数:8 最大值:18446744073709551615 最小值:0
double: 所占字节数:8 最大值:1.79769e+308 最小值:2.22507e-308
long double: 所占字节数:16 最大值:1.18973e+4932 最小值:3.3621e-4932
float: 所占字节数:4 最大值:3.40282e+38 最小值:1.17549e-38
size_t: 所占字节数:8 最大值:18446744073709551615 最小值:0
string: 所占字节数:24
type: ************size**************
7.2 typedef 声明
您可以使用 typedef 为一个已有的类型取一个新的名字。下面是使用 typedef 定义一个新类型的语法:
typedef type newname;
例如,下面的语句会告诉编译器,feet 是 int 的另一个名称:
typedef int feet;
现在,下面的声明是完全合法的,它创建了一个整型变量 distance:
feet distance;
8. C++ 变量类型
8.1 C++ 中的变量定义
变量定义就是告诉编译器在何处创建变量的存储,以及如何创建变量的存储。
变量定义指定一个数据类型,并包含了该类型的一个或多个变量的列表,如下所示:
type variable_list;
在这里,type 必须是一个有效的 C++ 数据类型,可以是 char、wchar_t、int、float、double、bool 或任何用户自定义的对象,variable_list 可以由一个或多个标识符名称组成,多个标识符之间用逗号分隔。下面列出几个有效的声明:
int i, j, k;
char c, ch;
float f, salary;
double d;
行 int i, j, k; 声明并定义了变量 i、j 和 k,这指示编译器创建类型为 int 的名为 i、j、k 的变量。
变量可以在声明的时候被初始化(指定一个初始值)。初始化器由一个等号,后跟一个常量表达式组成,如下所示:
type variable_name = value;
下面列举几个实例:
extern int d = 3, f = 5; // d 和 f 的声明
int d = 3, f = 5; // 定义并初始化 d 和 f
byte z = 22; // 定义并初始化 z
char x = 'x'; // 变量 x 的值为 'x'
不带初始化的定义:带有静态存储持续时间的变量会被隐式初始化为 NULL(所有字节的值都是 0),其他所有变量的初始值是未定义的。
8.2 C++ 中的变量声明
变量声明向编译器保证变量以给定的类型和名称存在,这样编译器在不需要知道变量完整细节的情况下也能继续进一步的编译。变量声明只在编译时有它的意义,在程序连接时编译器需要实际的变量声明。
当您使用多个文件且只在其中一个文件中定义变量时(定义变量的文件在程序连接时是可用的),变量声明就显得非常有用。您可以使用 extern 关键字在任何地方声明一个变量。虽然您可以在 C++ 程序中多次声明一个变量,但变量只能在某个文件、函数或代码块中被定义一次。
尝试下面的实例,其中,变量在头部就已经被声明,但它们是在主函数内被定义和初始化的:
#include <iostream>
using namespace std;
// 变量声明
extern int a, b;
extern int c;
extern float f;
int main ()
{
// 变量定义
int a, b;
int c;
float f;
// 实际初始化
a = 10;
b = 20;
c = a + b;
cout << c << endl ;
f = 70.0/3.0;
cout << f << endl ;
return 0;
}
cin
是 C++ 中的一个预定义对象,用于从标准输入设备(通常是键盘)接收输入。它是 <iostream>
库的一部分。cin
对象与 >>
运算符一起使用,通常被称为“从输入流中提取”的运算符。
以下是使用 cin
的基本示例:
#include <iostream>
using namespace std;
int main() {
int a;
cout << "Please enter an integer value: ";
cin >> a;
cout << "You entered: " << a << endl;
return 0;
}
在这个示例中,cin >> a;
这行代码从用户处获取输入,并将输入的值存储在整数变量 a
中。
注意,当 cin
与多个变量一起使用时,可以连续使用 >>
运算符,如下所示:
#include <iostream>
using namespace std;
int main() {
int a, b;
cout << "Please enter two integer values: ";
cin >> a >> b;
cout << "You entered: " << a << " and " << b << endl;
return 0;
}
在这个例子中,cin >> a >> b;
会首先等待用户输入一个值,存储在 a
中,然后再等待用户输入另一个值,存储在 b
中。这两个输入可以用空格或换行符分隔。
此外,cin
的返回值本身是一个 istream
对象,可以用来检查输入操作是否成功。例如,如果试图从非数字输入中读取一个数字,cin
会进入“失败状态”,并且返回的 istream
对象在布尔上下文中会被视为 false
。例如:
#include <iostream>
using namespace std;
int main() {
int a;
cout << "Please enter an integer value: ";
if (cin >> a) {
cout << "You entered: " << a << endl;
} else {
cout << "That was not a valid integer!" << endl;
}
return 0;
}
在这个例子中,如果用户输入了非数字字符,例如 “hello”,那么 cin >> a
将失败,将导致错误消息的输出。
9. C++ 变量作用域
一般来说有三个地方可以定义变量:
- 在函数或一个代码块内部声明的变量,称为局部变量。
- 在函数参数的定义中声明的变量,称为形式参数。
- 在所有函数外部声明的变量,称为全局变量。
作用域是程序的一个区域,变量的作用域可以分为以下几种:
- 局部作用域:在函数内部声明的变量具有局部作用域,它们只能在函数内部访问。局部变量在函数每次被调用时被创建,在函数执行完后被销毁。
- 全局作用域:在所有函数和代码块之外声明的变量具有全局作用域,它们可以被程序中的任何函数访问。全局变量在程序开始时被创建,在程序结束时被销毁。
- 块作用域:在代码块内部声明的变量具有块作用域,它们只能在代码块内部访问。块作用域变量在代码块每次被执行时被创建,在代码块执行完后被销毁。
- 类作用域:在类内部声明的变量具有类作用域,它们可以被类的所有成员函数访问。类作用域变量的生命周期与类的生命周期相同。
9.1 局部变量
#include <iostream>
using namespace std;
int main ()
{
// 局部变量声明
int a, b;
int c;
// 实际初始化
a = 10;
b = 20;
c = a + b;
cout << c;
return 0;
}
9.2 全局变量
在所有函数外部定义的变量(通常是在程序的头部),称为全局变量。全局变量的值在程序的整个生命周期内都是有效的。
全局变量可以被任何函数访问。也就是说,全局变量一旦声明,在整个程序中都是可用的。下面的实例使用了全局变量和局部变量:
#include <iostream>
using namespace std;
// 全局变量声明
int g;
int main ()
{
// 局部变量声明
int a, b;
// 实际初始化
a = 10;
b = 20;
g = a + b;
cout << g;
return 0;
}
在程序中,局部变量和全局变量的名称可以相同,但是在函数内,局部变量的值会覆盖全局变量的值。下面是一个实例:
#include <iostream>
using namespace std;
// 全局变量声明
int g = 20;
int main ()
{
// 局部变量声明
int g = 10;
cout << g;
return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:
10
在C++中,变量的作用域可以分为全局变量和局部变量。
全局变量:全局变量是在函数外部定义的变量,它在程序的生命周期内都是存在的,可以被程序中的任何函数访问。全局变量存储在内存的全局存储区中,占用静态的存储空间。
局部变量:局部变量是在函数内部定义的变量,它只能在该函数内部使用。当函数结束时,局部变量的生命周期就结束了。局部变量存储在栈上,当函数调用完成后,这部分内存就可以被回收。
下面是一个简单的代码示例:
#include <iostream>
using namespace std;
// 全局变量声明
int g = 20;
int main () {
// 局部变量声明
int g = 10;
cout << "局部变量 g = " << g << endl;
cout << "全局变量 g = " << ::g << endl;
return 0;
}
在这个例子中,我们声明了两个名为 g 的变量。一个是全局的,另一个是 main() 函数内的局部变量。
在 main() 函数内,我们使用了局部变量 g。当我们使用 ::g 时,它访问的是全局变量 g。这是因为 :: 是一个作用域解析运算符,它可以用来访问全局变量。
这个程序的输出将是:
局部变量 g = 10
全局变量 g = 20
这就是全局变量和局部变量的基本概念和一个简单的示例。
在C++中,局部变量只能在其被声明的函数或代码块中被访问。如果我们试图在其他地方访问它,编译器会报错。以下是一个例子:
#include <iostream>
using namespace std;
void someFunction() {
// 局部变量
int x = 10;
cout << "在 someFunction 中,x = " << x << endl;
}
int main() {
someFunction();
// 下面这行代码会导致编译错误,因为 x 在这里是不可见的
cout << "在 main 中,x = " << x << endl;
return 0;
}
在这个例子中,变量 x 是在 someFunction() 中声明的,所以它只能在这个函数中被访问。当我们试图在 main() 函数中访问 x 时,编译器会报错,因为在这个作用域中,x 是未定义的。
9.3 初始化局部变量和全局变量
当局部变量被定义时,系统不会对其初始化,您必须自行对其初始化。定义全局变量时,系统会自动初始化为下列值:
数据类型 | 初始化默认值 |
int | 0 |
char | ‘\0’ |
float | 0 |
double | 0 |
pointer | NULL |
正确地初始化变量是一个良好的编程习惯,否则有时候程序可能会产生意想不到的结果。
块作用域指的是在代码块内部声明的变量:
#include <iostream>
int main() {
int a = 10;
{
int a = 20; // 块作用域变量
std::cout << "块变量: " << a << std::endl;
}
std::cout << "外部变量: " << a << std::endl;
return 0;
}
以上实例中,内部的代码块中声明了一个名为 a 的变量,它与外部作用域中的变量 a 同名。内部作用域中的变量 a 将覆盖外部作用域中的变量 a,在内部作用域中访问 a 时输出的是20,而在外部作用域中访问 a 时输出的是 10。
当上面的代码被编译和执行时,它会产生下列结果:
块变量: 20
外部变量: 10
花括号是一种标点符号,也被称为大括号或者大括号。在英文中,它们被称为 “curly brackets” 或 “braces”。它们通常用于表示一组或一系列的元素,或者在数学和计算机科学中表示一组特定的元素或操作。
在计算机编程中,花括号经常被用来定义代码块。例如,在C,C++,Java,JavaScript,PHP,Ruby等许多编程语言中,花括号用于定义函数,循环,条件语句等的范围。
这是一个花括号的例子:
{
"这是": "一个例子"
}
在这个例子中,花括号被用来定义一个JSON对象,这是一种常见的数据格式。
9.4 类作用域
类作用域指的是在类内部声明的变量:
#include <iostream>
class MyClass {
public:
static int class_var; // 类作用域变量
};
int MyClass::class_var = 30;
int main() {
std::cout << "类变量: " << MyClass::class_var << std::endl;
return 0;
}
以上实例中,MyClass 类中声明了一个名为 class_var 的类作用域变量。可以使用类名和作用域解析运算符 ::
来访问这个变量。在 main() 函数中访问 class_var 时输出的是 30。
在C++编程语言中,类(Class)是一个用户自定义的数据类型,它用于表示现实生活中的某种类型的实体。在类中,你可以定义变量(也被称为属性)和函数(也被称为方法),它们被统一组织在一个名为类的结构中。在这个结构中,变量和函数的作用域由它们所处的类决定。
类作用域是指类内部的所有成员(即,变量和函数)都只在类的范围内可见和可访问。这种作用域的存在帮助保护数据的完整性,防止代码的误用,提高代码的重用性。
在C++中,类的作用域有三种级别:公有(public)、私有(private)和保护(protected)。
- 公有(Public):在类的公有部分声明的成员可以被任何函数访问,无论该函数是否是类的成员函数。它们也可以被类的任何对象以及派生类访问。
- 私有(Private):在类的私有部分声明的成员只能被类的成员函数、友元函数以及类内部访问,不能被类的对象或派生类访问。
- 保护(Protected):在类的保护部分声明的成员可以被类的成员函数、友元函数、类内部以及派生类访问,但不能被类的对象访问。
以下是一个关于类作用域的示例:
class MyClass {
public:
int publicVar;
private:
int privateVar;
protected:
int protectedVar;
};
在这个例子中,publicVar
可以在类的外部被访问和修改,privateVar
只能在类的内部被访问和修改,而protectedVar
可以在类的内部和派生类中被访问和修改,但不能被类的对象直接访问。
记住,在类中未显式指定访问修饰符时,默认为私有(private)。
10. C++ 常量
常量是固定值,在程序执行期间不会改变。这些固定的值,又叫做字面量。
常量可以是任何的基本数据类型,可分为整型数字、浮点数字、字符、字符串和布尔值。
常量就像是常规的变量,只不过常量的值在定义后不能进行修改。
10.1 整数常量
整数常量可以是十进制、八进制或十六进制的常量。前缀指定基数:0x 或 0X 表示十六进制,0 表示八进制,不带前缀则默认表示十进制。
整数常量也可以带一个后缀,后缀是 U 和 L 的组合,U 表示无符号整数(unsigned),L 表示长整数(long)。后缀可以是大写,也可以是小写,U 和 L 的顺序任意。
下面列举几个整数常量的实例:
212 // 合法的
215u // 合法的
0xFeeL // 合法的
078 // 非法的:8 不是八进制的数字
032UU // 非法的:不能重复后缀
以下是各种类型的整数常量的实例:
85 // 十进制
0213 // 八进制
0x4b // 十六进制
30 // 整数
30u // 无符号整数
30l // 长整数
30ul // 无符号长整数
10.2 浮点常量
浮点常量由整数部分、小数点、小数部分和指数部分组成。您可以使用小数形式或者指数形式来表示浮点常量。
当使用小数形式表示时,必须包含整数部分、小数部分,或同时包含两者。当使用指数形式表示时, 必须包含小数点、指数,或同时包含两者。带符号的指数是用 e 或 E 引入的。
下面列举几个浮点常量的实例:
3.14159 // 合法的
314159E-5L // 合法的
510E // 非法的:不完整的指数
210f // 非法的:没有小数或指数
.e55 // 非法的:缺少整数或分数
10.3 布尔常量
布尔常量共有两个,它们都是标准的 C++ 关键字:
- true 值代表真。
- false 值代表假。
我们不应把 true 的值看成 1,把 false 的值看成 0。
10.4 字符常量
字符常量是括在单引号中。如果常量以 L(仅当大写时)开头,则表示它是一个宽字符常量(例如 L’x’),此时它必须存储在 wchar_t 类型的变量中。否则,它就是一个窄字符常量(例如 ‘x’),此时它可以存储在 char 类型的简单变量中。
字符常量可以是一个普通的字符(例如 ‘x’)、一个转义序列(例如 ‘\t’),或一个通用的字符(例如 ‘\u02C0’)。
在 C++ 中,有一些特定的字符,当它们前面有反斜杠时,它们就具有特殊的含义,被用来表示如换行符(\n)或制表符(\t)等。下表列出了一些这样的转义序列码:
转义序列 | 含义 |
\ | \ 字符 |
’ | ’ 字符 |
" | " 字符 |
? | ? 字符 |
\a | 警报铃声 |
\b | 退格键 |
\f | 换页符 |
\n | 换行符 |
\r | 回车 |
\t | 水平制表符 |
\v | 垂直制表符 |
\ooo | 一到三位的八进制数 |
\xhh . . . | 一个或多个数字的十六进制数 |
下面的实例显示了一些转义序列字符:
#include <iostream>
using namespace std;
int main()
{
cout << "Hello\tWorld\n\n";
cout << "yunshu";
return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:
Hello World
10.5 字符串常量
字符串字面值或常量是括在双引号 “” 中的。一个字符串包含类似于字符常量的字符:普通的字符、转义序列和通用的字符。
您可以使用 \ 做分隔符,把一个很长的字符串常量进行分行。
下面的实例显示了一些字符串常量:
#include <iostream>
#include <string>
using namespace std;
int main() {
string greeting = "hello, runoob";
cout << greeting;
cout << "\n"; // 换行符
string greeting2 = "hello, \
runoob";
cout << greeting2;
return 0;
}
hello, runoob
hello, runoob
10.6 定义常量
在 C++ 中,有两种简单的定义常量的方式:
使用 #define 预处理器。
使用 const 关键字。
10.7 #define 预处理器
下面是使用 #define 预处理器定义常量的形式:
#define identifier value
具体请看下面的实例:
#include <iostream>
using namespace std;
#define LENGTH 10
#define WIDTH 5
#define NEWLINE '\n'
int main()
{
int area;
area = LENGTH * WIDTH;
cout << area;
cout << NEWLINE;
return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:
50
10.8 const 关键字
您可以使用 const 前缀声明指定类型的常量,如下所示:
const type variable = value;
具体请看下面的实例:
#include <iostream>
using namespace std;
int main()
{
const int LENGTH = 10;
const int WIDTH = 5;
const char NEWLINE = '\n';
int area;
area = LENGTH * WIDTH;
cout << area;
cout << NEWLINE;
return 0;
}
10.9 C++ define和 const的区别
#define
和 const
都可以在 C++ 中用来定义常量,但是它们在语法和工作方式上有一些区别:
- 预处理器与编译器:
#define
是预处理器指令,而const
是编译器处理的。在编译之前,预处理器会首先替换掉#define
定义的所有宏。另一方面,const
是在编译过程中处理的,也就是说,它遵循了 C++ 的类型检查和作用域规则。 - 类型和安全性:
#define
是没有类型的,只是简单的文本替换,而const
是有类型的,这意味着编译器会对const
进行类型检查,而不会对#define
进行类型检查。因此,使用const
会更安全。 - 作用域:
#define
宏在定义后,作用范围一直到文件结束(除非用#undef
取消定义),而const
变量则有其作用域,超出作用域则不能使用。因此,const
变量的作用域限制为定义该常量的块或文件,这对于防止命名冲突非常有用。 - 内存占用:
#define
宏只是一个在预处理时期进行的文本替换过程,并不会分配内存。而const
常量会在内存中占用空间。 - 调试:使用
#define
定义的宏在调试过程中可能会更难追踪,因为在预处理后,它们只是被替换为对应的值。而const
变量在调试过程中可以正常被追踪。
以下是两者在代码中的使用示例:
#define PI 3.14159
...
double area = PI * r * r; // PI 在这里会被替换为 3.14159
const double PI = 3.14159;
...
double area = PI * r * r; // PI 是一个常量,其值为 3.14159
虽然 #define
在某些情况下(如条件编译)非常有用,但是一般情况下,推荐使用 const
来定义常量,因为它更安全,更符合 C++ 的类型系统,也更易于调试。
11. C++ 修饰符类型
C++ 允许在 char、int 和 double 数据类型前放置修饰符。
修饰符是用于改变变量类型的行为的关键字,它更能满足各种情境的需求。
下面列出了数据类型修饰符:
- signed:表示变量可以存储负数。对于整型变量来说,signed 可以省略,因为整型变量默认为有符号类型。
- unsigned:表示变量不能存储负数。对于整型变量来说,unsigned 可以将变量范围扩大一倍。
- short:表示变量的范围比 int 更小。short int 可以缩写为 short。
- long:表示变量的范围比 int 更大。long int 可以缩写为 long。
- long long:表示变量的范围比 long 更大。C++11 中新增的数据类型修饰符。
- float:表示单精度浮点数。
- double:表示双精度浮点数。
- bool:表示布尔类型,只有 true 和 false 两个值。
- char:表示字符类型。
- wchar_t:表示宽字符类型,可以存储 Unicode 字符。
修饰符 signed、unsigned、long 和 short 可应用于整型,signed 和 unsigned 可应用于字符型,long 可应用于双精度型。
这些修饰符也可以组合使用,修饰符 signed 和 unsigned 也可以作为 long 或 short 修饰符的前缀。例如:unsigned long int。
C++ 允许使用速记符号来声明无符号短整数或无符号长整数。您可以不写 int,只写单词 unsigned、short 或 long,int 是隐含的。例如,下面的两个语句都声明了无符号整型变量。
signed int num1 = -10; // 定义有符号整型变量 num1,初始值为 -10
unsigned int num2 = 20; // 定义无符号整型变量 num2,初始值为 20
short int num1 = 10; // 定义短整型变量 num1,初始值为 10
long int num2 = 100000; // 定义长整型变量 num2,初始值为 100000
long long int num1 = 10000000000; // 定义长长整型变量 num1,初始值为 10000000000
float num1 = 3.14f; // 定义单精度浮点数变量 num1,初始值为 3.14
double num2 = 2.71828; // 定义双精度浮点数变量 num2,初始值为 2.71828
bool flag = true; // 定义布尔类型变量 flag,初始值为 true
char ch1 = 'a'; // 定义字符类型变量 ch1,初始值为 'a'
wchar_t ch2 = L'你'; // 定义宽字符类型变量 ch2,初始值为 '你'
为了理解 C++ 解释有符号整数和无符号整数修饰符之间的差别,我们来运行一下下面这个短程序:
#include <iostream>
using namespace std;
/*
* 这个程序演示了有符号整数和无符号整数之间的差别
*/
int main()
{
short int i; // 有符号短整数
short unsigned int j; // 无符号短整数
j = 50000;
i = j;
cout << i << " " << j;
return 0;
}
当上面的程序运行时,会输出下列结果:
-15536 50000
上述结果中,无符号短整数 50,000 的位模式被解释为有符号短整数 -15,536。
12. C++ 运算符
运算符是一种告诉编译器执行特定的数学或逻辑操作的符号。C++ 内置了丰富的运算符,并提供了以下类型的运算符:
- 算术运算符
- 关系运算符
- 逻辑运算符
- 位运算符
- 赋值运算符
- 杂项运算符
12.1 算术运算符
下表显示了 C++ 支持的算术运算符。
假设变量 A 的值为 10,变量 B 的值为 20,则:
运算符 | 描述 | 实例 |
+ | 把两个操作数相加 | A + B 将得到 30 |
- | 从第一个操作数中减去第二个操作数 | A - B 将得到 -10 |
* | 把两个操作数相乘 | A * B 将得到 200 |
/ | 分子除以分母 | B / A 将得到 2 |
% | 取模运算符,整除后的余数 | B % A 将得到 0 |
++ | 自增运算符,整数值增加 1 | A++ 将得到 11 |
– | 自减运算符,整数值减少 1 | A-- 将得到 9 |
12.1.1 实例
请看下面的实例,了解 C++ 中可用的算术运算符。
复制并粘贴下面的 C++ 程序到 test.cpp 文件中,编译并运行程序。
#include <iostream>
using namespace std;
int main()
{
int a = 21;
int b = 10;
int c;
c = a + b;
cout << "Line 1 - c 的值是 " << c << endl ;
c = a - b;
cout << "Line 2 - c 的值是 " << c << endl ;
c = a * b;
cout << "Line 3 - c 的值是 " << c << endl ;
c = a / b;
cout << "Line 4 - c 的值是 " << c << endl ;
c = a % b;
cout << "Line 5 - c 的值是 " << c << endl ;
int d = 10; // 测试自增、自减
c = d++;
cout << "Line 6 - c 的值是 " << c << endl ;
d = 10; // 重新赋值
c = d--;
cout << "Line 7 - c 的值是 " << c << endl ;
return 0;
}
当上面的代码被编译和执行时,它会产生以下结果:
Line 1 - c 的值是 31
Line 2 - c 的值是 11
Line 3 - c 的值是 210
Line 4 - c 的值是 2
Line 5 - c 的值是 1
Line 6 - c 的值是 10
Line 7 - c 的值是 10
12.3 关系运算符
下表显示了 C++ 支持的关系运算符。
假设变量 A 的值为 10,变量 B 的值为 20,则:
运算符 | 描述 | 实例 |
== | 检查两个操作数的值是否相等,如果相等则条件为真。 | (A == B) 不为真。 |
!= | 检查两个操作数的值是否相等,如果不相等则条件为真。 | (A != B) 为真。 |
> | 检查左操作数的值是否大于右操作数的值,如果是则条件为真。 | (A > B) 不为真。 |
< | 检查左操作数的值是否小于右操作数的值,如果是则条件为真。 | (A < B) 为真。 |
>= | 检查左操作数的值是否大于或等于右操作数的值,如果是则条件为真。 | (A >= B) 不为真。 |
<= | 检查左操作数的值是否小于或等于右操作数的值,如果是则条件为真。 | (A <= B) 为真。 |
实例
请看下面的实例,了解 C++ 中可用的关系运算符。
复制并黏贴下面的 C++ 程序到 test.cpp 文件中,编译并运行程序。
#include <iostream>
using namespace std;
int main()
{
int a = 21;
int b = 10;
int c ;
if( a == b )
{
cout << "Line 1 - a 等于 b" << endl ;
}
else
{
cout << "Line 1 - a 不等于 b" << endl ;
}
if ( a < b )
{
cout << "Line 2 - a 小于 b" << endl ;
}
else
{
cout << "Line 2 - a 不小于 b" << endl ;
}
if ( a > b )
{
cout << "Line 3 - a 大于 b" << endl ;
}
else
{
cout << "Line 3 - a 不大于 b" << endl ;
}
/* 改变 a 和 b 的值 */
a = 5;
b = 20;
if ( a <= b )
{
cout << "Line 4 - a 小于或等于 b" << endl ;
}
if ( b >= a )
{
cout << "Line 5 - b 大于或等于 a" << endl ;
}
return 0;
}
当上面的代码被编译和执行时,它会产生以下结果:
Line 1 - a 不等于 b
Line 2 - a 不小于 b
Line 3 - a 大于 b
Line 4 - a 小于或等于 b
Line 5 - b 大于或等于 a
12.4 逻辑运算符
下表显示了 C++ 支持的关系逻辑运算符。
假设变量 A 的值为 1,变量 B 的值为 0,则:
运算符 | 描述 | 实例 |
&& | 称为逻辑与运算符。如果两个操作数都 true,则条件为 true。 | (A && B) 为 false。 |
|| | 称为逻辑或运算符。如果两个操作数中有任意一个 true,则条件为 true。 | (A || B) 为 true。 |
! | 称为逻辑非运算符。用来逆转操作数的逻辑状态,如果条件为 true 则逻辑非运算符将使其为 false。 | !(A && B) 为 true。 |
实例
请看下面的实例,了解 C++ 中可用的逻辑运算符。
复制并黏贴下面的 C++ 程序到 test.cpp 文件中,编译并运行程序。
#include <iostream>
using namespace std;
int main()
{
int a = 5;
int b = 20;
int c ;
if ( a && b )
{
cout << "Line 1 - 条件为真"<< endl ;
}
if ( a || b )
{
cout << "Line 2 - 条件为真"<< endl ;
}
/* 改变 a 和 b 的值 */
a = 0;
b = 10;
if ( a && b )
{
cout << "Line 3 - 条件为真"<< endl ;
}
else
{
cout << "Line 4 - 条件不为真"<< endl ;
}
if ( !(a && b) )
{
cout << "Line 5 - 条件为真"<< endl ;
}
return 0;
}
当上面的代码被编译和执行时,它会产生以下结果:
Line 1 - 条件为真
Line 2 - 条件为真
Line 4 - 条件不为真
Line 5 - 条件为真
12.5 赋值运算符
下表列出了 C++ 支持的赋值运算符:
运算符 | 描述 | 实例 |
= | 简单的赋值运算符,把右边操作数的值赋给左边操作数 | C = A + B 将把 A + B 的值赋给 C |
+= | 加且赋值运算符,把右边操作数加上左边操作数的结果赋值给左边操作数 | C += A 相当于 C = C + A |
-= | 减且赋值运算符,把左边操作数减去右边操作数的结果赋值给左边操作数 | C -= A 相当于 C = C - A |
*= | 乘且赋值运算符,把右边操作数乘以左边操作数的结果赋值给左边操作数 | C *= A 相当于 C = C * A |
/= | 除且赋值运算符,把左边操作数除以右边操作数的结果赋值给左边操作数 | C /= A 相当于 C = C / A |
%= | 求模且赋值运算符,求两个操作数的模赋值给左边操作数 | C %= A 相当于 C = C % A |
<<= | 左移且赋值运算符 | C <<= 2 等同于 C = C << 2 |
>>= | 右移且赋值运算符 | C >>= 2 等同于 C = C >> 2 |
&= | 按位与且赋值运算符 | C &= 2 等同于 C = C & 2 |
^= | 按位异或且赋值运算符 | C ^= 2 等同于 C = C ^ 2 |
|= | 按位或且赋值运算符 | C |= 2 等同于 C = C | 2 |
实例
请看下面的实例,了解 C++ 中可用的赋值运算符。
复制并黏贴下面的 C++ 程序到 test.cpp 文件中,编译并运行程序。
#include <iostream>
using namespace std;
int main()
{
int a = 21;
int c ;
c = a;
cout << "Line 1 - = 运算符实例,c 的值 = : " <<c<< endl ;
c += a;
cout << "Line 2 - += 运算符实例,c 的值 = : " <<c<< endl ;
c -= a;
cout << "Line 3 - -= 运算符实例,c 的值 = : " <<c<< endl ;
c *= a;
cout << "Line 4 - *= 运算符实例,c 的值 = : " <<c<< endl ;
c /= a;
cout << "Line 5 - /= 运算符实例,c 的值 = : " <<c<< endl ;
c = 200;
c %= a;
cout << "Line 6 - %= 运算符实例,c 的值 = : " <<c<< endl ;
c <<= 2;
cout << "Line 7 - <<= 运算符实例,c 的值 = : " <<c<< endl ;
c >>= 2;
cout << "Line 8 - >>= 运算符实例,c 的值 = : " <<c<< endl ;
c &= 2;
cout << "Line 9 - &= 运算符实例,c 的值 = : " <<c<< endl ;
c ^= 2;
cout << "Line 10 - ^= 运算符实例,c 的值 = : " <<c<< endl ;
c |= 2;
cout << "Line 11 - |= 运算符实例,c 的值 = : " <<c<< endl ;
return 0;
}
当上面的代码被编译和执行时,它会产生以下结果:
Line 1 - = 运算符实例,c 的值 = 21
Line 2 - += 运算符实例,c 的值 = 42
Line 3 - -= 运算符实例,c 的值 = 21
Line 4 - *= 运算符实例,c 的值 = 441
Line 5 - /= 运算符实例,c 的值 = 21
Line 6 - %= 运算符实例,c 的值 = 11
Line 7 - <<= 运算符实例,c 的值 = 44
Line 8 - >>= 运算符实例,c 的值 = 11
Line 9 - &= 运算符实例,c 的值 = 2
Line 10 - ^= 运算符实例,c 的值 = 0
Line 11 - |= 运算符实例,c 的值 = 2
12.6 C++ 中的运算符优先级
运算符的优先级确定表达式中项的组合。这会影响到一个表达式如何计算。某些运算符比其他运算符有更高的优先级,例如,乘除运算符具有比加减运算符更高的优先级。
例如 x = 7 + 3 * 2,在这里,x 被赋值为 13,而不是 20,因为运算符 * 具有比 + 更高的优先级,所以首先计算乘法 3*2,然后再加上 7。
下表将按运算符优先级从高到低列出各个运算符,具有较高优先级的运算符出现在表格的上面,具有较低优先级的运算符出现在表格的下面。在表达式中,较高优先级的运算符会优先被计算。
类别 | 运算符 | 结合性 |
后缀 | () [] -> . ++ - - | 从左到右 |
一元 | + - ! ~ ++ - - (type)* & sizeof | 从右到左 |
乘除 | * / % | 从左到右 |
加减 | + - | 从左到右 |
移位 | << >> | 从左到右 |
关系 | < <= > >= | 从左到右 |
相等 | == != | 从左到右 |
位与 AND | & | 从左到右 |
位异或 XOR | ^ | 从左到右 |
位或 OR | | | 从左到右 |
逻辑与 AND | && | 从左到右 |
逻辑或 OR | || | 从左到右 |
条件 | ?: | 从右到左 |
赋值 | = += -= *= /= %=>>= <<= &= ^= |= | 从右到左 |
逗号 | , | 从左到右 |
实例
请看下面的实例,了解 C++ 中运算符的优先级。
复制并黏贴下面的 C++ 程序到 test.cpp 文件中,编译并运行程序。
对比有括号和没有括号时的区别,这将产生不同的结果。因为 ()、 /、 * 和 + 有不同的优先级,高优先级的操作符将优先计算。
#include <iostream>
using namespace std;
int main()
{
int a = 20;
int b = 10;
int c = 15;
int d = 5;
int e;
e = (a + b) * c / d; // ( 30 * 15 ) / 5
cout << "(a + b) * c / d 的值是 " << e << endl ;
e = ((a + b) * c) / d; // (30 * 15 ) / 5
cout << "((a + b) * c) / d 的值是 " << e << endl ;
e = (a + b) * (c / d); // (30) * (15/5)
cout << "(a + b) * (c / d) 的值是 " << e << endl ;
e = a + (b * c) / d; // 20 + (150/5)
cout << "a + (b * c) / d 的值是 " << e << endl ;
return 0;
}
当上面的代码被编译和执行时,它会产生以下结果:
(a + b) * c / d 的值是 90
((a + b) * c) / d 的值是 90
(a + b) * (c / d) 的值是 90
a + (b * c) / d 的值是 50
13. C++ 循环
有的时候,可能需要多次执行同一块代码。一般情况下,语句是顺序执行的:函数中的第一个语句先执行,接着是第二个语句,依此类推。
编程语言提供了允许更为复杂的执行路径的多种控制结构。
循环语句允许我们多次执行一个语句或语句组,下面是大多数编程语言中循环语句的一般形式:
13.1 循环类型
C++ 编程语言提供了以下几种循环类型。点击链接查看每个类型的细节。
循环类型 | 描述 |
while 循环 | 当给定条件成立,重复语句或语句组。它会在执行循环主体之前测试条件。 |
for 循环 | 多次执行一个语句序列,简化管理循环变量的代码。 |
do…while 循环 | 除了它是在循环主体结尾测试条件外,其他与 while 语句类似。条件不成立都会执行一次,如果成立则会一直执行,知道条件不成立 |
嵌套循环 | 您可以在 while、for 或 do…while 循环内使用一个或多个循环。 |
13.2 循环控制语句
循环控制语句更改执行的正常序列。当执行离开一个范围时,所有在该范围中创建的自动对象都会被销毁。
C++ 提供了下列的控制语句。点击链接查看每个语句的细节。
控制语句 | 描述 |
break 语句 | 终止 loop 或 switch 语句,程序流将继续执行紧接着 loop 或 switch 的下一条语句。 |
continue 语句 | 引起循环跳过主体的剩余部分,立即重新开始测试条件。 |
goto 语句 | 将控制转移到被标记的语句。但是不建议在程序中使用 goto 语句。 |
无限循环
如果条件永远不为假,则循环将变成无限循环。for 循环在传统意义上可用于实现无限循环。由于构成循环的三个表达式中任何一个都不是必需的,您可以将某些条件表达式留空来构成一个无限循环。
#include <iostream>
using namespace std;
int main ()
{
for( ; ; )
{
printf("This loop will run forever.\n");
}
return 0;
}
在 C++ 中,我们有三种基本的循环结构:while
循环、for
循环和do...while
循环。
1. while 循环:在 while
循环中,如果条件为真(非零),则循环体会一直执行。当条件为假(0)时,退出循环。
int i = 0;
while (i < 5) {
cout << i << endl;
i++;
}
这段代码会打印数字0到4,然后退出循环。
2. for 循环:for
循环提供了一个更简洁的方式来编写具有明确的初始化、条件检查和迭代步骤的循环。
for (int i = 0; i < 5; i++) {
cout << i << endl;
}
这段代码的功能与之前的 while
循环示例相同。
3. do…while 循环:do...while
循环与 while
循环非常相似,不同之处在于 do...while
循环至少会执行一次循环体,然后再检查条件。如果条件为真,循环会继续执行;如果条件为假,循环结束。
int i = 0;
do {
cout << i << endl;
i++;
} while (i < 5);
这段代码的功能与 while
和 for
循环示例相同,但即使 while
条件一开始就不满足,do...while
循环也会执行至少一次。
这就是 C++ 的三种基本循环结构。每种循环都有其特定的使用场景,选择哪种循环主要取决于你的具体需求和编程风格。
R
A <- matrix(rnorm(100*2), nrow = 100)
B <- matrix(rnorm(100*2), nrow = 100)
D <- matrix(0, nrow = 100, ncol = 100)
for(i in 1:dim(A)[1]){
for(j in 1:dim(B)[1]){
for(k in 1:dim(A)[2]){
D[i,j] <- D[i,j] + abs(A[i,k] - B[j,k])
} }
}
这段代码使用的是R语言,它的主要作用是计算两个矩阵(A和B)的差的绝对值之和,然后把这个和存储在一个新的矩阵D中。接下来,我将一步步解释每一行代码的含义。
首先,让我们来看看这段代码的第一行和第二行:
A <- matrix(rnorm(100*2), nrow = 100)
B <- matrix(rnorm(100*2), nrow = 100)
这两行代码创建了两个矩阵A和B。rnorm(100*2)
函数生成了一个包含200个从正态分布中随机抽取的值的向量,然后matrix
函数把这个向量转化成一个100行2列的矩阵。所以,A和B都是100行2列的矩阵,且矩阵的元素都是从正态分布中随机抽取的。
接下来是第三行代码:
D <- matrix(0, nrow = 100, ncol = 100)
这行代码创建了一个100行100列的矩阵D,所有的元素都初始化为0。
然后是最主要的部分,是一个三层的嵌套循环:
for(i in 1:dim(A)[1]){
for(j in 1:dim(B)[1]){
for(k in 1:dim(A)[2]){
D[i,j] <- D[i,j] + abs(A[i,k] - B[j,k])
} } }
这部分代码的主要作用是计算两个矩阵A和B的元素之间的差的绝对值,并把这个和存储在矩阵D中。具体来说:
- 最外层的循环
for(i in 1:dim(A)[1])
是遍历矩阵A的所有行,dim(A)[1]
返回的是矩阵A的行数。 - 中间层的循环
for(j in 1:dim(B)[1])
是遍历矩阵B的所有行,dim(B)[1]
返回的是矩阵B的行数。 - 最内层的循环
for(k in 1:dim(A)[2])
是遍历矩阵A的所有列,dim(A)[2]
返回的是矩阵A的列数。 - 对于每一个(i, j, k)的组合,我们计算A的第i行第k列的元素和B的第j行第k列的元素之间的差的绝对值,然后把这个值加到D的第i行第j列的元素上。
所以,最后的结果是一个矩阵D,其中的每个元素D[i,j]是矩阵A的第i行和矩阵B的第j行之间的差的
绝对值之和。
补充
1. 判断
假设需要一个 C++ 函数来判断一个数字是否为偶数。这个问题在C++中可以很容易地解决。
C++ 语法包括:
- 头文件:
#include
指令是用来包含头文件的。在C++中,我们通常会包含一些库文件,比如iostream
库文件用于输入/输出操作。 - 主函数:在C++中,程序的入口是
main
函数。 - if-else语句:在C++中,你可以使用if-else语句进行条件判断。
- 函数:在C++中,函数是用来封装一段可以执行特定任务的代码块。
下面是使用C++编写的一个函数,该函数可以检查一个数字是否为偶数:
#include <iostream>
// 声明函数
bool isEven(int number);
int main() {
int num;
std::cout << "请输入一个数字: ";
std::cin >> num;
// 使用if-else判断是否为偶数
if(isEven(num)) {
std::cout << num << " 是偶数。" << std::endl;
} else {
std::cout << num << " 是奇数。" << std::endl;
}
return 0;
}
// 定义函数
bool isEven(int number) {
return (number % 2 == 0);
}
以上代码定义了一个名为isEven
的函数,该函数接收一个整数作为参数,然后返回该整数是否为偶数。在主函数main
中,我们接收用户输入的一个数字,然后使用isEven
函数来判断这个数字是否为偶数,最后输出结果。
语法
在C++中,if
语句用于基于特定条件执行代码。它的基本语法如下:
if (condition) {
// code to be executed if condition is true
}
在这里,condition
是一个表达式,它被评估为一个布尔值(即真或假)。如果condition
为真(非零),则执行大括号 {}
内的代码。如果condition
为假(零),则跳过大括号内的代码。
我们也可以添加一个else
部分,如果if
条件不成立,就执行else
部分的代码。这是它的语法:
if (condition) {
// code to be executed if condition is true
} else {
// code to be executed if condition is false
}
还有一个else if
语句,可以用来检查多个条件,并且一旦一个条件满足,就会停止检查剩下的条件。它的语法如下:
if (condition1) {
// code to be executed if condition1 is true
} else if (condition2) {
// code to be executed if condition2 is true
} else {
// code to be executed if both condition1 and condition2 are false
}
这里有个例子:
#include <iostream>
int main() {
int num = 10;
if (num > 0) {
std::cout << "数值是正数。" << std::endl;
} else if (num < 0) {
std::cout << "数值是负数。" << std::endl;
} else {
std::cout << "数值是零。" << std::endl;
}
return 0;
}
在这个例子中,首先检查数字是否大于零。如果是,则输出"数值是正数。“。如果数字不大于零,那么就检查它是否小于零。如果是,则输出"数值是负数。”。如果前两个条件都不满足(也就是说,数字既不大于零也不小于零),那么就输出"数值是零。"。
2. 函数
在C++中,函数是一种可重复使用的程序模块,用于执行特定的任务。函数可以提高代码的可读性和重用性,减少错误和冗余,并使测试和修改更加容易。
C++函数的基本语法如下:
return_type function_name( parameter list )
{
body of the function
}
这里是每部分的详细解释:
- return_type: 这是一个函数返回的数据类型。这可以是任何有效的数据类型,例如 int,double,char,等等,或者用户自定义的对象。如果函数不返回任何值,则可以使用 void 类型。
- function_name: 这是函数的名称。函数名称和参数列表共同构成函数签名。
- parameter list: 参数是传递给函数的值。参数是可选的,也就是说,一个函数可能不包含参数。参数和它们的类型是函数签名的一部分。
- body of the function: 这是函数完成任务的指令集。
让我们来看一个简单的函数定义示例:
#include <iostream>
using namespace std;
// function declaration
int addition(int a, int b);
int main()
{
int result;
// calling the function
result = addition(10,20);
cout << "The result is " << result << endl;
return 0;
}
// function definition
int addition(int a, int b)
{
int sum;
sum = a + b;
return sum;
}
在这个例子中,我们定义了一个名为 addition 的函数,它接受两个 int 类型的参数,并返回它们的和。然后在 main 函数中调用了这个函数,并打印出结果。
函数可以接受任意类型的参数,并根据需要返回任何类型的值。此外,函数也可以没有返回值,也可以没有参数。但是,无论什么情况,函数定义始终需要包含参数列表和返回类型。
注意,函数的声明和定义可以分开。函数声明通常放在程序的顶部或在头文件中,而函数定义则放在主程序之外。这样做可以让我们在主程序中先使用函数,然后再在下面定义函数,使程序结构更加清晰。
3. 数组
数组是C++中的一种数据结构,它能够存储固定大小的相同类型的元素。
以下是数组在C++中的基本语法:
1. 声明数组:
在C++中,我们可以通过以下方式声明一个数组:
type arrayName [ arraySize ];
这里,type
是数组中元素的类型,可以是任何有效的C++类型。arrayName
是数组的名称。arraySize
必须是一个大于零的整数常量,表示数组可以容纳的元素的数量。
例如,要声明一个可以存储10个整数的数组,我们可以这样做:
int numbers[10];
2. 初始化数组:
在声明数组时,我们可以同时初始化数组。例如:
int numbers[5] = {1, 2, 3, 4, 5};
如果我们在初始化数组时没有提供足够的值来填充数组,例如:
int numbers[5] = {1, 2, 3};
那么,剩余的数组元素将被初始化为0。
如果我们不确定数组的大小,但我们有一个初始化列表,我们可以让编译器计算数组的大小,例如:
int numbers[] = {1, 2, 3, 4, 5}; // The size of this array is 5
3. 访问数组元素:
数组元素可以通过索引(也称为下标)访问。数组的索引从0开始,所以数组的第一个元素的索引是0,第二个元素的索引是1,以此类推。
我们可以通过以下方式访问数组的元素:
arrayName[index];
例如,要访问上述 numbers
数组的第四个元素,我们可以这样做:
int fourthNumber = numbers[3];
也可以修改数组中的元素,例如:
numbers[3] = 10; // now the fourth element of the array is 10
请注意,尝试访问数组边界之外的元素是不安全的,可能会导致未定义的行为。
这就是C++数组的基本语法。它是一种相当直接和简单的数据结构,但请注意,如果需要更复杂的操作,如动态大小调整、在数组中间插入或删除元素等,那么可能需要考虑使用其他数据结构,如向量(std::vector)。
4. 面向对象编程
面向对象编程(Object Oriented Programming,OOP)是一种计算机编程架构。OOP的基本构造是类(class)和对象(object)。在C++中,面向对象编程主要涉及以下几个方面:
- 类和对象:类是一种自定义数据类型,具有特定的属性(数据成员)和方法(成员函数)。对象则是类的实例。
示例:
class MyClass { // 类
public: // 公共访问修饰符
int myNum; // 数据成员
string myString; // 数据成员
void myMethod() { // 成员函数
cout << "Hello World!";
}
};
int main() {
MyClass myObj; // 创建对象
myObj.myMethod(); // 调用方法
return 0;
}
- 封装:这是一个防止数据访问的过程。通过将数据成员设置为私有(private),可以防止类外部直接访问它们。要访问这些数据成员,可以通过公有(public)方法(即 getter 和 setter)进行。
- 继承:一个类可以基于另一个类来创建,这就是继承。子类会继承父类的所有公有和保护属性和方法。
示例:
class Vehicle { // 基类
public:
string brand = "Ford";
void honk() {
cout << "Tuut, tuut! \n";
}
};
class Car: public Vehicle { // 派生类
public:
string model = "Mustang";
};
int main() {
Car myCar;
myCar.honk();
cout << myCar.brand + " " + myCar.model;
return 0;
}
- 多态:指的是子类可以定义父类中已存在的方法。你可以在子类中重写父类的方法,以便于它展现出与父类不同的行为。
示例:
class Animal {
public:
virtual void animalSound() { // 虚函数
cout << "The animal makes a sound \n";
}
};
class Pig: public Animal {
public:
void animalSound() {
cout << "The pig says: wee wee \n";
}
};
class Dog: public Animal {
public:
void animalSound() {
cout << "The dog says: bow wow \n";
}
};
int main() {
Animal myAnimal;
Pig myPig;
Dog myDog;
myAnimal.animalSound();
myPig.animalSound();
myDog.animalSound();
return 0;
}
请注意,这只是C++面向对象编程的基础概念。在实际编程过程中,还需要更深入的理解和更多的练习。