当前位置:网站首页>C language soul torture: do you know the difference between the two?

C language soul torture: do you know the difference between the two?

2022-06-25 21:11:00 HQYJ_

 Insert picture description here

** Baidu network disk full set of tutorials 、 file 、 Source data , Add a group and get it by yourself
 Insert picture description here

I believe many people have encountered such problems :printf("%d,%d",i++,++i);

I have also struggled with this problem , What is the answer . There is really no reference material . The only thing I know is , Almost all C Language textbooks say so :i++ Just use it first i Value of i Their own plus one , and ++i Is to make i Their own plus one , And then use i Value . Out of the pursuit of truth . Today we thoroughly understand this problem .

For example :
 Insert picture description here
We can know very well a and b The values of will be 10 and 11. There is no doubt about that , This is the result of running on any platform or compiler !

But for such a program :
 Insert picture description here
Imagine what the answer would be ?

We can run it on the compiler and see the results as follows :
Have a look first windows Next commonly used VC6 result :
 Insert picture description here
Well, I see , yes 30 and 37! Um. , but … The result seems a little strange .

Then take a look at Linux Next gcc Result :
 Insert picture description here
Oh , It turns out that it was 30 37 .

Let's take a look at the older ones TurboC Result :
 Insert picture description here
 Insert picture description here
It turned out to be 30 39 , oh ~ It's kind of weird .

Of course , Just C In terms of language code ,i++ and ++i There is only one line , It seems that the execution efficiency of the two is the same ? It's not , I'm learning C Language , Textbooks and teachers generally emphasize i++ and ++i The difference between , For example, the following paragraph C The language code :
 Insert picture description here
This paragraph C After the language code is executed ,j and k The values of are not equal :j be equal to 0,k be equal to 1. Since the execution results are different , Then the execution efficiency is likely to be different , And it is . View above C Assembly code corresponding to language code , as follows :
 Insert picture description here
The compiler version is gcc 4.8.4
so ,j=i++; Computers need 4 Instructions to explain , Than execution k=++i; One more instruction . The extra instruction is : In the face of i Before performing the self adding operation , First save i The current value of is reserved for later use ( The assignment is j).

What's going on here ? Different compilers have different results ?

And in this way , Seems to be ++i The implementation efficiency ratio of i++ higher ?
Why different compilers have different results
Let's talk about the reasons , We need to understand two knowledge points first . namely “ side effect ” And “ Order point ”.
Here we quote 《C Primer Plus》 That's what I'm saying :
“ Now let's talk about some C The term of . side effect (side effect) It is the modification of data objects or files .
for example , sentence :states = 50;
Its side effect is to change the variable states Is set to 50. It's a side effect ? This looks more like the main purpose ! However , from C From the perspective of , The main purpose is to evaluate expressions . to C An expression 4+6,C Its value will be calculated as 10. to C An expression states=50,C Its value will be calculated as 50. The side effect of calculating this expression is to put the variable states The value of is changed to 50. Same as assignment operator , The increment and decrement operators also have side effects , They are used mainly due to side effects .

A sequential point (sequence point) Is a point in program execution ; At that point , All side effects were calculated before proceeding to the next step . stay C in , A semicolon in a statement marks a point in order . It means that the assignment operator in a statement 、 All changes made by the increment budget operator and decrement operator must occur before the program enters the next statement . The end of any complete expression is also a sequence point .

What is a complete expression ? A complete expression (full expression) It is such an expression —- It is not a subexpression of a larger expression . Examples of complete expressions include an expression in an expression statement and an expression in an expression statement while An expression in a loop as a condition of judgment .

Sequence points help clarify when the suffix increment action occurs . for example , Consider the following code :
 Insert picture description here
Sometimes C Beginners will imagine in this program “ Use this value first , Then increase its value ” It means using printf() Add... After the statement guests Value . However , because guests++<10 yes while The judgment condition of cycle , So it's a complete expression , The end of this expression is a sequence point . therefore ,C Ensure side effects ( increase guests Value ) Before the program enters printf() Happened before . At the same time, the suffix form is used to ensure guests lie in 10 After comparison, it is increased .

Now consider this statement :
 Insert picture description here
expression 4+x++ Not a complete expression , therefore C There is no guarantee that a subexpression will be evaluated 4+x++ Increase immediately after x. here , The complete expression is the entire assignment statement , And the semicolon marks the sequence point , therefore C What is guaranteed is that before the program enters the following statement x Will be added twice .C There is no indication of x Whether to increase after each subexpression is evaluated or after the entire expression is evaluated , This is why we should avoid using such statements .

This is a 《C Primer Plus》 That's what I'm saying , I believe you should have some answers .

you 're right , That's about i=10;(++i)+(++i)+(++i); Such a statement .C The language standard does not stipulate . Some compilers calculate that 39, Because it will make i The value of increases three times to 13, Then use it three times, that is 13 Of 3 The values add up to 39. Some compilers calculate as 37, Such as VisaulC++6.0 The first two... Will be calculated first i The value of is 12, Third i The value of becomes the value after adding three times 13, So the result is 12+12+13=37. If you want to , You can go to VC6 and TC The last test ;(++i)+(++i)+(++i) +(++i) To gain insight into the processing rules of different compilers .

that , Go back to the original printf The problem of , After understanding the evaluation order , Look again. printf The evaluation problem of ,printf The parameters of are pushed into the stack from left to right , So the calculation is from right to left ( The characteristics of the stack : First in, then out ), So far , You must have fully figured out all these problems !

So that's it , You must know why , Different compilers have different processes . So there is no single standard answer ! Now do you understand ?

why ++i Than i++ The execution efficiency is higher ?

In order to write more efficient C Language program , Should I try to use it in the future ++i, instead of i++ What about it ? For example, the following C The language code :
 Insert picture description here
Is it the line above C The execution efficiency of language code is lower than the following ? It can only be said that the theory is so , actually , modern C The language compiler is smart enough , It will compile according to the context C The language code .

It should be understood that ,i++ and ++i The difference in efficiency mainly comes from the treatment of i++ when , You need to save i The current value of is reserved for later use . If no one uses it later i The current value of the , That is to say, No C Language code reading i++ Value , The compiler really doesn't have to save i The current value of , Therefore, this step will be optimized .

For the convenience of analysis , We write the following C The language code :
 Insert picture description here
Compared with the above example , The difference lies in the execution of i++ when , No one cares i The current value of . View this paragraph C Assembly code corresponding to language code :

 Insert picture description here
obviously ,i++ and ++i The corresponding instructions are identical , There is no longer a difference in execution efficiency .

C In language i++ and ++i There is a difference , This may lead to differences in efficiency . If there is any code concerned i++ In execution i Current value , The program is right i During the self adding operation , Will have to save first i The current value of the , and ++i There is no need to save the current value , This leads to a difference in efficiency . If no one cares i++ The current value of the , So most modern C The language compiler will optimize this difference , here i++ and ++i No longer the difference in efficiency .

原网站

版权声明
本文为[HQYJ_]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202181333428792.html