Wstęp do programowania w języku C/Tablice: Różnice pomiędzy wersjami

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
Linia 191: Linia 191:
Funkcja w C nie musi zwracać żadnej wartości. Oto funkcja tab,
Funkcja w C nie musi zwracać żadnej wartości. Oto funkcja tab,
która dostaje
która dostaje
na wejściu liczbę całkowitą $n\in [1..10]$ i wypisuje tabliczkę
na wejściu liczbę całkowitą <math>n\in [1..10]</math> i wypisuje tabliczkę
możenia przez $n$. Zwróć uwagę na słówko kluczowe void które
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ć
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ć
wywoływana jako część wyrażenia. Wywołanie funkcji tab musi mieć
postać:\\
postać:
tab({\it parametr});\\
 
tab(''parametr'');
 
<Source>
<Source>
void tab(int n)
void tab(int n)
Linia 213: Linia 215:
}
}
</Source>
</Source>
Tak'a funkcję wywułujemy:\\
 
gwiazdki();\\
Taką funkcję wywułujemy:
Ogólnie definicja funkcji ma postać:\\
 
{\it typ wartości} nazwa--funkcji ( parametry )\\
''gwiazdki();''
\{\\
 
\hspace{0.5cm}deklaracje\\
Ogólnie definicja funkcji ma postać:
\hspace{0.5cm}instrukcje\\
 
\}\\[0.3cm]
''typ wartości'' nazwa--funkcji ( parametry )
{
  deklaracje
  instrukcje
}
 
Zwróćmy uwagę na różnicę między parametrami i argumentami
Zwróćmy uwagę na różnicę między parametrami i argumentami
funkcji. {\it Prametry} występują na poziomie definicji funkcji.
funkcji. ''Prametry'' występują na poziomie definicji funkcji.
Są one ``zmiennymi'', którym muszą być przypisane rzeczywiste
Są one "zmiennymi", którym muszą być przypisane rzeczywiste
{\it argumenty} (wyrażenia) podczas wywołania funkcji. W C argumenty są
''argumenty'' (wyrażenia) podczas wywołania funkcji. W C argumenty są
przekazywane {\it przez wartość}: podczas wywołania funkcji obliczana
przekazywane ''przez wartość'': podczas wywołania funkcji obliczana
jest wartość każdego argumentu (wyrażenia) i ta wartość jest
jest wartość każdego argumentu (wyrażenia) i ta wartość jest
przypisywane do odpowiedniego parametru. Zmiany wartości parametru podczas
przypisywane do odpowiedniego parametru. Zmiany wartości parametru podczas
Linia 232: Linia 239:
nie specyfikować rozmiaru tablicy.
nie specyfikować rozmiaru tablicy.
Oto przykład parametru-tablicy:
Oto przykład parametru-tablicy:
<Source>
<Source>
int sum_tab(int a[], int n)
int sum_tab(int a[], int n)
Linia 259: Linia 267:
}
}
</Source>
</Source>
Pamiętajmy, że każda funkcja {\it nie}-void musi zwracać wartość.
Pamiętajmy, że każda funkcja ''nie''-'''void''' musi zwracać wartość.
Instrukcja return ma postać:\\
Instrukcja return ma postać:
return {\it wyrażenie};
 
return ''wyrażenie'';

Wersja z 20:51, 26 paź 2006

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 X={0,1,,n1} (n jest parametrem zadania). Domknięciem przechodnim relacji R nazywamy relację R* taką, że para (a,b)R* wtedy i tylko wtedy, gdy a = b lub dla pewnego l1 istnieje ciąg a0,a1,,al elementów z X taki, że a0=a,al=b,(a0,a1)R,,(al1,al)R. 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("na 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[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(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ą funkcję wywułujemy:

gwiazdki();

Ogólnie definicja funkcji ma postać:

typ wartości nazwa--funkcji ( parametry )
{
 deklaracje
 instrukcje
}

Zwróćmy uwagę na różnicę między parametrami i argumentami funkcji. Prametry występują na poziomie definicji funkcji. Są one "zmiennymi", którym muszą być przypisane rzeczywiste argumenty (wyrażenia) podczas wywołania funkcji. W C argumenty są przekazywane 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 nie-void musi zwracać wartość. Instrukcja return ma postać:

return wyrażenie;