Cee ehk minu C teadmised

printf ja scanf

Mugav võimalus formaaditud väljundu ja sisendiga töödata.

Väljund: printf(See on vastus %d, a); kus siis kuvatakse standardväljundisse, harilikult ekraanile: See on vastus 10 - oletame et muutuja a oli ennem väärtustatud int a = 10;

Sisend: scanf(%d, &a); loeb standardsisendist, harilikult klaviatuur, ja omistab selle antud juhul a väärtuseks. Functsiooni sees võib kasutada mitut parameetrit. Ntx. scan(“%d %d”, &a, &b); loeb standardsisendist kaks integer muutujat mis on eraldatud tühikuga.scan(“%dja%d”, &a, &b); loeb standardsisendist kaks arvu mis on eraldatud stringiga ’ja’

Kindlasti peab kasutama scanf() juures pointeri märki ’&’

Põhilised formaadid on:

int (4 baidine numbriline) – %d Olemas on veel double (8 baidine) ja short (2 baidine)
float (floating point values) – %f
char (single character values) – %c
character strings – %s

Unsigned versus Signed

Niipalju kui asi puudutab integer tüüpe siis
Signed tüübi puhul on vahemik minimaalne negatiivne arv ja maksimaalne positiivne arv. Ehk siis tüüp millel on märgi (-) positiivne või negatiivne bitt.

  • unsigned int two bytes or four bytes 0-65,535 or 2,147,483,647. Tüüp millel ei ole märgi bitti.
  • int two bytes or four bytes  32,768 or -2,147,483,648 – 32,767 or 2,147,483,647

Mäluregistrid(32bit)

EAX, EBX, ECX, EDX, ESI, EDI – põhiregistrid, millest ESI ja EDI on index registrid.
4 segment registers (CS, SS, DS, ES) – Kasutatakse segmented memory model modes.
EIP - instruction pointer – sisaldab mäluaadressi kus parajasti koodi täitmine käib.
EBP  - frame pointer.
ESP - stack pointer.
EFLAGS - näitab CPU hetke olekut.

#include – This line includes the “standard I/O library” into your program. The standard I/O library lets you read input from the keyboard (called “standard in”), write output to the screen (called “standard out”), process text files stored on the disk.

The line int main() declares the main function. Every C program must have a function named main somewhere in the code.

You can print all of the normal C types with printf by using different placeholders:
int (integer values) uses %d
float (floating point values) uses %f
char (single character values) uses %c
character strings (arrays of characters, discussed later) use %s
man 3 printf

Muutujad mis on defineeritud väljaspool functiooni on globaalsed. Functioonide seest saab neid kasutada.
näiteks:

int a = 10;

void test () {
int b = 20;

/*a = 10 ja b = 20*/

}

int main () {

/*a = 10 ja b on defineerimata*/
int b = 30;
/*b = 30*/

}

Typecasting (tüübiteisendus)

C nagu ka paljudes teistes keeltes, saab n.n lennult tüüpe teisendada. Kindlasti tuleb seda ette töödates pointeritega.

Näiteks float a; a=10/3 annab 3.000000 aga a=(float)10/3 annab 3.333333 S.t tüüp tuleb panna sulgudes muutuja ette.

makefile ja libraries

Suuremate ja keerulisemate programmide kirjutamisel on abiks kui te struktureerite oma programmi.
Funktsioone mida kasutate pidevalt tasub kirjutada eraldi faili ja hiljem includeda, nagu te näiteks includite stdio.h on tegelt kellegi poolt kunagi kokku pantud vajalikud functioonid – library.
Oletame et teil on funktsioonif mis kontrollivad sisendandmete õigsust - isikukood, email jne..
library koosneb alati kahest failist header fail mis on soovitatavalt .h laiendiga ja mis sisaldab endas infot selle kohta
milliseid teisi library-d kasutab loodav library. Samuti loodavas library-s kasutatavate funktsioonide prototüüpe. header failis defineeritud prototüübi ees on “extern” mis näitab ära selle et funktioon lingitakse hiljem.

ntx. myheader.h

funktioonid lähevad faili mis on tavaliselt .c laiendiga nagu tavaline C kood. Seal peab kindlasti olema #include “myheader.h” ehk siis header antud library-le. Oletame et antud faili nimi on meil mylibrary.c

Nüüd loome põhifaili main.c kus saame siis kasutada loodud library mylibrary.c võimalusi incluudides (#include “myheader.h”)

Nii nüüd tuleb kõik need failid linkida ja kompileerida.
Esiteks kompikeerime ja loome objektfaili gcc -c -g mylibrary.c mille tulemusena saame faili mylibrary.o e. objektfaili.
Teiseks kompileerime põhifaili gcc -c -g main.c
Kolmandaks seome(lingime) põhikoodi ja header faili gcc -o main.o mylibrary.o mille tulemusel on meil käivitatav main.

Samas kui te teete palju muudatusi ja arendate oma koodi jne… on suhteliselt tüütu koguaeg käsitsi kompileerida ja linkida.
Siinkohal saame kasutada makefile faili. Selles failis saab kirjeldada ära seosed ja kompileerimised ja linkimised
ja siis on teil ainult anda käsk make ja kogu kompileerimine ja linkimine tehakse ära automaatselt.

makefile formaat on lihtne

main: main.o myheader.o(reavahetus)
(tab)gcc -o main main.o myheader.o
main.o: main.c mylibrary.h(reavahetus)
(tab)gcc -c -g main.c
myheader.o: mylibrary.c myheader.h(reavahetus)
(tab)gcc -c -g mylibrary.c

Read mis on joondunud vasakule ehk formaadis fail: fail fail on n.n dependency read
ja antud juhu read mis algavad gcc on n.n käivitatavad read mis sisaldavad siis unix süsteemis käivitatavaid käske.

Funktsioonide prototüübid

Funktsiooni prototüüp kirjeldab programmi alguses ära programmis kasutatavad funktsioonid,
nende sisendmuutujate tüübid ja tagastatava väärtuse tüübi.

Struktuurid

Oletame et meiel tuleb tegeleda palju inimeste admetega. Meil oleks vaja hoida muutujaid, inimese eesnimi, inimese perenimi, inimese isikukood… jne…

Saame defineerida struktuuri:

struct inimene {
character eesnimi,perenimi;
int isikukood;
};

struct inimene p; // defineerime muutuja p struktuuriga inimene
Nüüd on meil võimalus teha:
p.eesnimi = ’Margus’;
p.perenimi = ’Roo’;
p.isikukood = ’***********’;

Typedef

Hea näide iseloomustamaks typedef võimalusi räägime sellest, et C puudub otseselt selline tüüp nagu boolean mida näiteks PHP-s ollakse harjunud kasutama. Samas pole mingi probleem alloleva näite varal see võimalus luua.

#define TRUE 1 // TRUE on 1
#define FALSE 0 // FALSE on 0
typedef int boolean; // boolean on int tüübi alias

void main(){
boolean b; // defineerime muutuja b boolean(int) tüüpi
b=FALSE; // b = 0
}

Define

Kui meil on tegemist mingite kindlate väärtustega programmi sees siis on need hea kusagil alguses defineerida.
Oletame et me kasutame pi väärtust oma arvutustes 3.14159265 Iga kord peaksime selle programmi sees väärtustama.
#define PI  3.14159265
antud lause ei lõpe “;” märgiga.

Ja nüüd kogu oma programmi sees kasutate 3.14159265 asemel PI
Hea on see veel sellepärast, et kui ükspäev mingi teadlane avastab, et pi ei ole 3.14159265 vaid on 3.14159266 siis peaksite te oma
programmis kõik pi väärtused ülesse otsima ja vahetama.
Aga kui te PI eelnevalt defineerite siis on ainult programmi päises vahetamise vaev ühes kohas.

definatsioonid kirjutatakse harilikult suurte tähtedega, siis on nad koodis äraruntavad.