Функції, масиви та два вказівники
Свайпніть щоб показати меню
Функції з вказівниками
Розглянемо базову функцію для зміни значення даних. Наприклад, уявіть, що потрібна функція для перетворення кілоомів у оми (1 кОм = 1000 Ом).
Main.c
12345678910111213141516#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.
Main.c
1234567891011121314151617#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, а не просто копію, і потім змінила значення за цією адресою.
Крім того, функція може повертати вказівник на об'єкт, який вона створила:
Main.c
123456789101112131415#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; }
Коли до адреси додається число (pX + 1), отримується адреса наступної комірки пам'яті! Напишемо цикл для переміщення по "послідовності" оперативної пам'яті:
Main.c
12345678910#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; }
Ви спрогнозували три кроки вперед. З отриманих адрес видно, що існує чітка ієрархія.
Масив по суті є фіксованою адресою (яку представляє ім'я масиву) разом із виділеною пам'яттю. Індекси елементів відображають їх зміщення від адреси початкового елемента!
Цю концепцію можна підтвердити наступною програмою:
Main.c
1234567891011#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; }
Ви не проходите безпосередньо по масиву. Ви використовуєте лише його адресу, а саме адресу його початкового елемента.
Дякуємо за ваш відгук!
Запитати АІ
Запитати АІ
Запитайте про що завгодно або спробуйте одне із запропонованих запитань, щоб почати наш чат