C++ Primer阅读笔记(一)

C++primer学习笔记

第一部分 c++基础

第二章 变量和基本类型

2.1基本内置类型

类型含义最小尺寸
bool布尔类型8bits
char字符8bits
wchar_t宽字符16bits
char16_tUnicode字符16bits
char32_tUnicode字符32bits
short短整型16bits
int整型16bits (在32位机器中是32bits)
long长整型32bits
long long长整型64bits (是在C++11中新定义的)
如何选择类型

1.当知晓数值不能为负数时,选用无符号类型

2.使用int执行整数运算,表示范围超过int时,选择long long类型

3.在算数表达式中不要使用char或者bool

4.浮点数选用double

类型转换

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

2.当赋给带符号类型一个超过它表示范围的值时,结果可能是未定义的,此时程序可能会崩溃或继续工作,也可能会产生垃圾数据

3.如果表达式既有无符号类型,也有有符号类型,带符号类型取值为负出现异常,因为带符号数会自动转换为无符号数

unsigned char c = -1;   //假设char占8比特,c的值为255,-1%256=255,注意,不同编译器结果不同,这里取正余数
signed char c2 = 236;  //c2的值是未定义的
字面值常量

一个形如42的值称作字面值常量,一望而知,每个字面值常量对应一种数据类型

2.2 变量

变量定义和初始化

1.变量定义的基本类型:随后紧跟一个或者多个变量名组成的列表

2.在C++中初始化和赋值是两个不同的操作,初始化的含义是创建变量时赋予一个初始值,赋值是把当前值擦除,使用一个新值来代替

3.列表初始化**(C++11)**,使用花括号来初始化变量称为列表初始化,但是有一个重要特点,如果使用列表初始化存在丢失信息的风险,编译器将报错:

long double ld = 3.14
int a{ld},b={ld}    //报错,因为存在丢失信息的风险

4.默认初始化,内置类型的变量未被显式初始化,它的值由定义的位置决定,定义域任何函数体之外被初始化为0,在函数体内部,则不被初始化,其值是未定义的。

变量申明和变量的定义

C++将变量的申明和定义分开,定义负责创建与名字关联的实体,申明使得名字为程序所知,如果申明一个变量而不是定义,使用extern关键字,而且不要显示初始化变量,如果给extern关键字标记的变量赋值,那么extern的作用就被抵消了。如果在多个文件中使用中使用同一个变量,就必须将申明和定义区分开

  • 名字的作用域(namescope
    • 第一次使用变量时再定义它
    • 嵌套的作用域
      • 同时存在全局和局部变量时,已定义局部变量的作用域中可用::reused显式访问全局变量reused。
      • 但是用到全局变量时,尽量不适用重名的局部变量。
变量命名规范
  1. 需体现实际意义
  2. 变量名用小写字母
  3. 自定义类名用大写字母开头:Sales_item
  4. 标识符由多个单词组成,中间须有明确区分:student_loan或studentLoan,不要用studentloan。

2.3 复合类型

申明语句更通用的描述,一条申明语句由一个基本数据类型和紧随其后的一个申明列表组成

引用

1.引用必须初始化并且指向一个对象,但引用本身不是一个对象,没有实际地址

2.引用初始化后不能解绑,并且只是将一个对象绑定,而不是拷贝

3.引用类型必须和绑定对象严格一致,但是有两种例外情况

  • 一种是在初始化常量引用时允许用任意表达式作为初始值,只要该表达式的结果能转换为引用类型即可
指针
  • 指针在定义时没有被初始化,将拥有一个不确定的值

  • 引用没有实际地址,不能定义指向引用的指针

  • 指针的类型和被指向的对象的类型必须一致

  • 得到空指针最好的办法是使用**字面值nullptr****(C++11)**来初始化,尽量避免使用NULL来初始化指针

  • void*指针是一种特殊的指针类型,可以存放任意对象的地址,和正常的指针相比,void*指针的作用:和别的指针作比较、作为函数的输入和输出、给另外一个void*指针赋值,不能直接操作void*指针所指向的对象。

  • 建议:初始化所有指针。

2.4 const限定符

  • 定义一个不可改变的常量,所以必须const对象必须要初始化且不可改变

  • 默认情况下,const对象仅在文件内有效,如果想在对各文件之间共享const对象,必须在变量的定义之前添加extern

const引用
  • 可以把引用绑定到const对象上,称为对常量的引用,这样做了之后,便不能通过引用改变引用对象的值
  • 不能让一个非常量引用指向常量对象
  • 常量引用仅对引用可参与的操作做出了限定,对于引用的对象本身是不是一个常量未作限定。
指针和const
  • 指向常量的指针不能用于改变其所指对象的值,要想存放指向常量的地址,只能使用指向常量的指针
const double pi = 3.14  
double *ptr = &pi   //错误,ptr是一个普通指针
const double *cptr = &pi    //正确
  • 和常量引用一样,指向常量的指针没有规定所指向的对象必须是一个常量
  • 常量指针必须初始化,初始化完成,存放在指针中的地址就不能在改变
//常量指针和指向常量的指针并不相同
int errNumb = 0;
int *const curErr = &errNumb;//这是常量指针
const int *const pip = &errNumb  //这是一个指向常量对象的常量指针
顶层const
  • 顶层const表示指针本身是一个常量

  • 底层const表示指针所指的对象是一个常量

  • 更一般的是顶层const可以表示任意的对象是常量,底层const则与指针和引用等符合类型的基本数据结构有关

  • 用于申明引用的const都是底层const

  • 在执行拷贝操作时,拷入和拷出的对象必须具备相同的底层const资格或者两个对象的数据类型必须能够转换,而顶层const不受影响

constexpr和常量表达式
  • 常量表达式:指值不会改变,且在编译过程中就能得到计算结果的表达式。
  • C++11新标准规定,允许将变量声明为constexpr类型以便由编译器来验证变量的值是否是一个常量的表达式。

2.5 处理类型

类型别名
  • 传统别名:使用typedef来定义类型的同义词。 typedef double wages;
  • **C++11:**别名声明(alias declaration): using SI = Sales_item;
// 对于复合类型(指针等)不能代回原式来进行理解
typedef char *pstring;  // pstring是char*的别名
const pstring cstr = 0; // 指向char的常量指针
// 如改写为const char *cstr = 0;不正确,为指向const char的指针

// 辅助理解(可代回后加括号)
// const pstring cstr = 0;代回后const (char *) cstr = 0;
// const char *cstr = 0;即为(const char *) cstr = 0;
auto类型说明符
  • C++11引入auto类型说明符,auto让编译器通过初始值来推算变量的类型,所以auto定义变量必须初始化
  • 在一条语句中如果使用auto申明多个变量,则所有变量的初始基本数据类型必须保持一致
  • auto会忽略顶层const,保留底层const
  • 如果希望是顶层const需要自己加const
decltype类型指示符
  • **C++11,**从表达式的类型推断出要定义的变量的类型
  • decltype:选择并返回操作数的数据类型
  • decltype(f()) sum = x; 推断sum的类型是函数f的返回类型
  • 不会忽略顶层const
  • 如果对变量加括号,编译器会将其认为是一个表达式,如int i–>(i),则decltype((i))得到结果为int&引用
  • 赋值是会产生引用的一类典型表达式,引用的类型就是左值的类型。也就是说,如果 i 是 int,则表达式 i=x 的类型是 int&
  • decltype((i)) (注意是双括号)的结果永远是引用,decltype(i) 只有当i本身是一个引用时才是引用
自定义数据结构

C++11规定,可以为数据成员提供一个类内初始值,创建对象时,类内初始值将用于初始化数据成员

编写自己的头文件

  • 预处理器(preprocessor):确保头文件多次包含仍能安全工作。
  • 当预处理器看到#include标记时,会用指定的头文件内容代替#include
  • 头文件保护符(header guard):头文件保护符依赖于预处理变量的状态:已定义和未定义。
    • #indef已定义时为真
    • #inndef未定义时为真
    • 头文件保护符的名称需要唯一,且保持全部大写。养成良好习惯,不论是否该头文件被包含,要加保护符。
  • 申明函数原型也放在头文件中,函数实现在源文件中
#ifndef SALES_DATA_H  //SALES_DATA_H未定义时为真
#define SALES_DATA_H
strct Sale_data{
    ...
}
#endif
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值