练习2.1
1、类型int、long、long long、short的区别
从变量的本质说起,变量就是固定大小内存块的别名。
那么从本质上说,区别其所代表的内存块大小不同。通俗一些,
就是该类型的对象所占内存字节数不相同。
在32位机器上
int占4个字节,long占4个字节,long long占8字节,short占2个字节。
在64位机器上
int占4个字节,long占8个字节,long long占8字节,short占2个字节。
2、无符号和有符号的类型的区别
最好从范围解释
无符号unsigned int 2^0 - 2^32 -1
有符号signed int -2^31 - 2^31 -1
int所代表的内存大小不变,但由于符号,会做以上变换。
3、float和double的区别
双精度double当然在描述浮点数上精度是优于单精度float的。
但实际上不必用到double的精度,而考虑到内存消耗会使用float。
double的描述占内存8个字节
float的描述占内存4个字节
练习2.2
使用double或者float
练习2.3
unsigned u = 10, u2 = 42;
std::cout << u2 - u << std::endl;
std::cout << u - u2 << std::endl;
int i = 10, i2 = 42;
std::cout << i2 - i << std::endl;
std::cout << i - i2 << std::endl;
std::cout << i - u << std::endl;
std::cout << u - i << std::endl;
32 4294967264 32 -32 0 0
练习2.4
解析
以上有问题的可能是第2条
第二条解析
由于unsigned规定该类型运算结果也必须大于零,当一个较小
的unsigned 类型减去一个较大的unsigned 类型,结果向下溢出。
结果就是 该类型的最大值减去向下溢出的值,结果会是一个极大的数值。
拓展:
当两个类型不同的对象进行运算时,会先进行隐式转换,转换方向总是代表内存大的类型。
例子:
char 和 int ,char类型对象会临时转化为int类型进行运算
unsigned 和signed中,signed会先转化为unsigned。
练习2.5
(a): character literal, wide character literal, string literal, string wide character literal.
(b): decimal, unsigned decimal, long decimal, unsigned long decimal, octal, hexadecimal.
(c): double, float, long double.
(d): decimal, unsigned decimal, double, double.
练习2.6
第一行是10进制
第二行 month赋值非法,day是8进制。
练习2.7
(a): Who goes with Fergus?(new line) "string"
(b): 31.4 "long double"
(c): 1024 "float"
(d): 3.14 "long double"
练习2.8
#include <iostream>
using namespace std;
int main()
{
cout << "\062\115\012";
cout << "\062\t\115\012";
system("pause");
return 0;
}
练习2.9
(a)错误C2062,意外的类型int
int input_value = 0;
std::cin >> input_value;
(b)错误C2397,从double转换到int需要收缩转换。
double i = { 3.14 };
(c)错误,wage未定义。
double wage;
double salary = wage = 9999.99;
(d)正确,但是结果 i = 3;
练习2.10
global_str会是空,global_int会是0.
其他都是未定义,不可知。
解释:程序中,全局变量会有默认的初始值,而局部变量没有。
练习2.11
(a)定义,(但大多是时候这样写会出现重复定义的错误)
(b)定义
(c)声明
知识点:
声明:使得名字被程序所知,如果一个文件想使用别处定义的名字
必须包含对那个名字的声明
定义:创建与名字相关联的实体。
练习2.12
a,c,d非法
练习2.13
100
练习2.14
100,45
练习2.15
b,d不合法
练习2.16
都是合法的
练习2.17
10 10
练习2.18
#include <iostream>
using namespace std;
int main()
{
int a = 0;
int* point = &a;
*point = 1;
cout << a << endl;
point = NULL;
cout << point << endl;
system("pause");
return 0;
}
练习2.19
指针和引用的区别从以下几点谈:
(1)首先分别解释指针和引用
指针:本质上是一个变量,不过它存放的内容是一般是另一个变量的地址。
引用:没有实体,不分配内存,仅是给一个变量起了一个别名。
(2)使用上
定义:定义时, 指针可以初始化,也可以不初始化,初始化可以指向另一个变量或者NULL,
引用必在定义时,必须用变量初始化。
对象指向:指针在初始化后,可以改变指向,可以指向另一个变量。
引用在初始化过后,就只能指向初始化的变量。
指向方式:指针是间接指向,通过寻址的方式指向变量
引用是直接直接,它就是该对象的名字。
指向对象:例如,引用可以指向任何变量,三级指针,它指向的一定是二级指针。
(3)如何选择
指针应用面比较广,以下介绍何种方式使用引用好过指针。
作为信号传递信息或者函数形参(INOUT类型)时尽量使用引用
由于引用不占内存,且指向速度快。
信号传递和函数多级传递该信息,防止变量压栈过多,导致栈内存消耗过多,尽量选择引用。
练习2.20
p1指向i,那么i的值变为 1764(42*42)
练习2.21
(a) 非法,double*指针仅能指向double
(b)非法,int型不可以用于int* 的初始化(它有别于 int* ip = 0)
(c)合法
练习2.22
(1)p的内容是否为0
(2)p所指向对象内容是否为0。
练习2.23
不能,需要更多的信息去确定指向对象是否有效。
练习2.24
因为void*可以接受任何类型变量的地址初始化。
练习2.25
ip是int*,i是int,r是引用。
i是int,ip是int*。
ip是指针,ip2是int。
拓展
typedef sk2 int*;
sk2 i,j;
i,j都是int*。
练习2.26
(a)没有初始值
(b)(c)合法
(d)sz是const类型不可改变
拓展
const int* const i = NULL;
两个const所起到的作用均不同,第一个导致i所指向的变量不可改变,即底层const
第二个导致i的指向即内容不可改变,即顶层const。
练习2.27
int i = -1, &r = 0; // illegal, r must refer to an object.
int *const p2 = &i2; // legal.
const int i = -1, &r = 0; // legal.const reference can refer to an code.
const int *const p3 = &i2; // legal.
const int *p1 = &i2; // legal
const int &const r2; // illegal, r2 must refer to an object.
const int i2 = i, &r = i; // legal.
练习2.28
int i, *const cp; // illegal, cp must initialize.
const int ic, &r = ic; // illegal, ic must initialize.
int *p1, *const p2; // illegal, p2 must initialize.
const int *const p3; // illegal, p3 must initialize.
const int *p; // legal. a pointer to const int.
练习2.29
i = ic; // legal.
p1 = p3; // illegal. p3 is a pointer to const int.
p1 = ⁣ // illegal. ic is a const int.
p3 = ⁣ // illegal. p3 is a const pointer.
p2 = p1; // illegal. p2 is a const pointer.
ic = *p3; // illegal. ic is a const int.
练习2.30
v2 is top-level const, p2 is low-level const.
p3: right-most const is top-level, left-most is low-level.
r2 is low-level const.
练习2.31
r1 = v2; // legal, top-level const in v2 is ignored.
p1 = p2; // illegal, p2 has a low-level const but p1 doesn't.
p2 = p1; // legal, we can convert int* to const int*.
p1 = p3; // illegal, p3 has a low-level const but p1 doesn't.
p2 = p3; // legal, p2 has the same low-level const qualification as p3.
练习2.32
int null = 0, *p = &null;
练习2.33
a = 42; // set 42 to int a.
b = 42; // set 42 to int b.
c = 42; // set 42 to int c.
d = 42; // ERROR, d is an int *. correct: *d = 42;
e = 42; // ERROR, e is an const int *. correct: e = &c;
g = 42; // ERROR, g is a const int& that is bound to ci.
练习2.34
略
练习2.35
i is const int.
j is int.
k is const int&.
p is const int *.
j2 is const int.
k2 is const int&.
练习2.36
c is an int, d is a reference of a. all their value are 4.
注:decltype的表达式如果是加上了括号的变量,结果将是引用。
练习2.37
c is an int, d is a reference of int.
the value: a = 3, b = 4, c = 3, d = 3
练习2.38
int i = 0, &r = i;
// 相同
auto a = i;
decltype(i) b = i;
// c是int, d是int&
auto c = r;
decltype(r) d = r;
练习2.39
struct Foo { /*空 */ }
int main()
{
return 0;
}
练习2.40
略
练习2.41
略