2015-06-01 15 views
5

Bu yüzden, C işaretçileri ve işaretçi aritmetiği ile oynuyordum, çünkü onlarla tamamen rahat değilim. Bu kodla geldim.Çift ve üçlü işaretçiler/çift boyut dizileriyle ilgili olarak

char* a[5] = { "Hi", "My", "Name", "Is" , "Dennis"}; 
char** aPtr = a; // This is acceptable because 'a' is double pointer 
char*** aPtr2 = &aPtr; // This is also acceptable because they are triple pointers 
//char ***aPtr2 = &a // This is not acceptable according to gcc 4.8.3, why ? 

//This is the rest of the code, the side notes are only for checking 
printf("%s\n",a[0]); //Prints Hi 
printf("%s\n",a[1]); //Prints My 
printf("%s\n",a[2]); //Prints Name 
printf("%s\n",a[3]); //Prints Is 
printf("%s\n",a[4]); //Prints Dennis 

printf("%s\n",*(a+0)); //Prints Hi 
printf("%s\n",*(a+1)); //Prints My 
printf("%s\n",*(a+2)); //Prints Name 
printf("%s\n",*(a+3)); //Prints Is 
printf("%s\n",*(a+4)); //Prints Dennis 

printf("%s\n",*(*(aPtr2) +0)); //Prints Hi 
printf("%s\n",*(*(aPtr2) +1)); //Prints My // ap = a, *ap = *a, *(ap)+1 = *a+1 ? 
printf("%s\n",*(*(aPtr2) +2)); //Prints Name 
printf("%s\n",*(*(aPtr2) +3)); //Prints Is 
printf("%s\n",*(*(aPtr2) +4)); //Prints Dennis 

char*** aPtr2 = &a neden gcc 4.8.3 göre kabul edilebilir değildir?

uyarı: Belki söylemeye çalıştığım şey belirsiz, bu yüzden gerekiyordu

[varsayılan olarak etkin] uyumsuz işaretçi türünden başlatma Maalesef

derleyici uyarı eklemek unuttum bu bağlantıyı ekleyin:

Bildirim hatları açıklanır (hat 6 üzerinden yorum).

+0

"Kabul edilemez" ile ne demek istiyorsunuz? Lütfen uyarı veya hata mesajını ekleyin. –

+3

Kırıldığından emin misin? http://ideone.com/KM516t (Bir noktalı virgülü eksik olduğunuzu ve aPtr2'nin adını kullandığınızı unutmayın) – mtijanic

+0

Gönderdiğim "ideone" bağlantısı gcc-4.9.2 için iyi bir derleme yaptı. Hangi derleyici bayrakları kullanıyorsunuz? – mtijanic

cevap

1

Bu C diziler ve adresleri kabul ettiği şekilde geliyor:

int a[5]; 

a

bir işaretçi bekleniyor nerede kullanabilirsiniz anlamına tip int * const, için de geçerlidir. Ancak, yığında işaretçinin alanı tahsis edilmez, sadece beş inçlik alan için yer ayrılmaz. Anlamı a, &a[0] ile aynıdır. Bu tüm beklenen, ancak burada garip kısmı geliyor:

a, &a ile aynıdır. Bunun nedeni, işaretçinin herhangi bir yerde saklanmaması, adresinin alınamamasıdır. Ama derleme başarısız olursa, C standardı sadece aynı olduklarını söylüyor, bu yüzden bazı aritmetik çalışacaktır. Ancak, char ***aPtr2 = &a; yapıyor olduğunuzdan, etkili bir şekilde char ***aPtr2 = a; yapıyorsunuz, bu yüzden bir segfault elde edersiniz. Bu sadece bir çift işaretçi, üçlü değil.

Sen ayıklayıcısında tüm değerleri inceleyebilirsiniz

daha net görebilmek, ya gibi bir programı çalıştırmak için:

0xfff65578 H 
0xfff65578 0x8048648 H 
0xfff65574 0xfff65578 0x8048648 H 
0xfff65578 0x8048648 H 

EDIT: çıktı üretir

#include <stdio.h> 

int main(void) 
{ 
    char *a[5] = { "Hi", "My", "Name", "Is" , "Dennis"}; 
    char **aPtr = a; 
    char ***aPtr2 = &aPtr; 
    char ***aPtr3 = &a; 

    printf("%p %c\n", a, *a); 
    printf("%p %p %c\n", aPtr, *aPtr, **aPtr); 
    printf("%p %p %p %c\n", aPtr2, *aPtr2, **aPtr2, ***aPtr2); 
    printf("%p %p %c\n", aPtr3, *aPtr3, **aPtr3); 

    return 0; 
} 

: Bir başka ilginç şey, fonksiyon işaretçilerinin aynı şekilde ele alınmasıdır.&func, func ile aynıdır.

int add(int a, int b) { return a + b; } 
typedef int (*PFUNC)(int, int); 

PFUNC p1 = add; 
PFUNC p2 = &add; 
if (p1 == p2) 
    printf("Huh. %d, %d\n", (*p1)(1,2), p2(3, 4)); // the dereference is also optional 
2

a 5 PTRs bir tampon çağrısını ve değişmez (diğer bir deyişle, sabit bir ptr) 'dir. Eğer

char ***aPtr2 = &a; 

izin sonra

*aPtr2 = &a[3]; 

aslında (verboten olan) adresini a değiştirir.