Lekt. Tomas G. Lipnevičius

Slides:



Advertisements
Similar presentations
Memory and Files Dr. Andrew Wallace PhD BEng(hons) EurIng
Advertisements

Strings, Arrays, and Pointers CS-2301 D-term Strings, Arrays, and Pointers CS-2301 System Programming C-term 2009 (Slides include materials from.
1 CSE1301 Computer Programming: Lecture 9 Input/Output.
Strings, Arrays, and Pointers CS-2301, B-Term Strings, Arrays, and Pointers CS-2301, System Programming for Non-Majors (Slides include materials.
CS 161 Introduction to Programming and Problem Solving Chapter 13 Console IO Herbert G. Mayer, PSU Status 9/8/2014 Initial content copied verbatim from.
First Program in C With Output. C Language Keywords.
Strings in C. Strings are Character Arrays Strings in C are simply arrays of characters. – Example:char s [10]; This is a ten (10) element array that.
CMPE13 Cyrus Bazeghi Chapter 18 I/O in C. CMPE Standard C Library I/O commands are not included as part of the C language. Instead, they are part.
CHAPTER 8 CHARACTER AND STRINGS
C++ Standard Library Includes derivatives of Standard C Library
1 Homework Introduction to HW7 –Complexity similar to HW6 –Don’t wait until last minute to start on it File Access will be needed in HW8.
CS-1030 Dr. Mark L. Hornick 1 History of C Ref: “The Development of the C Language” – Dennis Ritchie Summary of C (and Unix) History ATT-Bell Labs/GE.
Functions in C Outline 1Introduction 2Program Modules in C 3Math Library Functions 4Functions 5Function Definitions 6Function Prototypes 7Header Files.
Week 2 - Wednesday.  What did we talk about last time?  C compilation model  Lab 1.
22. FILE INPUT/OUTPUT. File Pointers and Streams Declarations of functions that perform file I/O appear in. Each function requires a file pointer as a.
File Handling In C By - AJAY SHARMA. We will learn about- FFile/Stream TText vs Binary Files FFILE Structure DDisk I/O function OOperations.
Characters and Strings File Processing Exercise C Programming:Part 3.
File IO and command line input CSE 2451 Rong Shi.
Digital Computer Concept and Practice Copyright ©2012 by Jaejin Lee C Language Part 4.
1 Lecture09: File I/O 11/19/2012 Slides modified from Yin Lou, Cornell CS2022: Introduction to C.
CS115 FALL Senem KUMOVA-METİN1 The Fundamental Data Types CHAPTER 3.
Chapter 8: Character and String CMPD144: Programming 1.
Basic I/O in C Computer Organization I 1 August 2009 © McQuain, Feng & Ribbens Stream Model of I/O header file: A stream provides a connection.
CSE1301 Computer Programming: Lecture 6 Input/Output.
GAME203 – C Files stdio.h C standard Input/Output “getchar()”
CTYPE.H Introduction  The ctype header is used for testing and converting characters.  A control character refers to a character that.
1 MT258 Computer Programming and Problem Solving Tutorial 03.
Files A collection of related data treated as a unit. Two types Text
Files. FILE * u In C, we use a FILE * data type to access files. u FILE * is defined in /usr/include/stdio.h u An example: #include int main() { FILE.
C Programming Day 2. 2 Copyright © 2005, Infosys Technologies Ltd ER/CORP/CRS/LA07/003 Version No. 1.0 Union –mechanism to create user defined data types.
Advanced Programming in the UNIX Environment Hop Lee.
Principles of Programming - NI Chapter 10: Character & String : In this chapter, you’ll learn about; Fundamentals of Strings and Characters The difference.
Strings, Arrays, and Pointers
Chapter 4 File Processing
ECE Application Programming
Lecture 11 File input/output
Functions, Part 2 of 2 Topics Functions That Return a Value
Chapter 18 I/O in C.
File I/O.
No Objects, No Type Safety
Introduction to C CSE 2031 Fall /3/ :33 AM.
CGS 3460, Lecture 41 Apr 21, 2006 Hen-I Yang
Standard Libraries in C
CSC215 Lecture Input and Output.
Plan for the Day: I/O (beyond scanf and printf)
C Programming:Part 3 Characters and Strings File Processing Exercise.
CSE1320 Files in C Dr. Sajib Datta
CSE1320 Files in C Dr. Sajib Datta
Programavimo ir IT pagrindai
Programming in C Input / Output.
Input and Output Lecture 4.
Algoritmai ir duomenų struktūros (ADS)
CSI 121 Structured Programming Language Lecture 7: Input/Output
Nijolė Kriščiūnienė PASCAL Nijolė Kriščiūnienė
Lecture 13 Input/Output Files.
CSC215 Lecture Input and Output.
CSC215 Lecture Input and Output.
Text and Binary File Processing
File Input and Output.
Assignment Operators Topics Increment and Decrement Operators
Strings in C Professor Hugh C. Lauer CS-2303, System Programming Concepts (Slides include materials from The C Programming Language, 2nd edition, by Kernighan.
Programming in C Input / Output.
Module 12 Input and Output
Introduction to C EECS May 2019.
File I/O.
Introduction to C CSE 2031 Fall /15/2019 8:26 AM.
Professor Jodi Neely-Ritz University of Florida
I/O CS580U - Fall 2018.
Functions in C Math Library Functions Functions Function Definitions
Chapter 18 I/O in C.
Presentation transcript:

Lekt. Tomas G. Lipnevičius Programavimo ir IT pagrindai 6 paskaita Lekt. Tomas G. Lipnevičius

Programavimo pagrindai Programavimas

Funkcijos //funkcija grazina rezultatą int input_integer(void); //prototipas void main() { int x, y, z; x = input_integer(); y = input_integer(); printf(“Dvieju skaiciu suma: %d\n", z=x+y); } int input_integer(void) int a; do printf(“Iveskite sveika skaiciu: "); scanf("%d", &a); } while (a <= 0); return a; }

Funkcijos //funkcija gauna parametra ir grazina rezultata void main() { int x, y, z=100; int funkcija(int n); //prototipas x = funkcija(z); y = funkcija(z); printf(“Skaiciu suma: %d\n", x+y); } int funkcija(int n) int a; do printf(“Iveskite sveika teigiama skaiciu mazesni nei %d: ", n); scanf("%d", &a); } while (a<=0 || a>n); return a; }

Funkcijos Norint naudoti funkcijas C kalboje reikia suvokti tris sąvokas: funkcijos apibrėžimas, funkcijos prototipas ir funkcijos kvietimas. Funkcijos apibrėžimas nurodo funkcijos pavadinimą, formaliųjų parametrų skaičių bei tipus, apibrėžimus ir operatorius, kurie nusako funkcijos veikimą. Tam tikra apibrėžimų ir operatorių seka yra vadinama funkcijos kūnu. Funkcijos apibrėžimui dar gali priklausyti rezultato, kurį įgauna funkcija, tipas ir atminties klasė. C kalboje nėra reikalavimo, kad funkcijos apibrėžimas eitų būtinai prieš funkcijos kvietimą, t.y. funkciją galima apibrėžti prieš ar po funkcijos main(), galima ją apibrėžti ir kitame faile. Norint, kad kompiliatorius galėtų atlikti tipų atitikimo patikrinimą perduodamų funkcijai parametrų (faktinių argumentų) su formaliais parametrais esančiai funkcijos apibrėžime, prieš funkcijos kvietimą turėtų būti bent funkcijos prototipas. Funkcijos prototipas turi tokį pat formatą kaip ir funkcijos apibrėžimas. Skirtumas tik tame, kad funkcijos prototipas arba aprašymas neturi kūno ir baigiasi kabliataškiu.

Funkcijos Funkcijos prototipas nusako funkcijos pavadinimą, formaliųjų parametrų skaičių ir jų tipus, gražinamo rezultato tipą ir atminties klasę. Formalieji parametrai gali turėti pavadinimus, bet jie kompiliatoriui nėra reikalingi, kadangi jis tikrintina tik tipų atitikimą. C kalbos standartinių bibliotekų funkcijų prototipai randasi atitinkamose antraščių (header) failuose.

Funkcijos apibrėžimas Funkcijos apibrėžimas: [atminties klasė] [tipas] funkcijos_pavadinimas ([formaliųjų parametrų sąrašas]) { Funkcijos kūnas } Atminties klase gali būti: extern arba static Tipas: Čia nurodomas funkcijos rezultato tipas. Šiuo tipu gali būti bet kuris iš bazinių tipų, struktūros ar išvardijimas (enum). Jei tipas nenurodomas pagal nutylėjimą yra manoma, kad tai bus int tipas.

Funkcijos apibrėžimas Funkcijos pavadinimas gali būti su simboliu *. Tai reiškia, kad funkcija grąžina rodyklę. Funkcijos negali grąžinti masyvų ar funkcijų, bet gali grąžinti rodyklę į bet kokį tipą įskaitant masyvus ir funkcijas. Funkcijos rezultato tipas būtinai turi atitikti tipą funkcijos prototipe. Funkcija grąžina rezultatą, jei jos įvykdymas pasibaigia operatoriumi return: return išraiška;

Funkcijos Išraiška gali būti skaičiuojama (pvz. return a + b;), konvertuojama (pvz. return (int) a;) jei būtina į funkcijos rezultato tipą aprašyto funkcijos prototipe ar apibrėžime, ir perduodama į funkcijos kvietimo vietą. Jei operatorius return nenurodomas ar neturi jokios išraiškos – funkcija negrąžina rezultato. Šiuo atveju būtina vietoje funkcijos rezultato tipo naudoti void.

Funkcijos parametrai Formaliųjų parametrų sąrašas: tai tam tikra tvarka surašyti formaliųjų parametrų aprašai. Iš tikrųjų tai yra kintamieji, kurie įgauna reikšmes, kurios yra perduodamos kviečiant funkciją. Formalieji parametrai yra atskiriami kableliais. Parametrų sąrašas gali baigtis ir daugtaškiu (,...). Tai reiškia, kad funkcijos parametrų sąrašas yra kintamas (pvz. funkcijos printf ir scanf). Bet manoma, kad funkcija gali turėti mažiausiai tiek parametrų, kiek jų yra aprašyta iki paskutinio kablelio. Funkcijai galime perduoti daugiau argumentų nei yra aprašyta parametrų iki paskutinio kablelio. Tokiems argumentams nebus daroma tipų patikrinimo kontrolė. Jei funkcijai parametrai nėra perduodami tada naudojame void. Formaliųjų parametrų tvarka ir tipai turi atitikti vienodi ir funkcijos apibrėžime ir prototipe. Faktinių argumentų tipai kviečiant funkciją turi atitikti formaliųjų parametrų tipus. Formalusis parametras gali būti bet kokio bazinio tipo, struktūra, sąrašo, išvardinimo, rodykle ar masyvu.

Funkcijos kūnas Funkcijos kūnas tai sudėtinis funkcijos operatorius, kurį sudaro operatoriai, nusakantys funkcijos veikimą. Jį gali sudaryti ir reikalingų kintamųjų apibrėžimai, kurie naudojami funkcijos kūne. Visi kintamieji apibrėžti funkcijoje yra lokalieji. Tuo metu kai kviečiama funkcija, lokaliems kintamiesiems yra išskiriama atmintis ir įvykdoma jų inicializacija (jei ji nurodyta). Funkcijoje valdymas yra perduodamas pirmam operatoriui ir prasideda funkcijos vykdymas, kuris tęsiasi tol kol nebus pasiektas operatorius return ar funkcijos kūno pabaiga. Valdymas tada yra perduodamas į tą programos vietą kurioje funkcija buvo kviečiama. Jei funkcija turi grąžinti rezultatą – reikia įvykdyti operatorių return ir nurodyti jam grąžinamą reikšmę.

Funkcijos parametrai C kalboje funkcijos parametrai yra perduodami pagal reikšmę ir funkcijoje yra traktuojami kaip lokalieji kintamieji, kuriems yra išskiriama atmintis prieš pradedant vykdyti funkciją, jie yra inicializuojami funkcijai perduodamomis reikšmėmis ir yra prarandami išėjus iš funkcijos kūno. Todėl funkcijoje negalima pakeisti parametro, nes funkcija dirba su argumentų kopijomis. Bet jei vietoje reikšmių funkcijai perduosime rodyklę, funkcijoje pasinaudojus išadresavimo funkcija galima pakeisti parametro reikšmę.

Funkcijos Reikšmių keitimo funkcija: //blogas pavyzdys void mainai (int x, int y) { int temp = x; x = y; y = temp; } //geras pavyzdys void mainai (int *ptr_x, int *ptr_y) int temp = *ptr_x; *ptr_x = *ptr_y; *ptr_y = temp;

Funkcijos prototipas Jei reikia iškviesti funkciją iki jos panaudojimo viename faile arba funkcijos apibrėžimas yra kitame faile, prieš kviečiant tokią funkciją reikia ją aprašyti, t.y. sukurti jai prototipą. Prototipas leis kompiliatoriui atlikti argumentų ir rezultato patikrinimą. Prototipas aprašomas tokiu būdu: [atminties klasė] [tipas] funkcijos_pavadinimas ([formaliųjų parametrų sąrašas]); Skirtingai nei funkcijos apibrėžimas, prototipas yra užbaigiamas kabliataškiu.

Funkcijos_pavadinimas ([išraiškų sąrašas]); Funkcijos kvietimas Funkcija kviečiama taip: Funkcijos_pavadinimas ([išraiškų sąrašas]); Išraiškų sąrašas tai faktiniai argumentai, kurie yra perduodami funkcijai. Funkcijos kvietimas atrodo sekančiu būdu: Pirmiausią yra atliekami skaičiavimai išraiškų sąraše. Pvz. kviečiame funkciją ir perduodame jai parametrus (a+b, c, d-e). Toliau, jei yra žinomas funkcijos prototipas, rezultato tipas yra lyginamas su formaliuoju rezultato tipu, t.y. žiūrima kokio tipo reikšmė yra return operatoriuje ir koks yra rezultato tipas prototipe. Jei jie neatitinka yra arba bandoma suvienodinti tipus arba yra gaunamas atitinkamas pranešimas (pvz. klaida). Toliau tikrinama ar faktinių parametrų skaičius sutampa su formaliųjų parametrų skaičiumi, išskyrus tą atvejį kai turime kintamą kiekį parametrų. Tokiu atveju kompiliatorius patikrina tiek argumentų kiek tipų yra formaliųjų parametrų sąraše ir esant reikalui bando juos suvienodinti. Jei funkcijos prototipe vietoje formaliųjų parametrų turime void, tai reiškia kad funkcijai nėra perduodami argumentai ir funkcijos prototipe neturi būti parametrų. Jei tai ne taip – duodamas atitinkamas pranešimas. Vykdomas formaliųjų parametrų keitimas faktiniais argumentai. Pirmas formalusis atitinka pirmąjį faktinį argumentą ir t.t. Valdymas perduodamas pirmam funkcijos operatoriui. Operatoriaus return vykdymas funkcijos kūne grąžina valdymą ir galimai rezultatą kviečiančiai funkcijai. Jei operatoriaus return nėra, valdymas bus gražintas įvykdžius paskutinį funkcijos operatorių.

Rekursiniai funkcijų kvietimai Bet kuri funkcija C kalboje gali būti išviesta rekursyviai, t.y. gali kviesti pati save. Kompiliatorius leidžia bet kokį skaičių rekursinių kvietimų, bet tą kiekį gali riboti operacinė sistema. Kiekvieno funkcijos kvietimo metu yra išskiriama nauja atmintis, tokiu būdu reikšmės iš prieš tai neužbaigtų kvietimų nedingsta, bet parametrai iš prieš tai neužbaigtų kvietimų nėra pasiekiami. Rekursijos pavydžiu gali būti faktorialo skaičiavimas: n! = 1, kai n=0 ir n!= n* (n-1)!, kai n>1. long faktorialas (int n) { return (n<=1) ? 1 : n * faktorialas (n-1); }

Rekursiniai funkcijų kvietimai //Faktorialo n!= 1* 2 *...* n skaiciavimas 0!=1, Vn>0, n!=n *(n -1)! #include<stdio.h> long Faktorialas(long); int main() { int n; printf("Iveskite sveika skaciu: "); scanf("%d", &n); printf ("%d! = %d\n", n, Faktorialas(n)); return 0; } long Faktorialas(long skaicius) if ( skaicius <=1 ) return 1; else return (skaicius * Faktorialas(skaicius - 1));

ctype.h <ctype.h> - simbolių tikrinimų funkcijos.   int isalnum(int c); grąžina 1 jei tai didžioji raidė, 2 – jei mažoji, 0 – jei skaičius. Analogais gali būti isalpha(c) ar isdigit(c); isalpha(c) or isdigit(c) grąžina 1 jei tai didžioji raidė, 2 – jei mažoji, 0 – jei skaičius. Analogais gali būti isupper(c) ar islower(c); int isalpha(int c); isupper(c) or islower(c) int iscntrl(int c); //is control character. In ASCII, control characters are 0x00 (NUL) to 0x1F (US), and 0x7F (DEL) int isdigit(int c); //is decimal digit

ctype.h int isgraph(int c); //is printing character other than space int islower(int c); //is lower-case letter int isprint(int c); //is printing character (including space). In ASCII, printing characters are 0x20 (' ') to 0x7E ('~') int ispunct(int c); //is printing character other than space, letter, digit int isspace(int c);/ /is space, formfeed, newline, carriage return, tab, vertical tab int isupper(int c); //is upper-case letter int isxdigit(int c); //is hexadecimal digit int tolower(int c); //return lower-case equivalent int toupper(int c);

math.h double exp(double x); exponential of x double log(double x); natural logarithm of x double log10(double x); base-10 logarithm of x double pow(double x, double y); x raised to power y double sqrt(double x); square root of x double ceil(double x); smallest integer not less than x double floor(double x); largest integer not greater than x double fabs(double x); absolute value of x double modf(double x, double* ip); returns fractional part and assigns to *ip integral part of x, both with same sign as x double fmod(double x, double y); if y non-zero, floating-point remainder of x/y, with same sign as x; if y zero, result is implementation-defined

math.h double sin(double x); sine of x double cos(double x); cosine of x double tan(double x); tangent of x double asin(double x); arc-sine of x double acos(double x);arc-cosine of x double atan(double x); arc-tangent of x double atan2(double y, double x); arc-tangent of y/x

stdio.h EOF Value used to indicate end-of-stream or to report an error. NULL Null pointer constant. SEEK_CUR Value for origin argument to fseek specifying current file position. SEEK_END Value for origin argument to fseek specifying end of file. SEEK_END Value for origin argument to fseek specifying beginning of file. stdin File pointer for standard input stream. Automatically opened when program execution begins. stdout File pointer for standard output stream. Automatically opened when program execution begins. stderr File pointer for standard error stream. Automatically opened when program execution begins.

stdio.h FILE Type of object holding information necessary to control a stream. FILE* fopen(const char* filename, const char* mode); Opens file named filename and returns a stream, or NULL on failure. mode may be one of the following for text files: "r“ text reading "w“ text writing "a“ text append "r+”text update (reading and writing) "w+”text update, discarding previous content (if any) "a+“ text append, reading, and writing at end or one of those strings with b included (after the first character), for binary files. FILE* freopen(const char* filename, const char* mode, FILE* stream); Closes file associated with stream, then opens file filename with specified mode and associates it with stream. Returns stream or NULL on error.

stdio.h int fflush(FILE* stream); Flushes stream stream and returns zero on success or EOF on error. Effect undefined for input stream. fflush(NULL) flushes all output streams. int fclose(FILE* stream); Closes stream stream (after flushing, if output stream). Returns EOF on error, zero otherwise. int remove(const char* filename); Removes specified file. Returns non-zero on failure. int rename(const char* oldname, const char* newname); Changes name of file oldname to newname. Returns non-zero on failure. int fprintf(FILE* stream, const char* format, ...); Converts (according to format format) and writes output to stream stream. Number of characters written, or negative value on error, is returned. Conversion specifications consist int printf(const char* format, ...); printf(f, ...) is equivalent to fprintf(stdout, f, ...) int fscanf(FILE* stream, const char* format, ...); Performs formatted input conversion, reading from stream stream according to format format. The function returns when format is fully processed. Returns number of items converted and assigned, or EOF if end-of-file or error occurs before any conversion. Each of the arguments following format must be a pointer.

stdio.h int scanf(const char* format, ...); scanf(f, ...) is equivalent to fscanf(stdin, f, ...) int fputc(int c, FILE* stream); Writes c, to stream stream. Returns c, or EOF on error. int getc(FILE* stream); Equivalent to fgetc except that it may be a macro. int getchar(void); Equivalent to getc(stdin). char* gets(char* s); Copies characters from stdin into s until newline encountered, end-of-file reached, or error occurs. Does not copy newline. NUL- terminates s. Returns s, or NULL on end-of-file or error. Should not be used because of the potential for buffer overflow. int putc(int c, FILE* stream); Equivalent to fputc except that it may be a macro. int putchar(int c); putchar(c) is equivalent to putc(c, stdout). int puts(const char* s); Writes s (excluding terminating NUL) and a newline to stdout. Returns non-negative on success, EOF on error. int feof(FILE* stream); Returns non-zero if end-of-file indicator is set for stream stream

stdlib.h RAND_MAX Maximum value returned by rand(). NULL Null pointer constant.   int abs(int n); long labs(long n); Returns absolute value of n. double atof(const char* s); ir double strtod(const char* s, char** endp); Converts initial characters (ignoring leading white space) of s to type double. If endp non-null, stores pointer to unconverted suffix in *endp. long atol(const char* s); ir long strtol(const char* s, char** endp, int base); Converts initial characters (ignoring leading white space) of s to type long. void* calloc(size_t nobj, size_t size); Returns pointer to zero-initialised newly-allocated space for an array of nobj objects each of size size, or NULL on error.

stdlib.h void* malloc(size_t size); Returns pointer to uninitialised newly-allocated space for an object of size size, or NULL on error. void* realloc(void* p, size_t size); Returns pointer to newly-allocated space for an object of size size, initialised, to minimum of old and new sizes, to existing contents of p (if non-null), or NULL on error. On success, old object deallocated, otherwise unchanged. void free(void* p); If p non-null, deallocates space to which it points. void exit(int status); Terminates program normally. int rand(void); Returns pseudo-random number in range 0 to RAND_MAX

string.h NULL Null pointer constant. char* strcpy(char* s, const char* ct); Copies ct to s including terminating NUL and returns s. char* strcat(char* s, const char* ct); Concatenate ct to s and return s. int strcmp(const char* cs, const char* ct); Compares cs with ct, returning negative value if cs<ct, zero if cs==ct, positive value if cs>ct.

time.h struct tm Represents the components of calendar time: int tm_sec; seconds after the minute int tm_min; minutes after the hour int tm_hour; hours since midnight int tm_mday; day of the month int tm_mon; months since January int tm_year; years since 1900 int tm_wday; days since Sunday int tm_yday; days since January 1 int tm_isdst;

limits.h CHAR_BIT number of bits in a char CHAR_MAX maximum value of type char CHAR_MIN minimum value of type char SCHAR_MAX maximum value of type signed char SCHAR_MIN minimum value of type signed char UCHAR_MAX maximum value of type unsigned char SHRT_MAX maximum value of type short

limits.h SHRT_MIN minimum value of type short USHRT_MAX maximum value of type unsigned short INT_MAX maximum value of type int INT_MIN minimum value of type int UINT_MAX maximum value of type unsigned int LONG_MAX maximum value of type long LONG_MIN minimum value of type long ULONG_MAX maximum value of type unsigned long

Masyvai C kalboje perduodant masyvus funkcijoms yra perduodama ne pati duomenų struktūra, o tik rodyklė į ją, t.y. nurodant masyvo pavadinimą iš tikrųjų turime omeny rodyklę į pirmą masyvo elementą. Dėl šios priežasties visi pakeitimai daromi kitose funkcijose su reikalingo masyvo elementais yra “matomi” funkcijose kurioje masyvas buvo apibrėžtas ar kuriai masyvas yra perduodamas. Išvada – masyvo grąžinti iš funkcijos nereikia.

Masyvai Perduodant masyvą funkcijai kartu prasminga perduoti ir jo elementų kiekį: int suma (int masyvas[], int kiekis) { int i, suma; for (i=0; i<kiekis; i++) suma+=masyvas[i]; return suma; } int main() int mas[10], kiekis=10; … printf (“Masyvo elementų suma lygi %d”, suma(mas, 10));

duomenu_tipas *vardas; Rodyklės – kas tai? Kintamasis tai objektas turintis vardą ir kintančią reikšmę. Kintamajam išskiriama atmintis, kurios dydis priklauso nuo tipo. Kintamojo reikšme gali būti adresas. Rodyklės tipo kintamasis apinrėžiamas taip: duomenu_tipas *vardas; pvz.: int *ptr; char *eilute; Teoriškai rodyklė galėtų “rodyti” į bet kokią atminties vietą, bet praktiškai rodyklė “rodo” į adresą kuriuo saugomas nurodyto tipo objektas.

duomenu_tipas *vardas; Rodyklės – kas tai? Kintamasis tai objektas turintis vardą ir kintančią reikšmę. Kintamajam išskiriama atmintis, kurios dydis priklauso nuo tipo. Kintamojo reikšme gali būti adresas. Rodyklės tipo kintamasis apibrėžiamas taip: duomenu_tipas *vardas; pvz.: int *ptr; char *eilute; Teoriškai rodyklė galėtų “rodyti” į bet kokią atminties vietą, bet praktiškai rodyklė “rodo” į adresą kuriuo saugomas nurodyto tipo objektas.

Rodyklės – kas tai? Rodyklė tai kintamasis kurios reikšme yra kito kintamojo adresas (eng. pointer). Sakome, kad jei vienas kintamas saugo kito kintamojo adresą, tai pirmas kintamasis “rodo” į antrą.

Rodyklės – kas tai? Kaip ir kito tipo objektams saugoti, rodyklės reikšmei saugoti reikalingas tam tikras baitų kiekis. Šis kiekis priklauso nuo naudojamos platformos. (Pvz. 32 bitų platformoje adresui saugoti reikia 4 baitų).

Pagrindiniai operatoriai Pagrindiniais operatoriais kurie operuoja rodyklės tipo operandais yra: * - išadresavimo operatorius. Šis unarinis operatorius “paima” tikrąją reikšmę pagal operando adresą. Šio operatoriaus operandais gali būti tik rodyklės tipo kintamieji. & - adreso operatorius. Šio unarinio operatoriaus rezultatas yra nurodyto kintamojo adresas. Šio operatoriaus rezultatas gali būti priskiriamas tik rodyklės tipo kintamiesiems. Šio operatoriaus operandais gali būti tik kintamieji arba masyvo elementai.

Pavyzdys #include <stdio.h> void main() { int num; int *p; num = 10; p=&num; printf(“Adreso operatoriaus panaudojimas: %p”, p); printf(“Išadresavimo operatoriaus panaudojimas: %d”, *p); }

Pavyzdys #include <stdio.h> void main(void) { int num, q; int *p; num = 100; p = &num; q = *p; printf("%d", q); }

Pavyzdys #include <stdio.h> int j, k; int *ptr; void main(void) { j = 1; k = 2; ptr = &k; printf("j reiksme %d ir jos adresas %p\n", j, &j); printf("k reiksme %d ir jos adresas %p\n", k, &k); printf("ptr reiksme %p ir jos adresas %p\n", ptr, &ptr); printf("Reiksme i kuria rodo ptr yra %d\n", *ptr); }

Pavyzdys #include <stdio.h> void main() { int num; num = 10; //Kam bus lygu *&num ? //O *&*&num ? //O *&*&*&*&*&*&*&num? }

Rodyklės tipo kintamųjų inicializavimas Paprastieji globalieji kintamieji, juos apibrėžiant bet nepriskiriant jiems reikšmės, įgauna reikšmę 0 (pagal ANSI standartą). Rodyklės tipo kintamasis nėra inicializuojamas pagal nutylėjimą, jei jam reikšmė nėra priskiriama apibrėžimo metu. Sakome, kad rodyklė rodys į jokį objektą, t.y. jos reikšmė bus NULL. NULL yra makrosas kuris leidžia, nepriklausomai nuo naudojamos platformos, realizuoti tuščią rodyklę. Šį makrosą galima naudoti priskyrime arba palyginimo sakiniuose, pvz.: if (ptr == NULL) ...

Rodyklių priskyrimas Reikšmės rodyklės tipo kintamiesiems priskiriami įprasta tvarka. #include <stdio.h> void main (void) { int x; int *p1, *p2; p1 = &x; p2 = p1; printf ("%р %р", p1, р2); }

Rodiklių aritmetika Unarinės operacijos * ir & turi aukščiausią prioritetą. Kuo skiriasi *ptr++; ir *(ptr++);? Rodyklės tipo kintamiesiems gali būti taikomos operacijos: galima pridėti integer tipo skaičių prie rodyklės tipo kintamojo reikšmės; pvz. ptr1++, ptr1 + i galima atimti integer tipo skaičių nuo rodyklės tipo kintamojo reikšmės; pvz. ptr1--, ptr1-i galima atimti vienos rodyklės tipo kintamojo reikšmę nuo kitos rodyklės tipo kintamojo reikšmės; pvz. ptr2-ptr1 – gausime elementų kiekį tarp ptr1 ir ptr2. Tas skaičius gali būti neigiamas. Adresų negalima dauginti, dalinti, iš jų negalima atimti ar pridėti float ar double tipo reikšmių. Rodyklės tipo kitamiesiems negalima taikyti postūmio operacijų. Tarkime turime int *ptr kur ptr adresas yra 1000. Jei atliksim operaciją ptr++; kokia bus ptr reikšmė? Int atveju 1004. Atitinkamai ptr— Adresą galime apskaičiuoti pagal formulę: Pradinis_adresas + n*sizeof(duomenu_tipas), kur n elementų kiekis.

Rodiklių aritmetika #include <stdio.h> int const N = 10; void Spausdinti(int *); int main() { int masyvas[N], i; for (i=0;i<N; i++) masyvas[i]=(i+1)*10; } Spausdinti(masyvas); return 0; void Spausdinti(int *p) int i; printf("%2d-asis masyvo elementas yra: %d\n", i+1, *(p+i)); printf("Masyvo elemntu kiekis: %d", (p+N) - p);

Rodyklių palyginimas Rodyklės tipo kintamiesiems gali būti taikomos palyginimo operacijos: == palyginti ar du rodyklės tipo kintamieji turi vienodas reikšmes; pvz ptr1 == ptr2 teisybė jei ptr1 ir ptr2 rodo į tą patį elementą != palyginti ar du rodyklės tipo kintamieji turi nevienodas reikšmes; pvz ptr1 != ptr2 teisybė jei ptr1 ir ptr2 rodo į skirtingus elementus >, <, >=, <= palyginti rodyklių reikšmes. ptr1<ptr2 arba ptr1<=ptr2 gausime teisybę jei ptr1 rodo į masyvo elementą su mažesniu ar lygiu indeksu nei ptr2

Rodyklių palyginimas #include <stdio.h> int const N = 10; int main() { int masyvas[N], i; int *p, *k; for (i=0;i<N; i++) masyvas[i]=(i+1)*10; } p = masyvas + 5; k = masyvas + 6; printf ("p reiksme: %d\n", *p); printf ("k reiksme: %d\n", *k); if (p == k) printf("rodykles p ir k rodo i ta pati objekta"); else printf("rodykles p ir k rodo i skirtingus objektus"); return 0;

Rodyklių palyginimas #include <stdio.h> int const N = 10; int main() { int masyvas[N], i; int *p, *k; for (i=0;i<N; i++) masyvas[i]=(i+1)*10; } p = masyvas + 5; k = masyvas + 6; printf ("p reiksme: %d\n", *p); printf ("k reiksme: %d\n", *k); if (p < k) printf("rodykles p rodo i masyvo elementa su mazesniu indeksu nei k"); return 0;

Rodyklės ir masyvai int main(void) { int my_array[] = {1,23,17,4,-5,100}; int *ptr; int i; ptr = &my_array[0]; // ptr rodys i pirma masyvo elementa //ptr = my_array; printf("\n"); for (i = 0; i < 6; i++) printf("my_array[%d] = %3d\t",i,my_array[i]); //eilute A: paimam masyvo reiksme naudojantis indeksu printf("ptr + %d = %3d\n",i, *(ptr + i)); //eilute B: paimam masyvo reiksme taikydami rodykliu postumius } return 0;

Rodyklės ir masyvai ptr = &my_array[0]; ir ptr = my_array; yra tas pats. Bet my_array = ptr rašyti negalima, nes ptr yra kintamasis o my_array yra konstanta, todėl pirmo masyvo elemento adreso pakeisti negalima, nes atmintis visiems masyvo elementams buvo jau išskirta masyvo apibrėžimo metu.

Pavyzdys #include <stdio.h> #define DYDIS 10 main() { int masyvas[DYDIS]; int suma = 0; int i; int *p; for (i=0;i<DYDIS;i++) {masyvas[i] = i+1;} //skaiciuojame masyvo elementu suma //1 budas {suma = suma + masyvas[i];} printf ("Masyvo elementu suma yra %d\n", suma);

Pavyzdys //2 budas suma = 0; p = &masyvas[0]; for (i=0;i<DYDIS;i++) { suma = suma + (*p); p++; } printf ("Masyvo elementu suma yra %d\n", suma); //3 budas suma = 0; {suma = suma + *(p + i);} printf ("Masyvo elementu suma yra %d\n", suma);

Daugiamačiai masyvai #define ROWS 5 #define COLS 10 int multi[ROWS][COLS]; Norint pasiekti konkretų elementą rašysime multi [row][col] arba *(*(multi + row) + col). Pakeiskime reiškinį *(multi + row) reikšme X – tada aukščiau parašytą reiškinį parašytume *(X + col). X šiuo atveju yra rodyklė o col yra integer tipo skaičius, t.y. matome paprastą aritmetinę operaciją kuriai pritaikyta išadresavimo operacija. Žiūrint į šiuos pertvarkymus galime pasakyti kad iš tikrųjų turime tik vienmatį masyvą kuriame eilutės eina viena po kitos, t.y. bet kurį daugiamatį masyvą galime pertvarkyti į vienmatį masyvą.

Daugiamačiai masyvai Trimatis masyvas int arr[L][M][N]. Kadangi šį masyvą galime interpretuoti kaip masyvą kurio elementais yra dvimačiai masyvai MxN tai norint gauti tam tikrus elementus masyve galime taikyti šias operacijas: ptr – masyvo L pirmo elemento adresas, t.y. šiuo atveju pirmas elementas yra pirmas masyvas MxN ptr + i *(M*N) - masyvo L i-tojo elemento adresas ptr + i*(M*N) + j *N - masyvo L j-tojo elemento adresas ptr + i*(M*N) + j *N + k - masyvo L k-tojo elemento adresas *(ptr + i*(M*N) + j *N + k) - masyvo L k-tojo elemento reikšmė

Rodyklės į neapibrėžtą tipą void * rodykles_vardas; Žodis void leidžia mums konkretizuoti tipą vėliau, t.y. programos vykdymo metu. Tokio tipo rodyklė gali rodyti į bet kokio objekto tipą. Bet norint operuoti su neapibrėžto tipo rodyklėmis reikia pirmiausia atlikti konvertavimo operaciją: #include <stdio.h> main() { int a = 10; double d = 5.236; void *vp; vp = &a; printf ("a=%d\n", *((int *) vp)); vp = &d; printf ("d=%f\n", *((double *) vp)); }

Rodyklių taikymas Duomenų perdavimas pagal adresą (byref) main() { int x,y; …. x = 5; y = 10; swap (x,y); … } void swap (int a, int b) int temp; temp = a; a = b; b = temp;

Rodyklių taikymas void swap (int *a, int *b) { int temp; temp = *a; *a = *b; *b = temp; } main() int x, y; … swap ( &x, &y);

Galimos klaidos #include <stdio.h> void main() { int x = 65000, y; short *ptr; ptr = &x; y = *ptr; printf ("x=%d\n", x); printf ("y=%d\n", y); // kodel gausime kita skaiciu??? }

Galimos klaidos void main (void) { int х, *р; х = 10; *р = х; // klaida, kodėl??? }

Galimos klaidos #include <stdio.h> void main(void) { int x, *p; x = 10; p = x; // klaida, kodel??? printf ("%d", *p); }