İ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.