C++学习笔记(2) 变量与基本类型

1.基本内置类型

(1)算术类型(arithmetic type)

整型(integral type):包括字符/bool类型

浮点型(floating-point type)

C++算术类型

类型含义最小尺寸
bool布尔类型未定义
char字符8位
wchar_t宽字符16位
char16_tUnicode字符16位
char32_tUnicode字符32位
short短整型16位
int整型16位
long长整型32位
long long长整型64位
float单精度浮点数6位有效数字
double双精度浮点数10位有效数字
long double扩展精度浮点数10位有效数字

注:Unicode是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。

注:基本的字符类型是char,一个char的空间应确保可以存放机器基本字符集中任意字符对应的数字值,也就是说,一个char的大小和一个机器字节一样。wchar_t,char16_t,char32_t属于扩展字符集(为了表示更多的欧洲常用字符对ASCII进行了扩展)。

内置类型的机器实现

字节(byte):可寻址的最小内存块

字(word):存储的基本单元

大多数机器以2的整数次幂个比特作为块来处理内存(每个bit非0即1),字节由8比特构成,字由32或64比特构成(即4或8字节)。将内存中的每个字节与一个数字(即地址,address)关联起来,从而可以使用某个地址来表示从这个地址开始的大小不同的比特串。

带符号类型与无符号类型

除bool和扩展的字符型之外,其他整型可以划分为带符号的(signed)和无符号的(unsigned):

字符型:char,signed char,unsigned char(char根据编译器的不同会表现为后两种中的一种)

其他整型:均为带符号的,无符号需在前面加上unsigned

建议:1)当明确知晓数值不可能为负数时,选用unsigned类型

2)使用int执行整数运算,若数值超过int的表示范围,则选用long long

3)在算数表达式中不要使用bool或char,只在存放字符或布尔值时才使用它们

4)执行浮点数运算时选用double而非float

类型转换

bool b = 42;    //b = true,bool值实际上非0即1
int i = b;      //i = 1
i = 3.14;       //i = 3
double pi = i;  //pi = 3.0
unsigned char c = -1; //c = 255
signed char c2 = 256; //c2值未定义

注:赋给无符号类型一个超出它表示范围的值时,结果是初始值对无符号类型表示数值总数取模后的余数;赋给带符号类型一个超出它表示范围的值时,结果是未定义的。 

字面值常量(literal)

 每一个值都为字面值常量,均对应一种数据类型,字面值常量的形式和值决定了它的数据类型。

通过添加前缀和后缀,可以改变整型/浮点型/字符型字面值的默认类型:

整型字面值
后缀最小匹配类型
u or Uunsigned
l or Llong
ll or LLlong long
浮点型字面值
后缀类型
f or Ffloat
l or Llong double
字符和字符串字面值
前缀含义类型
uUnicode16字符char16_t
UUnicode32字符char32_t
L宽字符wchar_t
u8UTF-8(仅用于字符串字面常量)char

注:布尔类型的字面值为true或false,指针字面值为nullptr。 

转义序列 

换行符\n
横向制表符\t
纵向制表符\v
反斜线\\
回车符\r
退格符\b
问号\?
进纸符-走纸换页\f
报警符(响铃符)-蜂鸣器响\a
双引号\"
单引号\'

(2)空类型(void)

空类型不对应具体的值,仅用于一些特殊场合,比如当函数不返回任何值时使用空类型作为返回类型。

2.变量

(1)变量定义

列表初始化(C++11新标准)

int a = 0;
int a = {0};
int a{0};
int a(0);

若使用long double的值初始化int变量:

long double ld = 3.1415926;
int a{ld}, b = {ld};  //错误,转换未执行(存在丢失信息的危险时花括号定义不执行)
int c(ld), d = ld;    //正确,转换执行,且确实丢失了部分值

 默认初始化:若定义变量时未指定初始值,则变量会被默认初始化。定义于任何函数体之外的变量被初始化为0,定义在函数体内部的内置类型变量将不被初始化(绝大多数类支持无须显式初始化而定义对象初始化为一个空串)。

(2)变量声明

变量定义:创建与名字关联的实体

变量声明:使得名字为程序所知,从而可以使用别处定义的名字,实现分离式编译

区别:定义申请了存储空间,也可能会为变量赋一个初始值;而声名不能显式初始化变量

声明的形式:

extern int i;

(3)标识符(identifier)

由字母/数字/下划线组成,其中必须以字母或下划线开头。

注: C++关键字为语言所保留,不能用作标识符;标准库也保留了一些名字:

1)用户自定义的标识符中不能连续出现两个下划线

2)不能以下划线紧连大写字母开头

3)定义在函数体外的标识符不能以下划线开头

变量命名规范:

1)变量名一般用小写字母

2)用户自定义的类名一般以大写字母开头

3)标识符由多个单词组成时,单词间应有明显区分如加下划线或大小写

(4)名字的作用域(scope)

名字的有效区域始于名字的声明语句,以声明语句所在的作用域末端为结束。(C++中大多数作用域都以花括号分隔)

全局作用域(global scope):名字定义在函数体之外,在整个程序的范围内都可使用

块作用域(block):名字定义在某个函数或某个循环语句内,只在其所在花括号中有效

嵌套的作用域(作用域能彼此包含,分为内层/外层作用域)

#include <iostream>

int reused = 42;  //reused拥有全局作用域

int main() {
  int unique = 0; //unique拥有块作用域
  std::cout << reused << " " << unique <<std::endl;  //42 0
  int reused = 0; //新建局部变量reused,覆盖了同名的全局变量
  std::cout << reused << " " << unique <<std::endl;  //0 0
  std::cout << ::reused << " " << unique <<std::endl;//42 0

3.复合类型

(1)引用(reference,实指左值引用,lvalue reference)

引用:为对象起了另一个名字

定义引用时,程序把引用和它的初始值绑定,而非将初始值拷贝给引用(引用类型的初始值必须是一个对象,而不能是一个定值)

int a = 1;
int &b = a;
a = 2;
std::cout << b << std::endl;

上述代码的输出结果为2,说明引用b的值始终与a值绑定,改变a的值即改变b的值;同时,改变b的值也即改变a的值。 

(2)指针(pointer)

指针:存放某个对象的地址

指针初始化:

int *p = &a;

 指针值:

1)指向一个对象

2)指向紧邻对象所占空间的下一个位置

3)空指针(没有指向任何一个对象,nullptr)

4)无效指针(上述情况之外的其他值)

4.const限定符

const:将一个变量限定定义为常量,任何试图对其赋值的行为都将引发错误

const对象在定义时必须初始化(默认情况下,const对象被设定为仅在文件内有效;若需要只在一个文件中定义const而在其他多个文件中声明并使用它,则对于const变量不管声明还是定义都添加extern关键字)

对const的引用

const int c =1024;
const int &c1 = c; //正确
int &c2 = c;  //错误:试图让一个非常量引用指向一个常量对象
int i = 42;
const int &i1 = i; //正确:允许将const int&绑定到一个普通int对象上,但不允许通过i1修改i的值

注:指向常量的指针不能用于改变其所指对象的值,但所指对象也不一定需要是一个常量。 

 const指针

int num = 0;
int *const ptr = &num; //ptr将一直指向num

顶层const:指针本身是一个常量(执行对象的拷贝操作时无影响)

底层const:指针所指的对象是一个常量(拷贝时受限)

int i = 0;
int *const p1 = &i; //顶层const
const int ci = 42;  //顶层const
const int *p2 = &ci;//底层const
const int &r = ci;  //底层const
const int *const p3 = p2;//靠右的const是顶层const,靠左的const是底层const 

常量表达式(constexpr)

constexpr int mf = 20;
constexpr int limit = mf + 1;

5.处理类型

类型别名(type alias):某种类型的同义词

定义类型别名:

typedef double wages;//wages是double的同义词
typedef wages base, *p;//base是double的同义词,p是double*的同义词

别名声明:

using SI = Sales_item;  //SI是Sales_item类的同义词

 auto类型说明符:编译器能够代替人分析表达式所属的类型

auto item = val1 + val2;

decltype类型指示符:推断要定义的变量的类型,但不用该表达式的值初始化变量

const int ci = 0, &cj = ci;
decltype(ci) x = 0; //x的类型是const int
decltype(cj) y = x; //y的类型是const int&, y绑定到变量x上
decltype(cj) z;     //错误:z是一个引用,必须初始化

6.自定义数据结构

定义类型struct(同C语言中的结构体),一般写在头文件中

预处理器概述:

1)预处理器读到#include时会用指定的头文件内容代替#include

2)头文件保护符(header guard)依赖于预处理变量,使用头文件保护符能够有效地方志重复包含的发生

#ifndef SALES_DATA_H  //检查该预处理变量是否已经定义,未定义时为真
#define SALES_DATA_H  //把一个名字设定为预处理变量
#include <string>
struct Sales_data {
  std::string bookNo;
  double revenue = 0.0;
} ;
#endif  //结束操作

 注:预处理变量无视C++中关于作用域的规则

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值