Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Функції, Масиви та Два Вказівники | Вказівники
Основи C
course content

Зміст курсу

Основи C

Основи C

1. Вступ
2. Дані
3. Оператори
4. Оператори управління
5. Функції
6. Вказівники

bookФункції, Масиви та Два Вказівники

Функції з вказівниками

Давайте експериментувати з базовою функцією для зміни значення наших даних. Наприклад, уявіть, що вам потрібна функція, яка перетворює кіло-Оми в Оми (1 кОм = 1000 Ом).

c

Main

copy
12345678910111213141516171819
#include <stdio.h> void Ohm(double R) { R = R * 1000; } int main() { double r = 1.5; // kOhm printf("The value of resistance before using function: %f\n", r); Ohm(r); printf("The value of resistance after using function: %f", r); return 0; }

Наша спроба змінити значення змінної r була невдалою. Це тому, що функція отримує копію змінної r, а не саме значення.

Щоб наша програма працювала як задумано, нам потрібно передати адресу змінної r у функцію. В результаті, функція Ohm повинна приймати double* замість просто double.

c

Main

copy
1234567891011121314151617181920
#include <stdio.h> void Ohm(double* R) { // dereferencing the entered address and changing the object it points to *R = *R * 1000; } int main() { double r = 1.5; // kOhm printf("The value of resistance before using function: %f\n", r); Ohm(&r); printf("The value of resistance after using function: %f\n", r); return 0; }

Зверніть увагу, що ми посилаємося на змінну r двічі. Після виклику функції Ohm, значення r змінюється. Це тому, що функція отримала оригінальну адресу змінної r, а не просто копію, і потім змінила значення за цією адресою.

Крім того, функція може повернути вказівник на об'єкт, який вона створила:

c

Main

copy
1234567891011121314151617181920
#include <stdio.h> #include <stdlib.h> int* func() { int* x = (int*)malloc(sizeof(int)); printf("Address into function: %p\n", x); return x; } int main() { int* pointerToFunc = func(); printf("Address after using function: %p\n", pointerToFunc); return 0; }

Чи є масиви просто вказівниками?

Що ви передбачаєте, що станеться, якщо до адреси додати число?

c

Main

copy
123456789101112
#include <stdio.h> int main() { int x = 100; int* pX = &x; printf("Address: %p | Adress + 1: %p", pX, pX + 1); return 0; }

Коли до адреси додається число (pX + 1), це дає адресу наступної комірки пам'яті!

Давайте напишемо цикл, щоб пройти "послідовність" ОЗП:

c

Main

copy
1234567891011
#include <stdio.h> int main() { int* pX = NULL; // pointer to `int` type (4 bites) for (int i = 0; i < 3; i++) printf("Address: %p\n", pX + i); return 0; }

Ми спроектували три кроки вперед. З отриманих адрес очевидно, що існує чітка ієрархія.

Оскільки тип int займає 4 байти, ми просуваємося на 4 байти з кожним кроком. Ця поведінка вражаюче нагадує масив!

Здається, масив по суті є фіксованою адресою (представленою ім'ям масиву) у поєднанні з виділеною пам'яттю. Індекси елементів представляють їх зміщення від адреси початкового елемента!

Цю ідею можна підтвердити наступною програмою:

c

Main

copy
12345678910111213
#include <stdio.h> int main() { int array[] = {1,2,3,4,5}; printf("Address of array: %p\n", array); for(int i = 0; i < 5; i++) printf("Value: %d | Address of element with index %d: %p\n", *(array + i), i , &array[i]); return 0; }

Як спостерігається, ми не проходимо безпосередньо через масив. Ми використовуємо лише його адресу, зокрема адресу його початкового елемента.

Все було зрозуміло?

Як ми можемо покращити це?

Дякуємо за ваш відгук!

Секція 6. Розділ 5
some-alt