C/C++基础知识:数组类型、函数类型到左值和右值的转换

本文深入探讨了C++中的左值和右值概念,解析了它们的区别及应用场景,并详细介绍了指针类型、数组类型和函数类型的特性。此外,还讲解了&和*操作符的作用以及不同类型之间的转换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、左值和右值

表达式的左值是它的地址,右值是该地址所存储的内容。比如下面代码:

= 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* 。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值