Khai báo một biến có hai kiểu: “int char”


81

Tôi là người mới bắt đầu học C ++ và tôi đang đọc Lập trình của Bjarne Stroustrup: Nguyên tắc và thực hành sử dụng C ++ .

Trong phần về 3.9.2 Chuyển đổi không an toàn , tác giả đã đề cập đến

Khi trình khởi tạo là một chữ số nguyên, trình biên dịch có thể kiểm tra giá trị thực và chấp nhận các giá trị không ngụ ý thu hẹp:

int char b1 {1000};     // error: narrowing (assuming 8-bit chars)

Tôi bối rối trước tuyên bố này. Nó sử dụng hai loại ( intchar). Tôi chưa bao giờ thấy khai báo như vậy trong Java và Swift trước đây (hai ngôn ngữ tôi tương đối quen thuộc). Đây là lỗi đánh máy hay cú pháp C ++ hợp lệ?


2
Bạn có ấn bản và in cuốn sách nào? Bạn đã tìm kiếm một phần của cuốn sách chưa?
Một số lập trình viên dude

2
Vậy bạn đang đọc phiên bản nào? Tôi chắc rằng Bjarne muốn biết về sai lầm này.
người kể chuyện - Unslander Monica

1
3.9.2 Chuyển đổi không an toàn Bằng cách chuyển đổi không an toàn, chúng tôi muốn nói rằng một giá trị có thể hoàn toàn bị biến thành giá trị của một loại khác không bằng giá trị ban đầu. ví dụ: int i = 20000; char c = i; Những chuyển đổi như vậy được gọi là chuyển đổi 'thu hẹp'. tăng gấp đôi để int, char hoặc bool int để char hoặc bool char để bool
Marichyasana

15
Đây float charlà một loại hữu ích khác, đặc biệt là trong bể bơi. Một số đi kèm với một ngăn đựng bia.
Yakk - Adam Nevraumont

1
Đây là lỗi đánh máy hay cú pháp C ++ hợp lệ? Hãy thử nó (OK, OK, không nó không hợp lệ).
Paul Sanders

Câu trả lời:


95

Đó là một sai lầm trong cuốn sách. Đó không phải là một khai báo C ++ hợp lệ, ngay cả khi không có chuyển đổi được cho là thu hẹp.

Tuy nhiên, nó không được đề cập trong bất kỳ erratas nào trên trang của Bjarne Stroustrup (in lần thứ 4 trở về trước), điều này thật kỳ lạ. Đó là một sai lầm đủ rõ ràng. Tôi tưởng tượng vì nó được bình luận nên //errorít người nhận ra lỗi trong chính phần khai báo.


Ví dụ mã dự định trong sách có lẽ là gì?
Pedro A

8
@Hamsterrific char b1 {1000};(vì điều đó sẽ gây ra lỗi được đề cập trong nhận xét). Tôi đoán những ngón tay gõ của Bjarne đã mệt mỏi vào ngày hôm đó.
Paul Sanders

1
@PaulSanders Mệt mỏi? Anh ấy đã gõ thêm intở đó! :-)
Leo Heinsaar

1
@ LeoHeinsaar Lol. OK, quá nhiều cà phê sau đó :) Hoặc có lẽ ông có một nói lắp :)
Paul Sanders

Ừ: mỏi ngón tay. Có vẻ như lỗi cắt-n-dán từ ví dụ trước đó. Trong ví dụ trước đó, anh ta đưa ra hai dòng: int a {1000}; // OK [\ n] char b {a} // error: int -> char có thể thu hẹp [\ n] và anh ấy có vẻ đã cắt-n-dán ví dụ đó cho ví dụ tiếp theo và lỡ xóa phần "int" : int char b1 {1000}; // lỗi: thu hẹp (giả sử ký tự 8 bit) [\ n] char b2 {48}; // OK [\ n]
L. Scott Johnson

24

Sách sai.

Chuỗi mã thông báo int char b1{1000};không phải là C ++ hợp lệ về mặt ngữ nghĩa.

Bạn đang cố gắng khai báo b1với nhiều loại, điều này không có ý nghĩa gì.


10

Nó là sai lầm. Trong C / C ++, các khai báo nhiều kiểu có thể đạt được thông qua việc sử dụng các hợp nhất. Ví dụ:

union {
    int i;
    char c;
} var;

var.i = 42;
/* OR */
var.c = ‘c’;

Bộ nhớ giống nhau, vì vậy .c và .i chỉ là các xử lý cho mỗi loại với cùng một giá trị.


6

Điều này sai trong cú pháp C / C ++. Ngoài unions (xem câu trả lời @Alex), có một cách C ++ để chỉ lưu trữ một trong các kiểu có sẵn được gọi là std::variant(type-safe union):

#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
}
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.