İki türde bir değişken bildirmek: "int char"


81

Ben bir C ++ acemisiyim ve Bjarne Stroustrup'un Programlama: İlkeler ve C ++ Kullanarak Uygulama okuyorum .

3.9.2 Güvenli olmayan dönüştürmelerle ilgili bölümde yazar,

Başlatıcı bir tamsayı değişmez değeri olduğunda, derleyici gerçek değeri kontrol edebilir ve daraltma anlamına gelmeyen değerleri kabul edebilir:

int char b1 {1000};     // error: narrowing (assuming 8-bit chars)

Bu beyan beni şaşırttı. İki tür kullanır ( intve char). Java ve Swift'de daha önce hiç böyle bir beyan görmemiştim (nispeten aşina olduğum iki dil). Bu bir yazım hatası mı yoksa geçerli bir C ++ sözdizimi mi?


2
Kitabın hangi baskısı ve baskısı sizde var? Kitabın yazım hatalarını aradınız mı?
Bazı programcı dostum

2
Peki hangi versiyonu okuyorsun? Eminim Bjarne bu hatayı bilmek ister.
StoryTeller - Unslander Monica

1
3.9.2 Güvenli olmayan dönüştürmeler Güvenli olmayan dönüştürme ile, bir değerin dolaylı olarak orijinal değere eşit olmayan başka bir türden bir değere dönüştürülebileceğini kastediyoruz. örneğin: int i = 20000; karakter c = i; Bu tür dönüşümlere "daraltma" dönüşümleri denir. double to int, char veya bool int to char veya bool char to bool
Marichyasana

15
float charÖzellikle yüzme havuzlarında faydalı olan bir diğer türdür. Bazılarında bira için bir tutacak bulunur.
Yakk - Adam Nevraumont

1
Bu bir yazım hatası mı yoksa geçerli bir C ++ sözdizimi mi? Deneyin (Tamam, Tamam, hayır geçerli değil).
Paul Sanders

Yanıtlar:


95

Kitapta bir hata var. Bu, sözde daraltma dönüşümü olmasa bile geçerli bir C ++ bildirimi değildir.

Yine de, Bjarne Stroustrup'un sayfasındaki (4. baskı ve öncesi) herhangi bir hatadan bahsedilmiyor , bu garip. Yeterince açık bir hata. Çok //erroraz kişi tarafından yorumlandığı için beyannamenin kendisindeki hatayı fark ettiğini hayal ediyorum .


Muhtemelen kitapta amaçlanan kod örneği neydi?
Pedro A

8
@Hamsterrific char b1 {1000};(çünkü bu, yorumda bahsedilen hatayı kışkırtabilir). Sanırım Bjarne'ın yazı yazması o gün yorulmuştu.
Paul Sanders

1
@PaulSanders Yorgun musun? Orada fazladan yazdı int! :-)
Leo

1
@ LeoHeinsaar Lol. Tamam, o zaman çok fazla kahve :) Ya da kekelemesi var :)
Paul Sanders

Evet: parmaklar yorgun. Kendinden önceki örnekte kes-yapıştır hatası gibi görünüyor. Bu önceki örnekte iki satır veriyor: int a {1000}; // Tamam [\ n] char b {a} // hata: int -> karakter daraltabilir [\ n] ve bu örneği bir sonrakine kesip yapıştırmış ve "int" bölümünü silmeyi kaçırmış gibi görünüyor : int char b1 {1000}; // hata: daraltma (8 bitlik karakterler varsayılarak) [\ n] char b2 {48}; // Tamam [\ n]
L. Scott Johnson

24

Kitap yanlış.

Belirteç dizisi int char b1{1000};anlamsal olarak geçerli C ++ değil.

b1Birden fazla türle beyan etmeye çalışıyorsunuz , bu hiç mantıklı değil.


10

Bu yanlış. C / C ++ 'da çoklu tip bildirimler, birliklerin kullanımıyla elde edilebilir. Örneğin:

union {
    int i;
    char c;
} var;

var.i = 42;
/* OR */
var.c = ‘c’;

Depolama aynıdır, dolayısıyla .c ve .i aynı değere sahip tür başına tutamaçlardır.


6

Bu, C / C ++ sözdiziminde yanlıştır. unionS'ye ek olarak (@Alex yanıtına bakın), std::variant(tür güvenli birleşim) adı verilen mevcut türlerden yalnızca birini depolamanın bir C ++ yolu vardır :

#include <variant>
#include <string>

int main()
{
    std::variant<int, float> v, w;
    v = 12; // v contains int
    int i = std::get<int>(v);
    w = std::get<int>(v);
    w = std::get<0>(v); // same effect as the previous line
    w = v; // same effect as the previous line

//  std::get<double>(v); // error: no double in [int, float]
//  std::get<3>(v);      // error: valid index values are 0 and 1

    try {
      std::get<float>(w); // w contains int, not float: will throw
    }
    catch (std::bad_variant_access&) {}

    std::variant<std::string> v("abc"); // converting constructors work when unambiguous
    v = "def"; // converting assignment also works when unambiguous
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.