2.3.1 什么是变量
左值(lvalue) : 左值 可以出现在赋值语句的左边和右边-就是变量地址,或者是一个代表"对象在内存中的位置"的表达式
右值(rvalue) : 右值 只能出现在赋值语句的右边-就是变量的值
变量是左值,数字字面值和字符字面值是右值。
int units_sold = 0; //OK
0 = 1; //NO
有些操作符,比如赋值,要求其中的一个操作数必须是左值。
units_sold = units_sold + 1;
这个表达式中 units_sold 变量被用做两种不同操作符的操作数。
+ 是将两个操作数相加.
= 是将右操作数写的左操作数.
在这个表达式中,加法运算的结果被保存与units_sold 相关联的存储单元中,而units_sold 之前的值则被覆盖.
2.3.2 变量名
变量名,即变量的标识符(identifier)
java,C#同C++一样:C++的变量名是由字母,数字,下划线组成,并且必须由字母或者下划线开头,大小写敏感禁,止使用C++保留字.
这个约束貌似不对 :标识符不能包含连个连续的下划线,也不能以下划线开头后面紧跟一个大写字母.有些标识符(在函数外定义的标识符)不能以下划线开头.(是规范)
2.3.3定义对象
声明对象以类型说明符(type specifier)开始 : int string className...
初始化分:直接初始化(direct-initialization)和复制初始化(copy-initialization)
初始化不是赋值
2.3.4 变量初始化规则
内置类型 (int long float...)在函数体外会自动初始化成0,在函数体内部不初始化.
类类型,如果有默认构造函数,在自动初始化(包括在函数体内部).如果没有,则不会自动初始化.
int _tmain(int argc, _TCHAR* argv[])
{
std::string msg;
std::cout << "msg = " << msg << std::endl;
return 0;
}
是不会报错的。
2.3.5声明和定义
// CPP02(extern).cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
/*
初始化式 必须要有储存空间来进行初始化
声明 declaration(声明有多次),不分配内存.使用extern关键字声明变量 ,从编译原理上来说,声明是仅仅告诉编译器,有个某类型的变量会被使用,但是编译器并不会为它分配任何内存
定义 definition(只能有一次),分配内存,初始化赋值.
如果声明有初始化式 , 那么它可以被当做是定义.即使使用了extern关键字
*/
//已初始化的extern都是定义 , 随后的定义都是错误
extern double pi = 3.1416; // definition (当做是定义)
extern double pi; //ok : declaration not definition (声明有多次)
extern double pi = 3.1416;//error : redefinition of pi (定义只有一次)
//C++ 中变量必须且仅能定义一次,而且在使用变量之前必须定义或声明.
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
extern的作用:
1.在文件 InvokePi.cpp中,定义了pi
2.在CPP02(extern).cpp中
3.运行结果:
2.3.6名字的作用域
1.用来区分名字不同意义得上下文称为作用域(scope),作用域是程序的一段区域
2.一般来说,名字从其声明点开始直到其声明所在的作用域结束处都是可见的
3.声明在函数外部的名字具有全局作用域(global scope),可以在程序的任何地方访问
4.声明在函数内部的具有局部作用域(local scope),只能在函数内部访问
5.声明在语句之中的(例如for循环中的变量)具有语句作用域(statement scope).
6.局部变量的定义会屏蔽相同名字的全局变量定义
2.3.7在变量使用处定义变量
最好是在变量第一次使用的地方定义变量.
而变量的声明有个约束:变量只是在从其定义处 开始 到 该变量 声明所在的作用域的 结束 处才是可访问的。
*必须在使用该变量的最外层作用域里面或者之前定义变量(可以简单的理解为变量只在它的作用域可用)