C++ Primer 5课后题练习
关于变量初始值
std::string global_str;
int global_int;
int main()
{
int local_int;
std::string local_str;
}
string类型本身接受无参数的初始化方式,所以不论变量定义在函数内还是函数外都被默认初始化为空串。
对于内置类型int来说,变量global_int定义在所有函数体之外,默认初始化为0;而变量local_int定义在main函数内部,不被初始化,若程序试图拷贝或输出未初始化的变量,将遇到一个未定义的奇异值。
关于变量声明和定义的关系
C++语言支持分离式编译机制,声明使得名字为程序所知,一个文件如果想使用别处定义的名字则必须包含对那个名字的声明。而定义负责创建与名字关联的实体,还申请存储空间,可能为变量赋一个初始值。
extern int i = 10;//声明并定义
extern int j;//声明
int k;//声明并定义
关于引用
int &r = 10;//引用必须指向一个实际存在的对象而非字面值常量
int &v;//由于无法令引用重新绑定到另外一个对象,所以引用必须初始化
关于指针
#include<iostream>
int main()
{
int i = 5, j = 10;
int *p = &i;
std::cout << p << " " << *p << std::endl;
p = &j;
std::cout << p << " " << *p << std::endl;
*p = 20;
std::cout << p << " " << *p << std::endl;
j = 30;
std::cout << p << " " << *p << std::endl;
return 0;
}
指针和引用的主要区别
指针“指向”内存中的某个对象,引用“绑定到”内存中的某个对象,都实现了对其他对象的间接访问。主要有两个区别:
一、指针本身是一个对象,允许对指针赋值和拷贝,在其生命周期内可以指向不同的对象;引用不是一个对象,无法令引用重新绑定到另外一个对象。
二、指针无须在定义时赋初始值,和其他内置类型一样,在块作用域内定义的指针如果没有初始化,将拥有一个不确定的值;引用则必须在定义时赋初值。
如何判断指针指向一个合法的对象
书上的答案:一种合理的处理办法是把if(p)置于try结构中,当程序块顺利执行时,表示p指向了合法的对象;当程序块出错跳转到catch时,表示p没有指向合法的对象。
关于常量引用、常量指针和指向常量的指针的初始化方法
int i = -1, &r = 0;//非法,非常量引用r不能引用字面值常量
const int i = -1, &r =0;//合法,i是一个常量,r是一个常量引用,r可以绑定到字面值常量
const int &const r2;//非法,引用本身不是对象,因此不能让引用恒定不变
const int i2 = i, &r = i;//合法,i2是一个常量,r是一个常量引用
const int *const p3 = &i2;//合法,p3是一个常量指针,p3的值永不改变,即p3永远指向变量i2;同时,p3指向的是常量,即不能通过p3改变所指对象的值。
int i, *const cp;//非法,cp为常量指针,因其值不能改变,所以必须初始化
const int ic, &r = ic;//ic为常量,必须初始化
const int *const p3;//非法,需初始化
const int *p;//合法,但是p没有指向任何实际对象
关于顶层const与底层const
人家讲的挺好的,附上链接:https://blog.csdn.net/qq_19528953/article/details/50922303
在执行拷贝操作时,顶层const和底层const区别明显。顶层const不受影响,这是因为拷贝操作不会改变被拷贝对象的值。而对于底层const来说,拷入和拷出的对象必须具有相同的底层const资格,或者两个对象的数据类型必须能够转换。一般来说,非常量可以转换成常量,反之则不行。
关于的decltype
int a = 3, b = 4;
decltype(a) c = a;//相当于 int c = a;
decltype((b)) d = a;//相当于 int &d = a;
++c;
++d;
//程序结束时a,b,c,d都为4
decltype(a=b) d = a;//当参数是表达式时,推断出的类型是引用。所以d的类型为int&
auto和decltype的区别
#include<iostream>
#include<typeinfo>
int main()
{
int a = 3;
auto c1 = a;
decltype(a) c2 = a;
decltype((a)) c3 = a//c3为变量a的别名
const int d = 5;//d为常量整数,含有顶层const
auto f1 = d;//auto忽略顶层const,所以推断结果为整数
decltype(d) f2 = d;//保留顶层const,f2为整形常量
std::cout << typeid(c1).name() << std::endl;
std::cout << typeid(c2).name() << std::endl;
std::cout << typeid(c3).name() << std::endl;
std::cout << typeid(f1).name() << std::endl;
std::cout << typeid(f1).name() << std::endl;
c1++;
c2++;
c3++;
f1++;
//f2++;
//错误:f2是整形常量,不能执行自增操作
std::cout << a << " " << c1 << " " << c2 << " "
<< c3 << " " << f1 << " " << f2 <<std::endl;
return 0;
}