PE

¸ TLE

Najpierw wykonuje si¸

e instrukcj¸

e, a potem oblicza wyraże-

nie. P¸

etla zostanie zatrzymana wtedy, gdy (wyrażenie) staje sie P¸

etle while i for

fałszywe.

Przykład:

#include <stdio.h>

while (wyrazenie)

void main()

instrukcja

{

int i,n,sum=0;

for (i=0; i<4; i++) {

printf("Podaj liczbe calkowita: "); P¸

etla

scanf("%d", &n);

sum+=n;

for (wyr1; wyr2; wyr3)

}

instrukcja

printf("Suma: %d\n",sum);

}

jest równoważna rozwini¸

eciu

Ten sam program z użyciem p¸

etli while:

wyr1;

while (wyr2){

#include <stdio.h>

instrukcja

void main()

wyr3;

{

}

int i=0,n,sum=0;

/* Nie zapominac o */

while (i<4) {

/* inicjalizacji

*/

printf("Podaj liczbe calkowita: "); Przykład:

scanf("%d", &n);

sum+=n;

/* ani o inkrementacji

*/

i++;

}

#include <ctype.h>

printf("Suma: %d\n",sum);

/*

atoi:

zamienia

s

na liczbe calkowita

*/

}

int atoi(char s[])

{

Ten sam program z użyciem p¸

etli do–while:

int i,n,sign;

for (i=; isspace(s[i]); i++)

/*

przeskocz

*/

;

/*

biale znaki

*/

#include <stdio.h>

sign=(s[i]==’-’) ? -1:1;

void main()

if (s[i] == ’+’ || s[i] == ’-’) /* przeskocz

*/

{

i++;

/* znak liczby */

int i=0,n,sum=0;

/* Nie zapominac o */

for (n=0; isdigit(s[i]); i++)

do {

/* inicjalizacji

*/

n=10*n+(s[i]-’0’);

printf("Podaj liczbe calkowita: "); return sign*n;

scanf("%d", &n);

}

sum+=n;

i++;

/* ani o inkrementacji

*/

} while (i<4);

printf("Suma: %d\n",sum); W p¸

etli

for

cz¸

esto stosuje si¸

e operator

,

.

}

Przykład:

#include <string.h>

Instrukcja switch

/*

funkcja odwraca tekst

s

w miejscu

*/

void reverse(char s[])

{

switch (wyrazenie) {

int c,i,j;

case

wyrazenie-stale: instrukcje

for (i=0, j=strlen(s)-1; i<j; i++,j--) {

case

wyrazenie-stale: instrukcje

c=s[i];

default: instrukcje

s[i]=s[j];

}

s[j]=c;

}

}

Przykład (program zlicza wyst¸

apienia litery l, spacji i pozostałych znaków):

Wyrażenia oddzielone przecinkiem oblicza si¸

e od lewej do pra-

wej strony, a typem i wartości¸

a wyniku jest typ i wartość prawego

#include <stdio.h>

argumentu.

void main()

{

int letterl=0,spaces=0,rest=0;

while ((c=getch()) != EOF) {

P¸

etla do-while

switch (c) {

case ’l’ : letterl++;

break;

case ’ ’ : spaces++;

do

break;

instrukcja

default:

rest++;

while (wyrazenie);

break;

}

}

float *pz;

printf("%d

%d

%d\n", letterl, spaces, rest);

}

Od wskaznika wymaga sie wskazywania obiektu okreslonego rodzaju!!

Wyjatek

-

wskaznik do

void !!

Instrukcje break i conti-

nue

Rownowazne zapisy:

*ip+=1;

++*ip;

(*ip)++;

W trzecim przypadku niezbedne nawiasy, gdyz operacje okreslone przez jednoargumentowe

*

i

++

sa

break – powoduje natychmiastowe wyjście z najbardziej zagnież-

wykonywane od prawej strony do lewej.

dżonej p¸

etli lub instrukcji switch, w której wyst¸

epuje.

continue – powoduje przerwanie bież¸

acego kroku p¸

etli i wykonanie

od pocz¸

atku nast¸

epnego kroku. Dla p¸

etli while i do ozna-

Wskaźniki i tablice

cza to natychmiastowe sprawdzenie warunku zatrzymania, natomiast w p¸

etli for powoduje przekazanie sterowania do cz¸

eści przyrostowej.

int a[10];

int *pa,x;

Przykłady:

pa=&a[0];

x=*pa;

jest rownowazne

x=a[0];

#include <stdio.h>

/* Liczymy wystapienia*/

*(pa+1)

odnosi sie do

a[1]

char *Ref="H e l l o"; /* spacji */

pa+i

adres do a[i]

void main()

*(pa+i)

rowne a[i]

{

int Count;

for (Count=0; *Ref; Ref++) {

nazwa tablicy

==

wskaznik do zerowego elementu

if (*Ref != ’ ’)

continue;

a == &a[0]

zatem

Count++;

pa=&a[0];

rownowazne

pa=a;

}

a[i]

rownowazne

*(a+i)

printf("%d\n", Count);

}

Różnica mi¸

edzy nazw¸

a tablicy i zmienn¸

a wskaźnikow¸

a

-------Drugi przyklad---------------

#define MAXL 1000

#include <stdio.h>

void main()

/* Usun koncowe odstepy i znaki tab */

pa=a;

pa++;

O.K.

{

int n;

char line[MAXL];

while ((n=getline(line, MAXL)>0) {

a=pa;

a++;

p=&a;

Zle!!

Niedopuszczalne!!

while (--n >= 0)

if (line[n] != ’ ’

&&

Jezeli

adresy

p

q

odnosza sie do tej samej

line[n] != ’\t’ &&

tablicy, to relacje

<, <=, > >=

dzialaja poprawnie.

line[n] != ’\n’)

Grozne moze byc porownywanie adresow do break;

roznych tablic!

line[n+1]=’\0’;

printf("%s\n", line);

}

Przykłady:

}

/*

WERSJA

I

*/

Instrukcja goto i etykiety strlen(char *s) /* podaj dlugosc tekstu */

{

int n;

Najcz¸

eściej jest stosowana do wyjścia z gł¸

eboko zagnieżdżo-

for (n=0; *s != ’\0’; s++)

nych p¸

etli, np.

n++;

return n;

}

for ( ... )

for ( ... ) {

...

if (failed)

/*

WERSJA

II

*/

goto err:

/* skocz do obslugi bledow */

strlen(char *s)

/*

podaj dlugosc tekstu

*/

}

{

...

char *p=s;

err:

/*

popraw lub wypisz komunikat */

while (*p != ’\0’)

p++;

return (p-s);

Wskaźniki i adresy

}

/*

WERSJA

III

*/

x

-

zmienna

strlen(char *s)

/*

podaj dlugosc tekstu

*/

px = &x;

-

przypisanie zmiennej px adresu zmiennej x

{

char *p=s;

px=&x;

y=*px;

jest rownowazne

y=x;

while (*p)

p++;

Deklaracje:

int x,y;

return (p-s);

int *px;

}

/*

WERSJA

IV

*/

strlen(char *s)

/*

podaj dlugosc tekstu

*/

{

char *p=s;

while (*p++)

;

return (p-s);

}

Arytmetyka na adre-

sach

Typowe operacje:

p++;

- przesuniecie do nastepnego elementu p+=i;

- przesuniecie do elementu oddalonego o

i

pozycji od aktualnego

Poprawnymi operacjami wskaźnikowymi s¸

a:

• przypisanie wskaźników do obiektów tego samego typu

• dodawanie lub odejmowanie wskaźnika i liczby całkowitej

• odejmowanie b¸adź porównywanie dwóch wskaźników do elementów tej samej tablicy

• przypisanie wskaźnikowi wartości zero lub przyrównanie wskaźnika do zera

Nie wolno:

• dodawać do siebie dwóch wskaźników ani ich mnożyć, dzie-lić, przesuwać albo składać z maskami, ani też dodawać do nich liczb zmiennoprzecinkowych (wskaźniki nie s¸

a

liczbami całkowitymi)

• wskaźnikowi do obiektów jednego typu przypisać bez rzu-towania wskaźnika do obiektów innego typu (z wyj¸

atkiem

typu void * ).

Argumenty - przeka-

zywanie przez wartość

W j¸

ezyku C wszystkie argumenty funkcji s¸

a przekazywane

przez ”wartość”. Oznacza to, że funkcja otrzymuje kopie argumentów i na nich pracuje. Wywołana funkcja nie może bezpo-

średnio zmienić wartości zmiennej w funkcji wywołuj¸

acej.

Przykład:

/*

Funkcja podnosi argument

base

do potegi

n

*/

int power(int base, int n)

{

int p;

for (p=1; n > 0; n--)

p=p*base;

return p;

}

Zmiana wartości zmiennej n wewn¸

atrz funkcji nie wpływa na

wartość argumentu, z którym została wywołana.