2.9
a、(输入时才定义是不合法的)不正确,需在cin之前定义input_value
std::cin >> int input_value;==>int input_value=0;std::cin>>input_value;
b、i强制类型转换成3
int i={3.14};==>int i=3;数据发送丢失 报错:从“double”转换到“int”需要收缩转换
c、wage未定义
double salary =wage=9999.99;其中wage未定义
d、i会被强制类型转换成3
int i=3.14;==>warning C4244 : “初始化” : 从“double”转换到“int”,可能丢失数据
需要注意的就是类型转换的问题,还有变量使用之前需要先定义声明
//2.10
//这里涉及到的就是默认初始化的问题
//如果在定义变量时没有指定初值,那么变量会被默认初始化。
//三条性质:1、定义在任何函数体外的变量会被初始化为0。 2、定义在函数体内部的变量不会被初始化。 3、类的对象未被初始化,则初值由类决定。
//所以第一个变量是一个空字符串,第二个变量是0,第三个变量不确定,第四个变量因为在std作用域内,而std作用域内有其定义,所以是个空字符串
std::string global_str;
int global_int;
int main()
{
int local_int;
std::string local_str;
system("pause");
return 0;
}
//2.11//涉及知识点:
//声明:使得名字为程序所知,如果想使用该变量,则必须实现包含其声明。声明会确定变量的名字和类型。
//定义:创建于名字关联的实体。定义会申请存储空间,可能会赋予初始值。
//如果想声明一个变量而不想定义它,那么可以在变量名前加extern关键字。
//所以1、定义 2、定义 3、声明
//如果想声明一个变量而非定义它,就在变量名前添加关键字extern,而且不要显式地初始化变量
extern int iz;//声明iz而非定义
extern int ix = 1024;//extern语句如果包含初始值就不再是声明,而是定义了
int iy;//声明并定义j
//变量能且只能被定义一次,但是可以被多次声明
2.12
字母+数字+下划线(必须以字母或者下划线开头)
C++中关于变量命名的规范:
1:能体现变量的实际意义
2:变量名一般采用小写字母
3:用户自定义类名一般以大写字母开头
4:多个单词定义的变量名应有区分Student_loan 而不是 Studentloan
a:错误:使用关键字double作为变量名
b:正确
c:错误:无效字符“—”
d:错误:不能以数字开头
e:正确(但是不好)
2.13
新建局部变量会覆盖同名的全局变量
j=100
int i = 42;
int main()
{
int i = 100;//新建局部变量i,覆盖全局变量i
int j = i;//100
system("pause");
return 0;
}
2.14
合法,与上题类似
但不同的是:显示访问i变量会访问到全局变量上 std::cout<<
i = 100 sum = 45
int i = 100, sum = 0;
int main()
{
for (int i = 0; i < 10; i++)
{
sum += i;//内层作用域没有重新定义sum 定义i只是局部变量,只作用于for循环体内
}
cout << i << " " << sum << endl;// 100 45
system("pause");
return 0;
}
所以程序中不要出现同名变量
//2.15//所谓引用:它只是为存在的对象所起的另外一个名字。它不是一个对象,没有实际的地址
int value = 10;
int &My_value = value; //引用,在定义引用的时候会将引用和它的初始值绑定在一起,而不是简单的赋值
int My_value = 5; //将5赋给了My_value和value
int Her_value = My_value; //相当于将value赋给了Her_value
int &My_value = 10; //错误:引用类型的初始值必须是一个对象
double vvalue = 40.6;
int &My_value = vvalue; //错误:引用类型的初始值必须是int型对象 引用的类型都要和与之绑定的对象严格匹配
int i = 0, &r1 = i;
double d = 0, &r2 = d;
int main()
{
r2 = 3.1415;
r2 = r1;//int==>double ok
i = r2;//会报警告,从double=>int 丢失数据
r1 = d;//会报警告,从double=>int 丢失数据
system("pause");
return 0;
}
int i = 0, &r1 = i;
double d = 0, &r2 = d;
int main()
{
i = 5; r1 = 10;
cout << i << " " << r1 << endl;// 10 10
//2.18
// 先简单的了解一下指针:它和引用类似也实现了与其他对象之间的间接访问.
// 定义指针类型的变量通常是:int *P P是变量名,加*号指的是其是一个int类型的指针。
// 指针类型也需要和匹配对象类型严格吻合
int a;
int *p1 = &a;//初始值为a的地址
int *p2 = p1;//初始值为int类型对象的指针-p2指针指向p1
int i = 10;
int &j = i;//&符号紧随类型名出现 它是声明的一部分 j是一个引用
int *p;//*符号紧随类型名出现 它是声明的一部分 p是一个指针
p = &i;//&符号出现在表达式之中,是一个取地址符号
*p = i;//*符号出现在表达式之中,是一个解引用符
int &j2 = *p;//&是声明的一部分 *解引用符
//2.20
//这段代码首先定义了一个int型的变量i,并赋初值42,随后定义了一个int型指针,初始值为i的地址,*P在表达式中,指的就是解操作符,而中间的*是乘的意思,所以作用就是将i改变为42 * 42。
//要注意的就是*这个符号的多重含义
int i = 42;//定义一个int型的变量i
int *p1 = &i;//定义一个int型指针 初始值为i的地址
*p1 = *p1 * *p1;//*p1=42*42;
2.21
1:非法定义,类型不一致
int i = 0;
a)double *dp=&i;//类型不匹配
2:非法定义,没有取址操作符
b)int *ip=i;//不能把int变量直接给int型指针
c)int *p=&i;//对哦
3:合法定义。
2.22
if(p)//p所指是否为空指针
if(*p)//p所指的对象内容-也就是p所指的内存空间中所储存的值是否为0
2.23 不可以,指针是否有效还不知道呢!!!得先看他是否有效的指针,然后才判断是否指向一个合法的对象2.25
1:ip是一个int类指针型的,i是一个int型的变量,r是一个int型的引用。
2;i是一个int型的变量,ip是一个空指针。
3:ip是一个int类型的指针,ip2是一个int类型的变量。
2.26
涉及知识点:const表示的不可改变的量!:const用在变量定义时的类型前表示该变量不可改变,注意:该变量必须初始化(可以在运行时初始化)。
a:不合法,变量未初始化。
b:合法
c:合法
d:不合法,变量sz是一个const变量,不能被改变。
2.27
涉及知识点:
指针与const:1:指向常量的指针:要想存放变量的地址,必须使用指向常量的指针:const int *p
2:常量指针:指针自身是一个对象,不可变。int *const p = &pi (常量指针必须初始化!!!)
3:指向常量的常量指针。const int *const p (不仅指针本身不可变,指针所指对象也不可变)
引用与const:
将引用定义为常量:const int &i
a:引用r的赋值对象必须是一个对象,所以不合法
b:合法,将p2设为一个常量指针,初始化为i2对象的地址
c:合法,将i设为常量,r设置为常量的引用(注意const int &r = 0 是正确的,但是int &r = 0是不正确的)
d:合法,p3为指向常量的常量指针,初始值为i2的地址
e:合法,p1为指向常量的指针,初始值为i2的地址
f:使用不合法
g:合法,正常的赋值
2.28
指向常量的指针不能用于改变所指对象的值,要想存放常量对象的地址,只能使用指向常量的指针
a:不合法,常量指针cp未初始化
int i,*const cp;
b:不合法,常量指针p2未初始化
int *p1,*const p2;
c:不合法,常量ic未初始化
const int ic,&r=ic;
d:不合法,常量指针p3未初始化
常量指针必须初始化
const int *const p3 = &pi;===》p3是一个指向常量对象的常量指针
e:合法
2.29
a:合法
b:不合法,const int 和 int 不是一个类型,指向常量的指针在赋值时必须类型一致
c:和b相同
d:不合法,p3是一个常量指针,不能被再次赋值 常量指针必须初始化 而且初始化完成,它的值就不能再改变
e:不合法,p2是一个常量指针,不能被再次赋值
f:不合法,ic是个常量,不能被再次赋值
指向常量的指针 --没有规定所指的对象必须是一个常量 所谓指向常量的指针仅仅要求不能通过该指针改变对象的值
2.4.3顶层constconst int ci=42;//不能改变ci的值 这是个顶层const
2.30
涉及知识点:
顶层const:指的是本身不可以被改变。
底层const:指的是自身所指对象不可以被改变
用于声明引用的const都是底层const
v2是顶层const;
p2是底层const;
p3最左是底层,右侧是顶层const;
const int *const p3 =p2;//靠左是底层const 靠右的const是顶层const
其他都不是const;
2.31
知识点:顶层const的拷贝不受限制,但是底层const的拷贝的对象必须具有相同的底层const资格。一般来说:非常量可以赋值给常量,反之则不行
答案:
a:合法;
b:不合法,p1是非常量,p2是常量,不能进行赋值操作;
c:合法;
d:不合法,p3既是底层也是顶层const,所以都得考虑到;
e:合法;
2.32
指向空的指针可以用nullptr或0带代替
所以该式可表达为:*p = nullptr;
const int *p=nullptr;//p是一个指针整型常量的指针p是一个指向常量的指针 q是一个常量指针 其中关键在于constexpr把它所定义的对象置为了顶层const
2.33
知识点一:使用类型别名:C++中可以定义一个类型的别名,有两种方式
1:使用typedef
- typedef double wages; //wages就成为了double的别名
- typedef wages base ,*p; //base 成了double的别名(同义词),p成了double *的同义词(double类型的指针)
- using SI = Sales_item; // SI 成为了Sales_item的别名
- auto a = b+c; //编译器会为我们判别类型
- auto a = 0, b = 3.14; //错误,auto语句中的类型必须一致。
知识点三:auto会自动忽略掉顶层const,而底层const会被保留。
知识点四:auto定义的变量必须有初始值。
2.36
知识点:decltype:希望从表达式的类型推断出想要定义的变量的类型,该操作返回操作数的类型。
- decltype(f) sum = s; //sum的类型就是f的返回类型
decltyoe((variable))(注意是双层括号)的结果永远是引用,而decltyoe(variable)结果只有当variable本身就是一个引用才是一个引用
decltype(())双层括号表示引用(注意引用必须初始化)a是int类型 4
b是int类型 4
c是int类型 4
d是int &类型 4
全是4!!!!!!!!!!!
2.37
知识点:赋值的表达式语句本身是一种引用:
a int 3;
b int 4;
c int 3;
d int & 3;
decltype(a = b) d =a;====>int &d=a;2.38
主要的区别有两点:
1:如果使用引用类型,auto会识别为其所指对象的类型,decltype则会识别为引用的类型。
2:decltype(())双括号的差别。
- int i = 0, &r = i;
- // same
- auto a = i;
- decltype(i) b = i;
- // different
- auto c = r;
- decltype(r) d = i; ===>int &d=i;===> decltype((i)) d = i;