Hirdetés
- 4K-s okosmonitor huppant le az MSI tervezőasztaláról
- Almás felhangokat pendít meg a Cougar legújabb, E-ATX-es háza
- A kelleténél jobban lebutítja egyes GeForce RTX 5090-es VGA-it a Zotac
- Komoly technikai frissítést kap a Grand Theft Auto V
- És akkor bevillant a nagy ötlet: miért ne lehetne hűteni egy tápcsatlakozót?
- Nvidia GPU-k jövője - amit tudni vélünk
- AMD Ryzen 9 / 7 / 5 7***(X) "Zen 4" (AM5)
- NVIDIA GeForce RTX 5070 / 5070 Ti (GB205 / 203)
- Kompakt vízhűtés
- Intel Core Ultra 3, Core Ultra 5, Ultra 7, Ultra 9 "Arrow Lake" LGA 1851
- Házimozi haladó szinten
- Apple MacBook
- Milyen házat vegyek?
- SSD kibeszélő
- Monitorkalibráló eszközök
Új hozzászólás Aktív témák
-
nevemfel
senior tag
-
pmonitor
aktív tag
válasz
sztanozs #6195 üzenetére
Bármennyire is adott azonban a lehetőség a Goto használatára, ne használjuk. Nincs olyan probléma, amely ne lenne megoldható nélküle is, használatával azonban áttekinthetetlenné válik a programunk, és ezzel a hibalehetőségek száma növekszik.
Továbbá:
A Goto parancs sok nyelvben létezik, használatát azonban el kell kerülni. Léteztek olyan ősnyelvek, amelyekben nélkülözhetetlen volt, a mai magasszintű nyelvekbe azonban többnyire hagyománytiszteletből került be, nincs rá szükség. Léteznek olyan nyelvek is, amelyekből hiányzik ez a parancs.
Ezért hasonlítom össze a C-t meg a Pascalt(meg minden olyan nyelvet, amiben létezik). Mindenesetre a fenti idézetek sem Stroustrup nézőpontját hangoztatják, hanem László Józsefét. Sőt, a második idézet egyértelműen kimondja, hogy léteznek olyan nyelvek is amelyekből hiányzik. Ezek szerint azokban a nyelvekben nem is lehet programozni, igaz?
-
Aki tanított neked az egyetemen kívül nem dolgozott. A papír/publikáció sok mindent elbír.
Ha bármelyik nyelvi elemet nem úgy használod ahogy kell, akkor is olvashatatlan és debuggolhatatlan lehet a kód.
Nem hiszem, esetleg WSL-ben mehet, azt próbáltad már?
Windows-on fejleszteni
.
-
pmonitor
aktív tag
válasz
sztanozs #6193 üzenetére
Az első mondatom meg szerintem nem értetted meg. Azt a goto-ra írtam.
Csak azért leírtam, hogy komoly könyv írója is tiltja a goto-t nem véletlenül.
Meg leírtam, hogy ezzel virtuálisan jól összeugrasztottam Stroustrup-ot és László Józsefet.Még a szakik sem értenek mondjuk egyet. De László József nem egy könyvet írt meg goto nélkül. Ez azért valamit csak jelent, nem?
-
-
pmonitor
aktív tag
válasz
sztanozs #6188 üzenetére
A break nem goto. Nem lehet vele visszafelé ugrani, meg if-es szerkezetekből sem tudsz kilépni vele.
Ebben a könyvben László József a következőket írja(többek között):
>A Pascal programokban betartunk még néhány hasznosnak vélt egyéb konvenciót is:
1: Angol elnevezést adunk az eljárásoknak, függvényeknek, típusoknak, változóknak, stb.,
.
3: A megjegyzéseket magyarul írjuk, lehetőleg minél tömörebben,
.
5: A goto utasítást a Pascal-ban nem használjuk, mert ugye programozók vagyunk.Na, most virtuálisan jól összeugrasztottam Stroustrup-ot és László Józsefet.
[ Szerkesztve ]
-
pmonitor
aktív tag
válasz
gregory91 #6185 üzenetére
A continue tiltásán 1 kicsit én is csodálkozom. Ami okot adhat erre, az talán az, hogy a ciklusnak alapvetően 2 lényeges pontja van: az eleje és a vége. A continue ezt rúgja fel. Gyakorlatilag így több (kis)ciklus lesz a (nagy)ciklusban, ami egyébként elkerülhető. Sztem ez lehet valamiféle ok a tiltására. De mondjuk ezt én nem venném fel a "soha" kezdetű listámra.
-
pmonitor
aktív tag
válasz
dabadab #6165 üzenetére
Stroustrup írta:
>A "soha ne tegyük ezt" alakú szabályokat haszontalannak tekintem.Ez általában igaz, viszont teljesen nem értek vele egyet. Hozzátenném, hogy azért nem ilyen sok van. 2 fő ökölszabály viszont biztos létezik a programozásban:
1.: SOHA ne használjunk gotot. A Szekvencia - Szelekció - Iterácó hármassal mindent meg lehet oldani. Nincs szükség goto-ra.
2.: Ha van egy típus, és létezik hozzá olyan függvény/metódus, hogy a konvertál(string s) az adott típusra alakítja a stringet, akkor ezt a konvertál() függvényt/metódust MINDIG használni kell, mielőtt műveletet végzünk vele. -
pmonitor
aktív tag
-
dabadab
titán
válasz
nevemfel #6179 üzenetére
Ez egészen rettentes, szerintem.
Az eredetinek van egy teljesen normális logikája, hogy sorban megy végig a lépéseken és ha bármelyik nem sikerül, akkor game over. Ez meg gondos átolvasást igényel, hogy az ember rájöjjön, hogy mi is történik itt - mert maga a struktúra azt sugallja, hogy háromféle, nagyjából egyenértékű dologgal próbálkozunk, amiből az egyiknek kellene sikerülnie.
[ Szerkesztve ]
-
-
nevemfel
senior tag
válasz
dabadab #6178 üzenetére
Ez se okés így? :
static int kvm_vcpu_check_block(struct kvm_vcpu *vcpu)
{
int ret = 0;
int idx = srcu_read_lock(&vcpu->kvm->srcu);
if (kvm_arch_vcpu_runnable(vcpu)) {
kvm_make_request(KVM_REQ_UNHALT, vcpu);
ret = -EINTR;
} else if (kvm_cpu_has_pending_timer(vcpu)) {
ret = -EINTR;
} else if (signal_pending(current)) {
ret = -EINTR;
}
srcu_read_unlock(&vcpu->kvm->srcu, idx);
return ret;
}[ Szerkesztve ]
-
pmonitor
aktív tag
válasz
dabadab #6175 üzenetére
Így?
static int kvm_vcpu_check_block(struct kvm_vcpu* vcpu)
{
int ret = 0;
int idx = srcu_read_lock(&vcpu->kvm->srcu);
int ex = 0;
if (kvm_arch_vcpu_runnable(vcpu)) {
kvm_make_request(KVM_REQ_UNHALT, vcpu);
ret = -EINTR;
ex = 1;
}
if (!ex && kvm_cpu_has_pending_timer(vcpu))
{
ret = -EINTR;
ex = 1;
}
if (!ex && signal_pending(current))
{
ret = -EINTR;
}
srcu_read_unlock(&vcpu->kvm->srcu, idx);
return ret;
} -
dabadab
titán
Ezzel (meg nevemfel megoldásával) elég nyilvánvalóan az a gond, hogy olyan függvényeket is meghívsz, amiket nem kellene (szabadna) és a kód azt mondja, hogy az, hogy h a vcpu nem runnable, az még tök oké, mert attól még csinálhatunk itt dolgokat, noha ennek pont az ellenkezője a helyzet.
[ Szerkesztve ]
-
nevemfel
senior tag
Én is így okoskodtam:
static int kvm_vcpu_check_block(struct kvm_vcpu *vcpu)
{
int ret = 0;
int idx = srcu_read_lock(&vcpu->kvm->srcu);
if (kvm_arch_vcpu_runnable(vcpu)) {
kvm_make_request(KVM_REQ_UNHALT, vcpu);
ret = -EINTR;
}
if (kvm_cpu_has_pending_timer(vcpu) || signal_pending(current)) {
ret = -EINTR;
}
srcu_read_unlock(&vcpu->kvm->srcu, idx);
return ret;
}
(ez a kódformázás, ehh...)
[ Szerkesztve ]
-
pmonitor
aktív tag
válasz
dabadab #6171 üzenetére
De sztem ki lehet az ilyeneket szervezni az ilyent külön függvénybe, és akkor tovább egyszerűsíthető. Azért a gyakorlatban ilyen nem nagyon fordul elő. A papír(vagy a monitor
) mindent elbír.
Szerk.: ja látom Livius gyorsabb volt. Mondtam, hogy csak szervezés kérdése. Csak nem én szerveztem jól.
[ Szerkesztve ]
-
Livius
őstag
válasz
dabadab #6169 üzenetére
Én ilyenkor inkább így szoktam:
static int kvm_vcpu_check_block(struct kvm_vcpu *vcpu)
{
int ret = 0;
int idx = srcu_read_lock(&vcpu->kvm->srcu);
if (kvm_arch_vcpu_runnable(vcpu)) {
kvm_make_request(KVM_REQ_UNHALT, vcpu);
ret = -EINTR;
}
if (kvm_cpu_has_pending_timer(vcpu))
{
ret = -EINTR;
}
if (signal_pending(current))
{
ret = -EINTR;
}
srcu_read_unlock(&vcpu->kvm->srcu, idx);
return ret;
}Persze ekkor az nincs lekezelve, hogy a többi if-et kihagyja a returnbe érés előtt, ez kérdés szabad-e ebben a Linux driverben.
[ Szerkesztve ]
-
pmonitor
aktív tag
válasz
dabadab #6169 üzenetére
Ha minden igaz így hirtelen:
static int kvm_vcpu_check_block(struct kvm_vcpu *vcpu)
{
int ret = -EINTR;
int idx = srcu_read_lock(&vcpu->kvm->srcu);
if (kvm_arch_vcpu_runnable(vcpu)) {
kvm_make_request(KVM_REQ_UNHALT, vcpu);
srcu_read_unlock(&vcpu->kvm->srcu, idx);
return ret;
}
if (kvm_cpu_has_pending_timer(vcpu) || signal_pending(current)) {
srcu_read_unlock(&vcpu->kvm->srcu, idx);
return ret;
}
ret = 0;
srcu_read_unlock(&vcpu->kvm->srcu, idx);
return ret;
}[ Szerkesztve ]
-
dabadab
titán
válasz
pmonitor #6168 üzenetére
Akkor tessék, demonstráld:
static int kvm_vcpu_check_block(struct kvm_vcpu *vcpu)
{
int ret = -EINTR;
int idx = srcu_read_lock(&vcpu->kvm->srcu);
if (kvm_arch_vcpu_runnable(vcpu)) {
kvm_make_request(KVM_REQ_UNHALT, vcpu);
goto out;
}
if (kvm_cpu_has_pending_timer(vcpu))
goto out;
if (signal_pending(current))
goto out;
ret = 0;
out:
srcu_read_unlock(&vcpu->kvm->srcu, idx);
return ret;
} -
pmonitor
aktív tag
válasz
dabadab #6165 üzenetére
> vagy minden helyre külön odakopipészteled a felszabadítást, vagy mindenhonnan a végére gotozol.
Mindenképpen mindenhová kell kopipésztelned vagy a gotot, vagy a felszabadítást. De sztem. ha ilyenre sor kerül a gyakorlatban, ott nem jól tervezték meg a logikai hálózatot. Biztos vagyok benne, hogy a megfelelő if-ek megválasztásával ha nem is teljesen, de nagyon nagy mértékben megszüntethető a sok helyről történő kilépés a függvényből. Max. 2 helyre nyugodtan lehet kopizni a felszabadítást is. De az is lehet, hogy megfelelő szervezéssel még a 2 helyet is le lehet redukálni egyre(de erre a fejemet nem teszem).
-
Livius
őstag
válasz
dabadab #6165 üzenetére
A mi C-ben írt CVI projektünkben egyelőre még ez a +10 év alatt jól volt kezelve az ilyen, hogy nincs szükség sehol calloc vagy malloc-ra és azok felszabadítására, tehát amit írsz példát nincs szükségünk rá nagyon, de ettől független láttam már benne go to-t olyan helyen, ahol csak a megértést nehezítette, de azt amit írsz előnyt semmit sem adott.
-
dabadab
titán
Valamint ELTE IK C/C++ gyakorlaton instant évismétlés járt a go to és continue használatért, és értettem hogy miért, miután egyszer valaha valami tele go to-zott programot kellett debugolnom, és visszafejtenem. Fenntarthatatlan és karbantarthatatlan lesz a program tőle.
A hülyén használt gototól. Ez pont olyan, mint amikor idióta magyartanárok előveszik a "macska fel van mászva a fára" mondatot, hogy ezzel szemléltessék, hogy magyarban miért nem szabad szenvedő szerkezetet használni - csak hát valójában a magyarban a szenvedő szerkezet teljesen rendben van, a macskás példával az a gond, hogy pont azt semmilyen nyelven sem mondják szenvedőben, mert az úgy hülyeség (angolul se mondaná senki, hogy "the cat is on the tree climbed").
A jól használt goto a C-ben az a jól olvasható kódhoz sok esetben gyakorlatilag elkerülhetetlen. Tipikus példája az, amikor egy függvény több helyen érhet véget, de mindenképpen fel kell szabadítani resource-oket. Ezt mondjuk C++-ban tök faszán lehet csinálni RAII-vel meg finallyvel C#-ban, de azok tök más nyelvek. C-ben nincs ilyen, ott vagy minden helyre külön odakopipészteled a felszabadítást, vagy mindenhonnan a végére gotozol. Egyértelmű, hogy az utóbbi megoldás az, ami olvashatóbb és ami kevesebb hibalehetőséggel jár.
A C az gyakorlatilag hordozható assembler, ennek megfelelően kell hozzáállni, aki ott azt mondaná, hogy a JMP használatát el kell kerülni, azt kiröhögnék.
-
Livius
őstag
válasz
buherton #6163 üzenetére
Ez a coding style vagy coding rules az NI LabWindows CVI-ban programozott GUI-s projekthez kell (rémisztően csak C-ben lehet használni ezt a GUI-s frameworköt). Én eddig a neten mindenhol azt olvasom és azt tanították nekem, hogy a globális változó egy nagy programban már szigorúan kerülendő (itt már nem 8 bites microcontroller a cél HW), jelenleg ahova kellene az már egy nagy program, tele káosszal már sajnos. Valamint ELTE IK C/C++ gyakorlaton instant évismétlés járt a go to és continue használatért, és értettem hogy miért, miután egyszer valaha valami tele go to-zott programot kellett debugolnom, és visszafejtenem. Fenntarthatatlan és karbantarthatatlan lesz a program tőle.
Az Ericsson-os codechekker az Windwos 10-en is életre kelthető? Ez a CVI fordító és IDE csak Windows 10-en megy, ebben megy a napi munka.
[ Szerkesztve ]
-
Bár C++, de nagyon jó: [Google C++ style guide]
Coding rules: [SEI CERT C]
Hogy ellenőrizni is tudd a kódot: [CodeChecker]
A globális változókat és a gotot kategorikusan elutasítani elég buta dolog. Hatékony eszközök bizonyos problémák megoldásához.
-
Livius
őstag
Asztali PC-és C programozáshoz tudtok linkelni valami bevált nagy techcégek által is használt coding rules-t vagy coding style-t? A neten tele van minden +20 éves beágyazott rendszerekhez kitalált coding style-okkal, de nagyon nem olyan kéne, hanem ami inkább Windows PC-és környezethez van és C-hez azon belül is C99 vagy újabbhoz.
Olyan féle is jól jönne, ami nem csak a nevezéktanról ír, hanem általános programozási alapelvekről is, hogy pl kerüljük a globál változókat, meg tiltott legyen a go to használat stb.
-
pmonitor
aktív tag
válasz
sztanozs #6160 üzenetére
Nem pejoratív értelemben gondoltam, amit írtam. Csupán azt jelenti, hogy aki ezt írja magáról: "Elkezdtem csak úgy érdeklődés szinten c-t tanulni mert érdekel. Az elején vagyok nagyon"
Ha ő megérti, akkor nagyon tehetséges. Ezt értettem a "viheti valamire" alatt. Egyébként az sem baj, ha most nem érti meg, és később visszanéz(és akkor gondolkodik el rajt). Viszont az olvasók között is lehet olyan, aki már eljutott odáig, hogy magától nem jutna eszébe, de ha így látja, akkor egyrészt megérti a működését, másrészt hogy mely esetekben célszerű ezt a formát használni. Sztem. az olvasókat kevesen emlegetik(talán senki), pedig többen vannak, mint akik ide írnak. Pl. itt is szóba került, hogy a kérdező kezdő, azért nem kellene kész megoldást adni. Az ilyenre írom, hogy azért olvasók is vannak, akik már megértik a másfajta megoldást is. Nem biztos, hogy mindig csak a kérdezőt kellene nézni. De a kódot "konyhanyelven" pszeudo kóddal is le lehet írni, ha valaki nem akar teljesen kész kódot adni. -
pmonitor
aktív tag
válasz
gregory91 #6150 üzenetére
Kicsit másképp
int main()
{
char name[20];
char chars[5] = { 'a','b','c','d','e' };
int yes = 0;
printf("Enter name: ");
scanf("%s", name);
int max[2] = { (int)(sizeof(name) / sizeof(char) - 1), (int)(sizeof(chars) / sizeof(char) - 1) };
int index[2];
int n = 1, act = -1;
int ok = 1;
do
{
while (act < n)
{
++act;
index[act] = 0;
}
if (name[index[0]] == chars[index[1]])
{
ok = !ok;
break;
}
while (act > -1)
{
if (index[act] < max[act])
{
++index[act];
break;
}
else --act;
}
} while (act > -1);
if (ok) printf("Name: %s\n", name);
else printf("Not a valid name!\n");
return 0;
} -
gregory91
senior tag
Csak úgy érdekességként:
#include <stdio.h>
int main (){
char name[20];
char chars[5]={'a','b','c','d','e'};
int yes=0;
printf("Enter name: ");
scanf("%s",name);
for(int i=0;i<sizeof(name)/sizeof(char);i++){
for(int j=0;j<sizeof(chars)/sizeof(char);j++){
if(name[i]==chars[j]){
yes=1;}
}
}
printf("%s",yes?"YES\n":"NO\n");
printf("%ld name",sizeof(name)/sizeof(char));
printf("%ld chars",sizeof(chars)/sizeof(char));
return 0;}[ Szerkesztve ]
-
pmonitor
aktív tag
Én csak tanulmányozásra írtam a kódot, hogy az strstr() miért is nem működik karakterekre. Mert a karakter nem kezelhető strstr()-el. Viszont a ciklust nem tudod elkerülni, akár az ststr()-t, akár az strchr()-t használod. Egyébként én is elkövettem 1 hibát. A break-re nincs szükség, mert az elején a feltételben vizsgálom.
-
kovisoft
őstag
Ha karaktereket keresel egyesével stringben, akkor javaslom az strchr() használatát strstr() helyett, mert az strstr()-nek keresőstringet kell megadni, ezért nem fog működni const char restrictions[5] = {'a', 'b', 'c'} formával. Ezt láthatod is pmonitor kódjában, ha majd megnézed.
-
kovisoft
őstag
Azért nem működik így, mert az strstr() egy összefüggő rész-stringet keres meg az adott stringben, te pedig azt szeretnéd, hogy a megadott karaktereket külön-külön nézze meg, hogy benne vannak-e valahol a stringben, nem feltétlenül összefüggően és nem feltétlenül ugyanabban a sorrendben. Pl. ha "abc"-t keresel, azt az strstr() megtalálja az "aabcc"-ben, de nem találja meg az "aabbcc"-ben, mert ez utóbbinak az "abc" nem rész-stringje.
Azt kell csinálnod, hogy egy ciklussal végigmész a restrictions[] karakterein, és mindegyikre megnézed, hogy benne van-e a name-ben az adott karakter.
Szerk: lassú voltam
[ Szerkesztve ]
-
pmonitor
aktív tag
int main()
{
const char name[20];
const char restrictions[7] = "a\0b\0c\0";
printf("Enter name: ");
scanf("%s", name);
int i, ok = 1;
for (i = 0; restrictions[i] && ok; i += 2)
{
if (strstr(name, &restrictions[i]) != NULL)
{
ok = !ok;
break;
}
}
if (ok) printf("Name: %s\n", name);
else printf("Not a valid name!\n");
return 0;
}[ Szerkesztve ]
-
Szőrös
veterán
Sziasztok, kis segítséget kérnék.
Elkezdtem csak úgy érdeklődés szinten c-t tanulni mert érdekel. Az elején vagyok nagyon, gyakorlásképpen csináltam egy kis kódot:#include <stdio.h>
#include <string.h>
int main ()
{
const char name[20];
const char restrictions[5] = "c";
printf("Enter name: ");
scanf("%s", name);
if (strstr(name, restrictions) != NULL)
{
printf("Not a valid name!\n");
} else
printf("Name: %s\n", name);
return 0;
}Bekér egy nevet és megadott karakter esetén kiírja, hogy az nem megfelelő.Ezt szeretném tovább bővíteni úgy, hogy több nem megengedett karakter legyen. Úgy gondoltam ezt talán tömbbel lehet szóval a
const char restrictions[5] = "a" sort átírtam így const char restrictions[5] = {'a', 'b', 'c'}
na így viszont már nem igazán akar működni. Valaki tud elvi iránymutatást adni, hogy ez miért nem jó? Tömbbel már nem működik igy az strstr? Köszi[ Szerkesztve ]
-
kovisoft
őstag
válasz
DopeBob #6140 üzenetére
Megpróbáltam lefordítani az eredeti kódodat, de nekem (treat warnings as errors beállítással) fordítási hibát dobott a scanf és a printf sorokra. Érthető, mivel az int (*statData)[statDay][OPEN_HOURS] egy kétdimenziós tömbre mutató pointer, nem pedig egy kétdimenziós tömb. A statData[i][j] nem egy int-et, hanem egy pointert jelent. Cast-olással kierőszakoltam, hogy leforduljon, valamint felcseréltem a statData deklarációjában a sorokat és az oszlopokat (int (*statData)[OPEN_HOURS][statDay]), és így már ez a változat is működött.
Ökölszabályként azt tartsd szem előtt, hogy amikor egy pointert deklarálsz, akkor azt tömbként is tudod használni (meg tudod indexelni [i] stílusban), tehát úgy is felfogható a dolog, hogy egy * ugyanúgy hozzáad egy dimenziót a deklarált tömbödhöz, mint egy [SIZE]. Fordítva is igaz a dolog: egy tömb utolsó dimenzióját lehagyva egy pointert kapsz.
Vagyis amikor ezt írod le: int (*statData)[OPEN_HOURS][statDay], akkor ez igazából egy 3 dimenziós tömb, aminek az első két dimenziója a fix [OPEN_HOURS] és [statDay], a harmadik dimenziója dinamikus, és ennek mérete a malloc-ban megadott értékből jön, ami jelen esetben [1] (mivel a teljes allokált méret OPEN_HOURS*statDay*1). Éppen ezért az így deklarált tömb elemeire ezen a módon kell hivatkozni: statData[i][j][0]. Kipróbáltam ezt is, és így is működik. Ezzel együtt nem javaslom ennek a formának a használatát, és nem is értem, hogy a Pluralsight miért így tanítja.
-
kovisoft
őstag
-
DopeBob
addikt
válasz
kovisoft #6137 üzenetére
Ah, megvan, azt nem állítom, hogy pontosan értem de működik:
Ez nem jó:
int (*statData)[statDay] = malloc(sizeof(int[statDay][OPEN_HOURS]));
Ez ok, szépen lehet indexelni, adatok a helyükön.
int (*statData)[OPEN_HOURS]= malloc(sizeof(int[statDay][OPEN_HOURS]));
Nagyon köszi a segítséget
-
kovisoft
őstag
válasz
DopeBob #6138 üzenetére
Amikor egy szimpla 1 dimenziós tömböt allokálsz, akkor azt egy szimpla pointerbe rakod bele:
int *array = malloc(sizeof(int[ARRAY_SIZE]));
És utána array[i]-vel hivatkozol az elemeire. Ha ezt ki akarjuk terjeszteni 2 dimenzióra, akkor hozzáteszünk mindkét oldalhoz +1 dimenziót, de miért tennénk +2 dimenziót a bal oldalhoz?
int (*twod_array)[COLUMNS] = malloc(sizeof(int[ROWS][COLUMNS]));
Így a twod_array egy olyan pointer, ami "COLUMNS db integerből álló tömb" típusú adatra mutat, ilyenekből allokáltunk ROWS db-ot, és twod_array[i][j]-vel hivatkozunk az elemeire. Legalábbis szerintem így kell, de bevallom, nem próbáltam ki.
Viszont mint írtam, csinálhatod azt is, hogy te számolod át a 2 dimenziós indexet 1 dimenziósra, ekkor elég egy nagy 1 dimenziós tömböt allokálni:
int *simulated_twod_array = malloc(sizeof(int)*ROWS*COLUMNS);
Aztán így hivatkozol az i. sor j. oszlopára: simulated_twod_array[i*COLUMNS+j].
-
DopeBob
addikt
válasz
kovisoft #6137 üzenetére
Megnézem, de ennél a résznél kezdem elveszteni már a fonalat
Pluralsight-on csinálom a C képzéseket, pont azt monta az oktató ennél a résznél, hogy ez a legegyszerűbb módja mert egyszerű utána felszabadítani a memóriát, és ugyan úgy lehet hivatkozni egy elemet, ahogy statikus 2D tömbnél. Neten- YT-n mindenhol a for ciklussal feltöltögetős verziót láttam, azért örültem meg ennek, de hát nem megy.
Amit írtál azt hogy kell elépzelni, nem teljesen értem. Egy sort ki tudok választani egy pointerre és egy elemet egy indexel?
[ Szerkesztve ]
-
kovisoft
őstag
válasz
DopeBob #6136 üzenetére
Szerintem a malloc sorral van a gond. Ahogy írtad, úgy eggyel több az indirekció a bal oldalon (pointer egy két dimenziós tömbre, ami így egy három dimenziós tömbbel lesz analóg). Helyette ez kellene:
int (*statData)[statDay] = malloc(sizeof(int[statDay][OPEN_HOURS]));
Másik lehetőség, hogy egy dimenziós tömböt használsz (szimpla pointert allokálsz) és [i*OPEN_HOURS+j] formában indexeled.
És a free-nél sem kell a csillag, csak simán free(statData).
-
DopeBob
addikt
Sziasztok, valaki ránézni, hogy mit rontok el? Nem jövök rá mi a baj. Az is lehet, hogy több sebből vérzik a dolog, egy ismerősnek próbálok segíteni vizsgára készülni, de hát eddig vak vezet világtalant
Első félében C-vel veszik a kedvüket egy életre a programozástól (gépész ráadásul)
Egy 2D-s tömböt kéne feltölteni, ez lenne egy feladat eleje. A sorok számát kell bekérni, oszlop szám adott, és utána az értékeket.
#include <stdio.h>
#include <stdlib.h>
#define OPEN_HOURS 5
int main (void) {
int statDay = 0;
printf("Hany nap adatait visszuk be? ");
scanf("%d", &statDay);
int (*statData)[statDay][OPEN_HOURS]= malloc(sizeof(int[statDay][OPEN_HOURS]));
for (int i = 0; i<statDay;i++) {
for (int j = 0; j<OPEN_HOURS;j++) {
printf("Kerem az %d. nap %d elemet: \n", i,j);
scanf("%d", &statData[i][j]);
}
}
printf("\nKiiras\n");
for (int i = 0; i<statDay;i++) {
printf("%d. nap:\t", i);
for (int j = 0; j<OPEN_HOURS;j++) {
printf("(%d;%d) %d\t", i,j, statData[i][j]);
}
printf("\n");
}
free(*statData);
return 0;
}
Látszólag működik is a dolog, de a tömbben rossz helyre kerülnek az értékek és nem jövök rá miért. Ha pl 0. napra 0, 1, 2... az 1. napra 10, 11, 12-t írok akkor ezt kéne kiírnia:0: 0 1 2 3 4
1: 10 11 12 13 14de helyette ez van:
0. nap: 0 1 2 10 11
1. nap: 10 11 12 20 21
2. nap: 20 21 22 23 24
0. napon 3 és 4 helyett 10 és 11 van, 1. napon 13 és 14 helyett 20 és 21...
-
Livius
őstag
Sziasztok!
Lenne egy Linux C/C++ programozási kérdésem, de lehet nem is annyira a C/C++ nyelv a lényeg benne, Linux kernel v4.x-et használok.A kérdés az, hogy amikor C/C++-ban a pthread.h-et használva indítok egy plusz threadet FIFO ütemezésben úgy, hogy előre attribútumban beállítom neki a CPU affinitást minden magra, a futás közben ezt a Linux hogy fogja figyelembe venni és kezelni? A thread amit indítok egy végtelen ciklusban figyelget egy thread-safe queue-t, és amikor van valami új elem azt kiveszi, majd csinál vele egy két műveletet, aztán megint blockolva várja a következőt. Ez a szál teljesen jól működik, kb 3-4%-os CPU használatot eredményez, de számomra nagyon gyanús az, hogy mintha a Linux véletlenszerűen indítaná az egyik magon a sok közül ezt a threadet, és utána örökké, csak azon a magon futtatja, vagyis a blockolás feloldása után mintha sose lenne olyan, hogy a másik magra kerülne át a futtatása, pedig a másik magon több szabad CPU idő lenne láthatóan htop-ban. Tud valaki valami infót vagy valami jó linket, hogy valami nagy könyv/biblia szerint a több magot is használható threadeknek hogy kéne managelődni a Linuxban a CPU magok között?
-
gregory91
senior tag
-
kovisoft
őstag
válasz
Sültbanán #6132 üzenetére
Így van, ez pl. egy lehetséges megoldás. De a config.h a többi olyan include előtt legyen, ami használja a TEST makrót.
A lényeg, hogy amelyik .c-ben (vagy .c-be include-olt .h-ban) használni akarod a makrót, oda előtte már valahogy bekerüljön. Amit közvetlenül a main.c-be írsz be, azt nem látja az elso.c vagy a masodik.c. Tehát vagy mindegyik .c-be beírod a definíciót, vagy egy olyan .h-ba, ami include-olva van mindegyik .c-be. Nyilván ez utóbbi a szebb megoldás. A .c-be olyan esetben célszerű beírni, ha ettől a makrótól függ valami működés, és különböző .c-kben eltérő definícióra van szükség (pl. egyik .c-ben a TEST értéke 0, egy másikban 1).
-
Sültbanán
friss újonc
Sziasztok,
Egy kis segítség kellene, sehogy sem tudom megoldani, hogy amint a main.c fájlban definiáltam makrót az elérhető legyen egy include-ban lévő include-ban.
pl.:
main.c:
#include "elso.h"
#define TEST 0
void main(void)
}
bla-bla
}
elso.h:
#ifndef masodik.h
#include "masodik.h"
#endif
És ha a masodik.c -ben hivatkozok a TEST makróra akkor azt a hibát dobja, hogy nincs definiálva. Szóval elso.c -ben még elérhető a makró de a második.c-ben már nem...
Valami tanács?
-
coco2
őstag
Az itt jelenlévők közül futott már valaki köröket a [WolfSSL] libbel ? Főleg linuxon szerver oldali aszinkron stílusban. Dokumentáltabbnak tűnik, mint az openSSL, de a felépítési alapelve szerintem gyengébb (összedrótozták a platformra jellemző socket kezelést a cipherrel ahelyett, hogy csak egy független cipher libet adnának), és kérdéses, hogy tényleg minden részletet kidolgoztak-e.
[ Szerkesztve ]
-
coco2
őstag
A jelek szerint csak akkora a kép. Mindössze kíváncsiságból kérdeztem meg utána kotorni, hogy ugyan mi oka lehet valahol a népeknek azt a szintaktikát használni. Ha szétszedik a fejlécet változónként egy sorra, ugyan úgy rugalmasabban szöveg-szerkeszthető eredményt kapnak, és áttekinthetőbben.
-
-
kovisoft
őstag
1/
int sub();
Ez egy forward declaration, arra szolgál, hogy ha majd csak később lesz ténylegesen definiálva a függvény, amit már előtte használni akarsz, akkor ebből tudja a fordító, hogy milyen argumentumai vannak és milyen típusú értéket ad vissza. Mivel te áthelyezted a sub() függvényt a main() elé, így a te változatodban nincs rá szükség.2/ Egy függvény argumentumait deklarálhatod úgy is, hogy rögtön odaírod a nevük elé a típusukat, de úgy is, hogy csak a nevüket írod a zárójelbe, a típusukat ekkor külön meg kell adni a zárójel után és a nyitó kapcsos zárójel előtt. Jelen esetben a fun() függvénynek egy par nevű argumentuma van, aminek a típusa egy int-et visszaadó argumentum nélküli függvénypointer. Ennek lesz majd átadva a sub() itt:
fun(sub)
-
Helló, egy tweetben láttam egy ilyet:
A kód picit csinosítva ez:
#include <stdio.h>
int fun(par)
int (*par)();
{
return (*par)();
}
int sub()
{
return 12;
}
int main()
{
int sub();
int var = fun(sub);
printf("%d", var);
}Dolgok, amiket nem igazán értek:
1/int sub();
Ez gondolom függvénypointer definiálás akar lenni, de akkor nem kellene csillagozni?
2/ Az elején nem értem azt a konstrukciót:int fun(par)
int (*par)();
Ez mi az isten? Tehát ha le van zárva pontosvesszővel, akkor utána miből returnölünk? -
coco2
őstag
Létezik fizetős licencelt C SSL sdk?
-
coco2
őstag
válasz
buherton #6115 üzenetére
Köszönöm a példa linket.
Van esetleg olyan szerver / kliens példa is valahol, ahol a server ténylegesen működik végtelenített echo funkcióval, és minden lépésnél kiírja, ami kliens oldalról éppen érkezett? A linkelt példa csak külső héj, tényleges adatkezelés nincs benne, csak a berkeley socket alapjai, amit megtalálok bárhol.
Az sha-nak a stream kódoláshoz folyamatosan változó kódolási állapota van. Az ember azt hinné, hogy a socketnak van egy kontextus állapota, amit tudni kell menteni / visszatölteni abban az esetben, ha egy thread-en nem csak egy socket-ot kezelek, hanem sokat. Vajon olyan példa is akadhat valahol?
-
Úgy kell neki állni, mint egy normál programozási feladat. Nézzük meg mit csinált más
.
Mielőtt beleugranál a programozásba érdemes kézzel kipróbálni azt, amit végül csinálni akarsz. Ehhez először olvass el néhány releváns how-to-t. Ezzel ki fogod ismerni magad a kulcsok világában és hogy az openssl-el ez hogyan működik. És megismered a hibaüzneteket, no meg azok formátumát
.
Ha ez megvan akkor érdemes megnézni a példa programokat. Például: Darrenjs [link]
A githubon találtam még régebben valahol egy nagyon jó example-t, amiben több formátumú kulcsra is voltak különféle példák.
Az openssl-nek van a neten dokumentációja, de szerintem rossz az elnevezés, mert az inkább egy referencia.
[ Szerkesztve ]
-
coco2
őstag
@kovisoft @buherton:
Most kotortam végig openssl doksikat amazonon, és nincs egy deka jelenkori könyv sem az sdk-ról
Kellene egy tapasztalt tanács. Ha amúgy nem vagyok agyhalott programozáshoz, meg dokumentációk megértéséhez, mennyi időt fogok vélhetően rászánni, mire átlátom, hogy mit tud a lib és mit nem?
-
-
kovisoft
őstag
A linkelt thread safety problémák az 1.0.x openssl verzióra vonatkoznak, de 1.1.0 óta már nem kell locking callbackeket definiálni.
-
coco2
őstag
Sziasztok!
TLS libekkel van valakinek közelebbi ismeretsége?
Egy közepes teljesítményű tcp szervert raknék össze (jellemzően linux), és ha lehet, C libeket használnék. Amit neten találni tudtam viszonylag friss nevet, az az openssl, de a c sdk-ja környékén (pld wiki page-en [link] ) olyan hírek vannak, hogy nem thread-safe a design, és az csúnya hátrány. Kellene nekem tcp stream codernek legalább 6-8 szál folyamatosan. Nem ártana egy normális összefoglaló leírás is, mert szálazni c-ben találomra - szóval az azért nem egészen úgy megy.
Ha valaki már küzdött meg hasonló problémával, örülnék az utólagos statisztika tapasztalatának. Az alternatíva dotnet core-t használni, de lévén temérdek sok apró csomagot kell majd kezelni, a gc nagyon csúnya hátrány lenne, a dot c-t azért hanyagolnám.
-
-
#90088192
törölt tag
válasz
#90088192 #6108 üzenetére
Most már értem, a karakter kiírásban, az y_offset a koordinatat határozza meg, a string kiiaratasban, meg ugye léptetését kell csinálni, hogy ne egymásra írja a karaktereket. Vagyis SZVSZ nem tudok vele semmit csinálni, hiszen van ahol csak 1db karaktert akarok kiiratni, akkor pedig nem működne ha jól sejtem
-
kovisoft
őstag
válasz
#90088192 #6106 üzenetére
Arra gondoltam, hogy egy korábbi hozzászólásodban így hívtad meg a write_char-t:
for(j=0;j<=i-1;j++) write_char(line,y_offset+j*Font_width,test[j]);
És ebben a második paraméterben használod a Font_width-et is, ezt lehetne kiiktatni, ha egy struktúrában úgyis átadod a font paramétereket. Ehhez át kellene alakítani egy kicsit a paraméterezést (pl. ahogy javasoltam: kettéválasztani egy y és egy j paraméterre, és a write_char függvényen belül elvégezni az y+j*Font_width számolást).
-
#90088192
törölt tag
válasz
kovisoft #6105 üzenetére
Köszönöm
Az y_offset át kell hogy nevezzem mert megtévesztő, ez az x tengelyen való eltolást jelöli, semmi dolga nincs magával a fonttal, vagy nem teljesen értelek
Próbáltam utána olvasni a struktúrának, egyenlőre nem vagyok vele meg kibékülve, de dolgozom rajta
A másik dolog amin ügyeskedek, a font magassága se jelentsen problémát, vagyis képes legyek több memória lapra kivetítve is elküldeni az adatokat. Arra mar rá jöttem, a font sima decimálisban van(olyat találtam mind a 16 bit egy számot alkot, ami a magasságát teszi ki a karakternek), akkor egyszer 8 pozíciót jobbra, máskor 8 pozíciót balra kell tolni és maris megvan a 8-8 bit, vagy legalábbis remélem
A memória olvasást megoldottam, így mar tudok 1 db pixelt bárhol kapcsolni, anélkül, hogy befolyásolnám az adott lapon levő többi pixelt
Köszönet a segítségért meg egyszer
[ Szerkesztve ]
-
kovisoft
őstag
válasz
#90088192 #6104 üzenetére
Persze, teheted a font paramétereket egy struktúrába, és akkor elég átadni erre a struktúrára mutató pointert a font választáshoz (vagy csúnyább esetben mehet az egész egy globális változóba). Pl:
#include "font1.h"
#include "font2.h"
struct font_type
{
long int *font;
int font_width;
int font_height;
int font_offset;
};
struct font_type myfont[2];
myfont[0].font = Font1;
myfont[0].font_width = Font1_width;
myfont[0].font_height = Font1_height;
myfont[0].font_offset = Font1_offset;
myfont[1].font = Font2;
myfont[1].font_width = Font2_width;
myfont[1].font_height = Font2_height;
myfont[1].font_offset = Font2_offset;
int write_char(int page_select, int y_offset, int character_code,struct font_type *use_font)
{
...
send_data_screen(use_font->font);
...
}
write_char(line,y_offset+j*myfont[0]->font_width,test[j],&myfont[0]);
write_char(line,y_offset+j*myfont[1]->font_width,test[j],&myfont[1]);De lehet, hogy jobb lenne az y_offset paramétert szétszedni egy y és egy j paraméterre, és a font_width-tel való szorzást beletenni a függvénybe, hogy ne kelljen azt is font-tól függően átadni:
int write_char(int page_select, int y, int j, int character_code,struct font_type *use_font)
{
int y_offset = y+j*use_font->font_width;
...
send_data_screen(use_font->font);
...
} -
#90088192
törölt tag
-
Hello,
Sry, hogy ide, de itt legalább van élet. (Dobjátok át másikba, ha nem fér el itt)
Valakinek van ötlete, hogy hogyan lehetne Androidon, Camera2 API -ból a preview tulajdonságait lekérni? Konkrétan az AWB_STATE_LOCKED, és az AE_STATE LOCKED kéne, amit mindenhol csak Capturerequest-ből látok lekérdezni, csahogy az én programomban nincs Capturerequest mert nem ment képet, csak a preview-ből jövő képeket dolgozza felKöszi bármilyen ötletet
-
kovisoft
őstag
válasz
#90088192 #6101 üzenetére
Ha jól értem, paraméterben szeretnéd átadni a write_char() függvényednek azt, hogy milyen betűkészletet használjon. Ehhez össze kell szedned, mi definiálja a betűkészletet. Egyrészt a Font[] tömb, másrészt a Font_width, Font_height, Font_offset (ha nem hagytam ki valamit). Ezeket fel kell venned még plusz paraméterként és átadnod a write_char()-nak, pl:
int write_char(int page_select, int y_offset, int character_code,
long int *font, int font_width, int font_height, int font_offset)És így tudod pl. meghívni:
write_char(line,y_offset+j*Font_width,test[j],Font,Font_width,Font_height,Font_offset);
Mivel az y_offset számolásában is használod a Font_width-et, így szebb lenne ezt a függvényen belül végezni.
Ha pedig mindegyik betűkészlet ugyanolyan méretű, akkor elég csak a font tömböt átadni, nem kellenek a betűméretek.
-
#90088192
törölt tag
Hello
Elmétek kiapadhatatlan tudás forrását, szeretném ismételten megcsapolni
Lenne egy olyan problémám, hogy a tömb nevét szeretném változtatni attól függően milyen betűtípust akarok használni. Font neven fut, és ha változóval próbáltam helyettesíteni nem ment.
Gondolom van rá megoldás, csak nekem újElőre is köszönöm
Ez lenne a példa részlet:
int write_char(int page_select, int y_offset, int charcater_code)
{ int x;
if(y_offset>=( Display_width/2) && y_offset <= Display_width - Font_width && charcater_code>=32 && charcater_code<=128) //Check which side of the screen need to be activated
{
goto_xy( page_select, y_offset);
for(x=( charcater_code - Font_offset ) * Font_width; x<(( charcater_code - Font_offset)* Font_width)+ Font_width; x++) //Decodes the character code and make sure the data is sent by 8 bits
{
send_data_screen( Font[x]); //Sends out the relevant section of the Array
}
} else if( y_offset<( Display_width/2) && y_offset>=0 && charcater_code>=32 && charcater_code<=128)
{
goto_xy( page_select, y_offset); //Selects pages of writing
for(x=( charcater_code - Font_offset)* Font_width; x<(( charcater_code - Font_offset) * Font_width)+ Font_width; x++) //Decodes the character code and make sure the data is sent by 8 bits
{ if( y_offset + (x-( charcater_code - Font_offset) * Font_width)!=( Display_width/2)) //Checks if the character has reached the border of the 2 sides of the screen
{
send_data_screen( Font[x]);
}
else
{ //If the Character is belong to the right side
goto_xy( page_select,( Display_width/2)); //Selects pages of writing
send_data_screen( Font[x]); //Sends out the relevant section of the Array
}
}
}
else
{
MEMBRANE_MUTE=1;
}
}[ Szerkesztve ]
Ú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!
- Nvidia GPU-k jövője - amit tudni vélünk
- Asszociációs játék. :)
- Samsung Galaxy A54 - türelemjáték
- Ukrajnai háború
- Szívós, szép és kitartó az új OnePlus óra
- Milyen autót vegyek?
- Formula-1
- Politika
- AMD Ryzen 9 / 7 / 5 7***(X) "Zen 4" (AM5)
- NVIDIA GeForce RTX 5070 / 5070 Ti (GB205 / 203)
- További aktív témák...
- Ryzen 7 5700X / RTX 4060 / B450 / 16GB vagy 32GB RAM / 256GB + 1TB M.2 SSD / 650W
- Fiio m15s dap hordozható zenelejátszó
- Bontatlan, iPhone 16 Pro Max 256gb, natúr titán, 3 év garanciával, eladó!
- Nintendo Switch CFW okos! 32+64GB Dual Boot OFW+CFW Tinfoil Hekate + hordozó tok + üvegfólia
- Samsung Galaxy S24 Ultra 5G 512GB, Kártyafüggetlen, 1 Év Garanciával