Új hozzászólás Aktív témák
-
shev7
veterán
válasz CPT.Pirk #219 üzenetére
probald ki mit csinal ez, es erteni fogod
#include <stdio.h>
int main( int argc, const char* argv[] )
{
// Prints each argument on the command line.
for( int i = 0; i < argc; i++ )
{
printf( "arg %d: %s\n", i, argv[i] );
}
}[ Szerkesztve ]
''Gee, Brain, what do you want to do tonight?'' ''The same thing we do every night, Pinky: Try to take over the world!''
-
doc
nagyúr
válasz CPT.Pirk #2119 üzenetére
a gond az hogy nem ertem mit szeretnel
az *argv[] mar eleve egy tomb. ha masolni szeretnel, hasznalhatod cikluson belul az strcpy fuggvenyt
ha parameterkent akarod atadni, akkor siman char* a tipus es kesz
ha azt akarod megnezni hogy ures-e, az a legegyszerubb
pl:bool isEmpty(char* s)
{
return !*s;
vagy
return s[0] == 0; (igy olvashatobb, de kevesbe helytakarekos, es foleg kevesbe 'geek' :D)
} -
doc
nagyúr
válasz CPT.Pirk #2121 üzenetére
ha space meg tab is uresnek szamit, akkor kicsit valtozik a logika, vegig kell iteralni a stringen, es ha olyan karaktert talalsz ami a fentiek egyike sem, akkor nem ures
pl:bool isempty(char *s)
{
char *p;
for (p=s; *p; ++p)
if (*p != ' ' && *p != '\t')
return false;
return true;
}ki nem probaltam, de igy ranezesre jonak kell lennie
a *s ugye a karakter amire az 's' valtozo mutat (jelen esetben, mivel a pointer es a tomb C-ben ugyanaz, a string elso karaktere)
ha ez a string veget jelzo 0, akkor nyilvan ures, tehat a !*s igaz lesz (ez ugyanaz mint a *s == 0)de a space/tab miatt ez ugyebar mar nem jatszik
-
doc
nagyúr
válasz CPT.Pirk #2123 üzenetére
ja igen, a bool nem C-s tipus (nagyon regota C++ -ozok ). a bool-t csereld ki int-re, a false-t 0-ra, a true-t meg 1-re es jo lesz
char *p; -csinál egy pointert. De ez most mutat valamire? Vagy csak üres tömb?
mivel erteket nem adtal neki, 'sehova' nem mutat, pontosabban de, csak teljesen random helyre (igy ha pl irni akarsz oda, akkor jo esellyel egybol segfaultot kapsz)for (p=s; *p; ++p) - itt a kezdőérték mi? A p megkapja az s elemeit? A feltétel meg az hogy amíg van eleme, és addig a ++p lépteti az elemeket?
a p ugyanoda fog mutatni ahova az s, vagyis a string elso karakterere
a *p azt a karaktert jelenti, ahova a p mutat. mivel C-ben a 0 hamis, a nem 0 pedig igaz, ez a feltetel akkor teljesul, ha *p nem 0. vagyis ha elertuk a string veget jelzo 0-t, a feltetel hamis lesz, es a ciklusnak vegea fuggvenynek semmi koze a scanf-hez, olyan stringgel hivod meg amilyennel akarod, ez nyilvan lehet egy scanf-el bekert is
amugy a scanf valoban az ordog muve, ne hasznald nincs pl semmi ellenorzes a hosszra, igy ha kicsi tombot foglalsz neki akkor egybol el is crashel a programod. azonkivul a whitespace karaktereket (pl space) mezoelvalasztonak fogja fel, tehat ha space-t is tartalmazo stringet akarsz beolvasni, akkor nem mesz vele sokraerre szokas irni ellenorzott getline fuggvenyt, Gyorben pl. Bauer is 'kiadott' egyet, amit nyugodtan lehet hasznalni vizsgan is
-
doc
nagyúr
válasz CPT.Pirk #2125 üzenetére
a parameteratadas pont ugy tortenik mint Lua-ban meg a programozasi nyelvek tulnyomo reszeben: a fuggvenynev utani zarojelbe irod igaz, a C tipusos nyelv, tehat azt is meg kell adni
viszont amit irsz, nem igazan jo
a while ciklusod addig fut, amig a string elso karaktere nem a lezaro nulla, viszont mivel a pointert nem valtoztatod, mindig ugyanoda (az elso karakterre) mutat
raadasul nem hasznaltal { } -t, igy ures stringnel a vegtelensegig azt fogja irogatni hogy ures
egyedul akkor fog visszaterni, ha NULL pointert adsz at neki, mivel akkor mar a while-ba sem fut bele, viszont olyankor meg fix 1-et ad visszacsak azt nem ertem, miert nem probalod ki a programot? akkor egybol kiderulne hogy nem jo...
-
doc
nagyúr
válasz CPT.Pirk #2131 üzenetére
na igy mar alakul
ket dolog: az if-nel megforditanam a ket feltetelt, tehat igy: if(!str || !*str), ugyanis igy eloszor a NULL pointert ellenorzod le, csak utana azt, ahova mutat, de a mostani megoldas is teljesen joa masik mar kicsit csunyabb: a fuggvenyednek csak akkor van visszateresi erteke, ha ures a string, kellene a vegere egy return 0; igy ha nem ures, akkor 0-t ad vissza (erre elvileg a fordito figyelmeztetett is teged!)
-
-
doc
nagyúr
válasz CPT.Pirk #2135 üzenetére
igen, ezert szoktak a main-t legalulra tenni (illetve a hasznalt fv-eket kulon file-okba)
de elkerulheted ezt az uzenetet, ha meg a main elott deklaralod a fuggvenyedet, igy pl. nem kapsz egy warningot sem:1 #include <stdio.h>
2
3 int strIsEmpty(const char *str);
4
5 int main ()
- 6 {
| 7 char test[]="";
| 8 strIsEmpty(test);
| 9 return 0;
| 10 }
11
12 int strIsEmpty(const char *str)
- 13 {
- 14 if(!*str || !str){
2 15 printf("A string ures\n");
2 16 return 1;
2 17 }
| 18 printf("Nem ures a string\n");
| 19 return 0;
| 20 } -
Gyuri16
senior tag
válasz CPT.Pirk #2210 üzenetére
remelem ez segit:
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
int i;
for (i=0; i<argc; i++) {
printf("argv[%d] = ",i);
printf("%s\n", argv[i]);
printf("strlen: %d\n", strlen(argv[i]));
printf("betunkent:\n");
int j = 0;
while (argv[i][j++]) {
printf("%c\n", argv[i][j]);
}
// pointeresen:
char * a = *(argv+i);
while (*a++) {
printf("%c\n", *a);
}
}
return 0;
}Nem vagyok egoista, csak uborkagyalu!
-
bpx
őstag
válasz CPT.Pirk #2210 üzenetére
a szövegbekérést hiányoltam, de most már látom, hogy a parancssori argumentumokra gondoltál
a problémát még mindig nem teljesen értem, ha már sikerült kiíratni az argumentumokat egyenként, akkor a hossznak is mennie kellene
ha az argv-t próbálod karakterenként kiíratni az nem fog menni (char ** ugye)ciklussal végigmész az argv-n, azzal minden egyes lépésben egy adott argumentumot vizsgálsz, egy belső ciklussal meg magán az aktuális argumentumon mész végig, pl.
int i, j = 0;
for (i = 0; i < argc; i++)
{
printf("argv[%d] - ", i);
for (j = 0; argv[i][j]; j++)
{
printf("%c", argv[i][j]);
}
printf(", hossz: %d\n", j);
}szerk: ja persze, én közben telefonáltam is és megelőztek
[ Szerkesztve ]
-
Jester01
veterán
válasz CPT.Pirk #2215 üzenetére
1. A programokat az operációs rendszer indítja, tipikusan másik programok kérésére. A main függvény argv/argc paraméterei a c/c++ nyelv szabványosított formája a program argumentumok kezelésére (mármint nem a nevükre gondolok itt, mert az ugye bármi lehet). Az argumentumokra általában nincs olyan megkötés, hogy nem tartalmazhatnak szóközt. Ha tehát a hívó program beleteszi őket, akkor te meg is fogod kapni. Vagyis csak az a kérdés, hogy a hívó programot hogy veszed rá erre. Windowson a hívó például lehet a parancsablak, a cmd.exe. Ezesetben értelemszerűen idézőjeleket használva valószínűleg jó lesz. Továbbá, ha nem platformfüggetlen kódot írsz, akkor windowson egyben is lekérheted az egész parancssort, a GetCommandLine függvénnyel (bár nem tudom a szóközökkel ezesetben mi lesz).
2. Az argv továbbadása. Az argv nem valami mágikus paraméter, csak egy sima string tömb. Mint ilyen, természetesen akár egészben akár darabokban továbbadhatod másik függvényeknek, pont úgy mint bármilyen más string tömböt. Az argc meg csak egy szerencsétlen int, azzal még ennyi gond sincs.
Jester
-
Jester01
veterán
válasz CPT.Pirk #2217 üzenetére
Ha bővebbet tudnál mutatni a linuxos hibáról akkor abban esetleg tudnánk segíteni.
Ami a kódot illeti: az i,j,len változókat kirakni globálisba nem szép dolog, tedd őket bele az strLen függvényedbe. Az if (i==1) len=0 felesleges mivel ha nem volt argumentum a len úgyis nulla. Az i-t ellenőrizni pedig megtévesztő, hiszen tulajdonképpen az argc-t akarod vizsgálni (persze az értéke ugyanaz lesz, csak logikailag gubancos).
Továbbá szebb lenne, ha a kiírás nem az strLen-ben lenne, hanem a main-ben az strLen visszatérési értéke alapján.
Ha jól értem a logikát, akkor az argumentumok között egy szóközt feltételezve korrigálod a hosszt. Ez ugye addig jó amíg tényleg annyi van. Ha a felhasználó egyetlen argumentummal futtatja akkor nyilván jó eredményt fog adni egyébként.
$ cat >test.c
#include <stdio.h>
int strLen(int argc, char *argv[]) {
int i, j, len = 0;
for (i = 1; i < argc; i++)
for (j = 0; argv[i][j]; j++)
len++;
if (argc > 2) len += argc - 2;
return len;
}
int main(int argc, char *argv[]) {
printf("hossz: %d\n", strLen(argc, argv));
return 0;
}
$ gcc -Wall -O2 test.c
$ ./a.out hello world
hossz: 11
$ ./a.out "hello world"
hossz: 11
$ ./a.out hello world
hossz: 11
$ ./a.out "hello world"
hossz: 13Jester
-
kolyka
csendes tag
-
Jester01
veterán
válasz CPT.Pirk #2587 üzenetére
Ennek már eleve a fordításnál el kellene "buknia":
c = buffer; Hiányzik egy csillag.
return *buffer; itt meg van egy fölösleges
if (c == "\n") ide karakter konstans kell, aposztrófok között nem idézőjelben
*buffer = *(buffer--); szerkezet nem szabályos
bár az if belsejét szépen behúztad, attól még oda kellene a kapcsoszárójel (így is fordul, csak mást csinál mivel a return *buffer; már nem lesz a feltétel hatása alattA logikáját amúgy sem értem. Ugye a while feltétel eleve növeli a pointert, tehát c-be a következő karakter kerül már. Ha ez \n (akárhol is van, tehát nem feltétlen a string végén) akkor ezt, és csak ezt, megpróbálja felülírni az ezt megelőző karakterrel és itt abba is hagyja a feldolgozást, visszatérési érték pedig a buffer aktuális értéke lesz (tehát nem a string eleje). Ha pl. a bemenet "abc\ndef" akkor a kimenet "cdef" esetleg "ccdef" lesz.
Mivel az a feladat, hogy szedje le az új sor jelet a string végéről, ezért egyszerűen meg kell keresni a lezáró nulla byteot és azt eggyel előrébb hozni ha az előző karakter \n volt.
Jester
-
Jester01
veterán
válasz CPT.Pirk #2589 üzenetére
Ez megint nem jó, mert a ++ az ugyebár megnöveli a változót. Tehát ha megtalálta a \n-t és a rákövetkező byte a lezáró nulla, akkor azt önmagával akarja felülírni. Ha viszont nem nulla, akkor abban a lépésben a buffer kétszer lesz növelve. A visszatérési érték pedig továbbra is rossz, mivel akkor a buffer már a string végére fog mutatni.
Embertelenül túlbonyolítod a kérdést. Összesen annyit kell csinálni, hogy megkeresed a végjelet és megnézed, hogy az előtte lévő karakter \n-e és ha igen, akkor azt felülírod.
Jester
-
Jester01
veterán
válasz CPT.Pirk #2591 üzenetére
Ez még mindig nagyon rossz, mivel most is minden lépésben nézed a \n-t, továbbá a -- és a ++ szépen kiüti egymást.
Igen, majd ha jól működik akkor két 0 lesz a végén de ez mindegy mert a stringnek az első nullánál lesz logikailag vége.
A visszatérési értéknek ha az eredeti paramétert akarod, akkor célszerű másolatot csinálni belőle és azt piszkálni, az eredetit meg békénhagyni.
Jester
-
Gyuri16
senior tag
válasz CPT.Pirk #2593 üzenetére
ez nem jo:
if (*buffer-- == '\n'){
a -- csak a feltetel kiertekelese utan fog vegrehajtodni, ezert ez az if sose teljesul (mindig 0 lesz a buffer erteke amikor ideer). ezert a fuggvenyed mindig az utolso (nem null) karakterre mutato pointert ad vissza.Ilyenkor a *buffer-t hogyan viszem vissza a kezdeti pozícióba?
ne a buffer pointert vidd vissza, hanem hasznalj egy masikat a mozgasra (ahogy azt.Jester01 mar irta). a fuggvenyed elejen csinalj egy ilyet:char * q = buffer;
es azutan a q-val dolgozz, a vegen petig visszaterhetsz a bufferral
mas:
mikozben ezt probaltam elojott a kovetkezo hiba, miert segfaultol a devcpp erre?
char * a = "abcd";
*a = 'b';Nem vagyok egoista, csak uborkagyalu!
-
Gyuri16
senior tag
-
Gyuri16
senior tag
válasz CPT.Pirk #2597 üzenetére
nem. ezek szerint nem erted a pointerek mukodeset.
egy darab stringed van, amit megkapsz a buffer valtozoban. ennek a valtozonak a tartalma egy memoriacim, ami a string elso karakterere mutat. a char *c = buffer; sor annyit csinal, hogy letrehoz egy masik pointert (mutatot), ami ugyan arra a memoriacimre fog mutatni. tehat a ket valtozo ugyanannak a stringnek az elejere mutat. ezutan a c-t hasznalod, hogy megkeresd a veget, visszalepj egyet. eddig a pontig csak a c pointert valtoztattad meg (tehat azt a memoriacimet ami a valtozoban van a stringet nem valtoztattad), a stringnek az utolso nem null karakterere mutat. ezutan a *c='\0'; sorral atirod azt a karaktert amire a c mutat (ezert van ott a csillag a c elott - a dereferencia operator). ezutan pedig a tomb elejere mutato pointerrel kell visszaternie a fuggvenynek, es az pedig a buffer valtozoban van.
Nem vagyok egoista, csak uborkagyalu!
-
Gyuri16
senior tag
válasz CPT.Pirk #2602 üzenetére
megprobalhatnad debuggolni, megnezed melyik tesztnel segfaultol es kitalalod mi a baja
ha azt a kodot hasznalod ami fentebb van, akkor szerintem ez a teszt hal meg:
assert(strcmp(strChomp(""),"")==0);
ha a fuggvenyed ures stringet kap parameterkent, akkor ez az if:
if (buffer && *buffer) {
nem fog teljesulni (a masodik feltetel miatt). ezert a fuggveny nullal ter vissza, es azt adod oda a strcmp-nek.[ Szerkesztve ]
Nem vagyok egoista, csak uborkagyalu!
-
buherton
őstag
válasz CPT.Pirk #5095 üzenetére
Jól megkavarod a dolgot.
Nem ismerem a CooCox-ot (LPCexpresso-t használok), de projekt mappában van a lib és h? Abszolút vagy relatív path? Utóbbinál jó a változó? Jogok jól vannak beállítva (Linuxon). Ezek voltak a basic kérdések.
Advanced level: gondolom itt van is console felület, ahol kiírja, hogy a linker-t milyen arugmentumokkal hívja meg. Itt megnézd meg, hogy a lib és h (nem tudom melyiknek kellene ott lennie) benne van-e. Ha benne van, akkor passz, ha nincs akkor itt a gond. Továbbá próbálkoznék azzal is, hogy kimásolnám az egész sort és kézileg próbálnám összelinkelni. Ha eddig semmi sem volt jó, akkor indulhat a szarakodás.
Munka (nem ócó a Keil)? Milyen NXP? Mit csinálsz ezzel? Miért nem arm-none-eabi? Bár ha fontos a kód méret, akkor megértem.
[ Szerkesztve ]
tely, baly, fojó, mennyél, mingyárt, telyföl, tolyás, malyd, kapú, egyenlőre, ejsd, jáccani, ahoz, fúj, hüje, muszály, alat, álok, lasan, fojtatás, ál, fontós, költsön, eggyüt, lyob (jobb?), mek, mongyak, milyért - !!! Tanúlyunk már meghejjessen irni... !!!
-
tototos
őstag
-
buherton
őstag
válasz CPT.Pirk #5100 üzenetére
Hóhó ez nagyon spéci cucc. Akkumulátor töltő vagy mi lesz belőle?
Most nekem is lenne egy kérdés. Nem igazán C viszont ha már felmerült az ARM, akkor megkérdezem.
Context switcher-t írok, de van két probléma, amivel nem tudok dűlőre jutni:
1. PendSV-ben történik a váltás, ahol értelemszerűen az MSP-t használom. Igen ám, de a stack pointer minden egyes meghíváskor 0x20-val csökken az értéke. Miért csinálja ezt?2. Így térek vissza a PendSV-ből:
volatile uint32_t LR_reg;
LR_reg = 0xFFFFFFFD;
__asm volatile ("BX %0" : "=r" (LR_reg));
Ennek ellnére még mindig privileged módban fut a cucc. Ha ez előtt beállítom direktbe a CONTROL regisztert, akkor user-ben fog futni, de nem erre találták ki az EXEC_RETURN-t?tely, baly, fojó, mennyél, mingyárt, telyföl, tolyás, malyd, kapú, egyenlőre, ejsd, jáccani, ahoz, fúj, hüje, muszály, alat, álok, lasan, fojtatás, ál, fontós, költsön, eggyüt, lyob (jobb?), mek, mongyak, milyért - !!! Tanúlyunk már meghejjessen irni... !!!
-
-
stepboy
csendes tag
válasz CPT.Pirk #5785 üzenetére
Ha van egy szabad portod, akkor tudnál port billegtetést csinálni és kívülről vizsgálni, hogy valóban annyi idő telik-e el mint amennyire számítasz:
port_fel;
delay();
port_le;ezt megnézni O2-vel, O3-mal meg LTO-val. Ha igen, akkor nem ezzel a függvénnyel lesz baj.
Nem tudom, lehet, hogy hülyeség - esetleg, nem inline-olja a függvényt és cseszi el a regisztereket az O3/LTO build? Sok helyről hívjátok ezt a függvényt? Ha nem, akkor gyorsan meg lehetne nézni azokat a területeket is egy disassemblyvel.
[ Szerkesztve ]
-
stepboy
csendes tag
válasz CPT.Pirk #5787 üzenetére
esetleg, próbáld ki ezt:
http://stackoverflow.com/questions/12114019/g-and-attribute-optimize-not-changing-debugger-behavioritt azt írja, hogy alapból O2-vel fordít, de egy függvényt ezzel az attribute-tal máshogy tud optimalizálni.
#include <iostream>
#include <vector>
int MyNormalFunction();
int MyDebugabbleFunction() __attribute__((optimize(0)));
int MyNormalFunction()
{
int val = 0; // breakpoint here - debugger does NOT stop here
val = 1;
val = 2;
return val;
} // debugger stops here instead
int MyDebugabbleFunction()
{
int val = 0; // breakpoint here - debugger stops here and steps through the next 3 lines as if it were built with only -g
val = 1;
val = 2;
return val;
}
int main()
{
int a = MyNormalFunction();
std::cout << a << std::endl;
int b = MyDebugabbleFunction();
std::cout << b << std::endl;
return 0;
} -
stepboy
csendes tag
válasz CPT.Pirk #5790 üzenetére
Valószínű, hogy máshol van a hiba, ami kihatással van az USB működésére. A projekt többi része működik/meg lehet állapítani, hogy működik?
Viszont a kódot biztosan rossz:
__attribute __((naked))
void delay_loop (unsigned n)
{
__asm volatile ("1: sub r0, #1");
__asm volatile (" bne 1b");
__asm volatile (" bx 1r");
}[Itt találod a GCC Basic Asm leírását]
Van benne néhány fontos megjegyzés:
Do not expect a sequence of asm statements to remain perfectly consecutive after compilation. If certain instructions need to remain consecutive in the output, put them in a single multi-instruction asm statement. Note that GCC’s optimizers can move asm statements relative to other code, including across jumps.vagy ezek:
GCC does not parse basic asm’s AssemblerInstructions, which means there is no way to communicate to the compiler what is happening inside them. GCC has no visibility of symbols in the asm and may discard them as unreferenced. It also does not know about side effects of the assembler code, such as modifications to memory or registers. Unlike some compilers, GCC assumes that no changes to general purpose registers occur. This assumption may change in a future release.For basic asm with non-empty assembler string GCC assumes the assembler block does not change any general purpose registers, but it may read or write any globally accessible variable.
Megnéztem az optimalizációs leírást is, O3-mal jön az inline valóban, de azt ki lehet kapcsolni "noinline" attribute-tal (bár ez egy jó régi GCC: 4.7.4).
Ami a megjegyzéseket illeti, az elsőt nem hiszem, hogy vonatkozik rád a volatile miatt, tehát a sorrend marad. Viszont az inline miatt előfordulhat, hogy nem az van az R0-ban, amire számítasz. Normál esetben a függvényhíváskor az első paraméter valóban oda kell, hogy kerüljön, de ha a függvényt inline-olja a fordító, akkor már nincs garantálva, hogy az R0-án keresztül ad át bármit is, mivel a fordító nem látja, hogy bármi is történik az "n" változóval és azt feltételezi, hogy a regisztereket nem módosítja az assembly kódod.
Azt gondolom, hogyha már mindenképpen beágyazott assembly-t akarsz írni, akkor azt valahogy így kéne csinálni:
void delay_loop (unsigned n)
{
__asm ("1: sub %0, #1 \n\t"
" bne 1b \n\t"
" bx 1r "
:
: "r" (n));
}Mindezt az Extended-Asm leírás alapján (a fenti link következő oldala); itt már jelzed a fordítónak, hogy egy regisztert biztosan használsz és minden egy helyen van, ezért nem változhat meg a sorrend.
Bár a legjobb mindenképpen az lenne, ha az egészet átrakod sima assemblyre és akkor a fordító számára egy függvényhívás lesz a kód, amivel már nem tud trükközni.
[ Szerkesztve ]
-
stepboy
csendes tag
válasz CPT.Pirk #5799 üzenetére
Remélem nem túl nagy a kód, különben elég nagy szívás függvényenként végigmenni.
Hátha ez egy kis segítség lehet: Options That Control Optimization
Új hozzászólás Aktív témák
● olvasd el a téma összefoglalót!
● ha kódot szúrsz be, használd a PROGRAMKÓD formázási funkciót!
- HDD 500GB 45DB
- Iphone 11 fehér 128 GB független
- Eredeti - Apple USB-C kábellel és Magsafe 2 - minden típus - macbook töltő - garancia
- Macbook Pro 16" - 2020 gyártás, i9 és i7, 32/512GB, 4GB Radeon, touchbar, garancia, szürke
- Macbook Pro 15" - 2019, 8 mag i9, 32/512 GB, 4GB Radeon, 90 ciklus, garancia, doboz, szürke (65)