x++

8 replies · 5,658 views

x++
C++ konusunda fazla bilgim yok, sadece $unu sormak istiyorum yanli$sam duzeltin.
printf( " %d %d
", ++x, x++);
bu kodda x in ilk degeri 1 olsun, kodun yapacagI i$ once Xin degerini stack a yollayacak (1) , sonra x in degerini bir arttiracak (x=2), sonra da x in degerini tekrar bir arttirip (x=3) yeniden stack a bu degeri yollayIp (3) yollayIp printf i cagIracak ve cIktI 3 1 $eklinde olacak .
en azIndan turbo C icin boyle ama bu kod VC++ da farkLI cali$abilir mi mesela cIktI 3 2 olabilir mi yani boyle bir uyumsuzluk yada yeni versiyon derleyicinin farkLI cali$masI gibi bi$ii olabilir mi (bug degildir belki ama dokumante edilmi$ yada edilmemi$ yeni bi standart mesela?) . bu soruyu kendi adIma degil bir ba$kasInin adIna soruyorum o yuzden elimdeki bilgi bu kadar. bana farkLI cali$masI gibi bi olasILIk var gibi gelmedi acIkcasI eger standartla$mI$ C yorumlama mantigini kullaniyorsa ama yine de sorayIm dedim..
x++
ansi c de kesin olan kurallar şunlar:
-x++ varsa, x'in değeri noktalı virgülden (😉 sonra artırılır.
-virgülle ayrılmış hedeler sağdan sola işlenir.
printf( " %d %d
", ++x, x++);
bu kodda virgülle ayrılmış elemanları sağdan sola işlersek
önce noktalı virgülden sonra x'in değeri artacak demiş sonra değeri artırıp x'i kullan demiş. burda bi gariplik var yani. bana c öğreten hoca virgülle ayrılmış elemanlarda ++'yı birden fazla kez kullanmayın demişti, ne çıkacağı tahmin edilemezmiş.
ki lccwin32 "2 1" yazdı. yazdıktan sonra x'in değeri de 2'ydi.
visual c ise "3 1" yazdı yazdıktan sonra x'in değeri ise 2'ydi.
yani virgülle ayrılmış ikinci elemanı görünce lcc noktalı virgülden sonra artırma işini iptal etti nası olsa burda artırdık diye. visual c ise sanki sadece orada artırılmış gibi 3 yaptı, komuttan çıkıldığında x'in değerini 1 artırdı.
ben olsam orda artırırdım komuttan çıkınca 1 daha artırırdım. yani "2 1" yazar çıkışta x'in değerini 3 yapardım.
öyle işte..
x++
Ufak bi ekleme :
VC++ 7.1 de (.NET 2003)
Debug build :
Output : 3 1
Release build :
Output : 2 1
Hem C , hem de C++ için denedim. İkiside yukarda yazdığım sonuçları verdi.
C disassembly : (calling convention __cdecl , compile as C code)
RELEASE Mode
--- c:documents and settingssinan cangadesktopeirikeirik.c ----------------

#include <windows.h>
#include <stdio.h>


void main()
{
	int x = 1;
     -----printf( " %d %d 
", ++x, x++);-------
00401000 push    1  
00401002 push    2  
00401004 push    offset string " %d %d 
" (408114h) 
00401009 call    printf (4010B4h) 



     -----system("pause");-----
0040100E push    offset string "pause" (40810Ch) 
00401013 call    system (40101Eh) 
00401018 add     esp,10h 
	return;
}

C disassembly: (calling convention __cdecl , compile as C code)
DEBUG Mode
--- c:documents and settingssinan cangadesktopeirikeirik.c ----------------

#include <windows.h>
#include <stdio.h>


void main()
{
00411B20 push    ebp 
00411B21 mov     ebp,esp 
00411B23 sub     esp,0D0h 
00411B29 push    ebx 
00411B2A push    esi 
00411B2B push    edi 
00411B2C lea     edi,[ebp-0D0h] 
00411B32 mov     ecx,34h 
00411B37 mov     eax,0CCCCCCCCh 
00411B3C rep stos  dword ptr [edi] 
	int x = 1;
00411B3E mov     dword ptr [x],1 
     -----printf( " %d %d 
", ++x, x++);-------
00411B45 mov     eax,dword ptr [x] 
00411B48 mov     dword ptr [ebp-0D0h],eax 
00411B4E mov     ecx,dword ptr [x] 
00411B51 add     ecx,1 
00411B54 mov     dword ptr [x],ecx 
00411B57 mov     edx,dword ptr [x] 
00411B5A add     edx,1 
00411B5D mov     dword ptr [x],edx 
00411B60 mov     eax,dword ptr [ebp-0D0h] 
00411B66 push    eax 
00411B67 mov     ecx,dword ptr [x] 
00411B6A push    ecx 
00411B6B push    offset string " %d %d 
" (426024h) 
00411B70 call    @ILT+1255(_printf) (4114ECh) 
00411B75 add     esp,0Ch 



     -----system("pause");-----
00411B78 push    offset string "pause" (42601Ch) 
00411B7D call    @ILT+570(_system) (41123Fh) 
00411B82 add     esp,4 
	return;
}

Ben olsam böyle kod yazmazdım 🙂
x++
ya.. bildigim kadari ile. .NET (vc) compiler'larda parametreler call style'a bagli olarak degishiyo (push'lanma sirasi)...ancak.. genelde bi cok sheyde.. .SAGDAN push'lar vc.. fakat.. printf function decleration
(...) (multiple parameter...) tarzinda oldugu ichin bi ihtimal farkli aligilyabilir.. o yuzden.. kesin emin olarak bishii diyemiyom.. denemedim... fakat..
tek diyebilecegim:
boole kod yazmayiniz lutfen 🙂
ve MUMKUN OLAN HER YERDE "pre-increment" kullaniniz..
--> ++x <--
<ODBC Error 2002: Invalid(-1) length at Column 1>
x++
Sensei'nin cevabina gelene kadar "boyle kod yazilmamasi tavsiye olunur" demek vardi aklimda ki o benden once davranmis zaten. 🙂
Bu tip entrikalarla ugrasmak yerine her zaman ilk bakista rahatca anlasilabilecek kod yazmak hem sizin hem de kodunuzu okumak zorunda kalan baska kimselerinin yararinadir. 🙂
Clarity comes first...
x++
ustalar ile ++x te x=2
sonrakinde x++ de gene 2, ve cikista 3 (; den sonra +1)
olmasi gerekmez miydi ? yani 2 2 (ve cikista 3)
x++
@ati:
soyle dusunun o zaman daha anlasilir olur sanirim;
++x (arttir ve kullan)
x++ (kullan ve arttir)
x++
şu ana kadar postfix prefix olayı yalnızca 256b javascript intro kodlarken işime yaradı. yani eğer derdiniz compile edilmiş sonuç değil de source code'un kendisini kısaltmaksa bu işinize yarayabilir. aksi taktirde düzenli yazılmış bir kodda extreme bir durum olmadığı sürece bu konuyu dert etmeniz gerekmeyecektir.