Курсовая работа: Особливості мови програмування С
2.1.1.4 Перетворення типів
Показник одного типу не можна привласнити показнику іншого типу без явного перетворення типів. Виняток становить показник void*(див. розділ 2.4), який трактується як показник на деяку ділянку пам'яті. Він називається родовим показником і може отримувати як значення показник на будь-якого іншого типа без явного перетворення.
int i;
void* pi=&i;
Явні перетворення типів в більшості випадків є потенційно небезпечними і повинні застосовуватися з крайньою обережністю. Так, в наступному прикладі
double d=*static_cast<double*>pi;
вміст змінної d непередбачувано.
Властивість показників void*(див. розділ 2.4) зберігати дані різнорідних типів використовується при створенні так званих родових (generic) масивів, тобто масивів, що зберігають різнотипні об'єкти. Наприклад:
int i=5;
char c='u';
double d[2]={3,6};
void* generic[]={&i,&c,&d};
cout<<*static_cast<int*>generic[0]<<’ ’
<<*static_cast<char*>generic[1]<<’ ’
<<(static_cast<double*>generic[2])[1];[4].
2.1.1.5 Вказівники і передача параметрів у функції
За допомогою вказівників можна організувати передачу параметрів у функції за допомогою посилання. Наприклад, наступна функція міняє місцями значення, що адресуються вказівниками:
void swap(int* pa, int* pb)
{ int t=*pa; *pa=*pb; *pb=t;}
У функціях стандартної бібліотеки можна зустріти безліч прикладів передачі параметрів з використанням вказівників. Така, наприклад, функція memcpy, призначена для копіювання даних з однієї області пам'яті в іншу. Вона має наступний прототип, оголошений в заголовному файлі <string.h> (або за стандартом 1998 р. в <cstring>):
void *memcpy(void *dest, const void *src, size_t n);
і забезпечує копіювання n байтів даних з src в dest. Параметр src
оголошений Вказівником на константу, що свідчить про те, що дані, на які він вказує, не можуть бути змінені функцією memcpy. Оскільки як тип фігурує void*, то замість src і dest при виклику функції memcpy можна підставляти вказівник на будь-якого типа. Нарешті, стандартний тип size_t використовується для вказівки того, що дана змінна зберігає розмір і є беззнакове ціле (зазвичай unsigned int або unsigned long).
Повернення функцією вказівника на локальну змінну є грубою помилкою. Наприклад, в ситуації
int* f()
{
int i=5;
return &i;
}змінна i руйнується після виходу з функції, тому результат роботи програми непередбачуваний.