c++ Primer 第二章 变量和基本类型

c++ Primer 第二章 变量和基本类型

1.基本内置类型

  • c++定义了算术类型和空类型在内的基本数据类型,其中算数类型包括字符、整型数、布尔值和浮点数。
类型 含义 最小尺寸
bool 布尔类型 未定义
char 字符 8位
wchar_t 宽字符 16位
char16_t Unicode 字符 16位
char32_t Unicode 字符 32位
short 短整型 16位
int 整型 16位
long 长整型 32位
long long 长整型 64位
float 单精度浮点数 |6位有效数字
double 双精度浮点数 |10位有效数字
long double 扩展精度浮点数 | 10位有效数字

如何选择类型

1.当明确知晓数值不可能是负数时,选用无符号类型;
2.使用int执行整数运算。一般long的大小和int一样,而short常常显得太小。除非超过了int的范围,选择long long。
3.算术表达式中不要使用char或bool。
4.浮点运算选用double。float 精度不够

练习1:int,long,long long和short有什么区别?在无符号和有符号类型之间?在浮点数和双数之间?

c++ 的保证short 和 int 至少16位,long至少32位,long long 至少64位
signed 可以为正数,负数和零,而unsigned 只能代表数字不低于0
float

类型的转换

  • 非布尔型赋给布尔型,初始值为0则结果为false,否则为true(非零值为true)。
  • 布尔型赋给非布尔型,初始值为false结果为0,初始值为true结果为1。

符号型

当符号型与非符号型相运算时,带符号数会转成无符号数

字面值常量

  • 一个形如42的值被称作字面值常量(literal)。
  • 整型和浮点型字面值。
  • 字符和字符串字面值。
  • 使用空格连接,继承自C。
  • 字符字面值:单引号, ‘a’
  • 字符串字面值:双引号, “Hello World”"
  • 转义序列。\n、\t等。
  • 布尔字面值。true,false。
  • 指针字面值。nullptr

变量

  • 变量提供一个具名的、可供程序操作的存储空间。
  • 变量的基本形式是:类型说明符
  • 变量的初始化:
    • 初始化不是赋值
    • 含义是创建变量时赋予其一个初始值
    • 与* 赋值 *区别:将当前对象的值擦除,而以一个新值替代。
    • 列表的初始化 使用花括号{},例如:int example{0};
    • 使用列表初始化且初始化存在丢失信息的风险时,则编译器会报错
      • 例如:
        long double id=3.1415926;
        int a{id},b={id};//错误:转换未执行,存在丢失信息的危险
        int c(id),d=id;//正确,转换执行,且确实丢失了数据
        
    • 默认初始化:定义时没有指定初始值会被默认初始化;在函数体内部的内置类型变量将不会被初始化。
    • 建议初始化每一个内置类型的变量。
    • 注意:定义于函数体内的内置类型的对象如果没有初始化,则其值未定义。类的对象如果没有显式地初始化,则其值由类确定

变量的声明与定义

  • 声明使得名字为程序所知。
  • 定义是创建与名字关联的实体,就是会申请存储空间
  • 变量只能被定义一次,但是可以多次声明。
extern int i //声明
int j;//声明且定义
extern double pi=3.1415826;//定义
  • 名字的作用域,c++语言中大多数作用域以花括号分割开
  • 一般,在对象第一次被使用的地方附近定义它是一种好的选择,因为这样做有助于容易找到变量的定义。
  • 嵌套作用域:内层作用域和外层作用域
int i = 42 ;
int  main()
{
    int i = 100 ;
    int j = i;
}
//j的值为100

左值与右值

  • 左值指的是可以取地址的变量,记住,左值与右值的根本区别在于能否获取内存地址,而能否赋值不是区分的依据。通常临时量均为右值。

复合类型

引用

  • 引用为对象起了另一个名字,引用类型引用另外一种类型。int b=10;int &a=b;
  • 注意:** 引用并非对象,引用和它的初始值是绑定在一起的,不是拷贝,引用必须初始化**
  • ** 引用只能绑定在对象上,而不能与字面值或某个表达式的计算结果绑定在一起**

指针

  • 是一种 "指向(point to)"另外一种类型的复合类型。
  • 定义指针类型: int *ip1;,从右向左读,ip1是指向int类型的指针。
  • 指针存放某个对象的地址。
  • 获取对象的地址: int i=42; int *p = &i;。 &是取地址符。
  • 指针的值的四种状态:
    • 1.指向一个对象;
    • 2.指向紧邻对象的下一个位置;
    • 3.空指针,意味着指针没有指向任何对象;
    • 4.无效指针,也就是上述情况之外的其他值。
  • 指针访问对象: cout << p;, 是解引用符* 解引用操作适用于那些确实指向了某个对象的有效指针**)。
  • 空指针不指向任何对象,用字面值nullptr初始化。
  • ** 使用未初始化的指针是引发运行错误的一大原因**
  • 赋值与指针:赋值永远改变的是等号左侧的对象
int a=20;
int *b=&a;//b的值被改变,b指向a,b存放了a的地址
*b=10;//a的值被改变,a=10,*b(就是指针b所指的对象,也就是a)
  • void*指针可以存放任意对象的地址。
  • 其他指针类型必须要与所指对象严格匹配。

理解复合类型的声明

  • int *p1,p2;//p1是指向int的指针,p2是int
  • 一般来说,声明符中修饰符的个数并没有限制。当有多个修饰符连携在一起时,按照其逻辑关系详加解释。(面对一条复杂的指针或者引用声明语句时,从右向左阅读有助于弄清楚它的真实含义

CONST

  • 动机:希望定义一些不能被改变值的变量。
  • const对象必须初始化,且不能被改变。
  • const变量默认不能被其他文件访问,非要访问,必须在指定const前加extern,默认情况下,const对象设定仅在文件内有效
  • eference to const(对常量的引用):指向const对象的引用,如 const int a=1; const int &b= a;,可以读取但不能修改b
  • 临时量(temporary)对象:当编译器需要一个空间来暂存表达式的求值结果时,临时创建的一个未命名的对象。
  • 对临时量的引用是非法行为。
指针与const
  • pointer to const(指向常量的指针):不能用于改变其所指对象的值, 如 const double pi = 3.14; const double *cptr = π。
  • const pointer:指针本身是常量,如 int i = 0; int *const ptr = &i;
顶层与底层const
  • 顶层const:指针本身是个常量。例:int * const a;
  • 底层const:指针指向的对象是个常量。拷贝时严格要求相同的底层const资格。例:int const *b;const int *b;
  • ** const int p 表示:「p」类型为 int 并且不可变;而 int * const p 表示:「 const p」属于 int,即:p 属于「int 」并且不可变。
constexpr和常量表达式
  • 常量表达式:指值不会改变,且在编译过程中就能得到计算结果的表达式。
  • C++11新标准规定,允许将变量声明为constexpr类型以便由编译器来验证变量的值是否是一个常量的表达式。

处理类型

类型别名
  • 用typedef 来定义:typedef double a;a b;//double b
  • 新方法:using a = double;
auto类型说明符
  • auto类型说明符:让编译器自动推断类型。
  • 会忽略顶层const。
decltype类型指示符
  • decltype作用是选择并返回操作数的数据类型。
  • decltype(f()) sum=x;//sum 的类型就是函数f 的返回类型。
  • decltype((a)) (注意是双层括号)的结果永远是引用,而decltype(variable)的结果只有当variable 本身就是一个引用时才是一个引用。

自定义数据类型

struct
  • 类可以以关键字struct开始,紧跟类名和类体。
  • 类数据成员:类体定义类的成员。
  • C++11:可以为类数据成员提供一个类内初始值(in-class initializer)。
struct sales_data{
	std::string bookno;
	unsigned units_sold=0;
	double revenue=0.0;
};
  • ** 在类定义后最后加上分号**

预处理技术

#define              //定义一个预处理宏
#undef             //取消宏的定义

#if                      //编译预处理中的条件命令, 相当于C语法中的if语句
#ifdef                //判断某个宏是否被定义, 若已定义, 执行随后的语句
#ifndef             //与#ifdef相反, 判断某个宏是否未被定义
#elif                  //若#if, #ifdef, #ifndef或前面的#elif条件不满足, 则执行#elif之后的语句, 相当于C语法中的else-if
#else                //与#if, #ifdef, #ifndef对应, 若这些条件不满足, 则执行#else之后的语句, 相当于C语法中的else
#endif              //#if, #ifdef, #ifndef这些条件命令的结束标志.
defined          //与#if, #elif配合使用, 判断某个宏是否被定义

#include           // 包含文件命令
#include_next   //与#include相似, 但它有着特殊的用途

#line                //标志该语句所在的行号
#                      //将宏参数替代为以参数值为内容的字符窜常量
##                   //将两个相邻的标记(token)连接为一个单独的标记
#pragma       //说明编译器信息

#warning       //显示编译警告信息
#error          //显示编译错误信息

你可能感兴趣的:(c++,primer,c++,编程语言)