C言語のこの小さなディテールを知っていましたか?
タイトルに細かいとあるので。 一旦、詳細を説明すると なんて無意味なんだああ、最初のピットはそれから詳細を紹介すればいいんだ、ねえ。7問はわかりやすいから、何問正解できるか見てみよう。
計算の詳細
①:
#include
What is the answer to this question? Don't look at the back of the answer yet!
The answer is -126, hey, did you get it wrong? Don't worry, keep reading the following questions
②:
#include
What do you think the answer to this question is? Don't look at the answers that follow!
The answer is c, hey, is not another wrong answer, do not rush, and then look at the back of the question
③:
#include
What do you think the answer to this question is? Don't look at the answers that follow!
The answer is 1 4 4, hey, is not another wrong answer, first do not worry, and then look at the back of the question
Expression details
①:
#include
What do you think the answer to this question is? Don't look at the answers that follow!
The answer is 5 or 4, yes
Not sure
The answer is 5 or 4, it is not sure
, hey, is it a wrong answer again, don't be anxious, look again after
The questions on the back
②:
int main()
{
int i = 10;
i = i-- - --i * ( i = -3 ) * i++ + ++i;
printf("i = %d\n", i);
return 0;
}
What do you think the answer to this question is? Don't look at the answers that follow!
There are many answers, and the results are different in different compilers, which means it's still
cannot determine the result
Hey, you still got the wrong answer, don't worry, just look at the rest of the question
#include
What do you think the answer to this question is? Don't look at the answers that follow!
The answer is
Different results for different compilers
Hey, did you get it wrong again? Don't worry, let's look at the rest of the question
④:
#include
This is the last question, how many have you gotten right so far? Please try in the comments. Hey!
The answer to this question is
Different results for different compilers
How many questions did everyone answer correctly? Feel free to comment!
1. Now formally explain all the above questions designed to the content of -------- expressions to find the value
The order in which expressions are evaluated is partly determined by the precedence and union of operators.
Similarly, some expressions have operands that may need to be converted to other types during the evaluation process.
1.1 Implicit type conversion (integer truncation and lifting)
What is implicit type conversion, integer boosting, and integer truncation?
C's integer arithmetic operations are always
at least to meet the precision of the integer type
to be performed.
To obtain this precision, an expression that has
char
and
short
types must be converted to integers before they can be used, a process called
Integer Boosting
.
The process by which a larger data type is stored in a smaller data type is called
Integer Truncation
, such as the integer
a = 500
, but a puts his value in the
Character type b
b cannot fully store a, and the
Integer truncation
.
And this conversion behavior is called
implicit type conversion
1.1.1 Explanation of the first question
#include
We know that everything in a computer is the complement of an operation. So it's the same here, (if you don't understand the original code and the inverse code, go to Baidu).
The original code, inverse code, and complement of a positive number are exactly the same
...for negative numbers, the complement is the inverse plus one, and the inverse is the inverse of the original code with all bits except the sign bit.
a has only 1 byte, and its complement is
00000011
(binary)
The b has only 1 byte, and its complement is
01111111
(binary)
a plus b, which is an arithmetic operation, needs to be raised to 4 bytes. And there are two ways to boost an integer
Arithmetic Boosting: Completes the first sign digit up to 32 bits
Logical boosting: just fill in the zeros no matter what, up to 32 bits
Most calculators do
arithmetic boosting
, which is explained here
Arithmetic Boosting
.
aAfter arithmetic lifting is
000000000000000000000000000000000011
bAfter the arithmetic boost is
000000000000000000000000000001111111
The result of a+b is ------
000000000000000000000000000010000010
The integer truncation occurs because c is only 1 byte, so only the last 8 bits are accessed.
10000010
At this point c is accessing complement, and c is signed,
Remember!!!
When you print the code, it will be restored to the original code, and the number corresponding to the complement is
-126
Here is a sheet of character types
Original code complement inverse code
The corresponding understanding diagram for
So the signed range is [-128,127]
The unsigned range is [0,255]
It's better to turn it into a circle and find it yourself by the symbols.
1.1.2 Explanation of the second question
#include
The binary of 0xb6 is
000000000000000000000000000010110110
Save it in a, truncate it, and get
1011 0110
The binary of 0xb600 is
00000000 00000000 10110110 00000000
The truncation occurs in b, and we get
10110110 00000000
0xb6000000
10110110 00000000 00000000 00000000
Save it in c just right.
a is now stored in the complement, and a is compared to 0xb6, which is involved in the operation, so the integer is raised to
11111111 11111111 11111111 10110110
,
The integer boosted number is not the same as the 0xb6 binary, so it is not equal.
b is stored as a complement, and b is compared to 0xb600, which is involved in the operation, so it is integer-boosted to
11111111 11111111 10110110 00000000
The integer boosted number is not the same as the 0xb600 binary, so it is not equal
c is stored at this point as
10110110 00000000 00000000 00000000
Note that some people may ask
0xb6000000
is a positive number,
Not !!!!!
, literal constants are the default int type as long as they don't have a sign. So at this point
0xb6000000
is more than int, it is considered to be the complement of a negative binary number. So c and
0xb6000000
is equivalent.
1.1.3 Explanation of the third question
#include
sizeof
Measures the value of the type attribute.
c
The type of the
char
The answer is 1, because there is only one byte
+c
,
+
It is a monomial operator, and with c, the integer is raised to int, so it is 4 bytes, and the answer is 4
-c
, and by the same token, still
4
1.2 Arithmetic conversions
As we said above, if the operand size is smaller than int, integer boosting occurs, but what if all types larger than or equal to int are involved in arithmetic operations? Here's where we get into the
Arithmetic conversion
.
What is an arithmetic conversion? For example, the following example:
#include
The result will print
a will be greater than b
Because this is an arithmetic conversion, i.e. it still needs to satisfy the same type of operation, unsigned int is higher than int, so the value of a will default to unsigned, and a will be larger than b.
Arithmetic boosting direction:
1.3 Operator Attributes
There are three factors that influence the valuation of complex expressions.
Operator precedence
Combinability of operators
Whether to control the order of evaluation.
1.3.1 What is priority?
It's deciding what to calculate first. For example
d = a + b*c
. Because
*
has a higher priority than
+
, so the
b*c
and then calculate
+
1.3.2 What is bonding?
It is the decision of which direction to calculate from, given the same priority. For example
d = a * b * c
because the successive
*
, the precedence is no longer useful, so it's a combination at this point,
*
The union is from left to right. This means that the
a*b
and then calculate
*c
.
1.3.3 What is the order of evaluation?
There are only a few operators in c that have evaluation order, such as
||, && , !
That
order of values
What exactly does that mean?
For example, a equals 0, b equals 2, and c equals 3,
d = a && b && c
The value of d ends up being 0, but it only goes as far as a when the operation is done, because
&&
is as long as you encounter false is false, after the true or false is no longer relevant, a is 0, is false, so do not care about the next. That's the order of the values.
Here are two small exercises on the order of values:
#include
The answer is
1 2 3 4
. Reason: a is a post ++, the value of a=0 is used first, it is encountered false at the beginning, and is not executed later. But a is still added, because the post-plus is
is used first and then added
#include
Answer:
1 2 3 4
The first ++, i.e., the first plus, a becomes 1, because
||
ends as soon as it meets true, and doesn't care if it's true or false. So only a changes.
Here's a table of operator properties:
Where the priority decreases from top to bottom
1.3.4 The fourth question explains
#include
ret = c + --c
There are two operation symbols in
Priority
,
--
has a higher priority than
+
, so it was decided to count -c first, but
+
When is the c to the left of the number prepared? As we know, c is a compiled language, so after the code is written, it needs to be compiled into machine language first and then executed. So at compile time, the value to the left of the + sign is in the
--c
before it is compiled, or
--c
was compiled afterwards? It's not certain.
Under the vs compiler the answer is 4, which is the same as the
--c
After preparing the c
Under the gcc compiler the answer is 5, which is in the
--c
before preparing the c
So: this is the problem code, let's not write such garbage code in the future.
1.3.5 Explanation of the fifth problem
int main()
{
int i = 10;
i = i-- - --i * ( i = -3 ) * i++ + ++i;
printf("i = %d\n", i);
return 0;
}
This is the same thing, although the priority is known, it is not certain when the operands in the union are ready, and you can see the result of the operation in different compilers:
Again, it's a garbage code
1.3.6 Explanation of the sixth problem
#include
()
The function call symbol has the highest priority, but there are three of them, so which one should be called first? Again, it's not clear.
The vs compiler calls them from left to right, resulting in -10.
But what about other compilers? Try gcc, codeblocks, Devc++, and you'll see that it's completely different.
1.3.7 Explanation of the seventh question
Before saying more about this question, the blogger must criticize some colleges, why? Schools teach people
++
The symbols are not the most like to use this type to test everyone? Here to tell you clearly, this is a complete waste of time!!!! Because this code is meaningless!!!!
is garbage code
#include
First,
()
The parentheses have the highest priority, but there are three of them, so which one should we count first?
Second, a
i
change, will it affect the other one? I'm not sure here. It's the same as in question 4, where we said that before compiling
c
exactly when to prepare the same. Not sure.!!!
The value of the vs compiler is 12 4
The value for the gcc compiler is 10 4
Different values for different compilers, different results, such code does not deserve to be called code.!!!!
So, if you see this kind of question in the future, just skip it, it doesn't make sense.
Summary:
- Knowing what integer lifting and truncation are
- Knew what an arithmetic conversion was
Knowing the properties of what operators are used, you can't write crap like this in the future.
#include
What do you think the answer to this question is? Don't look at the answers that follow!
The answer is c, hey, is not another wrong answer, do not rush, and then look at the back of the question
③:
#include
What do you think the answer to this question is? Don't look at the answers that follow!
The answer is 1 4 4, hey, is not another wrong answer, first do not worry, and then look at the back of the question
Expression details
①:
#include
What do you think the answer to this question is? Don't look at the answers that follow!
The answer is 5 or 4, yes
Not sure
The answer is 5 or 4, it is not sure
, hey, is it a wrong answer again, don't be anxious, look again after
The questions on the back
②:
int main()
{
int i = 10;
i = i-- - --i * ( i = -3 ) * i++ + ++i;
printf("i = %d\n", i);
return 0;
}
What do you think the answer to this question is? Don't look at the answers that follow!
There are many answers, and the results are different in different compilers, which means it's still
cannot determine the result
Hey, you still got the wrong answer, don't worry, just look at the rest of the question
#include
What do you think the answer to this question is? Don't look at the answers that follow!
The answer is
Different results for different compilers
Hey, did you get it wrong again? Don't worry, let's look at the rest of the question
④:
#include
This is the last question, how many have you gotten right so far? Please try in the comments. Hey!
The answer to this question is
Different results for different compilers
How many questions did everyone answer correctly? Feel free to comment!
1. Now formally explain all the above questions designed to the content of -------- expressions to find the value
The order in which expressions are evaluated is partly determined by the precedence and union of operators.
Similarly, some expressions have operands that may need to be converted to other types during the evaluation process.
1.1 Implicit type conversion (integer truncation and lifting)
What is implicit type conversion, integer boosting, and integer truncation?
C's integer arithmetic operations are always
at least to meet the precision of the integer type
to be performed.
To obtain this precision, an expression that has
char
and
short
types must be converted to integers before they can be used, a process called
Integer Boosting
.
The process by which a larger data type is stored in a smaller data type is called
Integer Truncation
, such as the integer
a = 500
, but a puts his value in the
Character type b
b cannot fully store a, and the
Integer truncation
.
And this conversion behavior is called
implicit type conversion
1.1.1 Explanation of the first question
#include
We know that everything in a computer is the complement of an operation. So it's the same here, (if you don't understand the original code and the inverse code, go to Baidu).
The original code, inverse code, and complement of a positive number are exactly the same
...for negative numbers, the complement is the inverse plus one, and the inverse is the inverse of the original code with all bits except the sign bit.
a has only 1 byte, and its complement is
00000011
(binary)
The b has only 1 byte, and its complement is
01111111
(binary)
a plus b, which is an arithmetic operation, needs to be raised to 4 bytes. And there are two ways to boost an integer
Arithmetic Boosting: Completes the first sign digit up to 32 bits
Logical boosting: just fill in the zeros no matter what, up to 32 bits
Most calculators do
arithmetic boosting
, which is explained here
Arithmetic Boosting
.
aAfter arithmetic lifting is
000000000000000000000000000000000011
bAfter the arithmetic boost is
000000000000000000000000000001111111
The result of a+b is ------
000000000000000000000000000010000010
The integer truncation occurs because c is only 1 byte, so only the last 8 bits are accessed.
10000010
At this point c is accessing complement, and c is signed,
Remember!!!
When you print the code, it will be restored to the original code, and the number corresponding to the complement is
-126
Here is a sheet of character types
Original code complement inverse code
The corresponding understanding diagram for
So the signed range is [-128,127]
The unsigned range is [0,255]
It's better to turn it into a circle and find it yourself by the symbols.
1.1.2 Explanation of the second question
#include
The binary of 0xb6 is
000000000000000000000000000010110110
Save it in a, truncate it, and get
1011 0110
The binary of 0xb600 is
00000000 00000000 10110110 00000000
The truncation occurs in b, and we get
10110110 00000000
0xb6000000
10110110 00000000 00000000 00000000
Save it in c just right.
a is now stored in the complement, and a is compared to 0xb6, which is involved in the operation, so the integer is raised to
11111111 11111111 11111111 10110110
,
The integer boosted number is not the same as the 0xb6 binary, so it is not equal.
b is stored as a complement, and b is compared to 0xb600, which is involved in the operation, so it is integer-boosted to
11111111 11111111 10110110 00000000
The integer boosted number is not the same as the 0xb600 binary, so it is not equal
c is stored at this point as
10110110 00000000 00000000 00000000
Note that some people may ask
0xb6000000
is a positive number,
Not !!!!!
, literal constants are the default int type as long as they don't have a sign. So at this point
0xb6000000
is more than int, it is considered to be the complement of a negative binary number. So c and
0xb6000000
is equivalent.
1.1.3 Explanation of the third question
#include
sizeof
Measures the value of the type attribute.
c
The type of the
char
The answer is 1, because there is only one byte
+c
,
+
It is a monomial operator, and with c, the integer is raised to int, so it is 4 bytes, and the answer is 4
-c
, and by the same token, still
4
1.2 Arithmetic conversions
As we said above, if the operand size is smaller than int, integer boosting occurs, but what if all types larger than or equal to int are involved in arithmetic operations? Here's where we get into the
Arithmetic conversion
.
What is an arithmetic conversion? For example, the following example:
#include
The result will print
a will be greater than b
Because this is an arithmetic conversion, i.e. it still needs to satisfy the same type of operation, unsigned int is higher than int, so the value of a will default to unsigned, and a will be larger than b.
Arithmetic boosting direction:
1.3 Operator Attributes
There are three factors that influence the valuation of complex expressions.
Operator precedence
Combinability of operators
Whether to control the order of evaluation.
1.3.1 What is priority?
It's deciding what to calculate first. For example
d = a + b*c
. Because
*
has a higher priority than
+
, so the
b*c
and then calculate
+
1.3.2 What is bonding?
It is the decision of which direction to calculate from, given the same priority. For example
d = a * b * c
because the successive
*
, the precedence is no longer useful, so it's a combination at this point,
*
The union is from left to right. This means that the
a*b
and then calculate
*c
.
1.3.3 What is the order of evaluation?
There are only a few operators in c that have evaluation order, such as
||, && , !
That
order of values
What exactly does that mean?
For example, a equals 0, b equals 2, and c equals 3,
d = a && b && c
The value of d ends up being 0, but it only goes as far as a when the operation is done, because
&&
is as long as you encounter false is false, after the true or false is no longer relevant, a is 0, is false, so do not care about the next. That's the order of the values.
Here are two small exercises on the order of values:
#include
The answer is
1 2 3 4
. Reason: a is a post ++, the value of a=0 is used first, it is encountered false at the beginning, and is not executed later. But a is still added, because the post-plus is
is used first and then added
#include
Answer:
1 2 3 4
The first ++, i.e., the first plus, a becomes 1, because
||
ends as soon as it meets true, and doesn't care if it's true or false. So only a changes.
Here's a table of operator properties:
Where the priority decreases from top to bottom
1.3.4 The fourth question explains
#include
ret = c + --c
There are two operation symbols in
Priority
,
--
has a higher priority than
+
, so it was decided to count -c first, but
+
When is the c to the left of the number prepared? As we know, c is a compiled language, so after the code is written, it needs to be compiled into machine language first and then executed. So at compile time, the value to the left of the + sign is in the
--c
before it is compiled, or
--c
was compiled afterwards? It's not certain.
Under the vs compiler the answer is 4, which is the same as the
--c
After preparing the c
Under the gcc compiler the answer is 5, which is in the
--c
before preparing the c
So: this is the problem code, let's not write such garbage code in the future.
1.3.5 Explanation of the fifth problem
int main()
{
int i = 10;
i = i-- - --i * ( i = -3 ) * i++ + ++i;
printf("i = %d\n", i);
return 0;
}
This is the same thing, although the priority is known, it is not certain when the operands in the union are ready, and you can see the result of the operation in different compilers:
Again, it's a garbage code
1.3.6 Explanation of the sixth problem
#include
()
The function call symbol has the highest priority, but there are three of them, so which one should be called first? Again, it's not clear.
The vs compiler calls them from left to right, resulting in -10.
But what about other compilers? Try gcc, codeblocks, Devc++, and you'll see that it's completely different.
1.3.7 Explanation of the seventh question
Before saying more about this question, the blogger must criticize some colleges, why? Schools teach people
++
The symbols are not the most like to use this type to test everyone? Here to tell you clearly, this is a complete waste of time!!!! Because this code is meaningless!!!!
is garbage code
#include
First,
()
The parentheses have the highest priority, but there are three of them, so which one should we count first?
Second, a
i
change, will it affect the other one? I'm not sure here. It's the same as in question 4, where we said that before compiling
c
exactly when to prepare the same. Not sure.!!!
The value of the vs compiler is 12 4
The value for the gcc compiler is 10 4
Different values for different compilers, different results, such code does not deserve to be called code.!!!!
So, if you see this kind of question in the future, just skip it, it doesn't make sense.
Summary:
- Knowing what integer lifting and truncation are
- Knew what an arithmetic conversion was
Knowing the properties of what operators are used, you can't write crap like this in the future.
関連
-
[解決済み】C 言語の添え字で配列の要素値を代入すると、配列でもポインタでもベクトルでもない値になる
-
[解決済み】"Expected expression before ' { ' token"(トークンの前に期待される式)。
-
[解決済み】インクリメントオペランドとして lvalue が必要です。
-
[解決済み] 警告: 引数 'from 非互換のポインタ型 [デフォルトで有効]' を渡す
-
[解決済み] C言語での無効なポインタの再割り当て [終了しました]。
-
[解決済み] strcpyとmemcpyの比較
-
[解決済み] ino_tのようなサイズ不明の型はどうすれば印刷できますか?
-
[解決済み] c で pread() による読み込みと pwrite() による書き込み
-
[解決済み] 動的計画法を用いてコイン列の問題を解くには?
-
[解決済み] C - すべての偶数ビットが1に設定されている場合、すべてを決定する。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】エラー:cの入力の最後に期待される宣言またはステートメント
-
[解決済み】配列型char[]が代入できない [重複]。
-
[解決済み] ダブルフリーオアコラプション(ファストトップ)
-
[解決済み] 以前の 'function' の宣言は C のここ [重複] であった。
-
[解決済み] stdinとSTDIN_FILENOの違いは何ですか?
-
[解決済み] C99 stricmp()とstrnicmp()を削除しますか?
-
[解決済み] 変数警告が設定されているが、使用されていない
-
[解決済み] Cの "Press Any Key to Continue "機能
-
[解決済み] C 言語でテキストファイル全体を char 配列に読み込む
-
[解決済み] struct hostentとは何の略ですか?