C++Primer 第二章

//1.程序尽量避免依赖于实现环境的行为。比如:如果将int的尺寸看成一个确定不变的已知值,那么这样的程序就称为不可移植的。
    typedef int int32;    //使用类似的typedef,可以有效的解决移植问题

//2.进行算术运算的时候,要注意有符号类型向无符号类型的提升
    long long value = (int)-1 + (unsigned int)0;        //value = 4294967295

//3.一个行如42的值被称为字面值常量,这样的值一看便知。每个字面值常量对应一种数据类型,字面值常量的形式和值决定了其数据类型。

//4.泛化的转义序列:形式是\x(注意是小写的x)后紧跟十六进制数字,或者\后紧跟1个,2个或者3个八进制数字,其中数字部分表示字符对应的数值
    char *str0 = "\x31";     //str0 = "1"
    char *str1 = "\X31";     //str0 = "X31"
    char *str2 = "\0615";    //str2 = "15"    注意这里仅有前3个数字与\构成转义序列

//5.可以通过为字面值常量添加前缀或者后缀来改变其默认类型,字符串都是添加前缀,算数类型都是添加后缀
    int value0 = sizeof L‘a‘;    //value0 = 2    L前缀 表示宽字符 对应 wchar_t 类型

    int value1 = sizeof ~0U;     //value1 = 4    u或U后缀 对于整形 表示最小匹配类型为 unsigned
    int value2 = sizeof ~0L;     //value2 = 4    L或l(字母l) 对于整形 表示最小匹配类型为 long
    int value3 = sizeof ~0LL;    //value2 = 8    LL或ll(字母l) 对于整形 表示最小匹配类型为 long long

    int value4 = sizeof 0.1;     //value4 = 8    默认以double存储浮点数
    int value5 = sizeof 0.1F;    //value5 = 4    F或f后缀 对于浮点型 表示float
    int value6 = sizeof 0.1L;    //value6 = 8    L或l后缀 对于浮点型 表示long double

    unsigned long long value7 = ~0LL;    //value7 = 0xffffffffffffffff    注意LL表示最小匹配类型为long long 而不是指定为long long, U L等后缀类似。
    unsigned long long value8 = 0xFFFFFFFFFFFFFFFFL;    //value8 = 0xffffffffffffffff 再次强调是最小匹配类型。

//6.定义与任何函数体之外的变量被初始化为0,定义在函数体内的变量不被初始化,任何试图访问和拷贝没有初始化的变量将会出错

//7.C++将声明和定义区分开来,声明使得名字为程序所知。定义负责创建与名字关联的实体。变量仅能定义一次,但能声明多次。
    extern int value0;         //声明
    int value1;                //定义
    extern int value2 = 0;     //定义

//8.变量命名规范:变量名一般为小写开头,用户自定义类型一般为大写开头。对于多个单词组成的变量,应用驼峰命名法。

//9.作用域操作符::有3种用法
    ::name;                     //全局作用域
    class::name;                //类作用域
    namespace::name             //命名空间作用域

//10.一条声明语句由一个基本数据类型和紧随其后的一个声明符列表组成。每个声明符命名了一个变量并指定了该变量为与基本数据类型有关的某种类型。在同一条声明语句中,基本数据类型是相同的,但是声明符不一定相同。
//   基本类型:是类型说明符,可用const修饰,在声明语句中位于声明符之前。基本类型提供了最常见的数据类型,以此基础构建声明符。
//   声明符:是声明的一部分,包括被定义对象的名字和类型修饰符。其中类型修饰符(比如const,registe等)可有可无。
    int value0 = 0;                //此定义语句中, int为基本数据类型, value0为声明符。此声明语句的结果是将声明符value指定为int类型。
    int *pvalue0, value1;         //在此定义语句中,定义了2个类型不同的变量。pvalue0为int*类型,其类型修饰符*是声明符的一部分, value1为int类型,它们的基本数据类型都是int。
//11.引用:为对象起了另一个名字,引用必须初始化,引用无法重新绑定到另一个对象上。引用本身不是一个对象。不能定义引用的引用,不能在容器中存储引用类型,不能定义一种元素类型为引用类型的数组。
//    引用类型要和其绑定的对象严格匹配,但是有两个例外:1.在初始化常量引用的时候,允许使用任意能转化为该引用类型的表达式作为初始值。2.父类引用能接受子类对象。
    double data0 = 3.14;
    const int &data1 = data0;    //合法,但data1和data0的地址不同

//12.指针:是指向另一种类型的复合类型。其本身就是一个对象。 void*指针是一种特殊的指针,可以用于存放任意对象的地址,不能对void*指针进行解引用。
//   指针类型必须和所指对象严格匹配,但是有两个例外:
//   1.允许一个指向常量的指针指向一个非常量对象。但这样的赋值有一个前提:只进行一层间接运算:int* 可以转化为const int *,而无法从int **”转换为“const int **
//   2.父类指针能指向子类对象。
    int number = 0;
    const int *pNumber0 = &number;
    int *const pNumber1 = &number;    //离pNumber1最近的符号是const,意味着pNumber1本身是一个常量,其类型由声明符的其余部分决定。

//13.默认情况下const对象被设定为文件内有效。当多个文件中出现了同名const变量,等同于在不同文件中分别定义了这些独立的变量。若在头文件定义了一个const变量,那么多个包含此头文件的源文件中都将定义自己的独立的const变量。
//   如希望将const变量进行文件间共享,则在一个源文件中进行定义,在头文件中进行extern声明即可,那么所有包含此头文件的源文件都将共享一个const变量。
//   const分为顶层const和底层const。顶层const可以表示任意的对象是常量,而底层const表示指针所指的对象是常量。由于引用不是对象,所以引用类型的const都是底层const。
//   在执行对象拷贝的时候,常量是顶层const还是底层const有明显区别。其中,顶层const不受影响。另一方面,底层const对象执行拷贝操作的时候,要求拷入和拷出的对象必须具有相同的底层const资格或者两个对象的数据类型能够转换。
//   const是一种类型修饰符
    const int *p0 = nullptr;        //此处的const是底层const
    int *const p1 = nullptr;        //此处的const是顶层const
    const int count = 0;            //此处的const是顶层const

//14.类型别名:使用关键字typedef。
    typedef int* pint;
    int nData = 0;
    const pint pData = &nData;        //等价于:     int *const pData = &nData; 注意点:声明中用到了pint,其基本数据类型是指针,若写成 const int *pData = &nData;则其基本数据类型是int, *变成了声明符的一部分。
    //pData = nullptr;                //错误        error C3892: “pData”: 不能给常量赋值

    typedef class B
    {
    }b;        //b为B的别名

//15.auto:让编译器通过初始值来推断变量的类型。显然,auto定义的变量必须具有初始值,且其基本类型必须相同。
//   auto在下列几种情况下推断出的类型与其初始值并不完全一样,编译器适当的改变结果类型使其更加符合初始化规则
//   A:编译器以引用对象的类型作为auto的类型。
//   B:auto会忽略顶层const并保留底层const
//   C:auto会将函数名转为对应函数指针类型
//   D:auto会将数组名转为对应指针类型

//16.decltype:希望从表达式中推断出要定义的变量的类型,但是不想用该表达式的值来初始化变量。在此过程中,只得到表达式的类型而不实际计算表达式的值。
//   decltype不会执行auto中编译器执行的转换。
//   如果decltype使用的表达式不是一个变量,则decltype返回表达式对应的类型。如果表达式的求值结果是左值,则decltype作用于该表达式(不是一个变量)得到一个引用类型。
//   左值:当对象用作左值的时候,使用的是对象的身份(在内存中的位置)
//   右值:当对象用作右值的时候,使用的是对象的值(内容)
//   赋值运算符:需要一个非常量左值作为其左侧运算符对象,得到的结果也是一个左值
//   取地址符:作用于一个左值运算对象,返回一个指向该运算对象的指针,这个指针是一个右值
//   解引用运算符和下标运算符:求值结果均为左值
//   前置递增递减运算符:求值结果为左值
//   后置递增递减运算符:求值结果为右值
    int nNumber0 = 10;
    int *pnNumber0 = &nNumber0;
    decltype (nNumber0) nNumber1;                 //nNumber1为int类型
    decltype (pnNumber0) nNumber2;                //nNumber2为int*类型
    decltype ((nNumber0)) nNumber3 = nNumber0;    //nNumber3为int&类型
    decltype (*pnNumber0) nNumber4 = nNumber0;    //nNumber4为int&类型

//17.结构体和类的类体的后面都可以跟其对象的定义
    class A
    {
    } a;    //a为类A的一个对象

//18.当预处理器看到#include标记时,就会用指定的头文件的内容代替#include
//   通常使用#ifdef  #endif 来防止重复包含。
//   预处理变量无视C++语言中关于作用域的限制            #define 指示的接受后面的名字,并把这个名字定义为预处理器变量,常用大写。
//   在程序编译之前,预处理器负责将程序中的预处理变量替换为它的真实值

//19.在数值上数组名等同于对数组名取地址,但是意义上不同,前者是一个数组首地址,后者为一个指向数组的指针
    int array[10] = {0};
    int size0 = sizeof array;        //size0 = 40
    int size1 = sizeof (&array);    //size1 = 4

//20.常量表达式:是指值不会变,并且在编译过程就能得到计算结果的表达式
    int fun(){return 10;}
    const int nValue0 = 10;                //常量表达式
    const int nValue1 = nValue0 + 1;       //常量表达式
    int nValue2 = 10;                      //并不是常量表达式,原因是:value2的值可以改变
    const int nValue3 = fun();             //并不是常量表达式,原因是:value3的值不能在编译的时候得到  
时间: 2024-12-25 21:14:41

C++Primer 第二章的相关文章

c++primer第二章读书笔记---变量和基本类型

C++中,什么是复合类型? 刚开始,还以为自定义的类是复合类型.查了C++ primer才知道复合类型不是类. 在C++中类型大致可以分为三种 一.内置类型 如int, char, float, unsigned等.内置类型是最基本的类型. 二.复合类型 复合类型:基于其他类型定义的类型,使用其它类型定义的类型.有三种复合类型:引用,指针,数组. 三.类类型 就是类.比如string以及自己定义的类. (一)复合类型---引用 引用就是为对象起了个名字 引用使用注意事项: 1.一个变量可取多个别

C++ Primer第二章习题(一)

习题2.1 /* 各种类型在本机所在字长 */ #include<iostream> int main(){ std::cout<<"sizeof(int)="<<sizeof(int)<<std::endl; std::cout<<"sizeof(long)="<<sizeof(long)<<std::endl; std::cout<<"sizeof(long

C++Primer 第二章 第二部分

//1.一条声明语句由一个基本数据类型和紧随其后的一个声明符列表组成.每个声明符命名了一个变量并指定了该变量为与基本数据类型有关的某种类型.在同一条声明语句中,基本数据类型是相同的,但是声明符不一定相同. // 基本类型:是类型说明符,可用const修饰,在声明语句中位于声明符之前.基本类型提供了最常见的数据类型,以此基础构建声明符. // 声明符:是声明的一部分,包括被定义对象的名字和类型修饰符.其中类型修饰符(比如const,* ,&等)可有可无. int value0 = 0; //此定义

C++ Primer 第二章 引用 指针 const限定符

1.引用: 为对象起了另外一个名字,引用类型引用另外一种类型,通过将声明符写成&d的形式来定义引用类型,其中d也就是声明的变量名(声明符就是变量名). PS:1.通过图片中编译所提示的报错信息也可知,引用必须被初始化: 2.引用并非对象,相反的,它只是为一个已经存在的对象所起的另一个名字而已: 2.指针: 与引用类似,指针也实现了对其他对象的间接访问,不过,指针本身就是一个对象,允许对指针赋值与拷贝,而且在其生命周期内可以先后指向几个不同的对象(引用只能指向一个初始化的). 指针无须再定义时赋初

c++primer 第二章编程练习答案

2.7.1 #include<iostream> int main() { using namespace std; char name[20]; char address[20]; cout << "input name :"; cin >> name; cout << "input address:"; cin >> address; cin.get(); cout << "nam

C++primer第二章 变量和基本类型

类型是程序的基础.类型告诉我们数据代表什么意思以及可以对数据执行那些操作. C++语言定义的几种类型: 字符型 整型 浮点型 还支持自定义数据类型 数据类型确定了数据和操作在程序中的意义 i=i+j; int:5=2+3: string:hello world = hello + world: 2.1.基本内置类型 计算:整型或者浮点型 用来存储数值 语句说明:字符串或者string类型 存储语句 判断条件:bool类型 存储真值 2.1.2. 整型 整数.字符和布尔值的算术类型合成为整型.与浮

C++ Primer 笔记 第二章

C++ Primer 第二章 变量和基本类型 2.1基本内置类型 有算数类型和void类型:算数类型储存空间大小依及其而定. 算数类型表: 类型 含义 最小储存空间 bool 布尔型 - char 字符型 8 wchar_t 宽字符型 16 short 短整型 16 int 整型 16 long 长整型 32 float 单精度浮点型 6位有效数字 double 双精度浮点型 10位有效数字 long double 扩展精度浮点型 10位有效数字 2.1.1整型 包括整数字符和布尔型. 字符型:

《C++ Primer 5th(中文版)》“概览的概览”之第一部分——C++基础,第二章

C++ Primer已经快读完了,但这本书光读一遍是绝对不行的.至少读两遍,把大部分可操作的习题做一遍,才能记住大部分细节.在这里,我想对C++第一部分--C++基础进行一次非常非常非常简略但结合核心部分的整合,带大家一览C++大略(很浅的那一部分),而不是迷失于细节. 第二章 变量和基本类型 2.1 基本内置类型 1.C++定义了算术类型和空类型.常见的类型有bool, char, short, int, long, long long, float, double, long double,

C++ Primer Plus学习:第二章

C++入门第二章:开始学习C++ 进入C++ 首先,以下是一个C++程序: //myfirst.cpp 显示一行文字 #include<iostream> //预处理器编译指令 int main() //函数头 { using namespace std; //编译指令 cout<<"学习C++"; //显示消息 cout<<endl; //开始下一行 cout<<"你不会后悔!"; //更多输出 return 0;