关于Objective-C 错误代码 Expression is not assignable 引发的问题

在Objective-C代码练习中遇到'Expression is not assignable'错误,原因是点语法与C语言语法的混淆。OC中的点语法在结构体中不适用,导致C语言函数调用形式错误。解决办法包括在main函数中新建结构体变量进行赋值,或使用箭头操作符替换点语法,并在.h文件中声明并设置成员变量为@public。

今天在一个OC代码练习中我遇到了 Expression is not assignable 这个问题,起因是这样的

我先是创建了一个Person 类,然后在类中定义了一个Studen 结构体,然后利用这个结构体定义一个 Bob 变量,.h文件的内容如下

#import <Foundation/Foundation.h>

typedef struct
{
    int age;
    int number;
}Student;

@interface Person : NSObject
{
    @public
    Student Bob;
}


@property (nonatomic, assign) Student Bob;


@end


然后我在main 函数里面创建了一个Person 的对象p1 ,我想利用p1 对其内置的Bob.age 属性赋值,很自然的我想到了这种方法

p1.Bob.age = 14;

结果刚写完就出现了这个


</

<think>嗯,用户问的是“expression is not assignable”这个错误。首先,我得确定这个错误通常出现在哪种编程语言里。根据经验,这种错误常见于C、C++或者类似静态类型的语言中,尤其是当用户试图给一个不可修改的表达式赋值的时候。 接下来,我需要回忆常见的导致这个错误的情况。比如,用户可能尝试给一个常量或者字面量赋值,比如5 = x;或者试图修改一个数组的名字,比如int arr[10]; arr = something;还有可能是在结构体或类中,成员访问权限不对,比如结构体变量作为右值却被赋值。另外,运算符优先级的问题也可能导致误解,比如*p++ = 5,如果用户意图是(*p)++,但实际可能被解析成*(p++),从而引发错误。 然后,我需要考虑如何组织这些例子,让用户更容易理解。应该分列出常见原因,每个原因配一个例子和解释。同时,要给出对应的解决方法,比如检查左值是否可修改,确认数组赋值是否正确使用memcpy或循环,检查结构体成员的访问权限,注意运算符优先级等。 还要注意用户可能不太熟悉左值的概念,需要简单解释一下左值是指可以出现在赋值左边的表达式,通常是变量或可修改的内存位置。此外,用户可能遇到的问题可能涉及到指针、数组、常量等多个方面,需要分别说明。 最后,要确保语言简洁明了,结构清晰,用中文表达,避免使用专业术语过多,必要时进行解释。同时,提醒用户遇到具体代码时可以贴出来进一步分析,这样更贴心。</think>在编程中,`expression is not assignable` 是一个常见的编译错误,通常出现在 **C/C++** 等静态语言中。它的核心含义是:你试图对一个 **不可修改的表达式(non-lvalue)** 进行赋值操作。以下是逐步分析: --- ### 错误原因分析 #### 1. **试图修改常量或字面量** ```c const int a = 5; a = 10; // 错误!a 是常量 ``` ```c 5 = x; // 错误!字面量 5 不可赋值 ``` - **解决方法**:检查左侧表达式是否为变量或可修改的内存位置。 #### 2. **数组名作为不可修改的左值** ```c int arr[5]; arr = {1,2,3}; // 错误!数组名 arr 是固定地址的指针 ``` - **原因**:数组名本质是常量指针(如 `int* const`),无法重新指向其他内存。 - **解决方法**:使用 `memcpy` 或循环逐个赋值。 #### 3. **错误的结构体/类成员访问** ```c struct Point { int x; }; struct Point p1; p1.x = 5; // 正确 (p1 + 1).x = 5; // 错误!表达式 (p1+1) 不是左值 ``` - **解决方法**:确保左侧是明确的变量或可修改的成员。 #### 4. **运算符优先级导致歧义** ```c int* p; *p++ = 5; // 实际解析为 *(p++) = 5,可能不符合预期 ``` - **原因**:`++` 优先级高于 `*`,导致修改了指针而非指针指向的值。 - **解决方法**:使用括号明确意图:`(*p)++ = 5`。 --- ### 关键概念:左值(lvalue) vs 右值(rvalue) - **左值**:可出现在赋值语句左侧的表达式,代表一个可修改的内存位置(如变量、解引用指针)。 - **右值**:只能出现在赋值语句右侧的表达式,代表临时值或常量(如字面量、函数返回值)。 --- ### 调试步骤 1. **定位报错行**:找到编译器提示的错误位置。 2. **检查赋值符号左侧**: - 是否为变量? - 是否被声明为 `const`? - 是否涉及指针/数组名? 3. **验证运算符优先级**:用括号明确运算顺序。 --- ### 示例修正 **错误代码**: ```c int a = 5, b = 10; (a + b) = 20; // 错误!(a+b) 是临时计算结果(右值) ``` **修正方法**: ```c int a = 5; a = 20; // 直接修改变量 a ``` --- 如果遇到具体代码场景,可以进一步分析! 🛠️
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值