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个字节
使用double或者float
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条 第二条解析 由于unsigned规定该类型运算结果也必须大于零,当一个较小 的unsigned 类型减去一个较大的unsigned 类型,结果向下溢出。 结果就是 该类型的最大值减去向下溢出的值,结果会是一个极大的数值。 拓展: 当两个类型不同的对象进行运算时,会先进行隐式转换,转换方向总是代表内存大的类型。 例子: char 和 int ,char类型对象会临时转化为int类型进行运算 unsigned 和signed中,signed会先转化为unsigned。
(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.
第一行是10进制 第二行 month赋值非法,day是8进制。
(a): Who goes with Fergus?(new line) "string" (b): 31.4 "long double" (c): 1024 "float" (d): 3.14 "long double"
#include <iostream>
using namespace std;
int main() { cout << "\062\115\012"; cout << "\062\t\115\012"; system("pause"); return 0; }
(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;
global_str会是空,global_int会是0. 其他都是未定义,不可知。 解释:程序中,全局变量会有默认的初始值,而局部变量没有。
(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
#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; }
指针和引用的区别从以下几点谈: (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*。
(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 略