C установка IDE C структура програми C змінні C типи даних С функція printf C константи C арифметичні операції C операції порівняння і логічні операції C порозрядні операції C операції присвоювання C перетворення типів C умовні конструкції C цикли С масиви і рядки С функція scanf C препроцесор. Директива #include C #define директива C макроси C умовна компіляція C функції. Визначення та опис функцій C функції. Передача параметрів в функцію C функції. Повернення результату з функції C функції. Рекурсивні функції C область видимості змінних C зовнішні об'єкти C вказівники C вказівник. Операції з вказівниками C покажчики. Арифметика покажчиків C покажчики. Константи і покажчики C покажчики. Покажчики та масиви C покажчики. Масиви покажчиків, рядки і багаторівнева адресація C покажчики. Покажчики в параметрах функції C покажчики. Динамічна пам'ять C покажчики. Покажчик як результат функції C покажчики. Управління динамічної пам'яттю C покажчики. Покажчики на функцію C покажчики. Покажчики на функції як параметри і результати функцій C покажчики. Функції зі змінною кількістю параметрів C struct. Визначення структур C struct. Структури як елементи структур C struct. Покажчики на структури C struct. Масиви структур C struct. Структури і функції C struct. union об'єднання C struct. Бітові поля С file. Введення-виведення і робота з файлами C file. Читання і запис бінарних файлів C file. Читання і запис структур в файл C file. Читання і запис текстових файлів C file. Форматування вводу-виводу C file. Позиціонування в потоці C file. Консольне введення-виведення

C покажчики. Покажчики в параметрах функції


При розгляді передачі параметрів у функцію вказувалося, що параметри передаються в функцію за значенням. Тобто функція не змінює значення переданих аргументів. Однак, використовуючи в якості параметрів покажчики, ми можемо отримати доступ до значення аргументу і змінити його.

Наприклад, нехай у нас буде найпростіша функція, яка збільшує число на одиницю:

#include <stdio.h>
 
void increment(int x)
{
    x++;
    printf("increment function: %d \n", x);
}
 
int main(void)
{
    int n = 10;
    increment(n);
    printf("main function: %d \n", n);
    return 0;
}

Тут змінна n приймає в якості аргументу для параметра x. Передача відбувається за значенням, тому будь-яка зміна параметра x в функції increment ніяк не позначиться на значенні змінної n. Що ми можемо побачити, запустимо програму:

#include <stdio.h>
 
void increment(int *x)
{
    (*x)++;
    printf("increment function: %d \n", *x);
}
 
int main(void)
{
    int n = 10;
    increment(&n);
    printf("main function: %d \n", n);
    return 0;
}

Для зміни значення параметра застосовується операція разименованія з подальшим инкрементом: (*x)++ . Це змінює значення, яке знаходиться за адресою, що зберігається в покажчику x.

Оскільки тепер функція як параметр приймає покажчик, то при її виклику необхідно передати адресу змінної: increment(&n); .

В результаті зміна параметра x також вплине на змінну n:

#include <stdio.h>
 
void swap(int *a, int *b)
{
    int temp = *a;
    *a = *b;
    *b=temp;
}
int main(void)
{
    int x = 100;
    int y = 200;
    swap(&x, &y);
    printf("x=%d \t y=%d \n", x, y);
    return 0;
}

Функція swap() в якості параметрів приймає два покажчика. За допомогою змінної temp відбувається обмін значеннями.

При виконанні функції swap в неї передаються адреси змінних x і y, і в результаті їх значення будуть змінені.


Масиви в параметрах

Якщо функція приймає як параметр масив, то фактично в цю функцію передається тільки адреса початку масиву. Тобто як і у випадку з покажчиками нам доступний адресу, за якою ми можемо змінювати значення. На відміну від параметрів примітивних типів, які передаються за значенням.

Наприклад, визначимо функцію для збільшення елементів масиву в два рази:

#include <stdio.h>
 
void twice(int n, int p[])
{
    for(int i=0; i<n; i++)
    {
        p[i] *=2;
    }
}
int main(void)
{
    int nums[] = {1, 2, 3, 4, 5};
    int length = sizeof(nums)/sizeof(nums[0]);
     
    twice(length, nums);
     
    for(int i=0; i<length; i++)
    {
        printf("%d \t", nums[i]);
    }
     
    return 0;
}

Функція twice в якості параметрів приймає масив і число його елементів і в циклі збільшує їх в два рази.

У функції main передаємо масив у функцію twice і потім виводимо його на консоль. В результаті ми побачимо, що масив nums був змінений:

#include <stdio.h>
 
void twice(int n, int *p)
{
    for(int i=0; i<n; i++)
    {
        *p++ *= 2;
    }
}
int main(void)
{
    int nums[] = {1, 2, 3, 4, 5};
    int length = sizeof(nums)/sizeof(nums[0]);
     
    twice(length, nums);
     
    for(int i=0; i<length; i++)
    {
        printf("%d \t", nums[i]);
    }
     
    return 0;
}

За допомогою виразу *p++ *= 2 отримуємо значення за адресою з покажчика, збільшуємо його в два рази і переміщаємо покажчик на один елемент вперед. У підсумку в даному випадку не буде великої різниці, який тип має параметр - масив або покажчик.


Наш партнер:
beta test mp3 playlist downloader