C ++ 'da kısa bir değişmez değeri nasıl yazarım?


120

Çok basit bir soru: shortC ++ dilinde bir harfi nasıl yazarım ?

Aşağıdakileri biliyorum:

  • 2 bir int
  • 2U bir unsigned int
  • 2L bir long
  • 2LL bir long long
  • 2.0f bir float
  • 2.0 bir double
  • '\2'Bir olduğunu char.

Ama nasıl shortharfiyen yazarım ? Denedim 2Sama bu bir derleyici uyarısı veriyor.


10
Sanırım kısa literal, değerlendirme sırasında int'ten daha az herhangi bir şeyin int'e "yükseltileceği" gerçeğinden dolayı desteklenmiyor. int en doğal boyuta sahiptir. Buna C ++ 'da tamsayı yükseltmesi denir.
user534498

Yanıtlar:


82
((short)2)

Evet, kesinlikle kısa bir literal değil, daha çok casted int, ama davranış aynı ve bunu yapmanın doğrudan bir yolu olmadığını düşünüyorum.

Yaptığım şey bu çünkü onun hakkında hiçbir şey bulamadım. Derleyicinin bunu kısa bir literalmiş gibi derlemek için yeterince akıllı olacağını tahmin ediyorum (yani aslında bir int ayırıp her seferinde onu yayınlamaz).

Aşağıdakiler bunun için ne kadar endişelenmeniz gerektiğini göstermektedir:

a = 2L;
b = 2.0;
c = (short)2;
d = '\2';

Derleme -> demonte etme ->

movl    $2, _a
movl    $2, _b
movl    $2, _c
movl    $2, _d

Yaptığım şey bu çünkü onun hakkında hiçbir şey bulamadım. Derleyicinin bunu kısa bir literalmiş gibi derlemek için yeterince akıllı olacağını tahmin ediyorum (yani aslında bir int ayırıp her seferinde onu yayınlamaz).
Kip

"Oyuncular" gerçekten hiçbir şey yapmıyor. C veya C ++ konuşurken "cast" derleyici talimatı yoktur (.NET MSIL farklı bir hikayedir). Metalin üzerinde, hepsi sadece ikili rakamlar
Isak Savo

9
Yukarıdaki a, b, c ve d türleri nelerdir?
Ateş Goral

2
@Ates Goral: Her şey. Short veya char olarak değiştirmek, muhtemelen talimatları pano boyunca hareket ettirmek veya hareket ettirmek için değiştirecektir.

2
Bu kısa bir kelime değil. Bu döküm ve derlemeyi GCC ve -Wconversion seçeneği ile kullandığınızda, yine de ifade için bir derleyici tanılaması elde edersiniz short foo = 1; foo += (short)2;. Ancak tamsayı ilerlemesi nedeniyle bu atlatılamaz.
harper

51

C ++ 11, istediğiniz şeye oldukça yaklaşmanızı sağlar. (Daha fazla bilgi edinmek için "kullanıcı tanımlı değişmez değerleri" arayın.)

#include <cstdint>

inline std::uint16_t operator "" _u(unsigned long long value)
{
    return static_cast<std::uint16_t>(value);
}

void func(std::uint32_t value); // 1
void func(std::uint16_t value); // 2

func(0x1234U); // calls 1
func(0x1234_u); // calls 2

// also
inline std::int16_t operator "" _s(unsigned long long value)
{
    return static_cast<std::int16_t>(value);
}

6
shortstd::uintimzalı bir tür olduğu için fiziksel olarak hiçbir şey olamaz . Ve 16 bit olması veya bir std::int16_t... ile aynı türde olması gerekli değildir ki bu , platform tam genişlik türünü sağlayamıyorsa, belirli bir uygulamada var olması bile gerekmez . Bu cevabın temel fikri iyidir, ancak açıklanamayan teğet tarafından OP'nin sormadığı ilgisiz tiplere değersizleştirilmiştir.
underscore_d

Kullanıcı tanımlı değişmez değerler, VS2015'e kadar Visual Studio'da desteklenmez: msdn.microsoft.com/en-us/library/hh567368(v=vs.140).aspx
parsley72

Onu sevmeli miyim yoksa nefret mi etmeli bilmiyorum ama bu, üzerinde çalıştığım C ++ güçlü tamsayı türü sistemimin son parçası , harika.
Sahsahae

@underscore_d yankılanıyor, oy verirdim ama bir düzenlemeden sonra shortOP tarafından onaylandığı gibi.
v.oddou

28

C99 standardının yazarları bile buna takıldı. Bu, Danny Smith'in kamu malı stdint.huygulamasından bir pasajdır :

/* 7.18.4.1  Macros for minimum-width integer constants

    Accoding to Douglas Gwyn <gwyn@arl.mil>:
    "This spec was changed in ISO/IEC 9899:1999 TC1; in ISO/IEC
    9899:1999 as initially published, the expansion was required
    to be an integer constant of precisely matching type, which
    is impossible to accomplish for the shorter types on most
    platforms, because C99 provides no standard way to designate
    an integer constant with width less than that of type int.
    TC1 changed this to require just an integer constant
    *expression* with *promoted* type."
*/

18

Microsoft Visual C ++ kullanıyorsanız, her tam sayı türü için mevcut olan değişmez son ekler vardır:

auto var1 = 10i8;  // char
auto var2 = 10ui8; // unsigned char

auto var3 = 10i16;  // short
auto var4 = 10ui16; // unsigned short

auto var5 = 10i32;  // int
auto var6 = 10ui32; // unsigned int

auto var7 = 10i64;  // long long
auto var8 = 10ui64; // unsigned long long

Bunların standart olmayan bir uzantı olduğunu ve taşınabilir olmadığını unutmayın . Aslında, MSDN'de bu son ekler hakkında herhangi bir bilgi bile bulamadım.


1
Eğer ekleriyle birini iz, söz konusu örneğin göreceksiniz ""ui8olarak tanımlanır '\000'esasen olan '\0'.
Nikita

10

Ayrıca sözde yapıcı sözdizimini de kullanabilirsiniz.

short(2)

Onu dökümden daha okunaklı buluyorum.


4
buna "işlevsel atım ifadesi" denir. Ben de çok seviyorum, özellikle Windows API ile programlama yaparken.
klaus triendl

6

Bildiğim kadarıyla sen yok, böyle bir sonek yok. Çoğu derleyici, bir tamsayı değişmez değeri, onu depolamaya çalıştığınız değişkene sığmayacak kadar büyükse uyaracaktır.

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.