21天学通C++读书笔记(二:使用变量和常量)

1. 什么是变量

1.1 声明变量以访问和使用内存
  • 变量类型向编译器指出了变量可存储的数据的性质,编译器将为变量预留必要的空间
  • 变量名由程序员选择,它替代了变量值在内存中的存储地址
    • 变量名可包含数字和字母,但不能以数字打头。变量名不能包含空格和算术运算符(+、-等)。另外,变量名不能是保留的关键字。例如,将变量命名为 return 将导致程序无法通过编译。变量名可包含下划线(_),这种字符经常包含在描述性变量名中
  • 除非给变量赋初值,否则无法确保相应内存单元的内容是什么
#include <iostream>
using namespace std;

int main () {
    cout << "Enter the first number: ";
    int firstNumber = 0;
    cin >> firstNumber;

    cout << "Enter the second number: ";
    int secondNumber = 0;
    cin >> secondNumber;

    int multiplicationResult = firstNumber * secondNumber;

	cout << firstNumber << " x " << secondNumber;
	cout << " = " << multiplicationResult << endl;
   
    return 0;
}
1.2 声明并初始化多个类型相同的变量
  • C++中可同时声明多个类型相同的变量
  • 在C++中可在需要时再声明变量,这让代码更容易理解
int firstNumber = 0, secondNumber = 0, multiplicationResult = 0;
1.3 理解变量的作用域
  • 常规变量(如前面定义的所有变量)的作用域很明确,只能在作用域内使用它们,如果在作用域外使用它们,编译器将无法识别,导致程序无法通过编译

  • 编译器将main( )中声明的变量视为独立的实体,即便它们与另一个函数中声明的变量同名,因为这些变量的作用域不同

1.4 全局变量
  • 在函数外定义的变量称之为全局变量,其作用域为从定义处开始到定义该全局变量的源文件结束处
  • 除非有必要,否则不建议使用全局变量,因为全局变量增大了程序的存储空间、降低了函数通用性、增加了函数理解的复杂度
  • 在同一个源文件中,若全局变量与局部变量同名,那么在局部变量作用域内,全局变量不起作用
1.5 命名约定
  • 对于变量名,采用骆驼拼写法
    • 变量名firstNumber、secondNumber 和multiplicationResult 中,第一个单词的首字母采用小写,这被称为骆驼拼写法
  • 对于函数名等其他元素,采用Pascal 拼写法
    • 在函数名MultiplyNumbers()中,每个单词的首字母都大写,这被称为Pascal 拼写法

2. 编译器支持的常见C++变量类型

  • 使用bool 变量存储布尔值
bool alwaysOnTop = false; // 1为true;其他为false
  • 使用char 变量存储字符
// char 变量用于存储单个字符
char userInput = 'Y'; // 初始化char为'Y'
  • 有符号整数和无符号整数的概念

    • 符号表示正或负。在计算机中使用的所有数字都以位和字节的方式存储在内存中。1字节的内存单元包含8位,每位都要么为0,要么为1(即存储这两个值之一),因此1字节的内存单元可以有2^8 (即256)个不同的取值。同样,16位的内存单元可以有2^16(65536)个不同的取值。
    • 如果这些取值是无符号的(即为正数),则1个字节的可能取值为0~255,而2 个字节的可能取值为0~65535。
    • 占用8 位的有符号数的取值范围为−127~127,而占用16 位的有符号数的取值范围为−32768~32768。
  • 有符号整型short、int、long 和long long

    • int 可能是使用得最多的类型,在大多数编译器中,其长度都是32 位。应根据变量可能存储的最大值给它指定合适的类型。
  • 无符号整型unsigned short、unsigned int、unsigned long 和 unsigned long long

    • 它们的最大取值为相应有符号类型的两倍
    • 如果预期变量的取值不会为负数,就应将其类型声明为无符号的
  • 选择正确的数据类型以免发生溢出错误

    • 就拿unsigned short 来说吧,它占用16 位内存,因此取值范围为0~65535。usigned short 变量的值为65535 后,如果再加1,将导致溢出,结果为0
    • 数据类型short 的取值范围为−32768~32768,如果这种变量的值已经是32768,则将其加1的结果为最小的负数
  • 浮点类型float 和double

    • 浮点数就是实数,可以是正,也可以是负,还可以包含小数值
    • C++14 新增了用单引号表示的组块分隔符。使用这种分隔符可提高代码的可读性,如下面的初始化语句所示:
    • int moneyInBank = -70'000; // -70000
      double pi = 3.141'592'653'59; // 3.14159265359
      

3. 使用sizeof确定变量的长度

  • 获悉标准C++变量类型的长度
#include <iostream>

int main() {
    using namespace std;
    
    cout << "Size of bool: " << sizeof(bool) << endl;
    cout << "Size of char: " << sizeof(char) << endl;
    cout << "Size of unsigned short int: " << sizeof(unsigned short) << endl;
    cout << "Size of short int: " << sizeof(short) << endl;
    cout << "Size of unsigned long int: " << sizeof(unsigned long) << endl;
    cout << "Size of long: " << sizeof(long) << endl;
    cout << "Size of int: " << sizeof(int) << endl;
    cout << "Size of unsigned long long: "<< sizeof(unsigned long long)<< endl;
    cout << "Size of long long: " << sizeof(long long) << endl;
    cout << "Size of unsigned int: " << sizeof(unsigned int) << endl;
    cout << "Size of float: " << sizeof(float) << endl;
    cout << "Size of double: " << sizeof(double) << endl;
    
    return 0;
}
Size of bool: 1
Size of char: 1
Size of unsigned short int: 2
Size of short int: 2
Size of unsigned long int: 4
Size of long: 4
Size of int: 4
Size of unsigned long long: 8
Size of long long: 8
Size of unsigned int: 4
Size of float: 4
Size of double: 8
  • C++11 引入了固定宽度的整型,让您能够以位为单位指定整数的宽度
    • 这些类型为int8_t和unit8_t,分别用于存储8位的有符号和无符号整数;还可能使用16位、32位和64位的整型,它们为int16_t、uint16_t、int32_t、uint32_t、int64_t和uint64_t
    • 要使用这些类型,必须包含头文件
      • #include <cstdint>
        

4. 使用auto自动推断类型

  • 让编译器去决定变量的类型,而编译器将根据初始值来确定合适的类型
  • 使用auto时必须对变量进行初始化,因为编译器需要根据初始值来确定变量的类型
#include <iostream>
using namespace std;

int main() {
    auto coinFlippedHeads = true;
    auto largeNumber = 2500000000000;
    
    cout << "coinFlippedHeads = " << coinFlippedHeads;
    cout << " , sizeof(coinFlippedHeads) = " << sizeof(coinFlippedHeads) << endl;
    cout << "largeNumber = " << largeNumber;
    cout << " , sizeof(largeNumber) = " << sizeof(largeNumber) << endl;
    
    return 0;
}

5. 使用typedef替换变量类型

  • C++允许您将变量类型替换为您认为方便的名称,为此可使用关键字typedef
typedef unsigned int STRICTLY_POSITIVE_INTEGER;
STRICTLY_POSITIVE_INTEGER numEggsInBasket = 4532;

6. 声明是常量

  • 在C++中,常量可以是:

    • 字面常量
    • 使用关键字const声明的常量
    • 使用关键字constexpr声明的常量表达式(C++11 新增的)
    • 使用关键字enum声明的枚举常量
    • 使用#define定义的常量(已摒弃,不推荐)
  • 字面常量

    • 字面常量可以是任何类型:布尔型、整型、字符串等
    • std::cout << "Hello World" << std::endl; // Hello World 就是一个字符串字面常量
      int someNumber = 10; // 10是不可修改的,因此也是字面常量
      int someNumber = 0b1010; // 从C++14 起,还可使用二进制字面量
      
  • 使用const将变量声明为常量

#include <iostream>

int main() {
    using namespace std;
    
    const double pi = 22.0 / 7;
    cout << "The value of constant pi is: " << pi << endl;
    
    return 0;
} 
  • 使用constexpr定义常量表达式
// 常量表达式必须包含简单的实现,并返回简单类型,如整数、双精度浮点数等
// C++14中,常量表达式可包含决策结构,如if和switch语句
// 在C++编译器中,都通过常量M_PI提供pi值,但必须包含头文件<cmath>
#include <iostream>
constexpr double GetPi() { // 通过关键字constexpr,可让常量声明像函数
    return 22.0 / 7;
}
constexpr double TwicePi() { // 在一个常量表达式中,可使用另一个常量表达式
    return 2 * GetPi();
}

int main() {
    using namespace std;
    const double pi = 22.0 / 7;
    
    cout << "constant pi contains value " << pi << endl;
    cout << "constexpr GetPi() returns value " << GetPi() << endl;
    cout << "constexpr TwicePi() returns value " << TwicePi() << endl;
    
    return 0;
}
  • 枚举
    • 可使用关键字enum来声明枚举
    • 枚举由一组称为枚举量的常量组成
    • 编译器将枚举量转换为整数,每个枚举量都比前一个大1。您可以指定起始值,如果没有指定,编译器认为起始值为0
// 使用枚举量指示基本方位
enum CardinalDirections
{
    North = 25,
    South,
    East,
    West
};
  • 使用#define定义常量
// 预处理器将进行文本替换,而不是智能替换
// 使用#define 定义常量的做法已被摒弃,因此不应采用这种做法
#define pi 3.14286 // #define 是一个预处理器宏
Q&A
  • 既然可以使用常规变量代替常量,为何还要定义常量?
    • 通过声明常量(尤其是使用关键字const 时),可告诉编译器,其值是固定的,不允许修改。这样,编译器将确保不给常量赋值,即便另一位程序员接手了您的工作,不小心试图覆盖常量的值。因此,在知道变量的值不应改变时,应将其声明为常量,这是一个不错的编程习惯,可提高应用程序的质量。
  • 为何应给变量赋初值?
    • 如果不初始化,就无法知道变量包含的初始值。在这种情况下,初始值将是给变量预留的内存单元的内容。下面的语句使得创建变量myFavoriteNumber 后,就将指定的初始值0 写入到为该变量预留的内存单元:
      int myFavoriteNumber = 0;
      有时候,需要根据变量的值(通常是核实它不为零)做条件处理,如果不对变量进行初始化,这样的逻辑将不可靠,因为未赋值或初始化的情况下,程序员通过选择合适的变量类型,可节省内存并提高速度。如果编写的是常规台式机或高端智能手机程序,选择不同整型带来的性能提升或内存节省将很小,有时甚至可以忽略不计。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值