Bagaimana cara menulis literal pendek dalam C ++?

120

Pertanyaan yang sangat mendasar: bagaimana cara menulis shortliteral dalam C ++?

Saya tahu yang berikut:

  • 2 adalah int
  • 2U adalah unsigned int
  • 2L adalah long
  • 2LL adalah long long
  • 2.0f adalah float
  • 2.0 adalah double
  • '\2'adalah a char.

Tapi bagaimana saya menulis shortliteral? Saya mencoba 2Stetapi itu memberikan peringatan kompiler.

Tidur
sumber
10
Saya kira literal pendek tidak didukung semata-mata karena fakta bahwa apapun yang kurang dari int akan "dipromosikan" menjadi int selama evaluasi. int memiliki ukuran paling alami. Ini disebut promosi integer di C ++.
pengguna534498

Jawaban:

82
((short)2)

Ya, ini tidak hanya literal pendek, lebih seperti casted-int, tapi perilakunya sama dan saya pikir tidak ada cara langsung untuk melakukannya.

Itulah yang saya lakukan karena saya tidak dapat menemukan apa pun tentang itu. Saya akan menebak bahwa kompilator akan cukup pintar untuk mengkompilasi ini seolah-olah itu literal pendek (yaitu tidak benar-benar mengalokasikan int dan kemudian melemparkannya setiap waktu).

Berikut ini ilustrasi betapa Anda harus mengkhawatirkan hal ini:

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

Kompilasi -> membongkar ->

movl    $2, _a
movl    $2, _b
movl    $2, _c
movl    $2, _d
Jonathan Leffler
sumber
Itulah yang saya lakukan karena saya tidak dapat menemukan apa pun tentang itu. Saya akan menebak bahwa kompilator akan cukup pintar untuk mengkompilasi ini seolah-olah itu literal pendek (yaitu tidak benar-benar mengalokasikan int dan kemudian melemparkannya setiap waktu).
Kip
Para "pemeran" sebenarnya tidak melakukan apa-apa. Tidak ada instruksi assembler "cast" ketika kita berbicara tentang C atau C ++ (.NET MSIL adalah cerita yang berbeda). Ada di logam, itu semua hanya digit biner
Isak Savo
9
Apa sajakah tipe a, b, c dan d diatas?
Ates Goral
2
@Ates Goral: Semua int. Mengubah menjadi short atau char mungkin akan mengubah instruksi menjadi movw atau movb secara keseluruhan.
2
Itu bukan literal pendek. Saat Anda menggunakan cast dan compile dengan GCC dan opsi -Wconversion, Anda masih mendapatkan diagnostik compiler untuk pernyataan tersebut short foo = 1; foo += (short)2;. Tetapi ini tidak dapat dielakkan karena promosi integer.
harper
51

C ++ 11 memberi Anda cukup dekat dengan apa yang Anda inginkan. (Telusuri "literal yang ditentukan pengguna" untuk mempelajari lebih lanjut.)

#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);
}
Ken Smith
sumber
6
shortsecara fisik tidak dapat menjadi std::uintapa pun, karena itu adalah tipe yang ditandatangani. Dan itu tidak perlu 16 bit atau tipe yang sama seperti std::int16_t... yang bahkan tidak diharuskan ada dalam implementasi tertentu jika platform tidak dapat menyediakan tipe lebar-tepat. Ide inti dari jawaban ini bagus, tetapi didevaluasi oleh garis singgung yang tidak dapat dijelaskan menjadi jenis yang tidak terkait yang tidak ditanyakan OP.
underscore_d
Catatan literal yang ditentukan pengguna tidak didukung dalam Visual Studio hingga VS2015: msdn.microsoft.com/en-us/library/hh567368(v=vs.140).aspx
parsley72
Saya tidak tahu apakah saya harus menyukainya atau tidak, tetapi ini adalah bagian terakhir dari sistem tipe bilangan bulat kuat saya yang sebenarnya di C ++ yang sedang saya kerjakan, luar biasa.
Sahsahae
echoing @underscore_d, saya akan memberikan suara positif tetapi setelah diedit shortsebagai yang dilakukan oleh OP.
v.oddou
28

Bahkan penulis standar C99 terperangkap oleh ini. Ini adalah cuplikan dari stdint.himplementasi domain publik Danny Smith :

/* 7.18.4.1  Macros for minimum-width integer constants

    Accoding to Douglas Gwyn <[email protected]>:
    "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."
*/
Michael Burr
sumber
18

Jika Anda menggunakan Microsoft Visual C ++, ada sufiks literal yang tersedia untuk setiap jenis bilangan bulat:

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

Perhatikan bahwa ini adalah ekstensi non-standar dan tidak portabel . Nyatanya, saya bahkan tidak dapat menemukan info apa pun tentang sufiks ini di MSDN.

Alexander Revo
sumber
1
Saat Anda menelusuri salah satu sufiks, Anda akan melihat bahwa misalnya ""ui8didefinisikan sebagai '\000', yang pada dasarnya '\0'.
Nikita
10

Anda juga dapat menggunakan sintaks konstruktor pseudo.

short(2)

Saya merasa lebih mudah dibaca daripada mentransmisikan.

jimvonmoon
sumber
4
itu disebut "ekspresi pemeran fungsional". Saya sangat menyukainya juga, terutama saat memprogram dengan API Windows.
klaus triendl
6

Sejauh yang saya tahu, Anda tidak, tidak ada sufiks seperti itu. Kebanyakan kompiler akan memperingatkan jika literal integer terlalu besar untuk dimasukkan ke dalam variabel apa pun yang Anda coba simpan.

beristirahat
sumber