Wstęp do programowania w języku C/Tablice
Tablice jednowymiarowe
W C tablice można inicjować podczas deklaracji.
int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
Jeśli liczba elementów początkowych jest mniejsza od długości tablicy, wówczas pozostałe elemnty tablicy inicjowane są na 0. Oto przykład inicjacji tablicy zerami.
int a[10] = {0};
Liczba elementów początkowych nie może być większa od rozmiaru tablicy.
Przykład
Należy wczytać liczbę całkowitą dodatnią typu long int i sprawdzić, czy w jej zapisie wszystkie cyfry są różne.
#include <stdio.h>
#define TRUE 1
#define FALSE 0
typedef int Bool;
main()
{
Bool widziane_cyfry[10] = { 0 };
int cyfra;
long int n;
printf("Podaj liczbe: ");
scanf("%ld", &n);
while (n > 0) {
cyfra = n % 10;
if ( widziane_cyfry[cyfra] )
break;
widziane_cyfry[cyfra] = TRUE;
n /= 10;
}
if ( n > 0 )
printf("Cyfry sie powatrzaja.\n\n");
else
printf("Cyfry nie powtarzaja sie\n\n");
return 0;
}
Rozważmy teraz następujące zadanie. Niech R będzie dwuargumentową relacją na zbiorze
(n jest parametrem zadania). Domknięciem przechodnim relacji R nazywamy relację taką, że para wtedy i tylko wtedy, gdy a = b lub dla pewnego istnieje ciąg elementów z X taki, że . Napisz program, który dla danej relacji R oblicza jej domknięcie przechodnie.#include <stdio.h>
#define Max_n 10
#define TRUE 1
#define FALSE 0
typedef int Bool;
main()
{
Bool R[Max_n][Max_n] = { FALSE };
int i, j, k, n;
printf("Podaj rozmiar zbioru X (1 <= . <= %d) : ",
Max_n);
scanf("%d%", &n);
/* Wczytanie relacji R */
printf("Podawaj kolejne pary relacji R.\n");
printf("Para -1 -1 konczy ciag wejsciowy\n");
printf("Pamietaj, ze relacja jest zdefiniowana\n");
printf(ńa zbiorze {0,...,%d\n", n-1);
scanf("%d %d", &i , &j);
while ( i != -1 ){
R[i][j] = TRUE;
scanf("%d %d", &i , &j);
}
/* Wypisanie poczatkowej relacji. */
printf("\n\nRelacja R\n\n");
for ( i = 0; i < n; i++){
for ( j = 0; j < n; j++)
printf("%d", R[i][j]);
printf("\n");
}
/*Obliczanie domkniecia relacji R*/
for ( i = 0; i < n; i++ )
R[i][i] = TRUE;
for ( k = 0; k < n; k++ )
/*Nzm.: R[a][b] = TRUE wiw, gdy a=b lub
istnieje ciag
elementow a_0, a_1, ...,a_l taki, ze
a_0 = a, a_l = b,
a_1,...,a_{l-1} naleza do {0,...,k-1} oraz
R[a_0][a_1] = TRUE,
R[a_1,a_2] = TRUE,...,
R[a_{l-1}][a_l] = TRUE.
*/
for ( i = 0; i < n; i++ )
for ( j = 0; j < n; j++ )
R[i][j] = R[i][j] || ( R[i][k] && R[k][j] );
/* Wypisanie domkniecia relacji. */
printf("\n\nDomkniecie relacji R\n\n");
for ( i = 0; i < n; i++){
for ( j = 0; j < n; j++)
printf("%d", R[i][j]);
printf("\n");
}
return 0;
}
Funkcje
Rozważmy program, który wczytuje dwie liczby rzeczywiste i liczy ich średnią.
#include <stdio.h>
main()
{
double x, y;
printf("podaj dwie liczby rzeczywiste: ");
scanf("%lf %lf", &x, &y);
printf("(%5.2f+%5.2f)/2 = %5.2f\n\n",x,y,(x+y)/2);
return 0;
}
Oto ten sam program zapisany z użyciem funcji obliczającej średnią.
#include <stdio.h>
double srednia(double x, double y)
{
return (x+y)/2;
}
main()
{
double x, y;
printf("podaj dwie liczby rzeczywiste: ");
scanf("%lf %lf", &x, &y);
printf("(%5.2f+%5.2f)/2=%5.2f\n",x,y,srednia(x,y));
return 0;
}
C nie wymaga definiowania funkcji przed jej wywołaniem. Dobrym zwyczajem jest jednak deklarować funkcję przed miejscem jej wywołania. Tym razem deklaracja funkcji została oddzielona od jej definicji.
#include <stdio.h>
double srednia(double x, double y);
/* Deklaracja funkcji */
main()
{
double x, y;
printf("podaj dwie liczby rzeczywiste: ");
scanf("%lf %lf", &x, &y);
printf("(%5.2f+%5.2f)/2=%5.2f\n",x,y,srednia(x,y));
return 0;
}
double srednia(double x, double y)
/* Definicja funkcji */
{
return (x+y)/2;
}
Funkcja w C nie musi zwracać żadnej wartości. Oto funkcja tab, która dostaje na wejściu liczbę całkowitą $n\in [1..10]$ i wypisuje tabliczkę możenia przez $n$. Zwróć uwagę na słówko kluczowe void które oznacza, że funkcja nie zwraca wartości. Taka funkcja nie może być wywoływana jako część wyrażenia. Wywołanie funkcji tab musi mieć postać:\\ tab({\it parametr});\\
void tab(int n)
{
int i;
for ( i = 1; i <= 10; i++ )
printf("%d * %d = %d\n", n, i, n*i);
}
Funkcja też może nie mieć żadnych parametrów, np.
void gwiazdki(void)
{
printf("*********************");
}
Tak'a funkcję wywułujemy:\\ gwiazdki();\\ Ogólnie definicja funkcji ma postać:\\ {\it typ wartości} nazwa--funkcji ( parametry )\\ \{\\ \hspace{0.5cm}deklaracje\\ \hspace{0.5cm}instrukcje\\ \}\\[0.3cm] Zwróćmy uwagę na różnicę między parametrami i argumentami funkcji. {\it Prametry} występują na poziomie definicji funkcji. Są one ``zmiennymi, którym muszą być przypisane rzeczywiste {\it argumenty} (wyrażenia) podczas wywołania funkcji. W C argumenty są przekazywane {\it przez wartość}: podczas wywołania funkcji obliczana jest wartość każdego argumentu (wyrażenia) i ta wartość jest przypisywane do odpowiedniego parametru. Zmiany wartości parametru podczas obliczeń nie mają wpływu na wartość argumentu. Parametrami mogą być także tablice. W deklaracji funkcji możemy nie specyfikować rozmiaru tablicy. Oto przykład parametru-tablicy:
int sum_tab(int a[], int n)
{
int i, sum = 0;
for (i = 0; i < n; i++)
sum += a[i];
return sum;
}
Gdy chcemy parametrem uczynić tablicę dwuwymiarową musimy podać liczbę kolumn tablicy.
#define L_kol 10
int sum_tab(int a[][L_kol], int n)
{
int i, j, sum = 0;
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
sum += a[i][j];
return sum;
}
Pamiętajmy, że każda funkcja {\it nie}-void musi zwracać wartość. Instrukcja return ma postać:\\ return {\it wyrażenie};