当前位置: 首页 > article >正文

c语言左值和右值的区别

在C语言中,左值(lvalue)和右值(rvalue)是互斥的概念,左值不能是右值。以下是详细的解释和总结:


1. 左值(lvalue)

  • 定义:左值是一个表达式,表示一个明确的内存位置(对象),可以出现在赋值语句的左侧(即可以被赋值)。
  • 示例
    int a = 10;   // `a` 是左值
    a = 20;       // 合法,`a` 是左值
    int arr[3]; 
    arr[0] = 5;   // `arr[0]` 是左值
    struct S { int x; } s;
    s.x = 42;     // `s.x` 是左值
    

2. 右值(rvalue)

  • 定义:右值是一个表达式,表示一个临时的值或计算结果,只能出现在赋值语句的右侧(不能被赋值)。
  • 示例
    int b = 5 + 3;       // `5+3` 是右值
    int c = b;           // `b` 作为右值(此时是取其值,而非内存位置)
    int d = func();      // 函数返回值是右值
    

3. 左值 ≠ 右值

  • 核心区别
    • 左值有内存地址,可以被赋值或取地址(如 &a)。
    • 右值无内存地址,是临时值,无法直接修改。
  • 错误示例
    // 以下代码均非法
    5 = 10;             // 字面量是右值,不可赋值
    (a + 1) = 20;      // `a+1` 是右值,不可赋值
    &(5);              // 无法对右值取地址
    

4. 特殊情况分析

(1) 复合字面量(C99特性)
  • 复合字面量(Compound Literals)允许创建匿名对象,其行为类似左值:
    (int){42} = 10;        // 合法(复合字面量是左值)
    int *p = &(int){42};   // 合法
    
    • 虽然看起来像右值,但复合字面量实际上是左值,有明确的内存地址。
(2) 函数返回左值
  • C语言中,函数无法返回左值(但可以通过返回指针间接实现类似效果):
    int* get_ptr(int *x) { return x; }
    *get_ptr(&a) = 30;    // 合法,通过指针间接操作左值
    

5. 为什么右值不能作为左值?

  • 内存生命周期:右值通常是临时计算结果(如 a + 1),没有持久的内存地址。
  • 安全性:允许对右值赋值可能导致不可预测的行为(如修改常量或临时数据)。

总结

特性左值右值
定义有内存地址的对象临时的值或计算结果
可赋值✔️
可取其地址✔️(如 &a❌(如 &5 非法)
示例a, arr[0], s.x5, a + 1, func() 的返回值

结论:C语言中,左值和右值是严格区分的,左值不能是右值。所有右值都无法直接赋值或取地址。


http://www.kler.cn/a/559383.html

相关文章:

  • 【GPU驱动】- 状态机
  • CF 13A.Numbers(Java实现)
  • nodejs:vue 3 + vite 作为前端,将 html 填入<iframe>,在线查询英汉词典
  • 常用的性能优化方法和技巧
  • 在Spring Boot中如何使用Freemaker模板引擎
  • Cocos Creator Shader入门实战(一):材质和Effect的了解
  • docker容器网络配置及常用操作
  • 如果二者隔离级别不一致,以哪个为主。例如@Transactional 隔离级别是RC,mysql是RR
  • FunAudioLLM:用语音大模型解锁智能语音交互的无限可能
  • 第六届全球数据库大赛:PolarDB TPC-C性能优化挑战赛方案分享(一)--参数调优
  • Linux相关概念和易错知识点(30)(线程互斥、线程同步)
  • SQLMesh 系列教程8- 详解 seed 模型
  • C#贪心算法
  • 第六次作业
  • HTTP实验(ENSP模拟器实现)
  • C语言基础之【函数】
  • docker下安装 es 设置账号密码
  • 使用 Grafana 监控 Spring Boot 应用
  • 离子阱量子计算机的原理与应用:开辟量子计算的新天地
  • 分布式服务注册与发现