【C/C++】《C++ Primer》(第五版)-第2章笔记(含完整练习答案)

  • C/C++的设计准则之一:尽可能地接近硬件。
  • float:一个字(32bit)double:2个字(64bit)long long:3或4个字(96/128bit)
  • 类型int,short,long 和 long long均为带符号的。
  • 如何选择类型:①不可能为负,选用无符号;(In a word: no negative, unsigned.)②使用int执行整数运算,超过int选用long long;(In a word: short < **int** < long < long long)③浮点数运算选用double,long double提供的精度没必要(In a word: float < **double** < long double)

E2.1:
  • short 和 int 至少16bits,long至少32bits,long long至少64bits
  • 有符号类型可以代表正数、负数和0,无符号类型只能代表不小于0的正数
  • C/C++标准不区分float、double、long double

E2.2:
  • 用double,或者float
The rate most like that: 4.50 % per year.
The principal most like that: $854.36
The payment most like that: $1,142.36


  • 赋给无符号类型一个超出它表示范围的值时,结果是初始值对无符号类型表示数值总数取模后的余数。
  • 控制变量递减的方式把10到0的数字降序输出

unsigned u = 11;
while(u > 0){
    - - u;    //先减1,这样最大一次迭代时就会输出0
    std::cout << u << std::endl;
}


E2.3:
  • 32
  • (int 32bits = 4294967296)4294967234
  • 32
  • -32
  • 0
  • 0

E2.4:
#include 
int main( )
{
    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;

}


E2.5:
(a)’a’字符型,L‘a’长字符型,”a"字符串,L”a"长字符串
(b)10整数型,10u无符号整数型,10L长整数型,10uL无符号长整数型,012八进制,0xC十六进制
(c)3.14double型,3.14f float型,3.14L long double型
(d)10整数型,10u无符号整数型,10. double型,10e-2 double型

E2.6:
int month = 9, day = 7;// 整数型
int month = 09, day = 07;//month无效,八进制没有9;day是八进制;

E2.7:
(a)Who goes with Fergus?
(new line) //字符串
(b)31.4//long double
(c)1024//float
(d)3.14//long double

E2.8:
#include

int main()
{
  std::cout << 2 << "\115\012";
  std::cout << 2 << "\t\115\012";

  return 0;
}
/*output:
 *2M

 *2     M

 */




  • 在C++的通常情况下,对象是指一块能存储数据并具有某种类型的内存空间’
  • 定义域函数体内的内置类型的对象如果没有初始化,则其值未定义。类的对象如果没有显式地初始化,则其值由类确定


E2.9:
(a) error: expected '(' for function-style cast or type construction.
int input_value = 0;
std::cin >> input_value;
(b)①没有声明”-std=c++11“时,warning: implicit conversion from 'double' to 'int' changes value from 3.14 to 3.
         ②声明”-std=c++11“时,error: type 'double' cannot be narrowed to 'int' in initializer list---conclusion: Obviously, list initialization becomes strict in c++11.
double i = { 3.14 };
(c)如果你提前声明了wage,就没问题。否则会报错:error: use of undeclared identifier ‘wage'
double wage;
double salary = wage = 9999.99;
(d)正确但会丢失数值。
double i = 3.14;

E2.10
global_str: 空串
int:0
local_int:未定义,有个未定值
local_str:未定义,但类定义了一个空串

  • 建议初始化每一个内置类型的变量
  • 变量能且只能被定义(负责创建与名字关联的实体)一次,但是可以被多次声明(使得名字为程序所知)
extern int i;//声明i而非定义i;
int j;//声明并定义j;
  • 变量名以字母、下划线开头

E2.11:
(a)定义
(b)定义
(c)声明

E2.12:
(a)(c)(d)

E2.13:
100

E2.14:
100 45

复合类型
  • 引用(&d)为对象起了另一个名字(即别名),必须初始化
  • 引用类型的初始值必须是一个对象,不能与字面值或某个表达式的计算结果绑定到一起


E2.15:
    b:必须对象
    d:必须初始化

E2.16:
    a:合法,给d赋值3.14159
    b:合法,给d赋值0
    c:合法,从double型0到Int 0丢失了信息
    d:合法,从double型0到Int 0丢失了信息

E2.17:
    10 10


  • 指针(*d)是指向另一种类型的符合类型。
  • 与引用不同于:①指针本身是对象,允许赋值和拷贝,而且在指针的生命周期内它可以先后指向几个不同的对象 ②无须定义时赋值,内置类型的话也将拥有一个不确定的值
  • 指针的类型被用于它所指向对象的类型,所以二者必须匹配
  • 指针值(即地址)
  • 解引用符(操作符*):仅适用于那些确实指向了某个对象的有效指针。为*p赋值实际上是为p所指的对象赋值。
  • 空指针(nullptr
  • 两者区别:
  1. 一旦定义了引用,就无法令其再绑定到另外的对象,之后每次使用这个引用都是访问它最初绑定的对象
  2. 指针和它存放的地址之间没有这种限制,给指针赋值就是令它存放一个新的地址,从而指向一个新的对象
  • 到底是改变了指针的值还是改变指针所指对象的值不太容易,最好的办法就是记住赋值永远改变的是等号左侧的对象。
pi = &ival;    //pi的值被改变,现在pi指向了ival
*pi = 0;       //ival的值被改变,指针pi并没有改变
  • 任何非0指针对应的条件值都是true
  • void* 指针可以存放任意对象的地址


E2.18:
int main()
{ int a = 0,b = 2;
  int *p1 = &a,*p2 = p1;
  p1 = &b;
  *p2 = b;
}

E2.19:

  1. 一旦定义了引用,就无法令其再绑定到另外的对象,之后每次使用这个引用都是访问它最初绑定的对象
  2. 指针和它存放的地址之间没有这种限制,给指针赋值就是令它存放一个新的地址,从而指向一个新的对象
  3. 指针本身是对象,允许赋值和拷贝,而且在指针的生命周期内它可以先后指向几个不同的对象 
  4. 指针无须定义时赋值,内置类型的话也将拥有一个不确定的值

E2.20:
int i = 42;    //定义一个int型i,赋值42
int *p1 = &i;  //定义一个int型指针p1,指向i的地址
*p1 = *p1 * *p1;//p1指向的i乘以p1指向的i(42*42),赋值给p1指向的i=1764

E2.21:
    a 非法,指针和它指向的对象的类型两者匹配  
    b  非法,int *ip = 0;//OK,但为空的意思,不能变量传递
    c 合法

E2.22:
if (p) // p为空?

if (*p) //p指向的对象是0?

E2.23:

    不能,需要更多的信息去判断是不是合法对象

E2.24:
    p是void* 指针可以存放任意对象的地址
    Lp是long型指针,不能指向int型i


  • 通过*的个数可以区分指针的级别。**表示指向指针的指针,***表示指向指针的指针的指针


E2.25:
(a)ip:int型指针,i:int型整数,r是i的引用;
(b)i:int型整数,ip:int型指针,为空
(c)ip:int型指针,ip2:int型整数

  • const限定符:变量的值不能被改变,对象一定要初始化,仅在文件内有效。当多个文件中出现了同名的const对象时,其实等同于在不同文件中分别定义了独立的变量
  • 共享const对象】对于const变量不管是声明还是定义都添加了extern关键字,这样只需定义一次便可以在其他文件总声明并使用它
  • 要想存放常量对象的地址,只能使用指向常量的指针
  • const 指针(常量指针)必须初始化,不变的是指针本身的值(某个对象的地址)而非指向的那个值


E2.27:
(a)r必须指向一个对象,不能是字面值
(b)答案说合法,存疑【?
(f)引用r2不能是常量

E2.28:
~【暂略】
E2.31

  • 常量表达式是指值不会改变并且在编译过程就能得到计算记过的表达式。
  • 允许将变量声明为constexpr类型以便编译器来验证变量的值是否是一个常量表达式。声明为constexpr的变量一定是一个常量,而且必须用常量表达式初始化。
  • 字面值类型:算术类型、引用和指针都属于字面值类型。
  • 在constexpr声明中如果定义了一个指针,限定符constexpr只对指针有效,与指针所指的对象无关


E2.32:
int null = 0, *p = nullptr;

类型别名typedef
auto类型说明符
  • 必须初始化。可以在一条语句中声明多个变量,但基本类型要一样
decltype类型指示符
  • 选择并返回操作数的数据类型
  • 双括号的结果永远是引用


2.36:
c int 4
d int& 4

2.37:
a、b int 3,4
c int 3
d int& 3

2.39:
struct Foo { /* empty  */ } ;//加分号
int main()
{
return 0;
}
 
  
2.40
struct Sales_data {
 
    
    std::string _Book_name;
    std::string _Book_shell;
    unsigned double _Book_price;
    unsigned  _Book_id;
    std::string _Book_author;
} ;
int main(){
 
    
    return 0;
}








你可能感兴趣的:(【C/C++】)