从零单排《C++ Primer》
——(4)变量,引用,指针
变量的初始化
所谓变量的初始化,指在创建变量的同时给予值。
初始化方法:
int units_sold = 0; int units_sold = {0}; int units_sold{0}; int units_sold{0}; long double ld = 3.1415926536; int a{ld}, b = {ld}; //error:narrowing conversion required int c(ld), d = ld;// ok:but value will be truncated
默认初始化:
当我们定义一个变量却不对其初始化的时候,变量将被默认初始化。一般来说,在函数外定义的基本类型变量,默认的初始化值是0。在函数内则是undefined。而对于类结构,一般由类内部定义。
Exercise 2.9: Explain the following definitions. For those that are illegal, explain what's wrong and how to correct it. std::cin >> int input_value; //error int i = {3.14}; //error double to int double salary = wage = 999.99; //error wage未定义 int i = 3.14; //ok
Exercise 2.10: What are the initial values, if any, of each of the following variables? std::string global_str;//empty int global_int; //0 int main(int argc, const char * argv[]) { int local_int;//uninitialized std::string local_str;//empty std::cout << local_str <<std::endl; return 0; }
声明和定义
在C++中,声明和定义是有区分的。定义也是一种声明,在声明的同时为变量分配内存和赋值。同一名称定义只能一次,但声明可以多次。C++支持分开编译。在不同的文件中可能需要同一个变量,这时就需要使用到声明。
要声明但不定义,使用关键字extern。
extern int i;// declares but does not define i int j; // deckares and defines j extern double pi = 3.1416; //definition 这时extern会被覆盖掉
Exercise 2.11:Explain whether each of the following is a declaration or a definition: (a) extern int ix = 1024; // definition (b) int iy; // definition (c) extern int iz; //declaration
标识符
可以用字母,数字或下划线。但必须由字母或下划线开始。大小写敏感。
变量命名规范
1)起名应该要有意义的
2)通常是小写字母
3)类名首字母一般大写
4)多个单词时应该容易区分,如student_loan or studentLoan
变量名作用范围
Exercise 2.13: what's the value of j in the following program? int i = 42; int main() { int i = 100; int j = i; //100 }
int i = 100, sum = 0; for(int i=0; i!=10; i++) sum += i; std::cout<< i << " " << sum << std::endl;// 100 45
复合类型
引用:
引用时一个对象的另外一个名字。引用必须要初始化。引用不能重新引用不同的对象,引用不是一个Object。
Exercise 2.15 Which of the following definitions,if any,are invalid?Why? int ival = 1.01; int &rval1 = 1.01; //error int-double int &raval2 = ival; int &rval3; //error must be initialized
Exercise 2.16:Which, if any, of the following assignments are invalid? If they are valid, explain what they do. int i = 0, &r1 = i; double d = 0, &r2 = d; r2 = 3.14159; //valid r2 = r1; //valid i = r2; //valid r1 = d; //valid
Exercise 2.17: waht does the following code print? int i, &ri = i; i = 5; ri = 10; std::cout<< i << " " << ri << std::endl; // 10 10
指针:
当一个指针指向一个对象时,可以用简介操作符(*)访问对象。
int i = 42; int &r = i; //&follows a type and is part of a declaration; r is a reference int *p; //*follows a type and is part of a declaration;p is a pointer p = &i; //& is used in an expression as the address-of operator *p = i; //* is used in an expression as the dereference operator int &r2 = *p; //& is part of the declaration; * is the dereference operator
空指针的三种方式:
int *p = nullptr // equivalent to int *p1 = 0; int *p2 = 0; //must #include cstdlib int *p3 = NULL; // equivalent to int *p3 = 0;
把int变量赋值给指针时非法的。
int zero = 0; pi = zero; //error:cannot assign an int to a pointer
注意:应该把所有指针都初始化!如果没有指针绑定的对象,也应该赋为nullptr或者0。
指针的其他操作
1)作为条件
int ival = 1024; int *pi = 0; int *pi2 = &ival; if(pi) // pi has value 0,so condition evaluates as false //... if(pi2)// pi2 points to ival,so it is not 0; the condition evaluates as true //...
2)void* Pointers
void* 是一种特殊的指针类型,可以保存任何类型的对象地址。
void*指针仅仅用来和其他指针作比较,或者作为函数的返回值,或者赋值给其他类型的void*指针。
Exercise 2.20: int i = 42; int *pi = &i; *pi = *pi * *pi; // i is evaluates to 1764
Exercise 2.21: Explain each of the following definitions.Indicate whether any are illegal and, if so,why. int i = 42; (a)double *dp = &i;//error (b)int *ip = i;//error (c)int *p = &i;//ok
Exercise 2.23: Given a pointerp, can you determine whetherp points to a valid object? If so, how? If not, why not?
No, you can‘t. Why? Because it would be expensive to maintain meta data about what constitutes a valid pointer and what doesn‘t, and in C++ you don‘t pay for what you don‘t want.
And you don‘t want to check whether a pointer is valid, because you know where a pointer comes from, either because
it‘s a private part of your code that you control, or because you specified it in your external-facing contracts.
指针到指针:
int ival = 1024; int *pi = &ival; int **ppi = &pi// ppi points to a pointer to an int cout << "The value of ival\n" << "direct value: " << ival << "\n" <<"indirect value: ">> *pi << "\n" <<"double indirect value: " << **pi <<endl;
引用到指针:
int i = 42; int *p; int *&r = p;// r is a reference to the pointer p r = &i; *r = 0;