Inne działy

 

 

Język C zmienna liczba parametrów

 

Zauważyłeś zapewne, że używając funkcji printf() lub scanf() po argumencie zawierającym tekst z odpowiednimi modyfikatorami mogłeś podać praktycznie nieograniczoną liczbę argumentów. Zapewne deklaracja obu funkcji zadziwi Cię jeszcze bardziej:


int printf(const char *format, ...);
int scanf(const char *format, ...);


Jak widzisz w deklaracji zostały użyte 3 kropki. Otóż język C ma możliwość przekazywania nieograniczonej liczby argumentów do funkcji (tzn. jedynym ograniczeniem jest rozmiar stosu programu). Cała zabawa polega na tym, aby umieć dostać się do odpowiedniego argumentu oraz poznać jego typ (używając funkcji printf, mogliśmy wpisać jako argument dowolny typ danych). Do tego celu możemy użyć wszystkich ciekawostek, zawartych w pliku nagłówkowym stdarg.h.


Załóżmy, że chcemy napisać prostą funkcję, która dajmy na to, mnoży wszystkie swoje argumenty (zakładamy, że argumenty są typu int). Przyjmujemy przy tym, że ostatni argument będzie 0. Będzie ona wyglądała tak:

 

#include <stdarg.h>
int mnoz (int pierwszy, ...)
{
va_list arg;
int iloczyn = 1, t;
va_start (arg, pierwszy);
for (t = pierwszy; t; t = va_arg(arg, int)) {
iloczyn *= t;
}
va_end (arg);
return iloczyn;
}

 

va_list oznacza specjalny typ danych, w którym przechowywane będą argumenty, przekazane do funkcji. “va_start” inicjuje arg do dalszego użytku. Jako drugi parametr musimy podać nazwę ostatniego znanego argumentu funkcji. Makropolecenie va_arg odczytuje kolejne argumenty i przekształca je do odpowiedniego typu danych. Na zakończenie używane jest makro va_end — jest ono obowiązkowe!

Oczywiście, tak samo jak w przypadku funkcji printf() czy scanf(), argumenty nie muszą być takich samych typów. Rozważmy dla przykładu funkcję, podobną do printf(), ale znacznie uproszczoną:

#include <stdarg.h>
void wypisz(const char *format, ...) {
va_list arg;
va_start (arg, format);
for (; *format; ++format) {
switch (*format) {
case 'i': printf("%d" , va_arg(arg, int)); break;
case 'I': printf("%u" , va_arg(arg, unsigned)); break;
case 'l': printf("%ld", va_arg(arg, int)); break;
case 'L': printf("%lu", va_arg(arg, unsigned long)); break;
case 'f': printf("%f" , va_arg(arg, double)); break;
case 'x': printf("%x" , va_arg(arg, unsigned)); break;
case 'X': printf("%X" , va_arg(arg, unsigned)); break;
case 's': printf("%s" , va_arg(arg, const char *)); break;
default : putc(*format);
}
}
va_end (arg);
}

 

 Przyjmuje ona jako argument ciąg znaków, w których niektóre instruują funkcję, by pobrała argument i go wypisała. Nie przejmuj się jeżeli nie rozumiesz wyrażeń *format i ++format. Istotne jest to, że pętla sprawdza po kolei wszystkie znaki formatu.

C ma wiele niuansów, o których wielu programistów nie wie lub łatwo o nich zapomina:

  • jeśli nie podamy typu wartości zwracanej w funkcji, zostanie przyjęty typ int (według najnowszego standardu C99 nie podanie typu wartości jest zwracane jako błąd);

 

  • jeśli nie podamy żadnych parametrów funkcji, to funkcja będzie używała zmiennej ilości parametrów (inaczej niż w C++, gdzie przyjęte zostanie, że funkcja nie przyjmuje argumentów). Aby wymusić pustą listę argumentów, należy napisaćint funkcja(void) (dotyczy to jedynie prototypów czy deklaracji funkcji);

 

  • jeśli nie użyjemy w funkcji instrukcji return, wartość zwracana będzie przypadkowa (dostaniemy śmieci z pamięci).


Kompilator C++ użyty do kompilacji kodu C najczęściej zaprotestuje i ostrzeże nas, jeśli użyjemy powyższych konstrukcji. Natomiast czysty kompilator C z domyślnymi ustawieniami nie napisze nic i bez mrugnięcia okiem skompiluje taki kod.

 

 

Zobacz nasze wszystkie kursy

WWW


HTML
HTML - Znaczniki
CSS - Tutorial
CSS - Selektory
PHP
JavaScript

XML

XSLT

Bazy danych


SQL
SQLite
MySQL
PostgreSQL

 

 

Programowanie


C
C++
C#
Java
VisualBasic
Python

Linux


Podstawy Linuxa
Bash
Linuks artykuły

Windows


Excel funkcje
Windows wskazówki
Outlook

Pozotałe działy


Programy
Rozrywka

 

 

 

This email address is being protected from spambots. You need JavaScript enabled to view it.