C uganka

Vse o programiranju na in za PC

Moderatorji: Kroko, tilz0R

C uganka

OdgovorNapisal/-a tilz0R » 16 Avg 2018, 13:00

Koda: Izberi vse
int cnt = 1;
printf("Total: %d item%s", cnt, "s" + (cnt == 1));
cnt = 0;
printf("Total: %d item%s", cnt, "s" + (cnt == 1));


Kaj izpišeta spodnji kodi? In kako je to možno?

Ta je lahka.
Knowledge sharing is people' caring., T. MAJERLE
Uporabniški avatar
tilz0R
 
Prispevkov: 1830
Pridružen: 18 Jan 2015, 00:12
Kraj: Črnomelj
Zahvalil se je: 230 krat
Prejel zahvalo: 517 krat
Uporabnika povabil: s56rga
Število neizkoriščenih povabil: 255

Re: C uganka

OdgovorNapisal/-a Kroko » 16 Avg 2018, 13:26

Dobra finta :-)

Koda: Izberi vse
Total: 1 item
Total: 0 items
http://www.planet-cnc.com poskakuješ na eni nogi in žvižgaš alpske podoknice Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 4809
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 687 krat
Prejel zahvalo: 1670 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: C uganka

OdgovorNapisal/-a S53DZ » 16 Avg 2018, 13:28

dobra, ja.
Končni efekt je kot tale, ampak tu je rezultat fiksni:
Koda: Izberi vse
printf("\nTotal: %d item%s\b ", cnt, "s");


FALSE = 0
TRUE = !FALSE
Zadnjič spremenil S53DZ, dne 16 Avg 2018, 13:31, skupaj popravljeno 1 krat.
Uporabniški avatar
S53DZ
 
Prispevkov: 1166
Pridružen: 18 Jan 2015, 10:58
Kraj: Ljubljana
Zahvalil se je: 204 krat
Prejel zahvalo: 392 krat
Uporabnika povabil: S52O
Število neizkoriščenih povabil: 42

Re: C uganka

OdgovorNapisal/-a Kroko » 16 Avg 2018, 13:30

@S53DZ
Ampak tvoj "fiksni" primer za cnt = 0 izpiše slovnično narobe.
http://www.planet-cnc.com poskakuješ na eni nogi in žvižgaš alpske podoknice Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 4809
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 687 krat
Prejel zahvalo: 1670 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: C uganka

OdgovorNapisal/-a tilz0R » 16 Avg 2018, 13:30

S53DZ je napisal/-a:Končni efekt je kot tale, ampak tu je rezultat fiksni:
Koda: Izberi vse
printf("\nTotal: %d item%s\b ", cnt, "s");

ne štekam, kako je lahko končni, saj sta različni vrednosti v pogoju.
Knowledge sharing is people' caring., T. MAJERLE
Uporabniški avatar
tilz0R
 
Prispevkov: 1830
Pridružen: 18 Jan 2015, 00:12
Kraj: Črnomelj
Zahvalil se je: 230 krat
Prejel zahvalo: 517 krat
Uporabnika povabil: s56rga
Število neizkoriščenih povabil: 255

Re: C uganka

OdgovorNapisal/-a S53DZ » 16 Avg 2018, 13:33

Saj zato pa pravim, da je dobra.
S tistim \b sem samo poskusil, če gre backspace, haha.
Uporabniški avatar
S53DZ
 
Prispevkov: 1166
Pridružen: 18 Jan 2015, 10:58
Kraj: Ljubljana
Zahvalil se je: 204 krat
Prejel zahvalo: 392 krat
Uporabnika povabil: S52O
Število neizkoriščenih povabil: 42

Re: C uganka

OdgovorNapisal/-a tilz0R » 16 Avg 2018, 13:34

S53DZ je napisal/-a:Saj zato pa pravim, da je dobra.

Rezultat pa ni isti pri cnt == 1 ali pa cnt != 1 ;)

S53DZ je napisal/-a:S tistim \b sem samo poskusil, če gre backspace, haha.

Da se nisi ujel v past ;)
Knowledge sharing is people' caring., T. MAJERLE
Uporabniški avatar
tilz0R
 
Prispevkov: 1830
Pridružen: 18 Jan 2015, 00:12
Kraj: Črnomelj
Zahvalil se je: 230 krat
Prejel zahvalo: 517 krat
Uporabnika povabil: s56rga
Število neizkoriščenih povabil: 255

Re: C uganka

OdgovorNapisal/-a S53DZ » 16 Avg 2018, 13:34

Hm ...
Uporabniški avatar
S53DZ
 
Prispevkov: 1166
Pridružen: 18 Jan 2015, 10:58
Kraj: Ljubljana
Zahvalil se je: 204 krat
Prejel zahvalo: 392 krat
Uporabnika povabil: S52O
Število neizkoriščenih povabil: 42

Re: C uganka

OdgovorNapisal/-a gumby » 16 Avg 2018, 13:40

"s" je polje dveh znakov, torej s in \0 na koncu.
printf() dobi kot parameter pointer na to tabelo, ki je v prvem primeru (cnt==1) povečan za 1, torej kaže na \0 (in se ne izpiše nič).
V drugem primeru se pa ne poveča (cnt!=1), zato kaže na "s" in se to tudi izpiše.

Dobra fora, ja :D
my brain hurts
Uporabniški avatar
gumby
 
Prispevkov: 2591
Pridružen: 14 Jan 2015, 19:49
Kraj: Lendava
Zahvalil se je: 109 krat
Prejel zahvalo: 612 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 63

Re: C uganka

OdgovorNapisal/-a Kroko » 16 Avg 2018, 13:41

Dodatno vprašanje:
Je ta primer portabilen in zakaj?
http://www.planet-cnc.com poskakuješ na eni nogi in žvižgaš alpske podoknice Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 4809
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 687 krat
Prejel zahvalo: 1670 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: C uganka

OdgovorNapisal/-a tilz0R » 16 Avg 2018, 13:43

Zagotovo je portabilno. sizeof(char) je vedno 1 in če 1 prišteješ (char *), ga tudi povečaš le za 1, tako da boš zagotovo kazal na \0 del stringa.
Knowledge sharing is people' caring., T. MAJERLE
Uporabniški avatar
tilz0R
 
Prispevkov: 1830
Pridružen: 18 Jan 2015, 00:12
Kraj: Črnomelj
Zahvalil se je: 230 krat
Prejel zahvalo: 517 krat
Uporabnika povabil: s56rga
Število neizkoriščenih povabil: 255

Re: C uganka

OdgovorNapisal/-a Kroko » 16 Avg 2018, 13:51

To je samo en del odgovora.

Kaj pa tole, če citiram S53DZ:
FALSE = 0
TRUE = !FALSE
http://www.planet-cnc.com poskakuješ na eni nogi in žvižgaš alpske podoknice Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 4809
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 687 krat
Prejel zahvalo: 1670 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: C uganka

OdgovorNapisal/-a tilz0R » 16 Avg 2018, 13:52

Kroko je napisal/-a:To je samo en del odgovora.


Nevem kaj pričakuješ več, to bi bilo vse. %s je kompatibilen z char *.
Knowledge sharing is people' caring., T. MAJERLE
Uporabniški avatar
tilz0R
 
Prispevkov: 1830
Pridružen: 18 Jan 2015, 00:12
Kraj: Črnomelj
Zahvalil se je: 230 krat
Prejel zahvalo: 517 krat
Uporabnika povabil: s56rga
Število neizkoriščenih povabil: 255

Re: C uganka

OdgovorNapisal/-a Kroko » 16 Avg 2018, 13:53

ki je v prvem primeru (cnt==1) povečan za 1


Je to vedno res?
http://www.planet-cnc.com poskakuješ na eni nogi in žvižgaš alpske podoknice Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 4809
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 687 krat
Prejel zahvalo: 1670 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: C uganka

OdgovorNapisal/-a tilz0R » 16 Avg 2018, 13:56

Kroko je napisal/-a:Je to vedno res?

Vedno. ==, >=, >, <, <=, != vedno vrnejo 1 če je true in 0 če je false. Je pa ta 1 ali 0 tipa int.
isto velja za &&, || in ! operande.

stdbool.h pa tudi definira true in false kot 1 in 0.

C99 standardi:
6.5.8, > <<=, >=
6.5.9, ==, !=
6.5.13 &&
6.5.14, ||
6.5.3.3/4, !

PS: Kakšen markdown support bi prav prišel na tem forumu :)
Knowledge sharing is people' caring., T. MAJERLE
Uporabniški avatar
tilz0R
 
Prispevkov: 1830
Pridružen: 18 Jan 2015, 00:12
Kraj: Črnomelj
Zahvalil se je: 230 krat
Prejel zahvalo: 517 krat
Uporabnika povabil: s56rga
Število neizkoriščenih povabil: 255

Re: C uganka

OdgovorNapisal/-a Kroko » 16 Avg 2018, 14:06

Točno to sem pričakoval. Točko 6.5.9.3, ki pravi, da operator == vrne int vrednost 1.
"true" in "false" sta tu povsem irelevantna.

Tule je dokument, če koga zanima:
http://www.open-std.org/JTC1/SC22/WG14/ ... /n1256.pdf
http://www.planet-cnc.com poskakuješ na eni nogi in žvižgaš alpske podoknice Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 4809
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 687 krat
Prejel zahvalo: 1670 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: C uganka

OdgovorNapisal/-a Kroko » 16 Avg 2018, 14:17

Koda: Izberi vse
int b = true;
int val = 1000 + b;
printf("Vrednost1: %d\n", val);

#undef true
#define true 99

b = true;
val = 1000 + b;
printf("Vrednost2: %d\n", val);

int c = 0;
val = 1000 + (c==0);
printf("Vrednost3: %d\n", val);
http://www.planet-cnc.com poskakuješ na eni nogi in žvižgaš alpske podoknice Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 4809
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 687 krat
Prejel zahvalo: 1670 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: C uganka

OdgovorNapisal/-a S53DZ » 16 Avg 2018, 14:19

Hm ...
Je pa že treba biti pozoren na rabo TRUE / FALSE konstant in true / false veljavnih besed posebej v C99.
Če prevajalnik C98 protestira, da true / false pač nista definirana, ju zlahka definiraš kot int, na primer: karkoli / 0. :_CR

Glej pod Boolean Type:
http://david.tribble.com/text/cdiffs.htm#C99-bool
Uporabniški avatar
S53DZ
 
Prispevkov: 1166
Pridružen: 18 Jan 2015, 10:58
Kraj: Ljubljana
Zahvalil se je: 204 krat
Prejel zahvalo: 392 krat
Uporabnika povabil: S52O
Število neizkoriščenih povabil: 42

Re: C uganka

OdgovorNapisal/-a tilz0R » 16 Avg 2018, 14:20

Vse štima. == ne vrne "true", tako da tudi če ga undef-aš bo še vedno 1 vrnil. Tudi če true daš na karkoli. Recimo true/false konstant se strogo izogibam in jih v nobenem primeru ne uporabljam.
Knowledge sharing is people' caring., T. MAJERLE
Uporabniški avatar
tilz0R
 
Prispevkov: 1830
Pridružen: 18 Jan 2015, 00:12
Kraj: Črnomelj
Zahvalil se je: 230 krat
Prejel zahvalo: 517 krat
Uporabnika povabil: s56rga
Število neizkoriščenih povabil: 255

Re: C uganka

OdgovorNapisal/-a gumby » 16 Avg 2018, 14:29

S53DZ je napisal/-a:... in true / false veljavnih besed posebej v C99.

Če z "veljavna beseda" misliš keyword, potem true in false v nobenem C-ju nista to.
my brain hurts
Uporabniški avatar
gumby
 
Prispevkov: 2591
Pridružen: 14 Jan 2015, 19:49
Kraj: Lendava
Zahvalil se je: 109 krat
Prejel zahvalo: 612 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 63

Re: C uganka

OdgovorNapisal/-a S53DZ » 16 Avg 2018, 14:32

Mislim na tole, v zgornjem linku:
C99 supports the _Bool keyword, which declares a two-valued integer type (capable of representing the values true and false). It also provides a standard <stdbool.h> header that contains definitions for the following macros:

bool Same as _Bool
false Equal to (_Bool)0
true Equal to (_Bool)1

C++ provides bool, false, and true as reserved keywords and implements bool as a true built-in boolean type.

C programs that do not include the <stdbool.h> header are free to use these keywords as identifiers and macro names, which may cause compatibility problems when such code is compiled as C++. For example:

typedef short bool; // Different

#define false ('\0') // Different
#define true (!false) // Different

bool flag = false;

Uporabniški avatar
S53DZ
 
Prispevkov: 1166
Pridružen: 18 Jan 2015, 10:58
Kraj: Ljubljana
Zahvalil se je: 204 krat
Prejel zahvalo: 392 krat
Uporabnika povabil: S52O
Število neizkoriščenih povabil: 42

Re: C uganka

OdgovorNapisal/-a tilz0R » 16 Avg 2018, 14:35

Teoretično lahko v C-ju obe, "true" in "false" daš na 0 (ali ne-nič) in imaš popolno zmedo.

Isto kot tole:

Koda: Izberi vse
#define if while
int a;
a = 4;
if (a) {
    printf("%d\r\n", a);
}


Tole sem naredil kolegu na faksu, medtem ko je šel na WC. 2 uri je razmišljal zakaj program ne dela (kao WDT reset).
Vem, prasec sem. Ne me obsojati.
Knowledge sharing is people' caring., T. MAJERLE
Uporabniški avatar
tilz0R
 
Prispevkov: 1830
Pridružen: 18 Jan 2015, 00:12
Kraj: Črnomelj
Zahvalil se je: 230 krat
Prejel zahvalo: 517 krat
Uporabnika povabil: s56rga
Število neizkoriščenih povabil: 255

Re: C uganka

OdgovorNapisal/-a gumby » 16 Avg 2018, 14:38

S53DZ: preberi še enkrat, kaj si citiral... keyword v C je samo _Bool
Ne mešat C++ zraven, tisto je druga zgodba :)
my brain hurts
Uporabniški avatar
gumby
 
Prispevkov: 2591
Pridružen: 14 Jan 2015, 19:49
Kraj: Lendava
Zahvalil se je: 109 krat
Prejel zahvalo: 612 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 63

Re: C uganka

OdgovorNapisal/-a Kroko » 16 Avg 2018, 17:00

Dobra programerska praksa je, da se uporabljajo tipi, ki izražajo kaj vrednost pomeni. V primeru logičnih vrednost to pomeni "bool" tipe.
Saj tudi namesto "int" uporabljaš "int32_t" mar ne? Je povsem isti štos.

Še en čuden primer.

Koda: Izberi vse
int length = 1000;
int position = 998;

while (position <= 1000)
{
    if ((length - position) == true)
      printf("%d - TRUE\n", position);
    else
      printf("%d - FALSE\n", position);
    position++;
}
http://www.planet-cnc.com poskakuješ na eni nogi in žvižgaš alpske podoknice Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 4809
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 687 krat
Prejel zahvalo: 1670 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: C uganka

OdgovorNapisal/-a tilz0R » 16 Avg 2018, 17:05

Izključno stdint.h, razen za char/float/double, ker so velikosti znane. Za length/size uporabljam size_t.
Knowledge sharing is people' caring., T. MAJERLE
Uporabniški avatar
tilz0R
 
Prispevkov: 1830
Pridružen: 18 Jan 2015, 00:12
Kraj: Črnomelj
Zahvalil se je: 230 krat
Prejel zahvalo: 517 krat
Uporabnika povabil: s56rga
Število neizkoriščenih povabil: 255

Re: C uganka

OdgovorNapisal/-a MitjaN » 16 Avg 2018, 18:22

tilz0R je napisal/-a:Izključno stdint.h, razen za char/float/double, ker so velikosti znane. Za length/size uporabljam size_t.


Niti ne. Nesrečna C2000 družina od TI-ja ima 16 bitni char. float in double pa sta 32 bitna. Za še večji žur je na glavnem CPU-ju void* 32 biten, int 16 biten, long 32 biten, long long pa 64 biten, na koprocesorju pa imaš void* ki je 16 biten, short ki je 16 biten, int 32 biten, long 32 biten, long long 32 biten. In če imaš res srečo imaš v istem ohišju še eno ARM M3 jedro. Tu se fenomenalno hitro naučiš zakaj obstaja stdint.h
MitjaN
 
Prispevkov: 92
Pridružen: 24 Feb 2015, 12:45
Zahvalil se je: 11 krat
Prejel zahvalo: 37 krat
Uporabnika povabil: aly
Število neizkoriščenih povabil: 7

Re: C uganka

OdgovorNapisal/-a tilz0R » 17 Avg 2018, 06:51

MitjaN, kaj ti pa vrne `sizeof(char)` na tvoji platformi, kjer je char 16-biten? Moral bi `1`, kar pomeni, da `uint8_t` ne obstaja, ali se motim? :)
Knowledge sharing is people' caring., T. MAJERLE
Uporabniški avatar
tilz0R
 
Prispevkov: 1830
Pridružen: 18 Jan 2015, 00:12
Kraj: Črnomelj
Zahvalil se je: 230 krat
Prejel zahvalo: 517 krat
Uporabnika povabil: s56rga
Število neizkoriščenih povabil: 255

Re: C uganka

OdgovorNapisal/-a MitjaN » 17 Avg 2018, 07:32

Yup, 'sizeof(char)' je 1 in 'uint8_t' ni definiran. Imaš pa 'int_least8_t'. Cel žur za komunikacijske stack-e
MitjaN
 
Prispevkov: 92
Pridružen: 24 Feb 2015, 12:45
Zahvalil se je: 11 krat
Prejel zahvalo: 37 krat
Uporabnika povabil: aly
Število neizkoriščenih povabil: 7

Re: C uganka

OdgovorNapisal/-a Kroko » 17 Avg 2018, 08:35

Zaradi takih primerov je na primer smiselno namesto int8_t uporabljati int_least8_t in int_ fast8_t. Odvisno od situacije.

Na "mojih" platformah teh težav k sreči ni. Zanašam se tudi na optimizator in pričakujem, da bo moje int8_t uporabil kot int_ fast8_t.
http://www.planet-cnc.com poskakuješ na eni nogi in žvižgaš alpske podoknice Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 4809
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 687 krat
Prejel zahvalo: 1670 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: C uganka

OdgovorNapisal/-a tilz0R » 17 Avg 2018, 08:38

Pri meni tudi tega na srečo (zaenkrat) ni. Pozna še kdo kakšno "aktivno" družino (ne nekaj iz leta 1980), ki ima char 16-biten, in podobno?
Knowledge sharing is people' caring., T. MAJERLE
Uporabniški avatar
tilz0R
 
Prispevkov: 1830
Pridružen: 18 Jan 2015, 00:12
Kraj: Črnomelj
Zahvalil se je: 230 krat
Prejel zahvalo: 517 krat
Uporabnika povabil: s56rga
Število neizkoriščenih povabil: 255

Re: C uganka

OdgovorNapisal/-a MitjaN » 17 Avg 2018, 08:58

Motorola/freescale/NXP 56K serija. Sicer jo je vedno manj, ampak imaš 24 bitni char, short in int, 48 bitni long in 48 bitni float (ni IEEE754)
MitjaN
 
Prispevkov: 92
Pridružen: 24 Feb 2015, 12:45
Zahvalil se je: 11 krat
Prejel zahvalo: 37 krat
Uporabnika povabil: aly
Število neizkoriščenih povabil: 7

Re: C uganka

OdgovorNapisal/-a Kroko » 17 Avg 2018, 09:24

Ponavadi se to sreča v DSP čipih. Na primer Alterin DSP blok je 36 biten.
http://www.planet-cnc.com poskakuješ na eni nogi in žvižgaš alpske podoknice Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 4809
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 687 krat
Prejel zahvalo: 1670 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: C uganka

OdgovorNapisal/-a s54mtb » 17 Avg 2018, 09:30

Ali kateri od prevajalnikov podpira 16 bitni half precision float?
https://en.wikipedia.org/wiki/Half-prec ... int_format
Namesto "Zahvali se" sprejemam tudi šalco kofeta: https://www.buymeacoffee.com/s54mtb
Uporabniški avatar
s54mtb
 
Prispevkov: 11327
Pridružen: 15 Jan 2015, 01:10
Zahvalil se je: 1571 krat
Prejel zahvalo: 4114 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 104


Vrni se na Programski jeziki

Kdo je na strani

Po forumu brska: 0 registriranih uporabnikov in 1 gost