C++ Primer 第五版学习 第一、二章

一、标准输入输出

cin是标准输入(istream对象)

cout是标准输出(ostream)

cerr是标准错误,用来输出警告和错误消息

clog用来输出程序运行时的一般性信息

二、 for 与 while 形式比较

在for循环中,循环控制变量的初始化和修改都放在语句头部分,形式较简洁,且特别适用于循环次数已知的情况。

在while循环中,循环控制变量的初始化一般放在while语句之前,循环控制变量的修改一般放在循环体中,形式上不如for语句简洁,但它比较适用于循环次数不易预知的情况(用某一条件控制循环)。

两种形式各有优点,但它们在功能上是等价的,可以相互转换。

三、读取数量不定的输入数据

while(cin>>value)

使用文件结束符Ctrl+Z结束输入。

四、选择类型的准则:

        (0开头是八进制,0x开头是十六进制)
    1. 当明确知道数值不可能为负时,选用无符号类型
    2. 使用int执行整数运算,在实际应用中,short常常显得太小而long一般和int有一样的尺寸。所以一旦数值范围超过了int,即选用long long
    3. 在算术表达式中不要使用char和bool,(类型char在一些机器上是有符号的,在另一些上可能没有符号)
        如果要使用,请明确指明它的类型是signed char还是unsigned char
    4. 执行浮点数运算时用double,long double一般是没有必要的

五、转义序列-----可使用泛化的转义序列

\n 换行符        \t 横向制表符        \a 报警(响铃)符        \v纵向制表符

\b 退格符       \“ 双引号        \\ 反斜线        \'单引号        \?问

\r 回车符        \f 进纸符

(使用不同的字符集,会有不同的表达方式)

六、什么是对象

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

七、初始化

列表初始化:

形如 

int units_sold = {0};
int units_sold{0};

称为列表初始化,是C++新11标准的一部分。

重要特点:如果我们使用列表初始化且初始值存在丢失信息的风险时,则编译器将报错。

默认初始化:

如果定义变量时没有指定初值,则变量被默认初始化,被赋予默认值。

内置类型的变量未被显式初始化的时候,其值由定义的位置决定。

        1. 定义于任何函数体之外的变量被初始化为0;

        2.定义在函数体内部的内置类型变量不被初始化。

八、变量声明和定义的关系

1. 声明使名字为程序所知; 定义负责创建与名字关联的实体。

2. 变量能且只能被定义一次,但是可以被多次声明。

3. 如果想声明一个变量而非定义它,就在变量名前添加关键字extern。在函数内部不能初始化一个由extern关键字标记的变量,会导致报错。

extern int i;    //声明i而并非定义i
int j;           //声明并定义j

4. 任何包含了显式初始化的声明即成为定义。(抵消extern的作用)

九、嵌套的作用域

1. 作用域能彼此包含,被包含(被嵌套)的作用域称为内层作用域,包含着别的作用域的作用域称为外层作用域。

2. 局部变量可覆盖全局变量。如果函数有可能用到某全局变量,则不再定义一个同名的局部变量。

3. 若函数中定义了与全局变量同名的局部变量后,还想要使用全局变量,则

cout<<::global<<enl;

若不加作用域操作符,则是使用局部变量。

十、引用和指针

1. 引用:为对象起了另一个名字(引用即别名)。引用类型引用另外一种类型。引用必须被初始化。即,改变都会改变,不论是对象本来的名字赋值变化还是引用别名进行赋值变化。

2. 指针:指针存放某个对象的地址,要想获得该地址,需要使用取地址符

int ival = 42;
int *p = &ival;  //p存放变量ival的地址,或者说p是指向名为ival的int对象

为*p赋值实际上是为p所指的对象赋值。

3. 建议初始化所有指针。如果不清楚指针应该指向何处,就把他初始化为nullptr或0;

4. 任何非零指针对应的条件值都是true。

if (p)     //p是否是空指针
if (*p)     //p指向的对象是否是零

5. void* 指针是一种特殊的指针类型,可用于存放任意对象的地址。void* 指针能做的事情有限:

        a)与别的指针比较 

        b)作为函数的输入输出

        c)赋给另一个void*指针

不能直接操作void*指针所指的对象。

6. 指针和引用的区别

指针是一个任何其他类型的“指向”,而引用是对象的“另一个名称”。

区别:

        a) 引用是已存在对象的另一个名称。指针本身就是一个对象。
        b) 一旦初始化,引用就绑定到它的初始对象上,无法重新绑定引用以引用不同的对象。而指针可以重新分配或拷贝。
        c) 引用必须初始化。指针在定义时可以不需要初始化。
        d) 引用不能为NULL,指针可以为NULL。

7. **表示指向指针的指针,***表示指向指针的指针的指针,以此类推。

8. 有指向指针的引用。因为引用本身不是一个对象,所以不能定义指向引用的指针。例子如下:

int i = 42;
int *p;
int *&r = p  //r是对指针p的一个引用,即别名

r = &i;   //r是p的别名,故即为令p指向i
*r = 0;   //解引用r,即将i的值改为0

十一、const限定符

1. const对象一旦创建后其值就不能再被修改,所以const对象必须初始化。初始值可以是任意复杂的表达式。只有const能够引用常量

2. 如果想在多个文件之间共享const对象(这个情况是指const变量它的初始值不是一个常量表达式,但又确实有必要在文件之间共享。即只在一个文件中定义const,而在其他多个文件中声明并使用它),必须在变量的定义之前添加extern关键字。

3. const的引用:与普通引用不同的是,对常量的引用不能被用作修改它所绑定的对象。

4. 一般情况下,引用的类型必须与其所引用对象的类型一致。

        例外情况:在初始化常量引用时,允许用任意表达式作为初始值,只要该表达式的结果能转换成引用的类型即可(隐式转换)。

5. 对const的引用可能引用一个并非const的对象。

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

const double pi = 3.14;
const double *cptr = &pi;

7. const指针。指针是对象而引用不是,将指针本身定为常量。常量指针必须初始化,一旦初始化完成,则它的值(即存放在指针中的那个地址)就不能再改变了。

int errNumb = 0;
int *const curErr = &errNumb;

8. 顶层const:表示指针本身是个常量。可以表示任意的对象是常量,对任何数据类型都适用。拷贝操作是,拷入和拷出的对象是否是常量都没什么影响。

    底层const:表示指针所指的对象是一个常量。执行对象的拷贝操作的时候,拷入和拷出的对象必须具有相同的底层const资格。

指针类型既可以是顶层也可以是底层。

const int *const p3 = p2;    //靠右的const是顶层const,靠左的是底层const
const int &r = ci;    //用于声明引用的const都使底层const

十二、 常量表达式与constexpr变量

1. 常量表达式:指值不会改变并且在编译过程就能得到计算结果的表达式。如常量值、用常量表达式初始化的const对象。(实际在一个复杂系统中,很难分辨一个初始值到底是不是常量表达式。故引用constexpr变量)

const int sz = get_size();   //sz不是常量表达式。
                             //尽管sz本身是一个常量,但它的具体值直到运行时才能获取到,所以也不是常量表达式

2. constexpr变量:C++11新标准规定,允许将变量声明为constexpr类型以便由编译器来验证变量是都是一个常量表达式。   

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

        指针和引用都可以定义成constexpr类型,但是初始值受限。constexpr指针的初始值必须是nullptr或0或存储于某个固定地址中的对象。

const int *p = nullptr;    //p是一个指向整型常量对象的指针
constexpr int *cp = nullptr;    //np是一个指向整型的常量指针

字面值类型:算数类型、引用、指针……

十三、类型别名

1. typedef

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

2. 别名声明

使用关键字using作为别名开始,其后紧跟别名和等号,其作用是把等号左侧的名字规定成等号右侧类型的别名。

using SI = Sales_item    //ST是Sales_item的别名

3. auto

auto定义的变量必须有初始值

使用auto也能在一条语句中声明多个变量,但是必须保证该语句中所有变量的初始基本数据类型一样。

auto会忽略掉顶层const,如果需要推断出的auto类型是一个顶层const,那么需要明确指出

const auto f  = ci

引用在auto上的初始化规则仍可以使用。

4. decltype类型指示符:选择并返回操作数的数据类型

在decltype的编译过程中,编译器仅分析表达式并得到它的类型,却不实际计算表达式的值

decltype(f()) sum = x;    //sum的类型就是函数f的返回类型

表达式中如果是解引用操作,那么结果类型就是引用类型。

decltype中的表达式如果是加上了括号的变量,结果将是引用。

decltype((p)) d;   //错误,因为d的类型是引用,故必须初始化。

赋值也是能够产生引用的一类典型表达式,引用的类型就是左值的类型

int a = 3, b = 4;
decltype(a) c = a;
decltype(a = b) d = a;    //d的类型是int&
//注意括号中的不实际计算,仅判断返回值类型

十四、预处理器

确保头文件多次包含仍能安全工作的常用技术是预处理器,它由C++语言从C语言继承而来。预处理器是在编译之前执行的一段程序,可以部分地改变我们所写的程序。

预处理指令:是以#开头的代码行,#号必须是该行除了任何空白字符外的第一个字符。

预编译处理指令:

#define 把一个名字设定为预处理变量,另外两个指令分别检查某个指定的预处理变量是否定义:

        #ifdef 当且仅当变量已定义时为真。

        #ifndef当且仅当变量未定义时为真。

        一旦检查结果为真,则执行后续操作直到遇到#endif指令为止。。

更多的进入这里看 C/C++预处理指令#define,#ifdef,#ifndef,#endif… - [0] - 博客园本文主要记录了C/C++预处理指令,常见的预处理指令如下: 本来只是想了解一下#ifdef,#ifndef,#endif的,没想到查出来这么多的预处理指令,上面的多数都是常见的,但是平时没有怎么注意预https://www.cnblogs.com/zi-xing/p/4550246.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值