2013-09-05 24 views
13

Aşağıdaki gözlem, this question'u char[] ve char* farkları ile izlediğimde ortaya çıktı.Neden char [] ve char * typedefs olarak farklı, ancak bazen ... değil?

#include <iostream> 

typedef char ar[]; 
typedef char* pr; 
void f2(ar x, pr y) 
{ 
    std::cout << std::is_same<decltype(x), decltype(y)>::value << '\n'; 
    std::cout << std::is_same<ar, pr>::value << '\n'; 
} 

int main() 
{ 
    char data[] = "data"; 
    char *ptr = data; 
    f2(data,ptr); 
    return 0; 
} 

Çıktı (Apple LLVM sürümü 4.2 üzerinde (çınlama-425.0.28))

1 
0 

Neden bu raporu gibi farklı türleri değil, farklı decltype() s do? Benim şüphe onlar dolayı typedef beyanlarına tip farklı aslında, ama o zaman neden değişkenler aynı türü olarak rapor edilir?

+0

Çürüyen? (fonksiyon parametreleri olarak) – dyp

+1

(yorumumun ayrıntılandırılması :) Fonksiyonun parametre türleri [dcl.fct]/5'e göre "bozulur": "Her bir parametrenin tipini belirledikten sonra," dizisi "türünde herhangi bir parametre T '”veya“ T 'döndüren işlev”, “T” işaretçisi veya “T” işlevini döndüren işaretçi ”olarak ayarlanır. Bu nedenle 'decltype (x)' * 'char' *' ın * işaretçisidir, 'char' * 'un bilinmeyen bir dizi dizisi değildir (' ar'den farklı olarak). – dyp

+0

@DyP Standart referans için teşekkürler, efendim. – WhozCraig

cevap

20

C++'da, C cinsinden olduğu gibi, dizi türünde olduğu bildirilen bir parametre ayarlanmış (derleme zamanında) işaretçinin türüne, özellikle dizinin öğe türüne göre bir göstericidir.

Bu dizi türü doğrudan veya bir typedef yoluyla belirlenip belirlenmediğini olur (Typedef varolan türü için, sadece bir takma ad yeni bir tür oluşturmak olmadığını unutmayın).

Yani bu:

void f2(char* x, char* y) 
{ 
    // ... 
} 

da C ve C++ tarafından paylaşılan bir diğer kural, düzen tipinde ifadesi çoğunda ama hepsi değil, olmasıdır:

typedef char ar[]; 
typedef char* pr; 
void f2(ar x, pr y) 
{ 
    // ... 
} 

gerçek anlamını Içerikler, örtülü olarak dönüştürülmüş dizi nesnesinin ilk öğeye bir işaretçi. Hangi bir dizi nesne tanımlarsak anlamına gelir:

char arr[10]; 

Eğer (sınırları bilgi kaybeder) bir char* parametre alan bir fonksiyon için bir argüman olarak bu nesne adını kullanabilir. C

bu kapalı dönüştürme olmaz durumlar şunlardır: Dizi ifadesi sizeof (sizeof arr işlenen olan

  1. dizinin boyutu, bir büyüklüğü elde edilir Işaretçi); Dizi ifadesi tekli & işlenen olan
  2. (&arr, bir işaretçi-dizi bir işaretçi-pointer); ve
  3. dizi sentezleme düzen tipinde bir nesneyi hazırlamak için kullanılan tam bir dizisi (char s[] = "hello"; bir işaretçi olarak, bir dizi olarak s başlatır) 'dir.Bu durumlarda (veya C meydana Diğer durumlarda ++) ait

hiçbiri çağrı, böylece programda görünür:

f2(data,ptr); 

f2 için tip char* iki işaretçi değerlerini geçirir.

f2 içinde, parametre x ve y tip char* arasında her ikisi de nesneler, bu std::is_same<decltype(x), decltype(y)>::value geçerlidir.

Ancak ar ve pr türleri farklıdır. ar, eksik bir dizi türü char[] ve pr, işaretçi türü char*'dur.

Programınızın çıktısını açıklar. Tuhaflık, ar dizi türüyle tanımladığınız x parametresi, pr ile aynı tür olan char* türünde olduğu için gerçekleşir.

+0

Teşekkür ederim, Keith. Bu çok iyi sunuldu ve Dyp'ın genel yorumdan standart referansı ile birlikte konser, tam olarak ne görüldüğünü açıklıyor. Çok müteşekkirim. – WhozCraig

2

C ailesi pass-by-değeri ve bir dizinin C değeri ilk elemana bir işaretçidir. Bir işlevin bir dizi olarak bildirilen bir öğeyi ilettiğinizde, gerçekten ne geçiyor, bu işaretçi ve C, prototipi bu şekilde bildirmişsiniz gibi davranır.

1

Kodu değiştirdim, böylece bir f2 çağrısının türü nasıl değiştirdiğini görebildik. Aramadan önce değişkenler farklı tiptedir. Telefonu kapattıktan sonra da aynı olmuştur

typedef char ar[]; 
typedef char* pr; 
void f2(ar x, pr y) 
{ 
    cout << is_same<decltype(x), decltype(y)>::value << '\n'; //same type 
} 

int main() 
{ 
    ar data = "data"; 
    pr ptr = data; 
    cout << is_same<decltype(data), decltype(ptr)>::value << '\n'; // different 
    f2(data,ptr); 
    return 0; 
} 

çıktı @jthill .as, @Dyp ve Thompson @keith bu çünkü işaretçi dizinin zayıflamasına olduğunu söylüyor.

+1

Sorunun başka bir "görselleştirmesi": 'is_same 've' is_same '' f2' içinde (ve tabii 'is_same '). – dyp

+1

Oh, ve ilginç bir şey: 'is_same ' ayrıca 'false' (çünkü' ar' eksik ve [basic.types]/6 farklı olduklarını söylüyor). – dyp