C++ Primer扫盲(变量和基本数据类型)

C++ Primer扫盲(1)

1.对比for循环与while循环,两种形式的优缺点各是什么?
在for循环中,循环控制变量的初始化和修改都放在语句头部分,形式较简洁,且特别适用于循环次数已知的情况。
在while循环中,循环控制变量的初始化一般放在while语句之前,循环控制变量的修改一般放在循环体中,形式上不如for语句简洁,但它比较适用于循环次数不易预知的情况(用某一条件控制循环)。
两种形式各有优点,但它们在功能上是等价的,可以相互转换。

2.int,long,long long,short的区别是什么?无符号类型和带符号类型的区别是什么?float和double的区别是什么?
(1)类型 int、long、long long 和 short 的区别是类型的尺寸(大小)不一样,C++ 算术类型的最小尺寸如下所示。

img

(2)无符号类型和带符号类型的区别是表示的数据范围不一样,带符号类型可以表示正数、负数和 0,而无符号类型仅能表示大于等于 0 的值。
(3)float 和 double 的区别是表示的精度不一样,在 32 位机器上,float 类型一般精确到小数点后 6 位,double 一般精确到小数点 10 位。

3.指针值
1)指向一个对象;
2)指向相邻对象所占空间的下一个位置;
3)空指针,意味着指针没有指向任何对象;
4)无效指针,也就是上述情况之外的其他值。

4.*为解应用符,解应用符仅适用于那些确实指向了某个对象的有效指针

5.空指针
不指向任何对象,在试图使用一个指针之前代码可以首先检查它是否为空。nullptr是一种特殊类型的字面值,它可以被转换成任意其他的指针类型。

int *p1 = nullptr;
int *p2 = 0;
int *p3 = NULL;

6.使用未经初始化的指针是程序员引发运行错误的一大原因,大多数编译环境下,使用未经初始化的指针,该指针所占内存空间的当前内容被看作一个地址值。访问该指针,相当于访问一个本不存咋的位置上的本不存在的对象。最坏的情况,当该地址刚好有内容,就很难分清楚该指针是否合法。因此建议初始化所有的指针,并在可能的情况下,尽量定义了对象后再定义指向它的指针。如何实在不清楚指针指向,就将其初始化为nullptr或者0,这样程序就能检测并知道它没有指向任何具体的对象。

7.void*指针:是一种特殊的指针类型,可以用于存放任意对象的地址。一个void*指针存放着一个地址。
它可以用于和其他指针比较、作为函数的输入和输出,或者给另外一个void*指针。不能直接操作void*指针所指对象。

8.指向指针的指针(声明符中的修饰符的个数并没有限制)**表示指向指针的指针,***表示表示指向指针的指针的指针

int val = 1024;
int *pi = &val;       //指向一个int型的数
int **ppi = π      //指向一个int型的指针
int ***pppi = &ppi;   //指向一个int型的指针的指针

9.指向指针的引用
引用本身不是对象,因此不能定义指向引用的指针;但指针是对象,存在对指针的引用

int i = 42;
int *p = nullptr;   //p是int型的指针
int *&r = p;        //r是一个对指针p的引用

r = &i;             //r引用一个指针,因此给r赋值&i就是令p指向i
*r = 0;             //解引用r得到i,也就是p指向的对象,将i的值改为0

10.const限定符(限定变量不能被修改(const修饰的变量被定义为常量),防止误操作改变值);
const变量一旦创建就不能修改,所有const对象必须初始化

int i = 42;
const int ci = i; //i的值被拷贝给ci
int j = ci;       //ci的值被拷贝给和j

初始化时,无需在意ci原本是不是常量,拷贝一个对象不会改变原本的对象,新的对象与原对象无关。

11.默认状态下,const对象被设定为仅在文件内有效。当const对象确实有必要在文件间分享,又不希望编译器每个文件分别生成独立的变量,希望该const变量只在一个文件中定义const,而其他多个文件中声明并使用它,解决办法是对于const变量不管声明还是定义都添加extern关键字。

//file_1.cc定义并初始化了一个变量,该变量能被其他文件访问
extern const int bufSize = fun();
//file_1.h头文件
extern const int bufSize;//与file_1.cc中的bufSize是同一个

12.const的引用
可以把引用绑定到const对象上,就像绑定到其他对象上一样,我们称为对常量的引用。与普通引用不同的是,对常量的引用不能被用作修改它所绑定的对象

const int ci = 1024;
const int &r = ci;//引用及其对应的对象都是常量
r = 42;           //不合法,r是对常量的引用,不可以修改r绑定的对象
int &r2 = ci;     //不合法,试图让一个非常量的引用指向一个常量对象

13.引用
引用并非对象,它只是为一个已经存在的对象所起的别名,不能定义引用的引用
为引用赋值,实际上是把赋值给与引用绑定的对象;获取引用的值,实际是获取与引用绑定的对象的值
所有引用的类型都要和与之绑定的对象严格匹配。
允许一个指向常量的指针指向一个非常量对象;与常量引用一样,指向常量的指针也没有规定其所指的对象是一个变量。

14.constexpr和常量表达式
常量表达式是指不会改变并且在编译过程就能得到计算结果的表达式。

const int max_file = 20;                         //是
const int limit = max_file + 1;                  //是
const int sz = get_size();                       //不是

C++11新标准规定,允许将变量声明为constexpr类型以便由编译器来验证是否为常量表达式。声明为constexpr的变量一定是一个常量,而且必须用常量表达式初始化

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

14.类型别名
关键字typedef作为声明语句的基本数据类型。含typedef的声明语句定义的不再是变量而是类型别名。

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

C++11新标准规定了一种新的方法,使用别名声明来定义类型的别名,这种方法用关键字using作为变量声明的开始,其后紧跟别名和等号,其作用是把等号左侧的名字规定成右侧类型的别名(类型别名和类型的名字等价,只要是类型的名字能出现的地方,就能使用类型别名)

using SI = Sale_item;     //Sale_item的同义词
wages hourly,weekly;      //等价于double hourly,weekly;

15.指针、常量和类型别名
类型别名是复合类型或常量,用到声明语句中效果

typedef char *pstring;       //pstring实际是指向char的指针
const pstring cstr = 0;     //cstr是指向char的常量指针
const pstring *ps;          //ps是一个指针,它的对象是指向char的常量指针

const char *cstr = 0;       //是对const pstring cstr的错误理解

char*重写声明语句后,数据类型成为char,*成为声明符的一部分。改写结果const char成为基本数据类型,完全不同。

16.auto关键字
C++11引入auto类型说明符,用它就能让编译器替我们去分析表达式所属的类型,auto让编译器通过初始值来推算变量的类型。
auto可以在一条语句中声明多个变量,因为一条声明语句中只能有一个基本数据类型,所有该语句中所有变量的初始基本数据类型应该相同

auto item = val1 + val2;

auto i = 0,*p = &i;      //i是整数,p是整型指针
auto sz = 0;,pi = 3.14;  //sz和pi的类型不一样

17.复合类型、常量和auto
编译器推断出来的auto类型有时和初始值并不完全相同,编译器会适当地改变结果类型使其更符合初始化规则。
设置auto类型的引用时,初始值中的顶层常量属性仍然保留。

int i = 0,&r = i;
auto a = r;          //a是一个整数

const int ci = i,&cr = ci;
auto b = ci;            //b是一个整数(ci的顶层const特性被忽略)
auto c = cr;            //c是一个整数(cr是ci的别名,ci本质是一个顶层const)
auto d = &i;            //d是一个整型指针(整数的地址就是指向整数的指针)
auto e = &ci;           //e是一个指向常数常量的指针(对常量对象取地址是一种底层const)
//如果希望推断出的auto类型是一个顶层const
const auto f = ci;      //ci的推演类型是int,f是const int
//将引用的类型设置为auto
auto &g = ci;           //g是一个整型常量引用,绑定到ci
auto &h = 42;           //错误,不能为非常量引用绑定字面值
const auto &j = 42;     //正确,可以为常量引用绑定字面值 

18.decltype类型指示符
希望从表达式的类型推断出要定义的变量的类型,但不想用该表达式的值初始化变量。c++11引入decltype,它的作用是选择并返回操作数的数据类型。在此过程中,编译器分析表达式并得到它的类型,却不实际计算表达式的值

decltype(f()) sum = x;   //sum的类型就是函数f的返回类型
//decltype使用的表达式是一个变量,则decltype返回该变量的类型(包括顶层const和引用在内)
const int ci = 0,&j = ci;
decltype(ci) x = 0;      //x的类型是const int
decltype(ci) y = x;      //y的类型是const int&,y绑定到变量x
decltype(ci) z;          //错误,z就是一个引用,必须初始化

19.decltype和引用
如果decltype使用的表达式不是一个变量,则decltype返回表达式结果对应的类型。
**注意:**decltype((func))的结果永远是引用,而decltype(f)的结果只有当f本身就是一个引用时才是引用。

//decltype的结果可以是引用类型
int i = 42,*p = &i,&r = i;
decltype(r + 0) b;    //正确,加法的结果是int,因此b是一个(未初始化)的int
//表达式的内容是解引用操作,则decltype将得到引用类型
decltype(*p) z;       //错误,c是int&,必须初始化

20.头文件保护符
头文件保护符依赖于预处理变量。预处理变量有两种状态:已定义和未定义;#define指令把一个名字设定为预处理变量,另外两个指令则分别检查某个指定的预处理变量是否已经定义:#ifdef当且仅当变量定义时为真,#ifndef当且仅当变量未定义时为真,一旦检查结果为真,则执行后续操作直到遇到#endif指令为止

术语表
地址(address): 是一个数字,根据它可以找到内存中的一个字节
别名声明(alias declaration): 为另一种类型定义一个同义词:使用 ”名字 = 类型“ 的格式将名字作为该类型的同义词。
算术类型(arithmetic type): 布尔值,字符,整数,浮点数等内置类型。
数组(array): 是一种数据结果,存放着一组未命名的对象,可以通过索引来访问这些对象。
auto: 是一种类型说明符,通过变量的初始值来推断变量的类型。
基本类型(base type): 是类型说明符,可以用 const 来修饰,在声明语句中位于声明符之前。基本类型提供了最常见的数据类型,以此为基础构建声明符。
绑定(bind): 令某个名字与给定的实体关联在一起,使用该名字也就是使用该实体。例如,引用就是将某个名字与某个对象绑定在一起。
字节(byte): 内存中可寻址的最小单位,大多数机器的字节占8位。
类成员(class member): 类的组成部分。
复合类型(class member): 是一种类型,它的定义以其他类型位基础。
const: 是一种类型修饰符,用于说明永不改变的对象。const对象一旦定义就无法再赋新值,所以必须初始化。
常量指针(const pointer): 是一种指针,它的值永不改变。
常量引用(const reference): 是一种习惯叫法,含义是指向常量的引用。
常量表达式(const expression): 能在编译时计算并获取结果的表达式。
constexpr: 是一种函数,用于代表一条常量表达式。
转换(conversion): 一种类型的值转变成另一种类型值的过程。C++语言支持内置类型之间的转换。
数据成员(data member): 组成对象的数据元素,类的每一个对象都有类的数据成员的一份拷贝。数据成员可以在类内部声明的同时初始化。
声明(declaration): 声称存在一个变量,函数或是别处定义的类型。名字必须在定义或声明之后才能使用。
声明符(declarator): 是声明的一部分,包括被定义的名字和类型修饰符,其中类型修饰符可以有也可以没有。
decltype: 是一个类型说明符,从变量或表达式推断得到类型。
默认初始化(default initalization): 当对象没被显式的赋予初始值时执行的初始化行为。由类本身负责执行的类对象的初始化行为。全局作用域的内置类型对象初始化为 0; 局部作用域的对象未被初始化即拥有未定义的值。
定义(definition): 为某一种特定类型的变量申请存储空间,可以选择初始化该变量。名字必须在定义或声明之后才能使用。
转义字符(escape sequence):字符特别时那些不可打印字符的替代形式。转义以反斜线开头,后面紧跟一个字符,或者不多于3个八进制数字,或者字母 x 加上 1 个十六进制数。
全局作用域(global scope): 位于其他所有作用域之外的作用域。
头文件保护符(header guard): 使用预处理变量防止头文件被某个文件重复包含。
标识符(identifier): 组成名字的字符序列,标识符对大小写敏感。
类内初始值(in-class initializer): 在声明类的数据成员时同时提供的初始值,必须置于等号右侧或花括号内。
在作用域内(in scope): 名字在当前作用域内可见。
被初始化(initalized): 变量在定义的同时被赋予初始值,变量一般都应该被初始化。
内层作用域(inner scope): 嵌套在其他作用域之内的作用域。
整型(iniegral type): 参见算术类型。
列表初始化(list initialization): 利用花括号把一个或多个初始值放在一起的初始化形式。
字面值(literal): 是一个不能改变的值,如数字,字符,字符串等。单引号内的是字符字面值,双引号内的是字符串字面值。
局部作用域(local scope): 是块作用域的习惯叫法。
底层 const(low-level const): 一个不属于顶层的const,类型如果由底层常量定义,则不能被忽略。
成员(member): 类的组成部分
不可打印字符(nonprintable character): 不具有可见形式的字符,如控制符,退格,换行符等。
空指针(null pointer): 值为 0 的指针,空指针合法但是不指向任何对象。
nullptr: 是表示空指针的字面值常量。
对象(object): 是内存的一块区域,具有某种类型,变量是命名了的对象。
外层作用域(outer scope): 嵌套着倍的作用域的作用域。
指针(pointer): 是一个对象,存放着某个对象的地址,或者某个对象存储区域之后的下一个地址。或者 0。
指向常量的指针(pointer to const): 是一个指针,存放着某个常量对象的地址。指向常量的指针不能用来改变它所指对象的值。
预处理器(preprocessor): 在C++编译过程中执行的一段程序。
预处理变量(preprocessor variable): 由预处理器管理的变量。在程序编译之前,预处理器负责将程序中的预处理量替换成它的真实值。
引用(reference): 某个对象的别名。
对常量的引用(reference to const): 是一个引用,不能用来改变它所绑定对象的值。对常量的引用可以绑定常量对象,或者非常量对象,或者表达式的结果。
作用域(scope): 是程序的一部分,在其中某些名字有意义。C++由几级作用域。
全局(global): 名字定义在所有其他作用域之外。
类(class): 名字定义在类内部。
命名空间(namespace): 名字定义在命名空间内部。
块(block): 名字定义在块内部。名字从声明位置开始直至声明语句所在的作用域末端为止都是可用的。
分离式编译(separate compilation): 把程序分割为多个单独文件的能力。
带符号类型(signed): 保存正数,负数或 0 的整型。
字符串(string):是一种库类型,表示可变长字符序列。
struct ** 是一个关键字,用于定义类。
临时值(temporary): 编译器在计算表达式结果时创建了一个临时值,则此临时值将一直存在直到包含该表达式的最大的表达式计算计算完成。
顶层 cosnt(top-level const): 是一个 const,规定某对象的值不能改变。
类型别名(type alias): 是一个名字,是另外一个类型的同义词,通过关键字 typedef 或别名声明语句来定义。
类型检查(type checking): 是一个过程,编译器检查程序使用某给定类型对象的方式与该类型的定义是否一致。
类型说明符(type specifier): 类型的名字。
typedef: 为某类型定义一个别名。当前关键字 typedef 作为声明的基本类型出现时,声明中定义的名字就是类型名。
未定义(undefined): 即C++语言没有明确规定的情况。不论是否有意为之,未定义行为可能引发难以跟踪的运行时错误,安全问题和可移植性问题。
未初始化(uninitialized): 变量已定义但未赋予初始值。一般来说,试图访问未初始化变量的值将引发未定义行为。
无符号类型(unsigned): 保存大于等于 0 的整型。
变量(variable): 命名的对象或引用。C++语言要求变量要先声明后使用。
void* : 可以指向任意非常量的指针类型,不能指向解引用操作。
void 类型: 是一种有特殊用处的类型,既无操作也无值。不能定义一个 void 类型的变量
字(word): 在指定及其上进行整数运算的自然单位。一般来说,字的空间足够存放地址。32位机器上的字通常占据 4 个字节。
& 运算符(& operator): 取地址运算符。
*** 运算符(* operator):** 解引用运算符。解引用一个指针将返回该指针所指的对象,为解引用的结果赋值也就是为指针所指的对象赋值。
#define: 是一条预处理指令,用于定义一个预处理变量。
#endif: 是一条预处理指令,用于结束一个 #ifdef 或 #ifndef区域;
#ifdef: 是一台预处理指令,用于判断给定的变量是否已经定义;
#ifndef: 是一条预处理指令,用于判断给定的变量是否尚未定义。

算符。
*** 运算符(* operator):** 解引用运算符。解引用一个指针将返回该指针所指的对象,为解引用的结果赋值也就是为指针所指的对象赋值。
#define: 是一条预处理指令,用于定义一个预处理变量。
#endif: 是一条预处理指令,用于结束一个 #ifdef 或 #ifndef区域;
#ifdef: 是一台预处理指令,用于判断给定的变量是否已经定义;
#ifndef: 是一条预处理指令,用于判断给定的变量是否尚未定义。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值