- Milyen belső merevlemezt vegyek?
- Sugárhajtómű ihlette a Zalman CPU-hűtőjét, de nem az üzemzaj tekintetében
- Gaming notebook topik
- NTFS, exFAT, FAT32 – Melyiket válaszd és miért?
- Vélemény: nem úgy tűnik, de Lip-Bu Tan most menti meg az Intelt
- Bambu Lab 3D nyomtatók
- Forrmell.enn
- OLED TV topic
- 3D nyomtatás
- Canon EOS DSLR topic
Új hozzászólás Aktív témák
-
dobragab
addikt
válasz
Krisztiiii #5916 üzenetére
Ez nem valami BME GPK szerencsétlenség és C#? Mintha ott már találkoztam volna ezzel a stílussal...
-
-
dobragab
addikt
válasz
alapz@j #5727 üzenetére
Vagy elolvasod ezt és lenyúlod a függvényeit. Mindenképpen utf-8-ként érdemes kezelni a szövegeket.
-
dobragab
addikt
Napi mitírki. Nem nehéz, de azért van benne egy apró csavar. Kérdés: mi a függvény visszatérési értéke?
unsigned set(unsigned *a, unsigned *b) {
*a = 1;
*b = 2;
return *a;
} -
dobragab
addikt
válasz
stepboy #5685 üzenetére
De, ezzel így semmi baj nincs. Csak ez azért ciki, mert a
temp
változó csakis azért létezik, hogy a függvénynek cím szerint oda tudd adni. Másra nem kell, ettől rondább lesz a kód.Így már szebb (szerintem):
evil_api_function_call(fp, ptr, (int[]){1});
Mert ugye ezt nem írhatod le.
evil_api_function_call(fp, ptr, &1);
-
dobragab
addikt
válasz
maestro87 #5683 üzenetére
"Összetett literális".
Alaptípusokra, mint amilyen az
int
, azunsigned long
, adouble
, tudsz a programkódba beágyazott konstansokat írni. Pl:0
,25UL
,0x0badc0de
,4.6f
,0.001
. Speciális literal még a string literal, amit így ismersz:"Hello world!\n"
.Struktúrákra, union-okra, tömbökre C89-ben ilyet csak inicializálásnál tudsz:
struct Pont p = {5, 12};
int arr[] = {1, 2, 3, 5, 8, 13, 21};
p = {12; -5}; // <- ERROR
p.x = 12;
p.y = -5; // <- macerásC99 behoz ezzel kapcsolatban két feature-t, a compound literal és a designated initializer.
Compound literal
Arra való, hogy a programkódban ne csak ilyen alaptípusokat, hanem összetett típusokat is meg lehessen adni egyetlen kifejezésben. Ehhez ugyanaz a szintaxis, mint az inicializálásnál, konyhanyelven annyi különbséggel, hogy a kapcsos zárójel tartalmát az adott típusra kell "cast-olni".
p = (struct Pont){12; -5};
struct Pont Pont_tukroz(struct Pont p)
{
return (struct Pont){p.y, -p.x};
}
struct Pont q = Pont_tukroz((struct Pont){10, 13});printf("%p\n", (int[]){1});
double osszeg = double_osszeg((double[]){1.0, 2.718, M_PI}, 3);Ezek a "változók" temporális objektumok, nincs nevük, nem képezheted a címét, mint ahogy ez is értelmetlen:
printf("%p", &1);
Élettartamuk a blokk végéig tart (bezáró
}
), nem úgy, mint C++-ban, ahol a pontosvesszőig (jó, nem pont így van a szabványban, de megközelítőleg pontos).Designated initializer
C-ben a struktúrák adattagjait közvetlenül érjük el, szinte mindig név szerint.
void Pont_kiir(struct Pont p)
{
printf("(%d, %d)", p.x, p.y);
}Kivéve: inicializálásnál.
struct Pont p = {5, 12};
Ez egyértelműnek tűnik, az
x
koordináta 5 lesz, azy
pedig 12. De mi történik, ha valami bunkó így definiálta astruct Pont
-ot?struct Pont
{
int y;
int x;
}Ilyenkor minden működik tovább, kivéve az inicializálást, akkor pont fordítva történnek a dolgok, mint ahogy az ember elképzelte. Ezért vezették be, hogy a struktúrákat inicializálni is lehessen név szerint:
struct Pont p = {.x = 5, .y = 12};
Természetesen compound literal-lal együtt is használható.
p = {.x = 5, .y = 12};
És nem csak struktúrákra, tömbökre is.
int arr[] = {[0] = 8, [1] = 13, [2] = 21};
Sőt, vegyesen is.
haromszog_rajzol((struct Pont[])
{
[0] = {.x = 12, .y = 5},
[1] = {.x = -12, .y = 5},
[2] = {.x = 0, .y = 0}
});Jó eséllyel ezeket a te fordítód is támogatja, ha GCC vagy Clang, csak -std=c99 kell neki. MSVC a C99 cuccokat a 2015-ös verzió óta zömmel tudja...
EQMontoya: bocsi a magyar változónevek miatt
-
dobragab
addikt
válasz
maestro87 #5676 üzenetére
C-ben is lehet OO kódot írni, csak nehezebb, öröklést csinálni pedig undorító. Az OOP elveket viszont explicite nem támogatja a C, azaz egy C-s "osztályt" bármikor lehet szarul használni, C++-ban többé-kevésbé a használójára rá lehet kényszeríteni a "jó" használatot. Legalábbis dióhéjban ennyi.
(#5675) ToMmY_hun
C++-ban szerintem gátlástalanul lehet
return
-ölni akárhonnan. C-ben vigyázni kell, mert lehet, hogy pl. hibajelzésre használt visszatérés előtt fel kéne szabadítani valami erőforrásokat, és nem történik meg automatikusan. Erre (C-s kivételkezelés) majd fogok szülni egy másik hsz-t, még agoto
kapcsán. -
dobragab
addikt
válasz
maestro87 #5671 üzenetére
++i
tök mást csinál.continue
igazából arra való, hogy ne legyen annyi egymásba ágyazás. A fenti kód így írható át:void print_primes(int * primes, int lenght)
{
for(int i = 0; i < lenght; ++i)
{
if(primes[i]>=2)
{
/* és egy rakás random utasítás */
if(is_prime(primes[i]))
printf("%d\n", primes[i]);
/* meg itt is sok utasítás */
}
}
}A bitb*szogatás nem az én területem, de tudomásom szerint a
continue
asm-ben 1 db jump lesz, ugyanúgy, ahogy azif
is.C++ C-hez képest nagyon sok mindent tud, amit neked első körben érdemes megnézned, az az objektumorientált tervezés.
-
dobragab
addikt
válasz
EQMontoya #5667 üzenetére
Jaja, nehéz leszokni róla, gondolom, itt is hiányzott az std::vector, range based for, std::ostream
Na meg szerintem nem is ezt akartad írni
void print_primes(int * primes, int lenght)
{
for(int i = 0; i < lenght; ++i)
{
if(primes[i]<2) continue;
if(is_prime(primes[i])) printf("%d\n", primes[i]);
}
} -
dobragab
addikt
Beszélgessünk a
goto
-ról!Általános vélemény a
goto
-ról, hogy kerülni kell, mint egyszeri kockának a napfényt, különben lesül a képünk. Sokan viszont azt mondják, hogy agoto
használata bizonyos esetekben egyszerűsíti és átláthatóbbá teszi a kódot, és egyáltalán nem lesz tőle spagettikód, ha ésszel használjuk. Ugyanúgy, ahogy acontinue
és abreak
is. Utóbbinál szerencsétlen, hogy ciklusoknál ésswitch
-nél tök mást jelent, úgyhogy az szerintem is a gonosztól származik.Nekem erről egyértelmű a véleményem, de előbb halljuk, mit mondtok ti
-
dobragab
addikt
válasz
maestro87 #5654 üzenetére
emp.doj
egy három elemű tömb, amit inicializálni csak akkor tudsz, amikor létrehozod azemp
változót.Employee emp = {
"John Sample", 0, 2500,
{1, 1, 1970},
{1, 1, 1970},
{1, 1, 1970}
};Külön inicializálni már nem tudod, csak értéket adhatsz neki. Illetve nem is neki, mert C-ben nincs tömbök közötti értékadás, hanem az elemeinek, mégpedig egy létező dátumot:
date date0 = {1, 1, 1970};
Ezután adhatsz értéket az
emp.doj
elemeinek.emp.doj[0] = date0;
emp.doj[1] = date0;
emp.doj[2] = date0;Itt segítségedre lehet a C99 compound literal:
emp.doj[0] = (date){1, 1, 1970};
Ha kinullázni szeretnéd egy struktúra adattagjait, akkor ez nem szabványos, normális fordító nem eszi meg:
date date0 = {};
Ez viszont igen:
date date0 = {0};
-
dobragab
addikt
Üdv!
Szerintem akkor jársz legjobban, ha előbb C-t tanulod meg, onnan már az AVR-specifikus dolgok könnyebben jönnek. C-t meg szerintem innen érdemes, elsősorban előadások anyagai.
-
dobragab
addikt
válasz
#36268800 #5614 üzenetére
Vagy legalább a Programkód formázást így.
void sztring (char*, char*);
int main()
{
char str1[]="AEBCD", str2[37]= {0};
sztring (str1,str2);
return 0;
}
void sztring (char *p1, char *p2)
{
int i=0;
while (*p1)
{
if (*p1=='A' || *p1=='E')
{
if (! (i%2) )
{
*p2=*p1;
p2++;
i++;
}
}
if (*p1=='B' || *p1=='C' || *p1=='D')
{
if (i%2)
{
*p2=*p1;
p2++;
i++;
}
}
p1++;
}
} -
dobragab
addikt
válasz
DrojDtroll #5607 üzenetére
feof-fal óvatosan, nem jóstehetség! Nem tudja kitalálni, hogy a következő beolvasás el fog-e halni (azaz a fájl végén vagyunk-e), hanem azt adja vissza, hogy az előző beolvasás EOF miatt halt-e el. Azaz könnyű rosszul használni, így tud még egy hibás adat bekerülni a lista végére.
-
dobragab
addikt
Javasolt valami whitespace-szel elválasztani a számokat. A scanf és társai ilyenkor nem tesznek különbséget egy ill. több különböző típusú whitespace között. Azaz ha a fájlban épp tabot vagy fájl végét sikerült használnod, azt is meg fogja enni space-ként.
1 2 3 4 5
6 7 8 9 10
...Az fscanf visszatérési értékét érdemes vizsgálni, ami a fájl végét illeti. Azt adja vissza, hány formátumsztringbeli értéket töltött fel sikeresen. Ha 5 számról volt szó, akkor sikeres beolvasásnál 5-öt ad vissza.
Primitív példakód:
int szamok[5];
while(fscanf(fp, "%d %d %d %d %d", szamok, szamok+1, szamok+2, szamok+3, szamok+4) == 5)
{
// egy sor feldolgozása
}Nem tudom, mennyire ismered a C-t, meg pontosan mit akarsz vele csinálni. Javasolt csinálni egy Lottoszam struktúrát, ha bármi komolyabbat csinálni kell vele. És lehet ciklusban olvasni az 5 db számot, csak akkor macerásabb a hibakezelés...
Ha mind el kell tárolni, akkor ismét érdekes kérdés következik:
1. ismerjük előre a darabszámot (fájl elejére oda van-e írva): VLA vagy malloc
2. nem ismerjük: nyújtózkodó tömb, láncolt lista, maximális pufferméret, stb.Szóval ez a C legmacerásabb problémája.
-
dobragab
addikt
válasz
feketeg5 #5599 üzenetére
Megírni nem fogom helyetted, de azért ötleteket adok.
Dönthetsz, hogy szövegként dolgozol-e vele, vagy számként. Előbbi esetben a karaktereket egyszerű összehasonlítani és a hosszát meghatározni. Ha számként használod, akkor egy kicsit több matek kell hozzá, de szebb a megoldás.
-
dobragab
addikt
válasz
EQMontoya #5596 üzenetére
Ó én mindent, és meg is van az értelme.
Elsődlegesen Win8.1 + Classic Shell.
Ezen kívül:
arch linux + gnome3
ubuntu 14.04 + cinnamon
linux mint + cinnamon (már nem használom)
ubuntu 16.04 + kde5 (csak kipróbáltam, lassan kuka)
win7
win10 + classic shellMindez egy gépen. Amúgy az egyik cinnamonra kifejezetten büszke vagyok
-
-
-
dobragab
addikt
válasz
jattila48 #5574 üzenetére
Jól mondod.
Az egyszerűség kedvéért úgy is lehet definiálni, hogy a tömbön mint típuson két művelet értelmezett:
- sizeof
- automatikus konverzió, ami a tömb első elemére mutató pointerré konvertáljaEbből minden más, tömbökre jellemző tulajdonság levezethető:
- indexelni is "csak" a pointert tudjuk, az indexelés meg ugye ekvivalens egy címszámítással és egy dereferálással
- a tomb + 5 kifejezés nem azt jelenti, hogy a tömbhöz adunk ötöt, hanem az elejére mutató pointerhez, azaz a tömb ötödik elemére mutató pointert jelenti
- *tomb egy dereferálás, mégpedig a tömb első elemét jelenti
- a címét nem képezhetjük, hiszen ahhoz először pointerré konvertálódik, az így keletkezett temporális objektumnak nem képezhető a címe
- tömbnek nem adhatunk értéket, hiszen a konverzió eredménye temporális objektum, ami C-ben nem balérték
- függvényparaméterként csak úgy adhatjuk át, hogy előtte pointerré konvertálódik
- ha struktúrába rakod, a neki lefoglalt hely természetesen sizeof(tomb) lesz -
dobragab
addikt
Neked az identifier.c-t kell megírnod, amiben van egy megadott deklarációjú függvény, abba bármit include-olhatsz. A feladat nem várja, hogy a ctype.h-t ne használd, sőt.
Üres sor problémára: az üres sort a gets üres sztringként olvassa be (""), így üres sztringként kapod meg a nevet.
Btw szégyen, hogy versenyen a skeleton-ban gets van.
-
dobragab
addikt
Igen, ugyanarról beszéltek. Futásidőben már nem tudható a pointer típusa, de fordítási időben baromi fontos. Onnan tudja a fordító, hogy pointer aritmetika / tömbindexelés esetén hány bájt offset-je van a következő elemnek.
int * a = tomb;
int * b = a + 1; // 4 bájttal tolta arrébb
char * c = "text";
char * d = c + 1; // 1 bájttal tolta arrébbFeltéve, hogy az int 4 bájtos.
-
dobragab
addikt
válasz
dabadab #5549 üzenetére
Igen.
Kicsit off, de hátha segít valakinek, ezért inkább leírom, ha már eszembe jutott.
int temp = 1;
evil_api_function_call(fp, ptr, &temp);C99-ben tudod lokális változónak is képezni a "címét" egy trükkel. Pontosabban: tudsz compound literal segítségével temp tömböt létrehozni egy elemmel, ami viszont már konvertálódik pointerre.
evil_api_function_call(fp, ptr, (int[]){1});
-
-
dobragab
addikt
válasz
aleister #5511 üzenetére
Elvileg VS2015 már (!) támogatja a C99-et is. Lassan ideje volt, elvégre jövőre nagykorú lesz a szabvány. Ennek ellenére C-hez ne használj VS-t, pl. a scanf miatt tuti szívni fogsz, de a szabványt is máshogy értelmezi, mint kéne.
Én egy MinGW-t javaslok, CodeBlocks-szal együtt még kényelmes is.
-
dobragab
addikt
C++-ban a character literal típusa char, mégpedig azért, hogy működjenek az overload-ok (pl. operator<<). Az unáris operator+ igazából semmit nem csinál, csakis azért van, hogy le tudd írni:
int i = +5;
Illetve mégis csinál valamit: minden egész művelet operandusai minimum int-re kasztolódnak fel, és a végeredménye is minimum int. Ezért +'a' már int típusú. Tehát az output C++-ban 14.C-ben a character literal típusa int, az unáris operator+ esetén ugyanúgy megvan az upcast, csak ugye int-ről int-re. C-ben a végeredmény 44.
%zu csak C99-ben és C++-ban van, így C-ben kell az -std=c99. MSVC-t ne használj C-re
Fogadjunk, hogy te a C++-os megoldást mondtad -
dobragab
addikt
válasz
don_peter #5493 üzenetére
Szerintem te a C# topikot keresed.
Ez a bin fájl pedig, mily érdekes, nem szöveges fájl. Nem szöveg van benne. Egy hexa editorban te is meg tudod nézni. HxD a legjobb Windowsos hexa editor szerintem.
-
-
dobragab
addikt
válasz
maestro87 #5481 üzenetére
Ha jól értelmezem, a --FLOAT és a --DOUBLE független egymástól. Azaz ha csak --FLOAT=32-t adsz neki, akkor a double ugyanúgy 24 bites marad, ami szerintem nem vicces. Zavaró lehet, hogy a float pontosabb, mint a double, sőt, szemantikailag is rossz.
Így a float 32 bites értékeket tud tárolni, de számolni csak 24 bittel tud. C szabvány szerint minden lebegőpontos művelet előtt double-re vagy long double-re konvertálódnak az operandusok. Szóval a te esetedben semmit nem ér.
Ha 32 bites lebegőpontos számítás kell, akkor --DOUBLE=32 mindenképp kell. Az a te döntésed, hogy a float-ot meghagyod-e 24 bitesnek, és ahol kell a pontosság, ott double-t írsz float helyett; vagy teszel az egészre és mindkettőt 32 bitesre állítod. Én az előbbit tenném, figyelembe véve a saját kódolási stílusomat. Mindenhol double-t használok, kivéve ott, ahol a memóriával takarékoskodni kell.
-
-
dobragab
addikt
válasz
maestro87 #5473 üzenetére
Nem ismerem a fordítód #pragma-kezelését, de szerintem nem így működik. A #pragma fordító-függő, mindegyik azt csinál vele, amit akar, és a számára értelmezhetetlen #pragma-kat ignorálja. Szóval ha ezt nem tudja értelmezni, akkor is lefordul.
--FLOAT=32
Én úgy értelmeztem a dokumentációt, hogy ezt a parancssori argumentumok között kéne odaadni a fordítónak.
cc whatever.c --FLOAT=32
-
dobragab
addikt
válasz
maestro87 #5468 üzenetére
Vigyázz a formátumsztringgel. A formátumnak egyeznie kell a paraméterként kapott típussal. pl. ha ezt akarod kiíratni:
10 * 10.5
akkor ahhoz %f kell, mert a kifejezés double típusú.
Ha ugyanezt szeretnéd integer-ként (%d) kiíratni, akkor a típust hozzá kell igazítani a formátumsztringhez.
printf("%d", (int)(10 * 10.5));
Új hozzászólás Aktív témák
Hirdetés
● olvasd el a téma összefoglalót!
● ha kódot szúrsz be, használd a PROGRAMKÓD formázási funkciót!
- Intel Core i7 6700K / GTX 1660TI / 16GB DDR4 RAM / 500 GB SSD konfig eladó
- Samsung Galaxy S23 128GB, Kártyafüggetlen, 1 Év Garanciával
- Samsung Galaxy A53 5G 128GB, Kártyafüggetlen, 1 Év Garanciával
- Megkímélt állapotú Xbox Series X 1TB eladó. Kitisztítva és újrapasztázva!
- Gamer PC - i5 13400F, GTX 1080ti és 16gb DDR5
- LG 27UL500-W - 27" IPS - 3840x2160 4K - 60Hz 5ms - HDR10 - AMD FreeSync - 300 Nits - sRGB 99%
- ÁRGARANCIA!Épített KomPhone Ryzen 7 7700X 32/64GB RAM RTX 4070Ti Super GAMER PC termékbeszámítással
- Frederick Forsythe: Isten ökle (nem olvasott)
- Apple iPhone 13 . 128GB , Kártyafüggetlen , 100% akku
- Mire Vágyik a Gamer Szíved? Mi tudjuk! Kamatmentes rèszletre is!
Állásajánlatok
Cég: Promenade Publishing House Kft.
Város: Budapest
Cég: CAMERA-PRO Hungary Kft
Város: Budapest