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

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

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

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

Main.c

Main.c

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.

Main.c

Main.c

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, а не просто копію, і потім змінила значення за цією адресою.

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

Main.c

Main.c

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; }

Чи є масиви лише вказівниками?

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

Main.c

Main.c

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), це дає адресу наступної комірки пам'яті!

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

Main.c

Main.c

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 байти з кожним кроком. Ця поведінка вражаюче нагадує масив!

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

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

Main.c

Main.c

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

Запитати АІ

expand

Запитати АІ

ChatGPT

Запитайте про що завгодно або спробуйте одне із запропонованих запитань, щоб почати наш чат

Awesome!

Completion rate improved to 2.63

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

Свайпніть щоб показати меню

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

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

Main.c

Main.c

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.

Main.c

Main.c

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, а не просто копію, і потім змінила значення за цією адресою.

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

Main.c

Main.c

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; }

Чи є масиви лише вказівниками?

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

Main.c

Main.c

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), це дає адресу наступної комірки пам'яті!

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

Main.c

Main.c

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 байти з кожним кроком. Ця поведінка вражаюче нагадує масив!

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

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

Main.c

Main.c

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