Kezdőoldal » Számítástechnika » Programozás » Mi történik mikor két változót...

Mi történik mikor két változót egyenlővé teszek C-ben?

Figyelt kérdés

Írtam egy szám beolvasást ami mindaddig működik amíg nem dolgozok a c változóval, amibe beolvastam az inputot. Nem tudok rájönni miért van így. A választ előre is köszönöm


#include <stdio.h>

#include <stdlib.h>


int main()

{

int m;

int n,c;

m = getchar();

while (m != '\n') {

if ((m >= 48) && (m <= 57)) {

n = m - 48;

} else {return 0;}

c = c*10+n;

m = getchar();

}


printf("%d\n",c);

int i;

i = c;/*ha az értékadást kiveszem jó*/

printf("%d\n",i);

return 0;

}


2018. febr. 14. 09:09
1 2 3
 11/25 tabaki ***** válasza:

Hát, most erre mit mondjak? Itt a programod futtatása az én linuxos gépemen:

123

123

123

Amint látod, semmi sem bukott ki, pedig a kódodon egy mikurkát sem változtattam. Csak feltételezem, hogy az inicializálatlan c változóban nálam véletlenül 0 volt (esetleg a fordítóm nullázta létrehozáskor), nálad meg nem.

Lefordítottam a programodat a windowsos gépemen is. Ott ezt kaptam:

123

60123

60123

Tehát nem egyezik meg a linuxos változattal sem, meg a tieddel sem -- ami erősen arra utal, hogy a fentebb elmondottaknak megfelelően véletlenszerű memóriaszemétről van szó. De az sem igaz, hogy az i = c; értékadás rontana el bármit. Ha kiveszek minden i-vel kapcsolatos dolgot, akkor printf("%d\n", c); után a te elmondásod szerint ennek kéne a képernyőn lennie:

123

123

Nálam pedig ez van:

123

60123

Vagyis a memóriaszemét ugyanúgy megbosszulja magát, akár van, akár nincs i = c; -- ha nálad szerencsésebben ütött ki, azt csak a vakvéletlennek köszönd.

Ha viszont c értékét 0-ra inicializálom, akkor bizony (i-vel vagy anélkül) a helyes értéket írja ki.

2018. febr. 16. 00:42
Hasznos számodra ez a válasz?
 12/25 anonim ***** válasza:

"az üres értékű változóba helyesen beleíródik a beolvasott szám"


A c változóba semmi értelmes nem kerül !!!!!

Másold ki ide légyszi azt a sort, amiben a c egy konkrét értéket kap. (Nem, nem a "c=c*10+n".)


Olyan, mintha azt kérdeznék tőled, mennyi x+2? Erre te azt mondod, hogy jó, de mennyi az x? Jobb híján a hasadra ütsz, és beírsz x-be egy akármilyen számot, kiszámolod, a kérdező meg örül, mert kapott egy eredményt. Te és a progid is pont ezt csináljátok a c változóval.

2018. febr. 16. 07:56
Hasznos számodra ez a válasz?
 13/25 A kérdező kommentje:

Köszi tabaki ! Szóval úgy látszik fordító függő ami történik és talán nem ezen a szinten kéne megérteni. Akik még nem vágtág le min rugózom azoknak leírom :

#include <stdio.h>

#include <stdlib.h>


int main()

{

int m;

int n,c;

m = getchar();

while (m != '\n') {

if ((m >= 48) && (m <= 57)) {

n = m - 48;

} else {return 0;}

c = c*10+n;

m = getchar();

}

printf("%d\n",c);

}


Nekem ez a kód ha hiszintek ha nem linux alatt gcc compilerrel tökéletesen lefut, igen azok ellenére, hogy a c-nek nem adtam értéket.


567

567

2018. febr. 16. 16:14
 14/25 A kérdező kommentje:
a probléma ott kezdődig ha a c váltózót nem csak kiíratni akarom hanem vizsgálni az értékét vagy kiolvasni változóba. Miért kap a fejéhez hogy akkor mégis szükség volna a kezdőértékre (int c=0;)?
2018. febr. 16. 16:20
 15/25 anonim ***** válasza:

Ha tényleg ennyire érdekel a fordítók és a natív kód világa, akkor kezd egy olyan progival, ami a problémát célozza meg.

Pl:


int main()

{

int c;

printf("%d\n",c);

c += 1;

printf("%d\n",c);

c = 1;

printf("%d\n",c);

}


Fordítsd le csak asm kódig, és vizsgáld meg, milyen szekvencia hajtódik végre különböző fordítók esetén.

2018. febr. 16. 16:47
Hasznos számodra ez a válasz?
 16/25 anonim ***** válasza:
Azt meg tudod csinálni, hogy assembly outputot generáltatsz a forrásodból és azt bemásolod ide?
2018. febr. 16. 17:09
Hasznos számodra ez a válasz?
 17/25 A kérdező kommentje:

.file "main.c"

.section .rodata

.LC0:

.string "%d\n"

.text

.globl main

.type main, @function

main:

.LFB2:

.cfi_startproc

pushq %rbp

.cfi_def_cfa_offset 16

.cfi_offset 6, -16

movq %rsp, %rbp

.cfi_def_cfa_register 6

subq $16, %rsp

call getchar

movl %eax, -12(%rbp)

jmp .L2

.L5:

cmpl $47, -12(%rbp)

jle .L3

cmpl $57, -12(%rbp)

jg .L3

movl -12(%rbp), %eax

subl $48, %eax

movl %eax, -4(%rbp)

movl -8(%rbp), %edx

movl %edx, %eax

sall $2, %eax

addl %edx, %eax

addl %eax, %eax

movl %eax, %edx

movl -4(%rbp), %eax

addl %edx, %eax

movl %eax, -8(%rbp)

call getchar

movl %eax, -12(%rbp)

jmp .L2

.L3:

movl $0, %eax

jmp .L4

.L2:

cmpl $10, -12(%rbp)

jne .L5

movl -8(%rbp), %eax

movl %eax, %esi

movl $.LC0, %edi

movl $0, %eax

call printf

movl $0, %eax

.L4:

leave

.cfi_def_cfa 7, 8

ret

.cfi_endproc

.LFE2:

.size main, .-main

.ident "GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.6) 5.4.0 20160609"

.section .note.GNU-stack,"",@progbits

2018. febr. 16. 17:19
 18/25 A kérdező kommentje:
Ez az amit legutóbb kommenteltem amiben csak kiírom és megy. Kiváncsi vagyok másoknak hogy fordul le
2018. febr. 16. 17:25
 19/25 anonim ***** válasza:
Basszus, ez az elmebeteg AT&T szintaxis. :/
2018. febr. 16. 17:36
Hasznos számodra ez a válasz?
 20/25 anonim ***** válasza:

Direkt szívatsz minket ezzel a szörnyű (és még mindig hibás) kóddal?


A deklarációk, ez négy int méret, ebből három a lokális változók.

(Ahogy korábban írtam, csak belerúg a stack pointerbe.)

subq $16, %rsp


A változóidat így találod meg:

-12(%rbp) -> m

-8(%rbp) -> c

-4(%rbp) -> n


Itt nyúl először a c-hez:

movl -8(%rbp), %edx


Számolgat vele, és itt írja vissza:

movl %eax, -8(%rbp)


Vagyis pont az történik, amit előttem már leírtak páran.

2018. febr. 16. 19:07
Hasznos számodra ez a válasz?
1 2 3

Kapcsolódó kérdések:




Minden jog fenntartva © 2025, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu

A weboldalon megjelenő anyagok nem minősülnek szerkesztői tartalomnak, előzetes ellenőrzésen nem esnek át, az üzemeltető véleményét nem tükrözik.
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!