Geri blogja

Tisztelt látogató!
Ez a blog 2017 óta átmenetileg szünetel!

Friss topikok

Bejegyzések

Programozás C nyelven

2015.09.13. 21:21 Gerilgfx

Mostanában sok bejegyzést látok affelől érdeklődve, hogy milyen egyszerű, könnyű, fingreszelgetés nélküli, lényegretörő szakirodalmat lehet a C nyelvű programozásról találni, amiből meg lehet tanulni a nyelvet, és el lehet sajátítani a C nyelvű programozáshoz szűkséges alapokat. Nyilván nem szeretne senki sem több száz oldalas, nagyzolós könyveket olvasni a semmiről, így aztán úgy döntöttem, hogy írok egy rövid, lényegretörő oktatóírást a C nyelvű programozásról, amely átöleli magát a nyelvet, és a legtöbb felmerülő kérdésekre is választ ad.

EZ A BEJEGYZÉS KÖZZÉTEHETŐ MAGÁNCÉLRA BÁRHOL, AZ EREDETI FORRÁS MEGJELÖLÉSE MELLETT ( http://gerilgfx.blog.hu ) A BEJEGYZÉST CSAK TELJES TERJEDELMÉBEN, VÁGATLANUL LEHET KÖZZÉTENNI.

 

Kinek való a C programnyelv?

-Ez a programnyelv neked való, hogyha már próbálgattál/írtál dolgokat más nyelvekben, amik nem voltak számodra elég ,,valódiak'', tehát nem voltak eléggé hardverközeliek, nem igazán tudtál bennük ,,valódi'' programot megírni, hanem folyamatosan hiányérzeted volt.

-Persze a programozást megtanulni is meg lehet C nyelven, nem bonyolultabb, mint a többi nyelv, a számítógép működésének megértését viszönt megköveteli. Mondjuk egy mérlegképtelen könyvelőaparatcsik nem fog tudni programozni más nyelven sem, úgyhogy ez igazából mindegy.

 

the_c_programming_language_logo_svg.pngMire való a C programnyelv?

-A C programnyelv egy több, mint 40 éves programnyelv, ami jelentős átalakuláson ezidő alatt nem esett át. A történeti áttekintéstől most eltekintenék, mert úgysem érdekel senkit. A C szabványosított változata a C99, a továbbfejlesztett változata a C++, ami már objektumorientált programozást is lehetővé tesz. Ma, amikor azt mondjuk, hogy C-ben írt program, vagy C-ben írt forráskód, akkor általában egy C99-ben megírt, és c++ fordítóval lefordított programot értünk alatta. A legtöbb nyílt forrású program ilyen. A c++ fordítók támogatják a C/C99 forráskódok lefordítását, ugyanis visszafelé kompatibilisek (a c++-nek része a C).

Megjegyzendő, hogy néhányan ezzel a szemlélettel nem értenek egyet, és azt állítják, hogy a C és a C++ nyelv két külön entitás, ezt bizonyítva próbálnak olyan speciális, a gyakorlatban nem létező, és nem kihasznált dolgokat példaként felhozni, ami ezt szerintük alátámasztja. Ez azonban egy teljesen téves és irreális elképzelés.

-A C programnyelvet eredetileg operációs rendszerek, kernelek, meghajtóprogramok megírására fejlesztették ki, de végülis kiderült, hogy egyszerűsége, és hatákonysága miatt minden másra is jó, így aztán mára ez vált a legelterjedtebb, legnépszerűbb programnyelvvé (bár néha az éppen aktuálisan népszerű megoldások letaszítják a trónról, így néha csak második helyezett, ez mindig az aktuális trendektől függ). Emellett meg szeretném jegyezni, hogy nem az alapján kell kiválasztani egy programozási nyelvet, hogy melyik népszerűbb, hanem hogy melyik számodra a legmegfelelőbb. Persze a C véletlenül az esetek többségében mindkét feltételt teljesíti.

-A C programnyelv segítségével tehát valódi programokat tudunk létrehozni, amikkel valódi problémákra, jól működő megoldásokat lehet nyújtani.

-A C nyelv egy teljesítményorientált nyelv, de érteni is kell ahhoz, hogy ezt a teljesítményt elő lehessen hozni. Ha valaki nem ért hozzá, sokkal lasabb kódot fog eredményezni, mint a többi nyelv, de ha ért, akkor akár több ezerszer gyorsabb kódot is írni lehet benne, mint a többi nyelvben. A C-ben nincsenek ellenőrzések, nincsenek felesleges műveletek: amit írsz, az történik.

-Ma szinte minden komoly programot C nyelven írnak, ez többnyire C99-et jelent, néhol használnak c++ kódrészleteket is, kényelmi szempontokból.

 

 

Mire NEM való a C programnyelv?

-Jaj, megtanulom a C nyelvet, és majd ezzel egy multi pincéjébe elmenve aladárkodni, majd én leszek a csoportkirály <- NEM.

-A C nyelv gyorsan, mindenféle hozzáértés nélkül sok pénz keresésére SEM való.

-Nem ideális a C nyelv akkor sem, ha életedben először, és utoljára kell egy programnyelv arra, hogy valamilyen bizonyos, célirányos dolgot elkészíts vele, mert valószínűleg van már rá valamilyen direkt arra a célra kifejlesztett megoldás.

-Buta embereknek sem való a C nyelv.

 

 

Mi a különbség a C programnyelv, és a többi programnyelv között?

-Csak úgy, mint a többi programnyelvben, a műveletek végrehajtása itt is fentről lefelé történik, lépésről lépésre. A kezdőfüggvény viszont mindig a main függvény, tehát a végrehajtás a main függvénynél indul.

-C nyelven a program különböző, jól körülhatárolható részeit (algoritmusokat) függvények formájában szokás implementálni. Ezek a függvények aztán további függvényeket is meghívhatnak. Például írsz egy két vonal metszését megállapító függvényt, amik az általad feljebb már implementált koordinátageometriai függvényeket hívják meg.

-A nyelv minimalisztikus. A C-hez tartozó runtime (amely vvagy részben az operációs rendszer része, vagy közvetlenül belefordul a futtatható fájlodba) tartalmaz pár alapvető függvényt, amelyek az operációs rendszerrel való alapvető interakcióhoz szűkségesek, de a C nyelvben közvetlenül nem találsz magas szintű dolgokat. Nem része tehát a C programnyelvnek olyan függvény, amivel zenét játszol le, hisz azt csak az operációs rendszer segítségével tudod megtenni. Ezért aztán ez az operációs rendszerbe épített különböző függvények kihasználásával érhető el, amik értelemszerűen minden platformon mások.

-A C programnyelvben tehát élesen különválik maga a programnyelv, és élesen különválnak azok a különböző API-k, amit az operációs rendszer biztosít számunkra például az ablakozáshoz, a perifériák eléréshez, így ezek nem is részei a C-nek, hanem az operációs rendszer által biztosított lehetőségeket kell hivogatni a C-n belül ezeknek az eléréséhez. Természetesen az adott platformhoz tartozó adott fordítóhoz mellékelve vannak az olyan header fájlok és/vagy előre lefordított libraryk, amik lehetővé teszik ezen képességek elérhetőségét.

-A C-t C nyelven írják, tehát egy olyan nyelvről van szó, amit önmaga segítségével írnak. A C-hez tartozó függvénykönytárakat is szintén egyszerűen C-ben implementálják.

-A C programnyelv félúton van a magasszintű, és az alacsony szintű nyelvek között annélkül, hogy platformspecifikus, vagy architektúraspecifikus lenne. A C tehát egy magas szintű programnyelv, alacsony szintű nyelvekre jellemző beütésekkel.

-Több fordítóprogram (compiler) létezik C nyelvre, ilyen például a gcc, a clang, a tinyc, vagy a visual studio. Ezek c++ fordítók (a tinyc csak c99). Néhány platform saját C fordítót használ. Elvileg minden C nyelven megírt program lefordítható bármilyen C compilerben, de természetesen előfordulhatnak olyan sajátságos esetek, amikor kompatibilitási probléma lép fel.

-Éppen ezért törekedni kell az egyértelmű, egyszerű, közérthető stílusú programoházsra, nem tanácsos C-ben menősködve, arcoskodva programkódokat írni, mert ez súlyosan visszaüthet egy komaptibilitási probléma esetén, ha a hiba forrását kell megkeresni.

-A c fordítók gyakorlatilag mindegyike az adott architektúrához tartozó gépi kódra fordít, ez manapság x86 (i386, i686), x86-64 (64 bites x86), vagy esetleg ARM architektúrát (pl android) jelent a gyakorlatban. Vannak különleges esetek is, ezekkel most nem kívánok foglalkozni.

 

 

Hogy érdemes nekilátni?

-Töltsd le a CodeBlocks nevezetű szoftvert. Linux alá csak egy féle van, Windows alá pedig azt, amelyikben van egy mingw32 nevezetű compiler (ez a gcc windowsos portja). A visual studiot, és a többi compilert egyelőre felejtsd el. A legjobb, ha Linuxot használsz, de természetesen Windowson is ugyanúgy mennie kell.

-Nyiss egy új, üres projektet (console application), mentsd el valamilyen néven, a fájlod legyen main.cpp (ebbe kerül a forráskód, amit begépelsz).

-Bal oldalt, a fájlok listájában a main.cpp-re kattints jobb gombbal, és a properties, advenced fülben győződj meg arról, hogy a compiler varible mezőben CPP áll. Ha nem, akkor írd be egyszerűen ide azt, hogy CPP, ugyanis a c99 dialektusú forráskódokat csak cpp (tehát c++) módban lehet lefordítani.

 

 

Egy alap program:

#include <stdio.h>
#include <stdlib.h>

int main(){

   printf("helo anyu\n");
}

Ha minden jól megy, akkor ennek le kell fordulnia, ezt codeblocks alatt F9-el érhetjük el. Ez a g++.exe -nek átadja a main.cpp fájlunkat, lefordítja, és futtatja. létrejön belőle egy projektnévnek megfelelő exe állomány, amit megtalálunk a projektünk könyvtárában.

Nézzük meg, hogy mit látunk: az stdio.h az a c nyelvben egy alapból jelen lévő úgynevezett header fájl, ezt majd később elmagyarázom. Ilyen header fájlokból van még jónéhány, például math.h. Az include pedig egyszerűen a fájlunk adott pontjára másolja ezeknek a fájloknak a tartalmát. Saját készítésű fájlok tartalmát is be lehet másolni természetesen, de erre egyelőre nem lesz szűkség. A függvények deklarációja mindig a függvény típusával kezdődik, ez main esetén legyen int. A függvények tartalma pedig kapocs közé kerül: tehát az { és a } jel közé. Ami a kapcsos zárójelek közé kerül, az mindig kerüljön beljebb, ez formai okok miatt, az átláthatóság megőrzése szempontjából fontos. A függvények hívása során egyszerű zárójelet használunk, ami közé a függvény paraméterei jönnek. A parancsok után pontosvesszőt ; teszünk, ezzel adjuk a fordítóprogram tudtára, hogy innéttől már a következő dolog következik.

 

MEGJEGYZÉS: Nem minden itt leírt példaprogramot fordítottam le és próbáltam ki, mert siettem. Ha valami nem fordul, gondolkozz logikusan, és cselekedj értelemszerűen, célszerűen.

 

#include <stdio.h>
#include <stdlib.h>

int kutya=12;

int paraszt=30;

int main(){
   int cica=12;  
   printf("ennyi paraszt van: %d\n", paraszt);
   printf("ennyi kutya van: %d\n", kutya);
   printf("ennyi macska van: %d\n", cica);
}

Itt néhány változót deklaráltunk, és kiírtuk az értéküket. A mainon belül deklarált cica egy lokális változó, ami csak a mainon belül él, a mainon kívül deklarált pedig globális változó, ami a deklarástól kezdve minden függvényben él (és meg is tartja az értékét). A lokális váltoizók a függvényből való visszatérést követően elvesztik az értéküket. Ha nem adunk meg értéket a változónak, az értéke nem definiált. Lehet nulla, de lehet memóriaszemét is! A C semmit sem csinál meg feleslegesen, hisz mint már említettem, ez egy teljesítmény-orientált nyelv.

A deklarálás tehát a változó típusával kezdődik, aztán szóköz, a változó neve, majd esetleg egy egyenlőségjel, és egy érték. A végén itt is ; jel van.

Típusok lehetnek:

-int (egész szám, általában 32 bites), minusz kétmilliárd valahánytól plusz kétmilliárd valahányig.
-long (64 biten 64 bites, 32 biten 32 bites)
-long long (64 bites)
-float (32 bites lebegőpontos, kb 5 tizedesjegy műveletprecizitású)
-double (64 bites lebegőpontos, kb 8 tizedesjegy műveletprecizitású)
-char (8 bites)
-short (16 bites)

Ezek mind előjeles számok, viszont amelyiket az adott platformon nem lehet hardverből támogatva kezelni (pl short), az lasabb lesz, hisz extra gépi kódú műveleteket igényel.

-unsigned int (egész szám, általában 32 bites), 0-tól 4milliárd valahányig.
-unsigned long (64 biten 64 bites, 32 biten 32 bites)
-unsigned long long (64 bites)
-unsigned char (8 bites)
-unsigned short (16 bites)

Ezek az előjel nélküli változatok. A signed változat pedig megegyezik az előzőleg ismertetett típusokkal.

A műveletekben több típus is felhasználható együttesen, tehát nem muszáj alakítgatni őket más formátumokra.

 

 

 

 

 

#include <stdio.h>
#include <stdlib.h>

int kutya=-12;

float paraszt=29.1;

int main(){
   int cica=12;  
   cica=kutya*paraszt+cica;  
   printf("eredmeny: %d\n", cica);
}

Értelemszerűen. A C programnyelv igyekszik a matematikai műveleti sorrendhez idomulni, de ez nem mindig sikerül egyértelműen. Zárójeleket természetesen lehet használni, ha szűkséges.

 

 

 

#include <stdio.h>
#include <stdlib.h>

int kutya=-12;

float paraszt=29.1;

int main(){
   float cica=12;  
   cica=kutya*paraszt+cica;  
   printf("eredmeny: %f\n", cica);
}

A printf függvény egy speciális függvény, hogy ez miért ilyen, azzal nem érdemes foglalkozni. Ha floating point számot akarunk kiíratni, akkor %f-et kell használni.

 

 

 

#include <stdio.h>
#include <stdlib.h>

int valamitkiszamolunk(int elso_bemenet, int masodik_bemenet){

   int kutya=-12;
   float paraszt=29.1;
   kutya =paraszt*elso_bemenet;
   kutya=masodik_bemenet+kutya;
   return kutya;
}

int main(){
   float cica=valamitkiszamolunk(4545,52617);  
   printf("eredmeny: %f\n", cica);
}

A fenti példában a függvények deklarációja látható. Először itt is a típus jön, aztán a függvény neve. Ezt követően zárójelben a paraméterek típusa és neve (vesszővel elválasztva). Majd végül egy nyílt kapcsos zárójel következik, a függvény tartalmát követően pedig egy bezáró kapocs. A return jelentése egyértelmű, a függvényben többször, bárhol lehetséges a return kulcsszó használata. C nyelvben is lehetséges a rekurzió, értelemszerűen.

Költői kérdés: Miért hívják a függvényeket függvényeknek?

Angolul function kifejezést használják, ami sokkal kifejezőbb: itt nem matematikai függvényekről van szó, hanem lényegében hívogatható kódrészletekről.

 

 

 

#include <stdio.h>
#include <stdlib.h>

int main(){

   int a=3;
   int b=6;
   if(a<b){
       printf("a kisebb\n");
   }
}

A feltételvizsgálat is hasonló konvenciót követ a zárójelezést tekintve.

 

 

 

 

 

#include <stdio.h>
#include <stdlib.h>

int main(){

   int a=3;
   int b=6;
   if(a<b) printf("a kisebb\n");
}

Itt azonban lehet egyszerűsíteni is, nem muszáj feleslegesen kapcsolszárójeleket használni, ha csak egyetlen műveletet szeretnénk végezni.

 

 

 

#include <stdio.h>
#include <stdlib.h>

int main(){

   int a=3;
   int b=1;
   if(a<b){
       printf("a kisebb\n");
   }else{
       printf("nope\n");
   }
}

Az else ág abban az esetben fut le, ha a kifejezés hamis.

 

 

 

#include <stdio.h>
#include <stdlib.h>

int main(){

   int a=1;
   if(a){
       printf("uhumn");
   }
   a=0;
   if(a){
       printf("muhumn");
   }
}

Ilyet is lehet, ekkor a kifejezés akkor lesz igaz, ha az a nem nulla.

 

 

 

#include <stdio.h>
#include <stdlib.h>

int main(){

   int a=1;
   if(a==1){
       printf("uhumn");
   }
}

Az értékegyenlőséget egy kifejezésben mindig dupla egyenlőségjellel kell jelölni, a sima egyenlőségjel ugyanis értékadást jelent, még az if-ben is!

 

 

#include <stdio.h>
#include <stdlib.h>

int main(){

   int a=0;
   if(!a){
       printf("uhumn");
   }
}

A felkiáltójel negációt jelent.

 

 

 

#include <stdio.h>
#include <stdlib.h>

int main(){

   int a=0;
   if(a!=1){
       printf("uhumn");
   }
}

Ha az a értéke nem 1, akkor lefut a kifejezés.

 

C-ben, csak úgy, mint más nyelveken, szintén vannak ciklusok.

 

 

#include <stdio.h>
#include <stdlib.h>

int main(){

   for(int a=0;a<10;a++){
       printf("uhumn %d\n", a);
   }
}

A for ciklus kissé érdekes, pontosvesszővel választjuk el egymástól a három komponensét. Az elsőben található az inicializálás (tehát az csak egyszer fut le), a másodikban a feltételvizsgálat, a harmadikban pedig a lépésenként végrehajtandó művelet. Ezek helyén bármi állhat, akár ki is lehet hagyni őket (tehát for(;;;)).

 

 

 

 

#include <stdio.h>
#include <stdlib.h>

int main(){

   for(int a=0;a<10;a++){
       if(a==5) break;
       printf("uhumn %d\n", a);
   }
}

A ciklus megtörése break segítségével, hasonlóan a többi programnyelvhez, itt is lehetséges. A végrehajtás a breaket elérve a ciklus végén folytatódik. Több egymásba ágyazott ciklus esetén mindig a legbelsőbb ciklusra vonatkozik a break.

 


 

#include <stdio.h>
#include <stdlib.h>

int main(){

   for(int a=0;a<10;a++){
       if(a==5) continue;
       printf("uhumn %d\n", a);
   }
}

Continue esetén a ciklus elejére ugrunk vissza.

 

 

Más jellegű ciklusok is vannak:

#include <stdio.h>
#include <stdlib.h>

int main(){

   int a=6;
   while(a>2){
       a--;
       printf("uhumn %d\n", a);
   }
}

A while funkciója hasonló a for ciklushoz. Hátultesztelős változata is létezik:

#include <stdio.h>
#include <stdlib.h>

int main(){

   int a=6;
   do{
       a--;
       printf("uhumn %d\n", a);
   }while(a>2);
}

A hátultesztelős változatát azonban nem használjuk, csak érdekességképp érdemes megnézni.

 

 

 

 

Az ASCII kódokkal könnyen tudunk bánni:

int main(){
   int a='x';
}

Így aztán nem kell kikeresni a kódját, elég a karaktert egy sima idézőjelbe írni, hogy megkapjuk az ASCII kódját. Ez szövegkezelés esetén válik különösen fontossá.

A fentebb már látott rejtélyes \n is egy ilyen ascii kódot reprezentál, az a soremelés ascii kódját jelenti.

 

 

 

 

 

Különleges műveletekre is lehetőség van a számokkal, nem csak a feljebb már látott szorzásra, összeadásra, kivonásra.

c=a%b;  osztási maradék
c=a<<b;  bit eltolás balra
c=a>>b;  bit eltolás jobbra
c=a^b;  bitenkénti kizáró vagy
c=a|b;  bitenkénti vagy
c=a&b;  bitenkénti és

Figyelembe kell venni azt, hogy nem minden platform little endian, a C ilyesmivel nem foglalkozik - mindig az adott platform natív számábrázolása alapján kell értelmezni a dolgokat.

Léteznek más különleges műveletek is:

a++;    az a értékét növeli egyel.
a--;     az a értékét csökkenti egyel.a*=b;   az a-t megszorozza b-vel
a+=b;   az a-hoz hozzáadja a b-t
(stb, a többi művelettel is működik)

 

 

 

 

 

#include <stdio.h>
#include <stdlib.h>

int main(){

   int a=6;
   int b=5;
   if((a>2)&&(b>2)){
       printf("hai\n");
   }
}

Feltételvizsgálatnál a && karakterekkel jelezhessük a logikai és műveletet.

 

#include <stdio.h>
#include <stdlib.h>

int main(){

   int a=6;
   int b=1;
   if((a>2)||(b>2)){
       printf("hai\n");
   }
}

A a || karakterekkel pedig a logikai vagy műveletet (altgr+w).

 

A tömbök működése elég egyszerű:

 

#include <stdio.h>
#include <stdlib.h>

int main(){

   int a[10];
   a[3]=1;
   for(int i=0;i<10;i++){
       printf("%d\n", a[i]);
   }
}

A tömb deklarálásához kockás zárójeleket használunk [ ]. (altgr f és g). A tömbök indexe nullától kezdődik, és a példában az utolsó használható index a 9-es. A 4. értéket (ami a 3. index) 1-re állítom, a tömbben lévő többi szám értéke viszont bármi lehet. Valószínűleg nulla lesz, de ez egyáltalán nem biztos, és ez nagyon fontos.

 

A c-ben nincs szövegkezelés, hanem helyette karaktertömböket lehet használni.

 

#include <stdio.h>
#include <stdlib.h>

char macskosz[20]=" cica";

int main(){
   char a[30];
   strcpy(a, "neko");
   printf("%s\n", a);
   strcat(a, macskosz);
   printf("%s\n", a);
}

Az strcpy szöveget másol tömbökbe más tömbökből. Az idézőjelbe írt szövegek belsőleg szövegtömbökké alakulnak. Az strcat a szöveg végéhez fűz hozzá dolgokat. Nagyon fontos, hogy a C-ben nincs tömb-méret nyilvántartás, ha kifutsz a tömbből, fagyás következhet be.

A C onnan tudja, hogy meddig tart a szöveged, hogy a szöveg végén egy nulla értékű karakter van. Az strcpy, strcat, stb jellegű függvények az általuk összeállított szövegek végére mindig egy nulla kódú karaktert fűznek be. A szöveg hosszát a

long long hossz=strlen(valtozo);

segítségével deríthetjük ki. Fontos megjegyezni, hogy ezek a szövegkezelő függvények pusztán az egyszerűség kedvéért kerültek be, de NAGYON lassúak! Sebességkritikus helyeken tilos őket használni!

 

 

C-ben a változók valójában egyfajta memóriacímek, és a tömbök is egyfajta memóriacímeknek tekinthetők. Mivel a C féluton van az alacsony, és a magasszintű nyelvek között, ezért ezekkel speciális dolgokat is elvégezhetünk. Valójában az strcat, és az strcpy is ezt csinálja, azok is csak egyszerű, C-ben implementált függvények.

 

 

#include <stdio.h>
#include <stdlib.h>

int main(){

   int a=0;
   int *b=NULL;

   b=&a;
   a=3;
   printf("%d\n", b[0]);
   printf("%d\n", *b);
}

A változó deklarálásában a * jel azt jelenti, hogy pointerként (memóriamutatóként) szeretnénk használni az adott kifejezést, tehát az nem közvetlenül egy változó lesz. Aztán a b nevű pointernek értéket adva a pointer úgy viselkedik, mint egy tömb. Lényegében a tömbök is memóriamutatók, csak a kezdőcímüket nem lehet átállítani.

A b=&a; kifejezésben a &a az lényegében az a változó címét dereferrálja (tehát nem az a változó értékét, hanem az a változó címét adjuk át).

 

 

 

 


 

#include <stdio.h>
#include <stdlib.h>

int main(){

   int *b=(int*)malloc(100);
   free(b);
}

 

A malloc segítségével memóriát kérünk a rendszertől. A memória, amit megkaptunk, a b pointeren foglal helyet, tömbként használhatjuk. Amikor már nincs rá szűkség, a free segítségével felszabadíthatjuk.

Magától ezek a területek sosem szabadulnak fel, tehát ha nem szabadítod fel, és sok ilyet lefuttatsz, betellik előbb-utóbb a memória, és lefagy a programod. Ha felszabadítottunk egy memóriaterületet, akkor azzal visszaadjuk az operációs rendszer számára azt.

FONTOS: a kényes adatokat - pl jelszavakat - tartalmazó adatokat töröljük le az előtt, hogy visszaadjuk az operációs rendszernek.

FONTOS2: az operációs rendszer által adott adatok NEM ÜRESEK, HANEM TELE VANNAK MEMÓRIASZEMÉTTEL.

 

 

 

 

 

 

#include <stdio.h>
#include <stdlib.h>

int main(){
   FILE * macska=fopen("cica.txt", "wb");

   fputs("bajszos", macska);
   fclose(macska);
}

A fájlkezelés hasonlóan történik más nyelvekhez. A fopen második paramétere specifikálja, hogy írási "wb", vagy olvasási "rb" módban nyitjuk meg a fájlt. A b betű a bináris fájlok esetén fontos, amúgy érdemes elhagyni, mert egyes platformok ugyanis máshogy kezelik le például a sorvégeket. fputs mellett létezik még fgets (ami kiolvas a fájlból), fprintf (ami printfhez hasonló, viszont fájlba ír), fread és fwrite (ami a megadott méretben a nyers adatokat másolja ki a fájlokból, vagy írja be). Az fseek függvénnyel ,,tekerhetünk'' a megnyitott fájlban a megadott bit-re. fseek(File, 9, SEEK_SET); - ez a kliencedik bájthoz teker, ez pedig: fseek (File , 9 , SEEK_CUR); 9 bájttal tovább teker. a SEEK_END paraméter az utolsó bájthoz képest visszateker, pl az fseek (File , 0 , SEEK_END); a fájl végére, ahonnét aztán a long long meret=ftell(File) segítségével megmondhatjuk pl a fájl méretét.

 

 

 

 

Kommentek:

C-ben is lehet kommenteket elhelyezni a forráskódban:

a=b+c; // Ez egy komment

vagy:

/*
ezek itt

kommentek
*/

 

 

Egyéb érdekes, és hasznos függvények:

long long eredmeny=strcmp(szoveg1, szoveg2);    // Ha az eredmény 0, akkor a két szöveg megegyezik
char * hely=strstr(ebbenaszovegben, eztkeresem);    // Egy pointert ad, ha az adott szövegben megtalálja a szövegrészletet
long long rand(); // visszaad egy véletlen számot (inicializálni kell egyszer a srand(time(NULL))) függvény segítségével. FIGYELEM: nem biztoságos függvény, titkosításokhoz nem használható.
long long atoi(szoveg);  // számot csinál a szövegből, math.h-ban találjuk
float atof(szoveg); // lebegő pontos számot csinál a szövegből, math.h-ban találjuk
memcpy(cel, forras, meret); // a forrás memóriacímről (tömbről, pointerről, stb) a cel-ra másol méret méretben. Ezt a string.h fájlban találjuk.
float szam2=sqrtf(szam); // gyökvonás, ezt a math.h-ban találjuk
float szam2=sinf(szam); // szinusz (és egyéb szögfüggvények), a bemenet radiánban értendő


 

Amire figyelni kell:

A tagoltság. Használj tabulátort ahhoz, hogy a megfelelő kifejezések beljebb kezdődjenek.

-Minden lefoglalt memóriaterületet fel kell szabadítani, ha már nincs rá szűkség. Persze a program kilépésénél exit(0); ezek autómatikusan felszabadulnak, de amíg a programunk fut, addig a memóriában maradnak, amíg másképp nem döntünk. A c közvetlen memóriakezelése lehetővé teszi a gyors kódok írását, de fokozott körültekintést igényel.

-Fordításnál érdemes bekapcsolni az optimizációt (Optimise code even more -O3), és a stripet (-s). Az optimizálás bekapcsolása nélkül lassú lehet a program futása.

-Figyeljünk arra, hogy a megfelelő architektúrára fordítsunk (pl march=i586), máskülönben olyan opkódokat fordíthat bele a fordító, mint amilyen a te géped is támogat (pl SSE3), így aztán régebbi gépeken a szoftvered nem fog futni. 64 bit esetében értelemszerűen nem az i586, hanem a march=athlon64 használata a legcélszerűbb, mert az minden 64 bites x86-on futni fog.

-Ha gyors programot akarsz írni, akkor a lassú részeket érdemes threadolni (több szálra bontani, így több processzormagon gyorsabban fog futni a programod). Ez azonban platformonként más, windows alatt CreateThread, linux alatt pthread_create. A threadeket is meg kell semmisíteni, ha már nincs szűkségük rá, ugyanis a handlereik, ha nem szabadítjuk fel őket, előbb utóbb a program fagyásához vezetnek, miután feltorlódnak.

Remélem, hogy az itt leírt leírás hasznos útmutatást nyújt minden érdeklődő számára, persze sok dologra a cikk időhiányban nem térhetett ki (pl több dimenziós pointerek és tömbök (int ** cica), (int cica[10][10], definek, ifdef, különböző érdekes beépített függvények, stb) de a lényeg igazából annyi, amennyi itt le van írva.

 

A C programnyelv lényege tehát, hogy közelebb hozza a processzort a programozóhoz annélkül, hogy közvetlenül az adott utasításkészletre kellene dolgozni, megtartja a magas szintű nyelvek kényelmét, miközben direkt elérést biztosít a memóriához, élesen elválasztja egymástól magát a programozást, a programnyelvet, és az operációs rendszer általá biztosított API-kat, és lehetővé teszi olyan szoftverek írását, amik kifacsarnak minden egyes órajelnyi teljesítményt a processzorból, miközben a nyelv, és a benne írt szoftver is megőrzi az egyszerűségét, primitívségét, könnyedségét.

A bejegyzés trackback címe:

https://gerilgfx.blog.hu/api/trackback/id/tr207785520

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

Nincsenek hozzászólások.
süti beállítások módosítása