c++变量和基本类型(c++ primer学习笔记)

1.1 基本内置类型

基本数据类型:空类型(arithmetic type)、算术类型(void)

1.1.1 算术类型

算术类型分为两类 : 整型、浮点型

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

带符号类型和无符号类型

除去布尔型和扩展的字符型外,其他数据可划分为有符号数和无符号数

对于char,有符号还是无符号由编译器决定

1.1.2 类型转换

对象的类型定义了对象能包含的数据和能参与的运算,类型转换运算被大多数类型支持

给无符号数赋值超过表示范围时,结果是初始值对无符号类型表示数值总数取模后的余数

有符号数超出范围结果是未定义的

1.1.3 字面值常量

short无字面值常量

整型和浮点型字面值

20 10进制

020 8进制

0x20 16进制

字符和字符串字面值

‘a’

“hello”

转义序列

\n \t \a \v \b (\ ')(\ \)

或者是\后跟八进制数,\x后跟16进制数

跟八进制数时,只有三个数有效,超过原样输出

指定字面值的类型

u/U,l/L,ll/LL,f/F

以u为后缀的数据将选择长度最小的无符号数据类型来进行匹配

布尔字面值和指针字面值

true false

nullptr

1.2 变量

1.2.1 变量定义

变量定义基本形式:首先是类型说明符,随后紧跟一个或多个变量名组成的列表

对象

通常,对象指一块能存储数据并具有某种类型的内存空间

初始值

当对象在创建时获得了一个特定的值,即初始化

初始化不是赋值,初始化的含义是创建变量时赋予其一个初始值,而复制的含义是把对象的当前值擦除,用一个新值来替代

列表初始化

int units_sold = 0;

​ = {0};

​ {0};

​ (0);

当存在数据丢失的风险时,编译器将报错,如:

double a = 0.112;

int b = {a};

默认初始化

定义在函数体内部的内置类型变量将不被初始化,未被初始化的内置类型变量的值是未定义的,拷贝、访问操作将引发错误

但是类的对象如果没有显式初始化,则其值由类决定

1.2.2 变量声明和定义的关系

c++支持分离式编译

声明使得名字为程序所知,定义负责创建和名字关联的实体

如果想要声明变量而非定义,在其前加extern,并且不要显式的初始化变量:

extern int i;

变量只可以被定义一次,但可以多次声明

1.2.3 标识符

不可以数字开头

1.2.3 名字的作用域

作用域是名字的一部分,在其中名字有其特定的含义

全局作用域、块作用域

嵌套作用域

内层作用域、外层作用域

::reused//全局作用域中的reused

#include <iostream>
int reused = 42;
int main(){
    int unique = 0;
    //42 0
    std::cout << reused << " " << unique << std::endl;
    int reused = 0;
    //0 0
    std::cout << reused << " " << unique << std::endl;
    //42 0
	std::cout << ::reused << " " << unique << std::endl;
    return 0;
}

1.3 复合类型

复合类型是指基于其他类型定义的类型,如引用和指针

1.3.1 引用

引用(reference)为对象起了另外一个名字

int ival = 1024;
int &refVal = ival;

定义引用时,程序把引用和它的初始值绑定在一起,无法重新绑定到另外一个对象

注意,引用并非对象,它只是为一个已经存在的对象所起的另外一个名字。

引用必须初始化,初始值必须是一个对象,对引用的更改相当于对所引用的变量进行更改

1.3.2 指针

指针是指向另外一种数据类型的复合类型

指针本身就是一个对象,可以赋值、拷贝,指针无需再定义是赋初值

获取对象的地址

指针存放对象的地址,对象地址的取得用&(取地址符)来进行

int ival = 12;

int *ival = &ival;

注意,引用不是对象,因此不能定义指向引用的指针

指针值

1、指向一个对象

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

3、空指针

4、无效指针

利用指针访问对象

使用解引用符 *

int ival = 42;
int *p = &ival;
cout <<  *p;

对指针解引用会得出指针所指对象,对其赋值也就是对原变量赋值

空指针

int *p1 = nullptr;	//nullptr是一种特殊类型的字面值,可转换为任意其他的指针类型
int *p1 = 0; 	//不可用int的0来赋值
int *p1 = NULL;	//需要首先#include cstdlib

赋值和指针

指针和引用都能提供对其他对象的间接访问,但是二者有很大不同,最明显的就是引用不是对象,引用一旦初始化,便不可以更改

void*指针

一种特殊的指针,可用于存放任意对象的地址,我们对该地址中对象的类型是不清楚的,因此也无法进行访问。

定义多个变量

写法1:

int *p1, *p2; //强调变量具有的数据类型

int* p1;

int* p2 //强调定义了一种复合类型;

指向指针的指针

int ival = 1024;
int *p1 = &ival;
int **p = &p1;

指向指针的引用

int i = 42;
int *p;
int *&r = p;

此类复杂定义一般从右向左读

1.4 const限定符

值无法被改变

const int bufSize = 512

任何试图改变const数据的行为都会报错,const对象必须初始化

初始化和const

对象的类型决定了其上的操作

默认状态下,const对象仅在文件内有效

编译器对const的处理是在编译过程中把任何用到该变量的地方都替换为对应的值,为支持这一用法,const对象默认只在本文件有效

可以使用extern使其在多个文件内有效

//file_1:
extern const int buf = fcn();
//file_2:
extern const int buf;

1.4.1 const的引用

可以把引用绑定到const对象上,称之为对常量的引用,此引用不可进行值的修改

const int a = 100;
const int &r1 = a;

注意,严格来说,并不存在常量引用,因为引用不是一个对象,我们没有办法使得引用本身恒定不变

初始化和对const的引用

引用的类型必须与引用的对象一致,但是有两个例外:

1、在初始化常量引用时允许用任意表达式作为初始值,只要该表达式的结果能够转换成引用的类型即可

int i = 42;
const int &r1 = i;
const int &r2 = 42;

double dval = 3.14;
const int &r = dval;
|
|
const int temp = dval;
const int &r = temp;
//绑定的是临时量,当不是const引用时,需要严格遵守数据类型一致

1.4.2指针和const

指向常量的指针不能用于改变其所指对象的值,要想存放常量对象的地址,只能使用指向常量的指针。

指针的类型必须与其所指对象的类型一致,但是有例外:允许一个指向常量的指针指向一个非常量对象

const指针

常量指针必须初始化,不变的是指针本身的值,而不是指向的那个值

int errNumb = 0;
int *const curErr = &errNumb;
const double pi = 3.1415;
const double *const pip = &pi;
    

1.4.3 顶层const

顶层const : 指针本身是一个常量

底层const : 指针所指的对象是一个常量

更一般的,顶层const可以表示任意的对象是常量,底层const和指针、引用等复合类型的基本类型部分有关

int i = 0;
int *const p1 = &i;	//不能改变p1,顶层
const int ci = 42;	//顶层
const int *p2 = &ci;	//允许改变p2,底层
const int *const p3 = p2;//顶   底
const int &r = ci;	//用于声明引用的const都是底层的

1.4.4 constexpr和常量表达式

常量表达式是指不会改变并且在编译过程就能得到计算结果的表达式。如字面值。

声明为constexpr的变量一定是一个常量,并且必须用常量表达式初始化

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

指针和constexpr

在constexpr声明中如果定义了一个指针,限定符constexpr仅对指针有效,与指针所指对象无关

const int* p = nullptr;	//指向常量的指针
constexpr int* q = nullptr;	//常量指针

1.5 处理类型

1.5.1 类型别名

typedef double wages;
typedef wages base, *p;
using SI = sales_item;

1.5.2 auto 类型说明符

auto item = val1 +val2; //item初始化为val1和val2相加的结果

复合类型,常量和auto

编译器推断出来的auto类型可能和初始值类型不完全一样,编译器会适当改变结果使其更符合初始化规则。

1、编译器以引用对象的类型作为auto的类型

2、auto一般会忽略顶层const,保留底层const

const int ci = i, &cr = ci;
auto b = ci;	//int
auto c = cr;	//int
auto d = &i;	//int*
auto e = &ci;	//指向整数常量的指针

//欲推断顶层const,需要:
const auto f = ci;
const auto &j = 42;

1.5.3 decltype 类型指示符

选择并返回操作数的数据类型,编译器分析表达式并得到它的类型,但并不实际计算表达式的值

注意,decltype(())的结果永远是引用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值