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.


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

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);
}

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

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.


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.


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.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.