C v kostce #2
Co všechno potřebujete vědět k úspěšnému ukončení předmetu
Dotaz - email - srozumitelnost
#include "stdio.h"
int main( int argc, char* argv[] )
{
return 5;
}
Doporučená literatura
Případně jiné ...
… k zapamatování (první přednáška)
Obsah
Vstupní bod programu
#include "stdio.h"
int main( int argc, char* argv[] )
{
return 5;
}
#include <stdio.h>
int main(void)
{
return 0;
}
#include <stdio.h>
void main(void)
{
}
Parametry programu - argc a argv
Stack ↓
Heap ↑
Globální proměnné
Text (a.out)
Výpis parametrů příkazové řádky
...ska$ clang priklad01_args.c
...ska$ ./a.out param1 param2 param3 4 parametr6
Argument 0, ./a.out
Argument 1, param1
Argument 2, param2
Argument 3, param3
Argument 4, 4
Argument 5, parametr6
...ska$ echo $?
5
...ska$
#include "stdio.h"
int main( int argc, char* argv[] )
{
int iCnt;
for( iCnt = 0; iCnt < argc; iCnt++ )
{
printf( "Argument %d, %s\n", iCnt, argv[iCnt] );
}
return 5;
}
Vstup a výstup do programu/procesu
OS nahrává binární kopii programu do paměti
ČAS
Význam návratové hodnoty programu
Čtení vstupu
#include "stdio.h"
int main( int argc, char* argv[] )
{
int iCnt;
int iInput = 0;
for( iCnt = 0; iCnt < argc; iCnt++ )
{
printf( "Argument %d, %s\n", iCnt, argv[iCnt] );
}
printf( "Zadej cislo :" );
scanf( "%d", &iInput );
fprintf( stdout, "Number %d", iInput );
fprintf( stdout, "Novy radek\n" );
if( iInput < 18 )
{
fprintf( stderr, "Err: Too low %d\n", iInput );
}
fprintf( stderr, "stdin=%d, stdout=%d, stderr=%d\n",
(unsigned int)stdin, (unsigned int)stdout, (unsigned int)stderr );
return iInput;
}
Obsah souboru: in.txt
10
Soubor: in.txt v HEXa� - příkaz OS: xxd in.txt
00000000: 3130 0a0a 10..
Překlad:
clang priklad02_presmerovani.c
Převody číselných soustav
Převody čísel: Mocnost * váha
Desítková soustava Dvojková soustava Šestnácková soustava
Obsah souboru - předchozí slide: 3130 0a0a
Ilustrace přesměrování
...ska$ ./a.out param1 param2 param3 4 parametr6 1>out.txt 2>err.txt <in.txt
...ska$
...ska$ cat out.txt
Argument 0, ./a.out
Argument 1, param1
Argument 2, param2
Argument 3, param3
Argument 4, 4
Argument 5, parametr6
Zadej cislo :Number 10Novy radek
...ska$
...ska$ cat err.txt
Err: Too low 10
stdin=177400032, stdout=177403424, stderr=177403200
...ska$
...ska$ echo $?
10
...ska$
Důraz
#include "stdio.h"
int main( int argc, char* argv[] )
{
int iCnt;
int iInput = 0;
for( iCnt = 0; iCnt < argc; iCnt++ )
{
printf( "Argument %d, %s\n", iCnt, argv[iCnt] );
}
printf( "Zadej cislo :" );
scanf( "%d", &iInput );
fprintf( stdout, "Number %d", iInput );
fprintf( stdout, "Novy radek\n" );
if( iInput < 18 )
{
fprintf( stderr, "Err: Too low %d\n", iInput );
}
fprintf( stderr, "stdin=%d, stdout=%d, stderr=%d\n",
(unsigned int)stdin, (unsigned int)stdout, (unsigned int)stderr );
return iInput;
}
Řetězce, načítání vstupu
Parametry programu - argc a argv
Stack ↓
Heap ↑
Globální proměnné
Text (a.out)
for( iCnt = 0; iCnt < argc; iCnt++ )
{
printf( "Argument %d, %s\n", iCnt, argv[iCnt] );
}
#include "stdio.h"
#include "string.h"
int main( int argc, char* argv[] )
{
char chArray[16]; // alokovany prostor, 16 je tzv. Magická konstanta
printf( "Zadej text a stiskni Enter:" );
scanf( "%s", chArray );
printf(, "Number %s", chArray );
return strlen(chArray);
}
16 znamená max. 15 znaků a pak musí být nula
Interakce s uživateleme pomocí std rozhraní
Standardní rozhraní
Existují standardní rozhraní, které je možné přepojovat.
Prototypy funkcí:
int printf( const char *format, … );
int fprintf( FILE *stream, const char *format, ...);
Použití se stejným výsledkem - vytiskne řetězec na obrazovku:
printf( "Ahoj\n" );
fprintf( stdout, "Ahoj\n" );
Pole = řetězec (pozor na paměť)�
#include "stdio.h"
#include "string.h"
#define cARR_MAXLEN 16
int main( int argc, char* argv[] )
{
char chArray[ cARR_MAXLEN ]; //
int iCnt;
printf( "Zadej text a stiskni Enter:" );
scanf( "%s", chArray );
printf( "\nText = %s\n", chArray );
for( iCnt = 0; iCnt < cARR_MAXLEN; iCnt++)
{
printf("The value is %i or as char '%c'\n", chArray[iCnt], chArray[iCnt]);
}
return strlen(chArray);
}
...ska$ ./a.out �Zadej text a stiskni Enter:test
Text = test
The value is 116 or as char 't'
The value is 101 or as char 'e'
The value is 115 or as char 's'
The value is 116 or as char 't'
The value is 0 or as char ''
The value is 0 or as char ''
The value is 0 or as char ''
The value is 0 or as char ''
The value is -32 or as char '�'
The value is 4 or as char ''
The value is 64 or as char '@'
The value is 0 or as char ''
The value is 0 or as char ''
The value is 0 or as char ''
The value is 0 or as char ''
The value is 0 or as char ''
...ska$
#define = direktiva preprocesoru - definice konstanty�Jednoduchá definice konstant - možné použít na několika místech v kódu
Pole v paměti
#define cARR_MAXLEN 6
char chArray[ cARR_MAXLEN ];
chArray[0] = 't';
chArray[1] = 'e';
chArray[2] = 's';
chArray[3] = 't';
chArray[4] = 0 ;
t =0x74
e
s
t
\0
?
Index: 0 1 2 3 4 5
t =0x00 00 00 74
V případě typu int bude obsazení paměti jiné.
#define cARR_MAXLEN 6
int iArray[ cARR_MAXLEN ];
iArray[0] = 't';
iArray[1] = 'e';
iArray[2] = 's';
iArray[3] = 't';
iArray[4] = 0 ;
Abstrakce dat v paměti
char chTmp;�chTmp = '0';��int iArray[3];�iArray[0] = 't'; �iArray[1] = 255; �iArray[2] = 255+1+1; // 0xFF+1+1 = 0x100+1 = 0x101
Prom: | chTmp | iArray[0] | iArray[1] | iArray[2] | | |||||||||
Hodnota: | '0' | 0 | 0 | 0 | 't' | 0 | 0 | 0 | 0xFF | 0 | 0 | 0x01 | 0x01 | |
Hodnota: | 0x30 | 0x00 | 0x00 | 0x00 | 0x74 | 0x00 | 0x00 | 0x00 | 0xFF | 0x00 | 0x00 | 0x00 | 0x00 | |
Adresa: | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | |
Ukazatel - Pointer
char chTmp;�char * pchTmp; // pointer na chTmp = pchTmp�chTmp = '0';
pchTmp = NULL; // přímé přiřazení�pchTmp = &chTmp; // přiřazení adresy proměnné chTmp
printf( "You entered %02i (%c)\n", chTmp, chTmp );
printf( "You entered %02i (%c)\n", *pchTmp, *pchTmp );
Prom: | chTmp | iArray[0] | iArray[1] | iArray[2] | pchTmp | |||||||||
Hodnota: | '0' | 0 | 0 | 0 | 't' | 0 | 0 | 0 | 0xFF | 0 | 0 | 0x01 | 0x01 | 0 |
Hodnota: | 0x30 | 0x00 | 0x00 | 0x00 | 0x74 | 0x00 | 0x00 | 0x00 | 0xFF | 0x00 | 0x00 | 0x00 | 0x00 | |
Adresa: | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 |
Ukazatel - Pointer
char chTmp;�char * pchTmp; // pointer na chTmp = pchTmp�chTmp = '0';
pchTmp = NULL; // přímé přiřazení�pchTmp = &chTmp; // přiřazení adresy proměnné chTmp
printf( "Value %02i (%c)\n", chTmp, chTmp ); // Value 48 (0)
printf( "Value %02i (%c)\n", *pchTmp, *pchTmp ); // Value 48 (0)
printf( "Value %02i (%c)\n", pchTmp, pchTmp ); // špatné použití ukazatele, výsledek 100, ASCII 100 = d, malé d � // Value 100 (d)
Prom: | chTmp | iArray[0] | iArray[1] | iArray[2] | pchTmp | |||||||||
Hodnota: | '0' | 0 | 0 | 0 | 't' | 0 | 0 | 0 | 0xFF | 0 | 0 | 0x01 | 0x01 | 100 |
Hodnota: | 0x30 | 0x00 | 0x00 | 0x00 | 0x74 | 0x00 | 0x00 | 0x00 | 0xFF | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 00 00 64 |
Adresa: | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113,114,115,116 |
Ukazatel - Pointer na integer
int iArray[3];�iArray[0] = 't'; �iArray[1] = 255; �iArray[2] = 255+1+1;�int * piArray; // pointer na iArray = piArray��
Prom: | chTmp | iArray[0] | iArray[1] | iArray[2] | piArray | |||||||||
Hodnota: | '0' | 0 | 0 | 0 | 't' | 0 | 0 | 0 | 0xFF | 0 | 0 | 0x01 | 0x01 | 101 |
Hodnota: | 0x30 | 0x00 | 0x00 | 0x00 | 0x74 | 0x00 | 0x00 | 0x00 | 0xFF | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 00 00 65 |
Adresa: | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113,114,115,116 |
piArray = NULL; // přímé přiřazení��piArray = 101; // přiřazení adresy proměnné iArray[0]�printf( "Value %i (%c)\n", *piArray, *piArray ); // Value 74 (t)
piArray = iArray; // přiřazení adresy proměnné iArray[0]�printf( "Value %i (%c)\n", *piArray, *piArray ); // Value 74 (t)
piArray = &iArray[0]; // přiřazení adresy proměnné iArray[0]�printf( "Value %i (%c)\n", *piArray, *piArray ); // Value 74 (t)
Ukazatel - Pointer na integer
Zápis
int x;
x = iArray[0]; // index je možné modifikovat
// x bude = ‘t’
Prom: | chTmp | iArray[0] | iArray[1] | iArray[2] | piArray | |||||||||
Hodnota: | '0' | 0 | 0 | 0 | 't' | 0 | 0 | 0 | 0xFF | 0 | 0 | 0x01 | 0x01 | 101 |
Hodnota: | 0x30 | 0x00 | 0x00 | 0x00 | 0x74 | 0x00 | 0x00 | 0x00 | 0xFF | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 00 00 65 |
Adresa: | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113,114,115,116 |
Ukazatel - Pointer na integer
int x;
int * piArray; // pointer na iArray = piArray
piArray = iArray;
piArray = &iArray[0];
Prom: | chTmp | iArray[0] | iArray[1] | iArray[2] | piArray | |||||||||
Hodnota: | '0' | 0 | 0 | 0 | 't' | 0 | 0 | 0 | 0xFF | 0 | 0 | 0x01 | 0x01 | 101 |
Hodnota: | 0x30 | 0x00 | 0x00 | 0x00 | 0x74 | 0x00 | 0x00 | 0x00 | 0xFF | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 00 00 65 |
Adresa: | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113,114,115,116 |
Ukazatel - Pointer na integer
int x;
int * piArray; // pointer na iArray = piArray
piArray = iArray;�piArray = &iArray[0]; // dva ekvivalentní zápisy
x = *piArray;
// x bude = ‘t’
Prom: | chTmp | iArray[0] | iArray[1] | iArray[2] | piArray | |||||||||
Hodnota: | '0' | 0 | 0 | 0 | 't' | 0 | 0 | 0 | 0xFF | 0 | 0 | 0x01 | 0x01 | 101 |
Hodnota: | 0x30 | 0x00 | 0x00 | 0x00 | 0x74 | 0x00 | 0x00 | 0x00 | 0xFF | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 00 00 65 |
Adresa: | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113,114,115,116 |
K čemu jsou ukazatele
#include "stdio.h"
int main( int argc, char* argv[] )
{
return 5;
}
Jak číst složité definice?
Např. argv je pole, ukazatelů na char.
Pointer na funkci
Program je sada instrukcí v paměti �- paměťově mapované v oblasti kódu. �Je možné získat adresu instrukce
Parametry programu - argc a argv
Stack ↓
Heap ↑
Globální proměnné
Text (a.out)
#include <stdio.h>
void hello(void)
{
printf("I like PRP!\n");
}
int main(void)
{
hello();
return 0;
}
#include <stdio.h>
void hello(void)
{
printf("I like PRP!\n");
}
int main(void)
{
void (*pFunc)(void) = hello;
pFunc();
return 0;
}
Čtení definicí
char chTmp; // chTmp je proměnná typu char, v paměti zabírá 1 byte = 8 bitů�int iRetVal; // iRetVal je proměnná typu char, v paměti zabírá 4 byte = 4*8 bitů�char chLogin[15]; // chLogin je pole patnácti promenných typu char, zabírá 15*1 byte�int iArray[3]; // iArray je pole tří proměnných typu int, v paměti zabírá 3*4 byte = 3*4*8 bitů�char * pchChar; // pchChar je ukazatel na hodnotu typu char, v paměti zabírá 4 byte = 4*8 bitů�int * piInt; // piInt je ukazatel na hodnotu typu int, v paměti zabírá 4 byte = 4*8 bitů�void (*pFunc)(void) = hello; // pFunc je ukazatel na funkci, která nemá parametr (void) a nevrací žádnou hodnotu void a je inicializovaná na začátek funkce hello - z toho plyne, že hlavička funkce hello musí být void hello(void)
Jak číst složité definice?
Shrnutí
Co se hodí ke zkoušce a státnicím: viz seznam - být schopen mluvit o jednotlivých bodech