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