C# में पॉइंटर्स (Pointers)
पॉइंटर एक वेरिएबल है जो **दूसरे वेरिएबल का मेमोरी एड्रेस** स्टोर करता है। C# में पॉइंटर्स केवल unsafe कॉन्टेक्स्ट में अनुमत हैं क्योंकि वे टाइप सेफ्टी और मेमोरी सेफ्टी को बायपास करते हैं।
सिंटैक्स
type* variableName; // C# स्टाइल // उदाहरण: int* p; // int पॉइंटर double* d; // double पॉइंटर char* c; // char पॉइंटर
मुख्य ऑपरेटर्स
| ऑपरेटर | नाम | कार्य |
|---|---|---|
& | एड्रेस-ऑफ | वेरिएबल का मेमोरी एड्रेस देता है |
* | डिरेफरेंस | पॉइंटर पर स्टोर एड्रेस पर वैल्यू एक्सेस/मोडिफाई |
-> | मेंबर एक्सेस | स्ट्रक्चर पॉइंटर के लिए: p->Member = (*p).Member |
[] | इंडेक्सर | पॉइंटर अंकगणित: p[i] = *(p + i) |
उदाहरण: बेसिक पॉइंटर उपयोग
using System;
class Program {
static unsafe void Main() {
int val = 50;
int* ptr = &val; // val का एड्रेस
Console.WriteLine($"Data: {val}");
Console.WriteLine($"Address: {(long)ptr:X}"); // हेक्स में एड्रेस
Console.WriteLine($"Value via pointer: {*ptr}");
// पॉइंटर के माध्यम से वैल्यू बदलें
*ptr = 100;
Console.WriteLine($"New val: {val}"); // 100
}
}
आउटपुट
Data: 50 Address: 00000012345678 (उदाहरण) Value via pointer: 50 New val: 100
पॉइंटर टाइप्स
- केवल **अनमैनेज्ड टाइप्स** (प्रिमिटिव्स, एनम्स, पॉइंटर्स, केवल अनमैनेज्ड फील्ड्स वाले स्ट्रक्चर्स) के पॉइंटर्स बना सकते हैं।
- रेफरेंस टाइप्स (क्लासेस, स्ट्रिंग्स, एरे, डेलीगेट्स) के पॉइंटर्स **नहीं** बना सकते (GC उन्हें मूव कर सकता है)।
void*जेनेरिक पॉइंटर (किसी भी टाइप को पॉइंट कर सकता है, डिरेफरेंस नहीं कर सकता)।
fixed स्टेटमेंट (पिनिंग)
मूवेबल वेरिएबल्स (एरे, स्ट्रिंग) को पिन करने के लिए:
int[] arr = { 1, 2, 3 };
fixed (int* p = &arr[0]) {
// GC arr को नहीं मूव करेगा
Console.WriteLine(*p); // 1
Console.WriteLine(p[1]); // 2
}
कंपाइलर सेटिंग
- Visual Studio: Project Properties → Build → "Allow unsafe code" चेक करें।
- कमांड लाइन:
csc /unsafe Program.cs - .csproj:
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
चेतावनी
पॉइंटर्स मेमोरी करप्शन, सिक्योरिटी होल्स, और डीबगिंग-हार्ड बग्स ला सकते हैं। 99% C# कोड में अनावश्यक हैं। ref/out, Span<T>, Memory<T>, ArrayPool प्रीफर करें।