为什么C中不允许使用表达式c =(a + b)++?

时间:2018-10-18 04:24:40

标签: c increment

我试图运行部分代码,并且不得不增加组合表达式a+b的值。为了做到这一点,我写了一条语句

c=(a+b)++

在此声明中出现以下错误-
 “表达式必须是可修改的值”

为什么会出现此错误,为什么在C中不允许增加表达式的值?

6 个答案:

答案 0 :(得分:4)

在C中,package edu.gatech.seclass.sdpvocabquiz.adapters; import android.support.v7.widget.RecyclerView; import android.text.Editable; import android.text.TextWatcher; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.EditText; import android.widget.TextView; import java.util.HashMap; import java.util.List; import edu.gatech.seclass.sdpvocabquiz.R; import edu.gatech.seclass.sdpvocabquiz.data.WordPair; public class WordPairAdapter extends RecyclerView.Adapter<WordPairAdapter.WordPairHolder> { private List<WordPair> wordPairs; private boolean addButtonClicked; public WordPairAdapter(List<WordPair> wordPairs) { this.wordPairs = wordPairs; } public void setFocusToLastAdded(){ addButtonClicked = true; } @Override public int getItemCount() { return wordPairs.size(); } @Override public void onBindViewHolder(WordPairHolder wordPairHolder, int i) { // Attaching an event listener to the dynamically created adapter item // Update our textfields every time we bind a new element via a textListener // Updating textEdit fields that are dynamically generated with adapters // Source: https://stackoverflow.com/questions/31844373/saving-edittext-content-in-recyclerview WordPair wp = wordPairs.get(i); wordPairHolder.wordListener.updatePosition(i); wordPairHolder.definitionListener.updatePosition(i); wordPairHolder.wordEditText.setText(wp.getWord()); wordPairHolder.definitionEditText.setText(wp.getCorrectDefinition()); wordPairHolder.wordEditText.setTag("word" + i); wordPairHolder.definitionEditText.setTag("def" + i); } @Override public WordPairHolder onCreateViewHolder(ViewGroup viewGroup, int i) { View itemView = LayoutInflater. from(viewGroup.getContext()). inflate(R.layout.cardview_word_pair, viewGroup, false); WordPairHolder wordPairHolder = new WordPairHolder(itemView, new AttachedWordEditTextListener(), new DefinitionEditTextListener()); return wordPairHolder; } public static class WordPairHolder extends RecyclerView.ViewHolder { AttachedWordEditTextListener wordListener; DefinitionEditTextListener definitionListener; protected EditText wordEditText; protected EditText definitionEditText; public WordPairHolder(View v, AttachedWordEditTextListener wordListener, DefinitionEditTextListener definitionListener) { super(v); // Reference our elements this.wordEditText = (EditText) v.findViewById(R.id.quizWordPairWord); this.definitionEditText = (EditText) v.findViewById(R.id.quizWordPairDefinition); // Reference and Attach our text listener this.wordListener = wordListener; this.definitionListener = definitionListener; this.wordEditText.addTextChangedListener(wordListener); this.definitionEditText.addTextChangedListener(definitionListener); } } private class AttachedWordEditTextListener implements TextWatcher{ private int position; public void updatePosition(int position){ this.position = position; } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { WordPair wp = wordPairs.get(position); wp.setWord(s.toString()); //String string = s.toString(); //check if empty for word // if(wp.getWord().trim().length() == 0 || wp.getWord().isEmpty()){ // wordPairHolder.wordEditText.setError("Cannot be left blank"); // } // // // check if empty for word definition // if(wp.getCorrectDefinition().trim().length() == 0 || wp.getCorrectDefinition().isEmpty()){ // wordPairHolder.definitionEditText.setError("Cannot be left blank"); // } // // // Set focus to latest item if added // if(i == getItemCount()-1){ // Log.i("WordPairAdapter","Item count: " + i + "getItemCount: " + String.valueOf(getItemCount())); // wordPairHolder.wordEditText.requestFocus(); // } } @Override public void afterTextChanged(Editable s) { } } private class DefinitionEditTextListener implements TextWatcher{ private int position; public void updatePosition(int position){ this.position = position; } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { WordPair wp = wordPairs.get(position); wp.setCorrectDefinition(s.toString()); } @Override public void afterTextChanged(Editable s) { } } } 的操作数必须为 lvalue -内存中的位置。 ++a都是左值-但它们的总和不是,它是一个 rvalue

答案 1 :(得分:3)

postincrement运算符只能应用于l值,即赋值运算符左侧出现的值,最常见的是变量。

当表达式中出现x++时,它的值为x,之后x增加。例如a = 2; b = 2 * (a++);等价于a = 2; b = 2 * a; a = a + 1;

您的示例无法编译,因为无法为a+b分配值。更明确地说,c=(a+b)++等同于c = (a + b); (a + b) = (a + b) + 1;,这没有任何意义。

答案 2 :(得分:2)

因为++运算符需要引用(左值),而不是值(右值)。

i++将使i增加1,并在增加之前返回i的值。

(a + b)++不能增加(a + b)的值,因为(a + b)实际上不是一个引用(在内存中,用于更新a + b的值)。

答案 3 :(得分:2)

C11 6.5.3.1p1

  
      
  1. 前缀递增或递减运算符的操作数应具有原子,限定或不限定的实数或指针类型,并且应为可修改的左值。
  2.   

这意味着如果我们有一个构造something ++,那么something

  • 必须为实数:整数或浮点数,但不能为复数
  • 或可以是指针类型(但空指针不起作用,因为它没有定义算术)
  • 它也可以是_Atomicvolatile
  • 但它必须是lvalue,即指定一个由增量修改的对象
  • 并且该左值必须是可修改的(例如,它不能为const限定)

表达式

a + b

不是左值表达式,它不指定对象。它是一个算术表达式;算术表达式的值不是左值。您可以在该值上加1,但表达式的值不是要修改的对象。


但是,给定

int a, *b, c[5][6];
struct FOO { char *bar; } foo, *fooz;
double *funnyfunc(int x);

所有这些表达式都是可修改的标量左值:

a
*(b + 5)
c[1][4]
foo.bar
fooz->bar
funnyfunc(5)[42]

,您可以将++应用于他们。


还有一个问题
c = (a + b) ++

后递增表达式的值是递增前 的值,即,即使a + b是可修改的,c也不会有值a + b + 1但无论如何a + b;并且a + b会更改其存储的值以用于后续评估。

答案 4 :(得分:1)

关于 increment 的含义有些困惑。在您的问题中,您应该在表达式a + b上加一个,可以描述为计算ab的总和并加一个 。在C中,增量运算符++具有非常特殊的语义:作为副作用,它将标量变量的值递增,并根据是放在该变量之前还是之后,将其计算为递增值或原始值。关于对象的类型以及在同一表达式中其他位置使用同一对象的进一步限制。

对于您的问题,解决方案是使用加法运算符1

添加a + b + 1

答案 5 :(得分:0)

一个容易记住的陈述是

LValue-左值

LValue必须是一个容器。换句话说,一个可以存储某些内容且不受限制的内存位置 而且,变量是C语言中唯一可用的容器。

在示例(a + b)++

(a + b)会得出一些值,不一定是可以再次用于在其上操作的容器。

例如考虑一下

const int a=10; 
a = 5;

即使a是一个容器,在这里也会出现类似的错误,但它没有用,因为它是constant,并且不允许其他操作。