Làm cách nào để viết một đoạn văn ngắn trong C ++?


120

Câu hỏi rất cơ bản: làm cách nào để viết một shortchữ trong C ++?

Tôi biết những điều sau:

  • 2 là một int
  • 2U là một unsigned int
  • 2L là một long
  • 2LL là một long long
  • 2.0f là một float
  • 2.0 là một double
  • '\2'là một char.

Nhưng làm thế nào tôi sẽ viết một shortnghĩa đen? Tôi đã thử 2Snhưng điều đó đưa ra cảnh báo trình biên dịch.


10
Tôi đoán nghĩa đen ngắn không được hỗ trợ chỉ vì thực tế là bất kỳ thứ gì nhỏ hơn int sẽ được "thăng cấp" thành int trong quá trình đánh giá. int có kích thước tự nhiên nhất. Đây được gọi là thăng hạng số nguyên trong C ++.
user534498

Câu trả lời:


82
((short)2)

Vâng, nó không hoàn toàn là một nghĩa đen ngắn, nhiều hơn là một hàm nhập, nhưng hành vi thì giống nhau và tôi nghĩ không có cách nào trực tiếp để làm điều đó.

Đó là những gì tôi đang làm bởi vì tôi không thể tìm thấy gì về nó. Tôi đoán rằng trình biên dịch sẽ đủ thông minh để biên dịch điều này như thể nó là một ký tự ngắn (nghĩa là nó sẽ không thực sự cấp phát một int và sau đó ép nó mỗi lần).

Những điều sau đây minh họa mức độ bạn nên lo lắng về điều này:

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

Biên dịch -> tháo rời ->

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

Đó là những gì tôi đang làm bởi vì tôi không tìm thấy gì về nó. Tôi đoán rằng trình biên dịch sẽ đủ thông minh để biên dịch điều này như thể nó là một ký tự ngắn (nghĩa là nó sẽ không thực sự cấp phát một int và sau đó ép nó mỗi lần).
Kip

"Dàn diễn viên" không thực sự làm nên chuyện. Không có hướng dẫn trình hợp dịch "ép kiểu" khi chúng ta đang nói C hoặc C ++ (.NET MSIL là một câu chuyện khác). Ở đó trên kim loại, tất cả chỉ là các chữ số nhị phân
Isak Savo

9
Các loại a, b, c, d trên là gì?
Ates Goral

2
@Ates Goral: Tất cả ints. Thay đổi thành short hoặc char có lẽ sẽ thay đổi hướng dẫn thành movw hoặc movb trên bảng.

2
Đó không phải là nghĩa đen. Khi bạn sử dụng truyền và biên dịch đó với GCC và tùy chọn -Wconversion, bạn vẫn nhận được chẩn đoán trình biên dịch cho câu lệnh short foo = 1; foo += (short)2;. Nhưng điều này không thể bị phá vỡ do quảng cáo số nguyên.
harper

51

C ++ 11 cung cấp cho bạn khá gần những gì bạn muốn. (Tìm kiếm "từ do người dùng xác định" để tìm hiểu thêm.)

#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
shortvề mặt vật lý không thể là std::uintbất cứ thứ gì, vì nó là một loại có dấu. Và nó không bắt buộc phải là 16 bit hoặc cùng loại với std::int16_t... mà bản thân nó thậm chí không bắt buộc phải tồn tại trong một triển khai nhất định nếu nền tảng không thể cung cấp loại chiều rộng chính xác. Ý tưởng cốt lõi của câu trả lời này là tốt, nhưng nó bị mất giá bởi sự tiếp xúc không thể giải thích được thành các loại không liên quan mà OP không hỏi về.
underscore_d

Lưu ý literals người dùng định nghĩa không được hỗ trợ trong Visual Studio cho đến khi VS2015: msdn.microsoft.com/en-us/library/hh567368(v=vs.140).aspx
parsley72

Tôi không biết mình nên yêu hay ghét nó nhưng đây là phần cuối cùng của hệ thống kiểu số nguyên Strong thực sự của tôi trong C ++ mà tôi đang làm việc, nó thật tuyệt vời.
Sahsahae

echoing @underscore_d, tôi sẽ ủng hộ nhưng sau khi chỉnh sửa với sự hỗ trợ shortcủa OP.
v.oddou

28

Ngay cả những người viết tiêu chuẩn C99 cũng bị bắt gặp bởi điều này. Đây là một đoạn trích từ stdint.htriển khai miền công cộng của 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

Nếu bạn sử dụng Microsoft Visual C ++, có các hậu tố chữ có sẵn cho mọi loại số nguyên:

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

Lưu ý rằng đây là một tiện ích mở rộng không chuẩnkhông di động . Trên thực tế, tôi thậm chí không thể tìm thấy bất kỳ thông tin nào về các hậu tố này trên MSDN.


1
Khi bạn theo dõi một trong các hậu tố, bạn sẽ thấy ví dụ đó ""ui8được định nghĩa là '\000', về cơ bản là như vậy '\0'.
Nikita

10

Bạn cũng có thể sử dụng cú pháp của hàm tạo giả.

short(2)

Tôi thấy nó dễ đọc hơn là đúc.


4
nó được gọi là "biểu thức ép kiểu hàm". Tôi cũng rất thích nó, đặc biệt là khi lập trình với Windows API.
klaus triendl 22/02/17

6

Theo như tôi biết, bạn không, không có hậu tố như vậy. Tuy nhiên, hầu hết các trình biên dịch sẽ cảnh báo nếu một ký tự số nguyên quá lớn để phù hợp với bất kỳ biến nào bạn đang cố gắng lưu trữ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.