A=A+1;
cout<<A;
اما دستور a=a+1 فرقی با ++a ندارد. پس می توان نوشت:
A++;
cout<<A;
اما اگر به جای ++A اینبار بنویسیم:
B=A++;
cout<<A;
cout<<B;
- a = a+1
- a++
- ++a
- a = ( a += 1)
می توان جای + را با - تغییر داد تا واحد ها کم شوند. ما در اینجا برای راحتی کار + را مورد توجه داریم.
اما اینکه آنها چه فرقی دارند و چرا در نمونه برنامه ما آنطور که باید برنامه کار نکرد باید گفت که نخست همه این چهار روش یک کار را به صورت کلی یکسان انجام می دهند اما در باطن یکی از آنها با بقیه متفاوت است.
روش های 1،3و4 همه به یک نوع کاراضافه کردن واحد را انجام میدهند و اثبات این کار در پایان این پست موجود است. اما در روش 2 که ++a است، متغییر حالت ابتدایی خود را تنها در زمانی که معادل یک متغییر دیگر نباشد تغییر می دهد و کاملاً شبیه روش های 1،3و4 عمل میکند. اما زمانی که یک عمل گر یا Operator همراه دستور ++a باشد داستان تغییر می کند و متغییر مقدار اولیه خود را (که صفر بود) حفظ می کند اما مقدار اضافه شده و نهایی را به متغییر عمل شده نسبت می دهد. در مثال و روش های بالا از عمل گر استفاده نشده بود؛ هم اکنون چند مثال از حالتی که از عملگر استفاده شده را خواهید دید.
اما قبل از دیدن مثال باید بدانیم اصلاً عملگر چیست؟
عملگر در حقیقت همان عبارت *=a هست که * در آن مقداری است نسبت می دهیم و a مقداری است که کاربر به کامپیوتر فهماند.
و اما مثال:
- b=a=a+1
- b=a++
- b=++a
- b=a=(a+=1)
!نکنه مهم
هم حالت 2 و هم حالت 3 هردو عملگر دارند ولی همانطور که گفته شد نتایج حالات 1 و 3 و 4 با حالت 2 متفاوت است، چرا؟
برای اینکه در حالت 3 و باقی حالات به جز حالت 2؛ مقدار اولیه a یکی اضافه می شود و مقدار نهایی a به علاوه یک نمایش داده می شود اما در حالت دوم؛ به مقدار اولیه a یکی اضافه می شود اما مقدار نهایی برای مقدار b نسبت داده می شود و مقدار a همان مقدار نخستین آن که 0 بود؛ می ماند. اما چرا؟
چون به سی پلاس پلاس اینگونه فهمانده شده است. ما دستور های نوشته شده را باز کردیم و به صورت زبان اسمبلی در زیر نمایش دادیم و می توان دید که همه حالات جز حالت شماره دوم قاعده یکسانی دارند:
(a++
) (متفاوت با بقیه)
(gdb) disassemble foo
Dump of assembler code for function foo:
0x00000000004004b4 <+0>: push %rbp
0x00000000004004b5 <+1>: mov %rsp,%rbp
0x00000000004004b8 <+4>: movl $0x0,-0x8(%rbp)
0x00000000004004bf <+11>: mov -0x8(%rbp),%eax
0x00000000004004c2 <+14>: mov %eax,-0x4(%rbp)
0x00000000004004c5 <+17>: addl $0x1,-0x8(%rbp)
0x00000000004004c9 <+21>: pop %rbp
0x00000000004004ca <+22>: retq
End of assembler dump.
(++a
)
(gdb) disassemble foo
Dump of assembler code for function foo:
0x00000000004004b4 <+0>: push %rbp
0x00000000004004b5 <+1>: mov %rsp,%rbp
0x00000000004004b8 <+4>: movl $0x0,-0x8(%rbp)
0x00000000004004bf <+11>: addl $0x1,-0x8(%rbp)
0x00000000004004c3 <+15>: mov -0x8(%rbp),%eax
0x00000000004004c6 <+18>: mov %eax,-0x4(%rbp)
0x00000000004004c9 <+21>: pop %rbp
0x00000000004004ca <+22>: retq
End of assembler dump.
(a += 1
)
(gdb) disassemble foo
Dump of assembler code for function foo:
0x00000000004004b4 <+0>: push %rbp
0x00000000004004b5 <+1>: mov %rsp,%rbp
0x00000000004004b8 <+4>: movl $0x0,-0x8(%rbp)
0x00000000004004bf <+11>: addl $0x1,-0x8(%rbp)
0x00000000004004c3 <+15>: mov -0x8(%rbp),%eax
0x00000000004004c6 <+18>: mov %eax,-0x4(%rbp)
0x00000000004004c9 <+21>: pop %rbp
0x00000000004004ca <+22>: retq
End of assembler dump
(a = a + 1
)
(gdb) disassemble foo
Dump of assembler code for function foo:
0x00000000004004b4 <+0>: push %rbp
0x00000000004004b5 <+1>: mov %rsp,%rbp
0x00000000004004b8 <+4>: movl $0x0,-0x8(%rbp)
0x00000000004004bf <+11>: addl $0x1,-0x8(%rbp)
0x00000000004004c3 <+15>: mov -0x8(%rbp),%eax
0x00000000004004c6 <+18>: mov %eax,-0x4(%rbp)
0x00000000004004c9 <+21>: pop %rbp
0x00000000004004ca <+22>: retq
End of assembler dump.
این بلاگ را برای خواندن مطالب مربوط به مهندسی فناوری اطلاعات به دیگران پیشنهاد دهید.