我试图运行部分代码,并且不得不增加组合表达式a+b
的值。为了做到这一点,我写了一条语句
c=(a+b)++
在此声明中出现以下错误-
“表达式必须是可修改的值”
为什么会出现此错误,为什么在C中不允许增加表达式的值?
答案 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)
- 前缀递增或递减运算符的操作数应具有原子,限定或不限定的实数或指针类型,并且应为可修改的左值。
这意味着如果我们有一个构造something ++
,那么something
_Atomic
或volatile
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
上加一个,可以描述为计算a
和b
的总和并加一个 。在C中,增量运算符++
具有非常特殊的语义:作为副作用,它将标量变量的值递增,并根据是放在该变量之前还是之后,将其计算为递增值或原始值。关于对象的类型以及在同一表达式中其他位置使用同一对象的进一步限制。
对于您的问题,解决方案是使用加法运算符1
a + b + 1
答案 5 :(得分:0)
一个容易记住的陈述是
LValue-左值
LValue必须是一个容器。换句话说,一个可以存储某些内容且不受限制的内存位置 而且,变量是C语言中唯一可用的容器。
在示例(a + b)++
(a + b)
会得出一些值,不一定是可以再次用于在其上操作的容器。
例如考虑一下
const int a=10;
a = 5;
即使a
是一个容器,在这里也会出现类似的错误,但它没有用,因为它是constant
,并且不允许其他操作。