Функції, масиви та два вказівники
Функції з вказівниками
Розглянемо базову функцію для зміни значення даних. Наприклад, уявіть, що потрібна функція для перетворення кілоомів у оми (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; }
Ви не проходите безпосередньо по масиву. Ви використовуєте лише його адресу, а саме адресу його початкового елемента.
Дякуємо за ваш відгук!
Запитати АІ
Запитати АІ
Запитайте про що завгодно або спробуйте одне із запропонованих запитань, щоб почати наш чат
Awesome!
Completion rate improved to 2.63
Функції, масиви та два вказівники
Свайпніть щоб показати меню
Функції з вказівниками
Розглянемо базову функцію для зміни значення даних. Наприклад, уявіть, що потрібна функція для перетворення кілоомів у оми (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; }
Ви не проходите безпосередньо по масиву. Ви використовуєте лише його адресу, а саме адресу його початкового елемента.
Дякуємо за ваш відгук!