fb pixel
გამოიწერე YouTube-ის არხიyoutube logoგამოწერა
val-do.com-ის ლოგო
კურსებიბლოგირეზიუმეებიხ.დ.კ.წესებიკონტაქტიკონვერტორები

კურსებიბლოგირეზიუმეებიხ.დ.კ.წესებიკონტაქტიკონვერტორები
შესვლა
  1. მთავარი
  2. კურსები
  3. C პროგრამირების ენის საფუძვლები
  4. C - მიმთითებლები (Pointers)
C - მიმთითებლები (Pointers)

C - მიმთითებლები (Pointers)

მიმთითებლები (Pointers) C ენის ერთ-ერთი ყველაზე მნიშვნელოვანი თემაა, ამიტომ ამ გაკვეთილში შევეცდები პრაქტიკული მაგალითების გამოყენებით კარგად გავიაზროთ მისი მუშაობის პრინციპები.

მიმთითებლები (Pointers) მაღალი დონის ენებში - როგორიცაა JavaScript, Python, Java, C# და სხვა - პირდაპირ არ გვხვდება. ამიტომ, თუ ამ გაკვეთილამდე სწორედ ამ ენების საფუძვლებით მოხვდით, გილოცავთ - ახლა სრულიად ახალ კონცეფციას გაეცნობით და კიდევ უფრო უკეთ გაიგებთ, როგორ მუშაობს კომპიუტერის მეხსიერება.


გაკვეთილის თემები:

  • Pointers (მიმთითებლები)
  • Pointer declaration (მიმთითებლის დეკლარაცია)
  • Assign value (მნიშვნელობის მინიჭება)
  • Dereference operator (დერეფერენს ოპერატორი)
  • Pointer to pointer (მიმთითებელი მიმთითებელზე)
  • Const pointers
  • Pointer as function parameter (მიმთითებელი, როგორც ფუნქციის პარამეტრი)
  • Return as pointer (მიმთითებლის დაბრუნება ფუნქციიდან)

მიმთითებლის ცვლადი (Pointer Variable)

მიმთითებლების (Pointers) კარგად გასააზრებლად აუცილებელია ვიზუალურად კარგად წარმოვიდგინოთ თუ როგორ ინახება ინფორმაცია კომპიუტერის მეხსიერებაში.

თანამედროვე კომპიუტერებში მეხსიერება დაყოფილია ბაიტებად, რომლებსაც შეუძლიათ შეინახოთ 8 ბიტის ინფორმაცია, თვითეულ ბაიტს აქვს უნიკალური მისამართი მეხსიერებაში.

სწორედ ამ მისამართის დახმარებით ხდება მეხსიერებაში არსებული მონაცემების მართვა - შეგვიძლია კონკრეტულ მისამართზე შენახული ინფორმაციის ამოკითხვა, შეცვლა ან წაშლა.

სხვა სიტყვებით რომ ვთქვათ, მეხსიერება შეგვიძლია წარმოვიდგინოთ როგორც უჯრების დიდი ნაკრები, სადაც თითოეულ უჯრას თავისი მისამართი აქვს და მონაცემებზე წვდომა სწორედ ამ მისამართების საშუალებით ხორციელდება.

მიმთითებელი ცვლადის გამოცხადება

C-ში მიმთითებელი ცვლადის გამოცხადების 3 გზა არსებობს, მაგრამ სამივე ერთსა და იმავეს გულიხმობს.

int *p;
int* p;
int * p;

ზემოთ მოყვანილი ყველა ჩანაწერი ერთმანეთის ეკვივალენტურია, თუმცა ამ კურსის ფარგლებში დარჩენილ მაგალითებში გამოვიყენებ int *p სტილის ჩანაწერს.

როგორც მაგალითიდან ჩანს მიმთითებელი ცვლადის გამოცხადებისას აუცილებელია გამოვიყენოთ * სიმბოლო.

მიმთითებელი ცვლადის მნიშნველობის მინიჭება

მოვიყვანოთ მარტივი მაგალითი:

#include <stdio.h>

int main() {
    int x = 5;
    int *p = &x;

    printf("x = %d\n", x); // დაიბეჭდება:  x - 5;
    printf("p = %p\n", p); // დაიბეჭდება: p - 0x16b2aeb88;

    return 0;
}

გავარჩიოთ ზემოთ მოყვანილი მაგალითი: int main() ფუნქციაში აღწერილი გვაქვს int ტიპის x ცვლადი, რომელსაც მივანიჭეთ მნიშვნელობა 5.

ასევე აღწერილია int ტიპის მიმთითებელი ცვლადი *p, რომელსაც მინიჭებული აქვს x ცვლადის მისამართი - &x. სიმბოლო & წარმოადგენს მისამართის ოპერატორს, რომელიც აბრუნებს მოცემული ცვლადის მდებარეობას მეხსიერებაში.

როგორც მაგალითიდან დავინახეთ p ცვლადის დაბეჭვდისას დაიბეჭდა ე.წ. ჰექსიდეციმალი, რომელიც წარმოადენს იმ მეხსიერების მისამართს სადაც ჩაიწერა x-ის მნიშვნელობა 5.

ასევე კოდს თუ დავაკვირდებით დავინახავთ, რომ მიმთითებელი ცვლადის დასაბეჭდად printf ფუნქციაში გამოყენებულია შესაბამისი ფორმატის მიმთითებელი %p

დერეფერენს ოპერატორი

ალბათ გაგიჩნდებათ კითხვა - როგორ არის შესაძლებელი მიმთითებელი ცვლადიდან არა თავად მეხსიერების მისამართის, არამედ ამ მისამართზე შენახული მონაცემის ამოკითხვა. სწორედ ამისთვის გამოიყენება ე.წ. დერეფერენს ოპერატორი, რომელიც ასევე * სიმბოლოთი აღინიშნება.

მნიშვნელოვანია კარგად გავიაზროთ განსხვავება მიმთითებლის გამოცხადებასა და დერეფერენს ოპერაციას შორის, რადგან ორივე შემთხვევაში ერთი და იგივე * სიმბოლო გამოიყენება, თუმცა მათი დანიშნულება ერთმანეთისგან განსხვავებულია.

მოვიყვანოთ მაგალითი:

#include <stdio.h>

int main() {
    int x = 5;
    int *p = &x;

    printf("x = %d\n", x);     // დაიბეჭდება:  x - 5;
    printf("p = %p\n", p);     // დაიბეჭდება: p - 0x16b2aeb88;
    printf("p = %d\n", *p);    // დაიბეჭდება: p - 5;

    return 0;
}

არსებულ მაგალითში, ბოლო printf ფუნქციაში შევცვალეთ ფორმატის მითითება — %p ნაცვლად გამოვიყენეთ %d, რადგან დერეფერენსის (*p) გამოყენების შემდეგ იბეჭდება უკვე int ტიპის მნიშვნელობა და არა მეხსიერების მისამართი.

მიმთითებელი მიმთითებელზე (Pointer to pointer)

როგორც უკვე ვიცით, ჩვეულებრივი მიმთითებელი ინახავს რომელიმე ცვლადის მისამართს მეხსიერებაში. თუმცა უნდა გავითვალისწინოთ, რომ თავად მიმთითებელიც ჩვეულებრივი ცვლადია და მასაც აქვს საკუთარი ადგილი მეხსიერებაში, ანუ საკუთარი მისამართი.

შესაბამისად, შესაძლებელია შევქმნათ მიმთითებელი, რომელიც სხვა მიმთითებლის მისამართს შეინახავს. ასეთ მიმთითებელს ეწოდება pointer to pointer.

მოვიყვანოთ მაგალითი:

#include <stdio.h>

int main() {
    int x = 5;
    int *p = &x;
    int **pp = &p;

    printf("x = %d\n", x);
    printf("*p = %d\n", *p);
    printf("**pp = %d\n", **pp);

    return 0;
}

მოცემულ მაგალითში x ცვლადი ინახავს მნიშვნელობას 5-ს, ხოლო p წარმოადგენს მიმთითებელს, რომელიც ინახავს x-ის მისამართს.

ამის შემდეგ ვქმნით pp მიმთითებელს, რომელიც უკვე p მიმთითებლის მისამართს ინახავს. შედეგად, pp მიუთითებს p-ზე, ხოლო p თავის მხრივ მიუთითებს x-ზე. ამიტომ, როდესაც ვიყენებთ **pp ჩანაწერს, თავდაპირველად ხდება pp-ის დერეფერენსი, რის შედეგადაც ვიღებთ p-ს, ხოლო შემდეგ p-ის დერეფერენსით ვიღებთ საბოლოოდ x ცვლადში შენახულ მნიშვნელობას.

const pointers

ზოგიერთ შემთხვევაში საჭიროა შევზღუდოთ ან მიმთითებლის მიერ შენახული მისამართის, ან ამ მისამართზე არსებული მონაცემის შეცვლის შესაძლებლობა. ამისათვის გამოიყენება const საკვანძო სიტყვა, რომლის პოზიციაც განსაზღვრავს თუ რა იქნება მუდმივი.

int x = 5;
const int *p = &x;

ამ შემთხვევაში მიმთითებლის საშუალებით შეუძლებელია იმ მონაცემის შეცვლა, რომელზეც ის მიუთითებს. ანუ *p-ის გამოყენებით მნიშვნელობის შეცვლა შეცდომას გამოიწვევს, თუმცა თავად p შეგვიძლია გადავამისამართოთ სხვა ცვლადზე.

სხვა შემთხვევაში:

int x = 5;
int *const p = &x;

აქ უკვე თავად მიმთითებელია მუდმივი, რაც ნიშნავს, რომ მისი გადამისამართება სხვა ცვლადზე შეუძლებელია. მიუხედავად ამისა, *p-ის გამოყენებით იმ მონაცემის შეცვლა კვლავ შესაძლებელია, რომელზეც ის მიუთითებს.

ასევე შესაძლებელია ორივე შეზღუდვის ერთად გამოყენება:

const int *const p = &x;

ამ შემთხვევაში ვერც მისამართის შეცვლა იქნება შესაძლებელი და ვერც მონაცემის.

მიმთითებლები ფუნქციის პარამეტრებად

როდესაც ფუნქციას გადავცემთ ჩვეულებრივ ცვლადს როგორც პარამეტრს, ფუნქცია იღებს ამ ცვლადის მნიშვნელობის ასლს, რის გამოც ფუნქციის შიგნით განხორციელებული ცვლილებები არ აისახება ორიგინალ ცვლადზე.

თუმცა თუ ფუნქციას გადავცემთ ცვლადის მისამართს, ანუ მიმთითებელს, ფუნქცია იმუშავებს პირდაპირ მეხსიერებაში არსებულ ჩანაწერზე.

#include <stdio.h>

void changeValue(int *p) {
    *p = 10;
}

int main() {
    int x = 5;
    changeValue(&x);

    printf("x = %d\n", x);

    return 0;
}

მოცემულ მაგალითში ფუნქციას გადავეცით x ცვლადის მისამართი, რის შედეგადაც პარამეტრი p მიუთითებს იმავე მეხსიერების უჯრაზე, სადაც ინახება x. შესაბამისად, *p = 10 ოპერაცია ცვლის არა პარამეტრის ასლს, არამედ თავად x ცვლადში შენახულ მნიშვნელობას.

მიმთითებლის დაბრუნება ფუნქციიდან

ფუნქციას ასევე შეუძლია დააბრუნოს მეხსიერების მისამართი, რაც საშუალებას გვაძლევს ფუნქციის გარეთ მივიღოთ წვდომა კონკრეტულ მეხსიერების უბანზე.

#include <stdio.h>

int* getAddress(int *p) {
    return p;
}

int main() {
    int x = 5;
    int *ptr = getAddress(&x);

    printf("*ptr = %d\n", *ptr);

    return 0;
}

აქ ფუნქციას გადავეცით x ცვლადის მისამართი და ფუნქციამ იგივე მისამართი დააბრუნა. დაბრუნებული მისამართი შევინახეთ ptr მიმთითებელში, რის შემდეგაც *ptr-ის გამოყენებით მივიღეთ იმავე მნიშვნელობა, რაც x ცვლადში ინახებოდა.


მიმთითებლები (Pointers) C ენის ერთ-ერთი ყველაზე ძლიერი და მნიშვნელოვანი მექანიზმია, რადგან მათი დახმარებით ხდება მეხსიერების პირდაპირი მართვა, მონაცემების ეფექტური გადაცემა ფუნქციებს შორის და რთული მონაცემთა სტრუქტურების შექმნა.

კარგად უნდა გავიაზროთ განსხვავება მიმთითებლის გამოცხადებასა და დერეფერენს ოპერაციას შორის, ასევე const pointers-ის, pointer to pointer-ის და ფუნქციებში მიმთითებლების გამოყენების მნიშვნელობა.

ეს ცოდნა არა მხოლოდ C-ში მუშაობისას არის აუცილებელი, არამედ საშუალებას გვაძლევს უკეთ გავიგოთ კომპიუტერის მეხსიერების მუშაობის პრინციპები, რაც ნებისმიერი პროგრამირების ენისთვის მნიშვნელოვან საფუძველს წარმოადგენს.

შეჯამებით, მიმთითებლები C-ში ფუნქციონირებასთან ერთად გახსნიან გზას დინამიური მეხსიერების მართვის, მონაცემთა სტრუქტურების მოქნილი გამოყენებისა და მაღალი ეფექტურობის მქონე პროგრამების შექმნისკენ.


დამატებითი რესურსები

  • Telegram
  • Discord

სხვა კატეგორიები

შეისწავლეთ ვებდეველოპმენტის ენები სრულიად უფასოდ, ისეთები როგორებიცაა Javascript, HTML, CSS და კიდევ სხვა მრავალი ენა

HTML, CSS-ის სა...

HTML, CSS-ის საწყისი კურსი, დამწყებთათვის (deprecated - მოძველებული)

ჯავასკრიპტის კუ...

ჯავასკრიპტის კურსი

JavaScript-ის D...

JavaScript-ის DOM-ის კურსი

TypeScript-ის კ...

TypeScript-ის კურსი

Angular-ის კურს...

Angular-ის კურსი

HTML, CSS-ის კუ...

HTML, CSS-ის კურსი

Reactjs-ის კურს...

Reactjs-ის კურსი დამწყებთათვის

ალგორითმები...

ალგორითმები

Node.js-ის კურს...

Node.js-ის კურსი

Dart-ის კურსი...

Dart-ის კურსი

C პროგრამირების...

C პროგრამირების ენის საფუძვლები

ბოლოს დაწერილი ბლოგები პროგრამირებაზე

ქვემოთ მოცემულია უახლესი 3 ბლოგი პროგრამირების თემატიკასთან დაკავშირებით

როგორ ინახება ი...

როგორ ინახება ინფორმაცია. რა არის Bit და Byte?

რატომ არის კომფ...

რატომ არის კომფორტული სამუშაო ოთახი აუცილებელი კოდის წერისა და პროდუქტიული მუშაობისთვის?

რატომ ვერ პოულო...

რატომ ვერ პოულობენ ჯუნიორები სამსახურს?

  • C - შესავალი, გარემოს მომზადება
  • C - პირველი პროგრამა
  • C - კომენტარები
  • C - ცვლადები
  • C - მონაცემების შეტანა, გამოტანა (I/O)
  • C - მასივები
  • C - ციკლები
  • C - ფუნქციები
  • C - მიმთითებლები (Pointers)
პროგრამირების კურსები
HTML, CSSJavaScriptTypeScriptAngularReactJSNodeJSC
გამომყევი
mipov.net/valdo

© val-do.com 2026 წელი - ყველა უფლება დაცულია

ვერსია 0.2.2