首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

*(ptr++) += 123 的懂得

2013-01-02 
*(ptr++) + 123的理解这样的话:【代码1:】#includestdio.h#includestdlib.h#includetime.h#includeW

*(ptr++) += 123 的理解
这样的话:

【代码1:】


#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<Windows.h>

int main()
{
    int arr[] = {6,7,8,9,10};  
    int *ptr = arr;  
    *(ptr++) = *(ptr++) + 123;   
    printf("%d ,%d\n",*ptr,*(++ptr)); 

    system("pause");
    return 0; 
}

结果是:9 ,9



但是这个:

【代码2:】

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<Windows.h>

int main()
{
    int arr[] = {6,7,8,9,10};  
    int *ptr = arr;  
    *(ptr++) += 123;   
    printf("%d ,%d\n",*ptr,*(++ptr)); 

    system("pause");
    return 0; 
}


这样的话运行结果是8 ,8



我有几点疑问:
1、*(ptr++) += 123;  的写法与*(ptr++) = *(ptr++) + 123;  的写法难道是有区别的吗?他们应该在任何时候都是对等的吧?

2、按照我的理解:
   【代码1:】的结果应该是8,9
   【代码2:】的结果应该是7,8

3、printf("%d ,%d\n",*ptr,*(++ptr)); 
   这一句的话,难道还是先执行*(++ptr),然后再执行*ptr吗?这个到底是c89,c99标准规定的还是是未定义行为,跟具体的编译器,集成环境有关系吗,它到底是怎么自行的呢,是参数*(++ptr)先入栈,然后参数*ptr才入栈吗?这个是标准规定的吗?


[解决办法]
3、printf("%d ,%d\n",*ptr,*(++ptr)); 
   这一句的话,难道还是先执行*(++ptr),然后再执行*ptr吗?这个到底是c89,c99标准规定的还是是未定义行为,跟具体的编译器,集成环境有关系吗,它到底是怎么自行的呢,是参数*(++ptr)先入栈,然后参数*ptr才入栈吗?这个是标准规定的吗?

>> 应该是先执行*(++ptr), printf是输入参数数目不定, 对参数的解析是从后往前,即从右往左
[解决办法]
不太懂汇编,不过从看反汇编过来,printf("%d ,%d\n",*ptr,*(++ptr));应该是先执行的(++ptr),而*(ptr++) = *(ptr++) + 123; ptr指针加了2次。

//第一段代码
*(ptr++) = *(ptr++) + 123;   
004113E7  mov         eax,dword ptr [ptr] 
004113EA  mov         ecx,dword ptr [eax] 
004113EC  add         ecx,7Bh 
004113EF  mov         edx,dword ptr [ptr] 
004113F2  mov         dword ptr [edx],ecx 
004113F4  mov         eax,dword ptr [ptr] 
004113F7  add         eax,4 
004113FA  mov         dword ptr [ptr],eax 
004113FD  mov         ecx,dword ptr [ptr] 
00411400  add         ecx,4 
00411403  mov         dword ptr [ptr],ecx 
printf("%d ,%d\n",*ptr,*(++ptr)); 
00411406  mov         eax,dword ptr [ptr] 
00411409  add         eax,4 


0041140C  mov         dword ptr [ptr],eax 
0041140F  mov         esi,esp 
00411411  mov         ecx,dword ptr [ptr] 
00411414  mov         edx,dword ptr [ecx] 
00411416  push        edx  
00411417  mov         eax,dword ptr [ptr] 
0041141A  mov         ecx,dword ptr [eax] 
0041141C  push        ecx  
0041141D  push        offset string "%d ,%d\n" (415644h) 
00411422  call        dword ptr [__imp__printf (4182BCh)] 
00411428  add         esp,0Ch 
0041142B  cmp         esi,esp 
0041142D  call        @ILT+305(__RTC_CheckEsp) (411136h) 


而*(ptr++) += 123;,ptr指针只加了一次,同样printf("%d ,%d\n",*ptr,*(++ptr));,先执行的应该是++ptr.

*(ptr++) += 123;   
004113E7  mov         eax,dword ptr [ptr] 
004113EA  mov         ecx,dword ptr [eax] 
004113EC  add         ecx,7Bh 
004113EF  mov         edx,dword ptr [ptr] 
004113F2  mov         dword ptr [edx],ecx 
004113F4  mov         eax,dword ptr [ptr] 
004113F7  add         eax,4 
004113FA  mov         dword ptr [ptr],eax 
printf("%d ,%d\n",*ptr,*(++ptr)); 
004113FD  mov         eax,dword ptr [ptr] 
00411400  add         eax,4 
00411403  mov         dword ptr [ptr],eax 
00411406  mov         esi,esp 
00411408  mov         ecx,dword ptr [ptr] 
0041140B  mov         edx,dword ptr [ecx] 
0041140D  push        edx  
0041140E  mov         eax,dword ptr [ptr] 
00411411  mov         ecx,dword ptr [eax] 
00411413  push        ecx  
00411414  push        offset string "%d ,%d\n" (415644h) 
00411419  call        dword ptr [__imp__printf (4182BCh)] 
0041141F  add         esp,0Ch 
00411422  cmp         esi,esp 


00411424  call        @ILT+305(__RTC_CheckEsp) (411136h) 


[解决办法]
*(ptr++) += 123;
*(ptr++) = *(ptr++) + 123;  
一个是一个++,另一个是两个++,怎么可能一样呢?
[解决办法]
3、printf("%d ,%d\n",*ptr,*(++ptr)); 
VC,VS中函数默认的入栈顺序从右向左,因此先执行*(++ptr)再输出。

如下面这个程序会输出5 ,5
#include <stdio.h>
int main()
{
int i = 4;
printf("%d ,%d\n", i, ++i); 
return 0;
}

[解决办法]
1. *(ptr++) = *(ptr++) + 123;
实际执行时,右边的ptr++会先被执行一次,然后把结果赋给左边,ptr++又被执行一次,所以ptr一共被加了两次
很显然,第二段代码里ptr只被加了一次

2. 关于printf
由于函数间参数传递是通过栈,并且入参是前面的参数在堆栈的低位,所以对于printf("%d ,%d\n",*ptr,*(++ptr));必须先把*(++ptr)的值压栈,然后再压*ptr,最后压"%d ,%d\n",因此ptr会被先加一次
[解决办法]

[解决办法]
引用:
为什么要为了这些毫无意义的东西纠结????????????????????????



回忆下 鲁迅如何解释自己的鼻子扁平
[解决办法]
printf函数执行顺序自右向左
输出顺序自左向右
[解决办法]
lz说对了
  *(ptr++) += 123;   
    printf("%d ,%d\n",*ptr,*(++ptr));
 
着两行都是未定义行为

热点排行