C++ funksiyaga ko'rsatkich va havola uzatish
C++ Functions qo'llanmasida biz funksiyaga argumentlarni uzatish haqida bilib oldik. Amaldagi bu usul pass by qiymat deb ataladi, chunki haqiqiy qiymat uzatiladi.
Biroq, argumentlarni o'tkazishning yana bir yo'li bor - havola orqali o'tish.
Malumot orqali o'tish - bu funksiyaga ularning qiymatlari emas, balki haqiqiy parametrlarning havolalari uzatiladigan funksiyalarda argumentlarni o'tkazish usuli.
Masalan,
// qiymatni parametr sifatida qabul qiladigan funksiya
void func1(int num_val) {
// kod
}
// parametr sifatida mos yozuvlarni qabul qiladigan funksiya
// parametrdan oldin & ga e'tibor bering
void func2(int& num_ref) {
// kod
}
int main() {
int num = 5;
// qiymat bo'yicha o'tish
func1(num);
// ma'lumotnoma orqali o'ting
func2(num);
return 0;
}
void func2(int& num_ref) da & ga e'tibor bering. Bu bizning parametrimiz sifatida variable havolasidan foydalanayotganimizni bildiradi.
Shunday qilib, biz main() da func2() funksiyasini num o'zgaruvchisini argument sifatida berish orqali chaqirganimizda, biz aslida 5 qiymati o'rniga num o'zgaruvchisiga havolani uzatamiz.
#include <iostream>
using namespace std;
// qiymatlarni almashtirish uchun funksiya ta'rifi
void swap(int& n1, int& n2) {
int temp;
temp = n1;
n1 = n2;
n2 = temp;
}
int main() {
// o'zgaruvchilarni ishga tushirish
int a = 1, b = 2;
cout << "Before swapping" << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
// raqamlarni almashtirish uchun qo'ng'iroq funksiyasi
swap(a, b);
cout << "\nAfter swapping" << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
return 0;
}
Chiqish
Before swapping
a = 1
b = 2
After swapping
a = 2
b = 1
Ushbu dasturda biz a va b o'zgaruvchilarni swap() funksiyasiga o'tkazdik. Funksiya ta'rifiga e'tibor bering,
void swap(int& n1, int& n2)
Bu erda funksiya o'z parametrlari sifatida havolalarni qabul qilishini bildirish uchun & dan foydalandik.
Shunday qilib, kompilyator haqiqiy qiymatlar o'rniga o'zgaruvchilarning havolasi funksiya parametrlariga o'tkazilishini aniqlay oladi.
swap() funksiyasida n1 va n2 funksiya parametrlari mos ravishda a va b o‘zgaruvchilari bilan bir xil qiymatga ishora qiladi. Shuning uchun almashtirish haqiqiy qiymat bo'yicha amalga oshiriladi.
Agar o'zgaruvchilar qiymatlarini o'zgartirish kerak bo'lmasa, biz ularni const havolalari sifatida o'tkazishimiz mumkin.
Keling, bir misolni ko'rib chiqaylik.
#include <iostream>
using namespace std;
// ikkita raqamni qo'shish funksiyasi
// const havolalaridan foydalanish
int add(const int& num1, const int& num2) {
return num1 + num2;
}
int main() {
int number1, number2;
// kiritish
cout << "Enter the first number: ";
cin >> number1;
cout << "Enter the second number: ";
cin >> number2;
// qo'ng'iroq qilish funksiyasi
int sum = add(number1, number2);
// natijani ko'rsatish
cout << "The sum of " << number1 << " and " << number2 << " is " << sum << endl;
return 0;
}
Chiqish
Enter the first number: 1
Enter the second number: 2
The sum of 1 and 2 is 3
Bu erda biz const havolalari yordamida qiymatlarni uzatish uchun const kalit so'zidan foydalandik.
const havolalaridan foydalanish funksiya ichidagi qiymatlarni o'zgartirishni oldini oladi. Masalan, ikkita raqamni almashtirish uchun const havolalaridan foydalanishga harakat qilaylik.
#include <iostream>
using namespace std;
// qiymatlarni almashtirish uchun funksiya ta'rifi
// const havolalaridan foydalanish
void swap(const int& n1,const int& n2) {
int temp;
temp = n1;
n1 = n2;
n2 = temp;
}
int main() {
// o'zgaruvchilarni ishga tushirish
int a = 1, b = 2;
cout << "Before swapping" << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
// raqamlarni almashtirish uchun qo'ng'iroq funksiyasi
swap(a, b);
cout << "\nAfter swapping" << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
return 0;
}
Chiqish
ERROR!
/tmp/RXT9OkJpWq.cpp: In function 'void swap(const int&, const int&)':
/tmp/RXT9OkJpWq.cpp:9:8: error: assignment of read-only reference 'n1'
9 | n1 = n2;
| ~~~^~~~
/tmp/RXT9OkJpWq.cpp:10:8: error: assignment of read-only reference 'n2'
10 | n2 = temp;
| ~~~^~~~~~
const havolalari yordamida uzatilgan oʻzgaruvchilar qiymatlarini oʻzgartirishga urinib koʻrganimiz uchun bu yerda xatoga yoʻl qoʻydik.
[!NOTE]
consthavolalaridan foydalanib, biz kodimiz ustidan ko'proq nazoratga ega bo'lamiz, chunki biz qaysi funksiyalar o'zgaruvchilar qiymatlarini o'zgartirishi va o'zgartira olmasligini aniq aniqlashimiz mumkin. Bu kod xavfsizligini oshiradi va disk raskadrovkani osonlashtiradi.
Yuqoridagi vazifani ko'rsatkichlar yordamida bajarish mumkin. Ko'rsatkichlar haqida bilish uchun C++ Pointers ga tashrif buyuring.
Keling, bir misolni ko'rib chiqaylik.
#include <iostream>
using namespace std;
// funksiya prototipi parametr sifatida ko'rsatkichlar bilan
void swap(int*, int*);
int main() {
// o'zgaruvchilarni ishga tushirish
int a = 1, b = 2;
cout << "Before swapping" << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
// o'zgaruvchan manzillarni o'tkazish orqali chaqiruv funksiyasi
swap(&a, &b);
cout << "\nAfter swapping" << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
return 0;
}
// raqamlarni almashtirish uchun funksiya ta'rifi
void swap(int* n1, int* n2) {
int temp;
temp = *n1;
*n1 = *n2;
*n2 = temp;
}
Chiqish
Before swapping
a = 1
b = 2
After swapping
a = 2
b = 1
Bu erda biz oldingi misoldagi kabi chiqishni ko'rishimiz mumkin. Chiziqqa e'tibor bering,
// &a - a manzili
// &b - b manzili
swap(&a, &b);
Bu erda o'zgaruvchining manzili o'zgaruvchiga emas, balki funksiya chaqiruvi vaqtida uzatiladi.
Qiymat o'rniga manzil uzatilganligi sababli, ushbu manzilda saqlangan qiymatga kirish uchun * yo'qotish operatoridan foydalanish kerak.
temp = *n1;
*n1 = *n2;
*n2 = temp;
*n1 va *n2 mos ravishda n1 va n2 manzillarida saqlangan qiymatni beradi.
n1 va n2 a va b manzillarini o'z ichiga olganligi sababli, *n1 uchun hamma narsa bajariladi va *n2 a va b ning haqiqiy qiymatlarini o'zgartiradi.
Demak, main() funksiyasida a va b qiymatlarini chop etganimizda qiymatlar o'zgartiriladi.
[!NOTE] Ko'rsatkichlar o'rniga havolalardan foydalanish odatda osonroq va xatoga yo'l qo'ymaydi, chunki u to'g'ridan-to'g'ri ko'rsatkich operatsiyalarini o'z ichiga olmaydi. Ko'rsatkichlar faqat ko'rsatkichlar zarur bo'lgan kontekstlarda yoki C kutubxonalari bilan o'zaro aloqada bo'lganda argumentlarni uzatish uchun ishlatilishi kerak.