C++ 变量和类型:Int、Char、Float、Double、String & Bool
C++中的变量
C++ 中的变量为我们提供了命名的存储能力。它允许程序员根据需要操作数据。每个 C++ 变量都有一个类型。变量类型有助于确定变量内存映射的大小和布局、可存储在该内存中的值范围以及可应用于它的操作集。
C++ 中变量的基本类型
以下是 C++ 变量的基本类型
Int
整数是数值字面量(与数字关联),没有分数或指数部分。例如:120、-90 等。
Double
它是双精度浮点值。例如:11.22、2.345
字符
字符字面量是通过将单个字符包含在单引号中创建的。例如:‘a’、‘m’、‘F’、‘P’、‘}’ 等。
Float
浮点文字量是具有分数形式或指数形式的数值文字量。例如:1.3、2.6
字符串字面量
字符串字面量是一系列用双引号括起来的字符。例如:“你好吗?”
布尔值
它存储布尔值 true 或 false。
C++ 中声明变量的规则
以下是一些为变量命名的通用规则
- C++ 变量名只能包含字母、数字和下划线。
- C++ 变量名不能以数字开头。
- 变量名不应以大写字母开头。
- 在 C++ 中使用的变量名不能是关键字。例如,int 是用于表示整数的关键字。
- C++ 变量名可以以下划线开头。但是,这不被认为是良好的实践。
C++ 变量数据类型
C++ 定义了一整套原始类型
void 类型没有相关联的值,并且只能在少数情况下使用。它最常用于不返回值函数的返回类型。
算术类型包括字符、整数、布尔值和浮点数。算术类型进一步分为两个类别
- 浮点类型。float(或浮点类型)表示十进制数。IEEE 标准规定了最少有效数字位数。大多数编译器通常提供的精度比指定的最小值要高。通常,float 用 32 位表示,double 用 64 位表示,long double 用 96 位或 128 位表示。
- 整数类型(包括字符、整数和布尔类型)。布尔类型只有两种值:True 或 False。有几种 **char** 类型,其中大多数是为了支持国际化而存在的。最基本的字符类型是 char。char 的大小与单个机器字节相同,意味着一个字节。
整数类型可以是符号的或无符号的。
有符号类型:它们表示负数或正数(包括零)。在有符号类型中,范围必须在正负值之间均等地划分。因此,一个 8 位有符号 char 可以存储 -127 到 127 的值。
无符号类型:在无符号类型中,所有值都大于或等于 0。一个 8 位无符号 char 可以包含 0 到 255(两者都包含)。
变量名或标识符
标识符可以由一些字母、数字和下划线字符组成,或者它们的组合。对名称长度没有限制。
标识符必须
- 以字母或下划线('_')开头。
- 并且区分大小写;大写和小写字母是不同的
// 定义四个不同的 int 变量
int guru99, gurU99, GuRu99, GURU99;
C++ 语言为自己保留了一些名称。
在 各种编程语言 中,有许多被接受的为变量命名的约定。遵循这些约定可以提高程序的清晰度。
- 标识符应至少给出其含义的一些指示。
- 变量名通常是小写的—guru99,而不是 Guru99 或 GURU99。
- 我们定义的类通常以大写字母开头。
- 包含多个单词的标识符应在视觉上区分每个单词。例如,guru99_website 而不是 guru99website。
C++ 变量声明和定义
变量的声明使程序在定义的范围内知道一个名称。示例
int a=5; int b; char c='A';
int a,b; a=b=1000;
List initialization int a(5); int b{5};
C++ 中的 const 限定符
假设有一个名为 buffsize 的变量,它表示要从用户那里获取的输入数量。在这里,我们不想在整个程序中更改 buffsize 的值。我们想定义一个值我们知道不应更改的变量。
在这种情况下,请使用 const 关键字
const int bufSize = 512; // input buffer size
这会将 bufSize 定义为常量。任何尝试为 bufSize 赋值或更改 bufSize 的操作都会导致错误。
在这里,我们不能在创建 const 对象后更改其值,它必须是强制声明和初始化的。否则编译器会抛出错误。
const int i = get_size(); // ok: initialized at run time const int j = 42; // ok: initialized at compile time const int k; // error: k is uninitialized const int i = 42; const int ci = i; // ok: the value in i is copied into ci
C++ 中变量的作用域
作用域是程序中变量有意义的范围。通常,同一名称可以在不同作用域内引用不同的实体。变量从声明点开始可见,直到其声明出现的范围结束。
#include <iostream> int main() { int sum = 0; // sum values from 1 through 10 inclusive for (int val = 1; val <= 10; ++val) sum += val; // equivalent to sum = sum + val cout << "Sum of 1 to 10 inclusive is "<< sum <<endl; return 0; }
此程序定义了 3 个名称:main、sum 和 val。它使用了命名空间 std,以及该命名空间中的另外两个名称—cout 和 endl。
- 函数名“main”在花括号外部定义。函数名 main—就像在函数外部定义的其他大多数名称一样—具有全局作用域。这意味着一旦声明,位于全局作用域中的名称在整个程序中都是可访问的。
- 变量 sum 在块的作用域内定义,即 main 函数的主体。它可以从其声明点到 main 函数主体的其余部分访问。但是,不能在它之外访问。这意味着变量 sum 具有块作用域。
- 变量 val 在“for 语句”的作用域内定义。它可以在该语句中使用,但不能在 main 函数的其他地方使用。它具有局部作用域。
嵌套作用域
作用域可以包含其他作用域。被包含的(或嵌套的)作用域称为内部作用域。包含作用域是外部作用域。
#include <iostream> using namespace std; // Program for illustration purposes only: It is bad style for a function // to use a global variable and also define a local variable with the same name int reused = 42; // reused has global scope int main() { int unique = 0; // unique has block scope // output #1: uses global reused; prints 42 0 cout << reused << " " << unique << endl; int reused = 0; // new, local object named reused hides global reused // output #2: uses local reused; prints 0 0 cout << reused << " " << unique << endl; // output #3: explicitly requests the global reused; prints 42 0 cout << ::reused << " " << unique << endl; return 0; }
输出 #1 出现在 reused 的本地定义之前。因此,此输出
语句是使用全局作用域中定义的名称 reused 的语句。此语句输出
42 0
输出 #2 出现在 reused 的本地定义之后。它现在在作用域内。因此,第二个输出语句只是使用了名为 reused 的本地对象,而不是全局对象,并输出
0 0
输出 #3 使用作用域运算符覆盖了默认的作用域规则。全局作用域没有名称。因此,当作用域运算符 (::) 的左侧为空时。它被解释为请求获取全局作用域右侧的名称。因此,表达式使用全局 reused 并输出
42 0
变量类型转换
一种类型的变量可以转换为另一种类型。这称为“类型转换”。让我们看看转换不同 C++ 变量类型的规则
将非布尔值赋给布尔变量,如果值为 0,则结果为 false,否则为 true。
bool b = 42; // b is true
将布尔值赋给其他算术类型之一,如果布尔值为 true,则结果为 1;如果布尔值为 false,则结果为 0。
bool b = true; int i = b; // i has value 1
将浮点值赋给 int 类型的变量会导致值被截断。存储的值是小数点前面的部分。
int i = 3.14; // i has value 3
将 int 值赋给 float 类型的变量会导致小数部分变为零。如果整数的位数超过浮点变量可以容纳的位数,则通常会丢失精度。
Int i=3; double pi = i; // pi has value 3.0
如果我们尝试将超出范围的值赋给无符号类型的变量,结果是该值 %(模) 的余数。
例如,一个 8 位无符号 char 类型可以包含 0 到 255(含)的值。赋给超出此范围的值将导致编译器将该值模 256 的余数赋给它。因此,根据上述逻辑,将 –1 赋给一个 8 位无符号 char 会给该对象的值 255。
unsigned char c = -1; // assuming 8-bit chars, c has value 255
如果我们尝试将超出范围的值赋给有符号类型的对象,结果是不可预测的。它是未定义的。程序可能看起来能正常工作,也可能崩溃,或者可能产生垃圾值。
signed char c2 = 256; // assuming 8-bit chars, the value of c2 is undefined
当我们在需要其他类型值的地方使用一种类型的值时,编译器会应用相同的类型转换。
int i = 42; if (i) // condition will evaluate as true i = 0;
如果此 value = 0,则条件为 false;所有其他(非零)值均返回 true。根据相同的概念,当我们在算术表达式中使用布尔值时,它的值总是会转换为 0 或 1。因此,在算术表达式中使用布尔值通常几乎肯定是错误的。
注意:请勿混合有符号和无符号类型
混合有符号和无符号的表达式在有符号值为负数时会产生令人惊讶和错误的结果。如上所述,有符号值会自动转换为无符号。
例如,在算术表达式中,如
x* y
如果 x 是 -1 且 y 是 1,并且 x 和 y 都是 int,那么结果如预期,是 -1。
如果 x 是 int 而 y 是 unsigned,那么此表达式的值取决于编译机器上的整数位数。在我们的机器上,此表达式产生 4294967295。
寄存器变量
与内存变量相比,寄存器变量访问速度更快。因此,可以使用 **register** 关键字将 C++ 程序中频繁使用的变量放入寄存器。register 关键字告诉编译器将给定的变量存储在寄存器中。是否将其放入寄存器由编译器决定。通常,编译器本身会进行各种优化,包括将一些变量放入寄存器。C++ 程序中的寄存器变量数量没有限制。但是编译器可能不会将变量存储在寄存器中。这是因为寄存器内存非常有限,通常由操作系统使用。
定义
register int i;
评论
注释是代码中被编译器忽略的部分。它允许程序员在源代码/程序的相关区域做笔记。注释可以是块形式或单行形式。程序注释是解释性语句。它可以包含在 C++ 代码中,帮助任何阅读其源代码的人。所有编程语言都允许某种形式的注释。C++ 支持单行和多行注释。
- 单行注释以 // 开头,一直延续到行尾。如果注释行中的最后一个字符是 \,则注释将继续到下一行。
- 多行注释以 /* 开头,以 */ 结尾。
/* This is a comment */ /* C++ comments can also * span multiple lines */
转义序列
某些字符,例如退格符和控制字符,没有可见的图像。这些字符称为不可打印字符。其他字符(单引号和双引号、问号和反斜杠)在许多编程语言中具有特殊含义。
我们的程序无法直接使用这些字符中的任何一个。相反,我们可以使用转义序列来表示这样的字符。转义序列以反斜杠开头。
C++ 编程语言定义了多个转义序列
它做什么? | 字符 |
---|---|
换行符 | \n |
垂直制表符 | \v |
反斜杠 | \\ |
回车符 | \r |
水平制表符 | \t |
退格符 | \b |
问号 | \? |
窗体馈送 | \f |
警报(铃声) | \a |
双引号 | \” |
单引号 | \’ |
我们像使用单个字符一样使用转义序列
cout << '\n'; // prints a newline cout << "\tguru99!\n"; // prints a tab followed by "guru99!" and a newline
我们还可以使用 \x 后跟一个或多个十六进制数字的通用转义序列。或者使用 \ 后跟一个、两个或三个八进制数字。通用转义序列表示字符的数值。一些示例(假设为 Latin-1 字符集)
\7 (bell) \12 (newline) \40 (blank) \0 (null) \115 ('M') \x4d ('M')
我们可以像使用其他任何字符一样使用预定义的转义序列。
cout << "Hi \x4dO\115!\n"; // prints Hi MOM! followed by a newline cout << '\115' << '\n'; // prints M followed by a newline
摘要
- C++ 变量为我们提供了命名的存储能力。
- C++ 变量类型:int、double、char、float、string、bool 等。
- 被包含的(或嵌套的)作用域称为内部作用域,包含作用域是外部作用域。
- 一种类型的变量可以转换为另一种类型。这称为“类型转换”。
- 与内存变量相比,寄存器变量访问速度更快。
- 注释是代码中被编译器忽略的部分。
- 某些字符,例如退格符和控制字符,没有可见的图像。