1、左值和右值
表达式的左值是它的地址,右值是该地址所存储的内容。比如下面代码:
x=x+1;
这两个 x 有什么不同呢?第一个表达式 x 表示的是它的左值,而第二个表达式 x 表示的是它的右值。一个表达式能不能放到 赋值操作符
的左边,取决于这个表达式有没有左值,同样的,一个表达式能不能放到 赋值操作符 的右边,取决于它有没有右值。
一个表达式究竟是取左值还是右值,需要结合上下文,大多数表达式同时具有左值和右值。
2、指针类型、数组类型和函数类型
C++是一种强类型语言,类型在程序中的非常重要,每个变量和表达式都有一个确定的类型,类型匹配和类型转换也是C++语言中的重要部分。除了内建的一些类型和用户自定义类型(包括类类型),下面重点说一下指针类型、数组类型和函数类型。
T*a;
声明一个变量a,它的类型是T*(指向类型T的指针类型)。
Tarr[100];
声明一个变量arr,它的类型是 T[100](一维,维长100,元素类型为T的数组)。
Tf(void){}
声明一个变量f,它的类型是 T(void)(返回值为T,参数为void的函数)
特别要强调的是,arr 的类型和 f 的类型都不是指针。这两个类型的表达式没有右值。
3、 、* 操作符
* 操作符应用与左值表达式,以表达式左值为地址,取出表达式类型的值,作为右值返回。
操作符应用于左值表达式,返回表达式的左值。
注意*、 操作符的操作数必须拥有左值。
4、左值到右值的转换
C++ 标准转换包含
左值到右值的转换。因为数组类型和函数类型的表达式没有右值,所以特别这里要说明数组类型和函数类型到右值的转换。比如上文所说 arr
,当它作为赋值操作符的操作数时,它需要转换为 T* 类型的指针(注意类型是指针!!),其值等于第一个元素的地址。而上文中所说的
f,当它作为赋值操作符的操作数时,它需要转换为 T(*)(void) 的指针(注意类型是指针!!),它指向f的地址。
5、对数组类型或者函数类型施加 、*操作符
arr、 *arr、 f、 *f 这些表达式都是什么呢?打开RTTI,在VC里运行下面代码:
1#include stdafx.h
2#include iostream
3usingnamespacestd;
4
5intfunc()
6{
7inti=2;
8returni;
9}
10
11int_tmain(intargc,_TCHAR*argv[])
12{
13intarr[100]={0,1,2,3};
14
15cout typeid(func).name() endl;
16cout typeid(*func).name() endl;
17cout typeid( func).name() endl;
18cout endl;
19cout typeid(arr).name() endl;
20cout typeid(*arr).name() endl;
21cout typeid( arr).name() endl;
22cout typeid(int*).name() endl;
23
24getchar();
25return0;
26}
运行结果如下:
int__cdecl(void)
int__cdecl(void)
int(__cdecl*)(void)
int[100]
int
int(*)[100]
int*
可以看出 *func 和 func 类型相同,是函数类型,而 func 是指向函数的指针。arr 是数组类型,*arr 是 T 类型,
arr 是 指向数组的指针(这个比较费解)
因为*func 和 func 是等价的,所以可以这样调用 func:
(***********************func)();
如果要用 func,必须这样(注意第一个一定是 *):
(* * * * * * * * * * * * * * * func)();
至于 arr、*arr、 arr 因为类型不同,不可混用,当然用来 memset 的话,表达式 arr 和 arr
的值都为第一个元素的地址,最终都被转换为 void* 。
来自:
本文转载自:lol战斗力查询 http://www.niaojue.com/ wk11 相关的主题文章: