¸ 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.