大家好,我是陈同学。我们开始今天的分享。
三元运算的介绍
三元运算符相信大家都不陌生,它可以进行一些简单的判断操作。
在C和C++中三元表达式如下:
条件表达式 ? 表达式1 : 表达式2;
其中,条件表达式的值会被判断,如果为真,则整个表达式的值为表达式1的值;如果为假,则整个表达式的值为表达式2的值。
在这里我们需要注意的是C语言中的三元运算表达式返回的是一个具体的值,也就是说它不可以作为左值的。与之不同的是在C++中三元运算表达式返回的是变量本身,他是可以作为左值的。
我们下面通过几个简单的例子来比较两者差异。
例子1
/**
*@file 04C语言中的三目运算符.c
*@author chenshining
*@version v1.0
*@date 2023-07-08
*/
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include <math.h>
/**
* 在C语言中三目运算符的使用
* C语言中表达式的返回结果存放于寄存器中
* C语言 表达式的返回值是一个确定的值而不是一个变量
*
*/
int main(){
int a = 10;
int b = 11;
//( a < b ? a : b) = 30; =====> 10=30; 报错: 表达式必须是可修改的左值
int c = ( a < b ? a : b); // c=min(a,b)
printf("c:%d\n",c);
return 0;
}
根据上面的例1我们可以作如下总结
- C语言中三元表达式的返回结果存放于寄存器中
- C语言中三元表达式的返回值是一个确定的值而不是一个变量
例子2
/**
*@file 04三目运算符.cpp
*@author chenshining
*@version v1.0
*@date 2023-07-06
*/
#include <iostream>
#include <vector>
using namespace std;
/**
*
* 1)C语言返回变量的值 C++语言是返回变量本身
* C语言中的三目运算符返回的是变量值,不能作为左值使用
* C++中的三目运算符可直接返回变量本身,因此可以出现在程序的任何地方
* 2)注意:三目运算符可能返回的值中如果有一个是常量值,则不能作为左值使用
* (a < b ? 1 : b )= 30;
* 3)C语言如何支持类似C++的特性呢?
* ====>当左值的条件:要有内存空间;让表达式返回一个内存空间/内存首地址 指针
* 思考:如何让C中的三目运算法当左值呢?
* 4) 本质:C++编译器完成了取地址的工作
**/
int main(){
int a = 10;
int b = 11;
(a < b ? a : b) = 30; /// 返回a b中小的变量,并将该变量赋值30
cout << "a:" << a <<endl;
cout << "b:" << b <<endl;
return 0;
}
与C语言不同的是C++的三元运算符返回的是变量本身,因此可以出现在程序的任何地方。当然这里有一个注意点,当C++中的三元运算表达式中有一个是常量,则则不能作为左值使用。
那么如何让C语言的三元运算表达式也可以作为左值呢?
首先我们了解作左值的必要条件(ChatGTP的回答):
- 可寻址性(Addressability): 左值必须有内存地址,这样才能在内存中定位并进行赋值操作
- 持久性(Persistency): 左值必须是持久的,也就是说,它们所引用的内存地址在整个表达式的生命周期中保持不变。
- 非位字段(Not a Bit-field): 左值不能是位字段,位字段是一种特殊的数据结构,无法直接进行地址取得和赋值操作。
- 非寄存器变量(Not a Register Variable): 在C语言中,寄存器变量是存储在寄存器中的变量,无法通过地址来访问,因此不能作为左值。
- 不是常量(Not a Constant): 左值不能是常量,因为常量是不可修改的
总结一下就是,左值必须有可寻址的持续的内存空间。我们可以联想到指针,具体请见例3。
例子3
/**
*@file 04C语言中的三目运算符.c
*@author chenshining
*@version v1.0
*@date 2023-07-08
*/
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include <math.h>
/**
* 在C语言中三目运算符的使用
* C语言中表达式的返回结果存放于寄存器中
* C语言 表达式的返回值是一个确定的值而不是一个变量
*
*/
int main(){
int a = 10;
int b = 11;
*(a < b ? &a : &b) = 30; // 返回a b中小的变量,并将该变量赋值30
printf("a:%d\n",a);
return 0;
}