C/C++基础知识:数组类型、函数类型到左值和右值的转换
2010-05-20 23:42
706 查看
1、左值和右值
表达式的左值是它的地址,右值是该地址所存储的内容。比如下面代码:
x = x + 1;
这两个 x 有什么不同呢?第一个表达式 x 表示的是它的左值,而第二个表达式 x 表示的是它的右值。一个表达式能不能放到 赋值操作符 的左边,取决于这个表达式有没有左值,同样的,一个表达式能不能放到 赋值操作符 的右边,取决于它有没有右值。
一个表达式究竟是取左值还是右值,需要结合上下文,大多数表达式同时具有左值和右值。
2、指针类型、数组类型和函数类型
C++是一种强类型语言,类型在程序中的非常重要,每个变量和表达式都有一个确定的类型,类型匹配和类型转换也是C++语言中的重要部分。除了内建的一些类型和用户自定义类型(包括类类型),下面重点说一下指针类型、数组类型和函数类型。
T* a;
声明一个变量a,它的类型是T*(指向类型T的指针类型)。
T arr[100];
声明一个变量arr,它的类型是 T[100](一维,维长100,元素类型为T的数组)。
T f(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>
3 using namespace std;
4
5 int func()
6 {
7 int i = 2;
8 return i;
9 }
10
11 int _tmain(int argc, _TCHAR* argv[])
12 {
13 int arr[100] = {0,1,2,3};
14
15 cout<<typeid(func).name()<<endl;
16 cout<<typeid(*func).name()<<endl;
17 cout<<typeid(&func).name()<<endl;
18 cout<<endl;
19 cout<<typeid(arr).name()<<endl;
20 cout<<typeid(*arr).name()<<endl;
21 cout<<typeid(&arr).name()<<endl;
22 cout<<typeid(int*).name()<<endl;
23
24 getchar();
25 return 0;
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* 。
表达式的左值是它的地址,右值是该地址所存储的内容。比如下面代码:
x = x + 1;
这两个 x 有什么不同呢?第一个表达式 x 表示的是它的左值,而第二个表达式 x 表示的是它的右值。一个表达式能不能放到 赋值操作符 的左边,取决于这个表达式有没有左值,同样的,一个表达式能不能放到 赋值操作符 的右边,取决于它有没有右值。
一个表达式究竟是取左值还是右值,需要结合上下文,大多数表达式同时具有左值和右值。
2、指针类型、数组类型和函数类型
C++是一种强类型语言,类型在程序中的非常重要,每个变量和表达式都有一个确定的类型,类型匹配和类型转换也是C++语言中的重要部分。除了内建的一些类型和用户自定义类型(包括类类型),下面重点说一下指针类型、数组类型和函数类型。
T* a;
声明一个变量a,它的类型是T*(指向类型T的指针类型)。
T arr[100];
声明一个变量arr,它的类型是 T[100](一维,维长100,元素类型为T的数组)。
T f(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>
3 using namespace std;
4
5 int func()
6 {
7 int i = 2;
8 return i;
9 }
10
11 int _tmain(int argc, _TCHAR* argv[])
12 {
13 int arr[100] = {0,1,2,3};
14
15 cout<<typeid(func).name()<<endl;
16 cout<<typeid(*func).name()<<endl;
17 cout<<typeid(&func).name()<<endl;
18 cout<<endl;
19 cout<<typeid(arr).name()<<endl;
20 cout<<typeid(*arr).name()<<endl;
21 cout<<typeid(&arr).name()<<endl;
22 cout<<typeid(int*).name()<<endl;
23
24 getchar();
25 return 0;
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* 。
相关文章推荐
- C++的基础知识(十一)--数组做函数参数、数组名a与&a区别、数组名a的"数据类型"
- C++ 表达式基础知识(左值、右值未掌握)
- C++基础知识复习--结构体类数组作为函数参数
- Java基础小知识——基本数据类型和字符串以及字节数组的转换
- Java基础小知识——基本数据类型和字符串以及字节数组的转换
- C语言基础知识之(六):数组-----数组类型、定义数组、读取数组、排序数组、字符串数组函数
- 一段小学信息技术基础知识的C++源程序: 函数,输入输出,数据类型,循环
- 深入讲解C++数据类型转换的相关函数的知识
- JAVA基础知识思维导图:unit01_开发环境,变量,基本类型及转换,数学运算,流程控制,数组
- C++语法基础--模板实参推断,模板类型形参的实参的受限转换,模板实参推断与函数指针
- 语言程序设计经典书籍《C++ Primer》 C++基础知识:函数,类 .........
- 《C++标准函数库》中说的有三个函数可以将字符串的内容转换为字符数组和C—string (CString、char*、String三种类型互换)
- DirectX 3D_基础之HLSL(高级着色语言) HLSL着色器程序的编制 HSLS变量 HLSL入口函数 HLSL程序编译 变量常量类型 设置方法 前缀 关键字 类型 语句 类型转换
- 20140729 while((*pa++=*pb++)!='\0') 合并数组代码 C++类型转换关键字 封装 多态 继承
- python基础知识积累(一)数据类型转换
- c++基础:如何string类型转换为int类型
- c++基础:如何string类型转换为int类型
- C++的基础知识(十六)--在字符串copy函数中引入辅助指针变量
- C++ TCHAR数组转换为C#的System::String类型
- C++强制转换不同声明或类型的函数指针隐患