Tại sao “sizeof (a? True: false)” cho kết quả đầu ra là 4 byte?

133
msc 2017-10-30 22:37.

Tôi có một đoạn mã nhỏ về sizeoftoán tử với toán tử bậc ba:

#include <stdio.h>
#include <stdbool.h>

int main()
{
    bool a = true;
    printf("%zu\n", sizeof(bool));  // Ok
    printf("%zu\n", sizeof(a));     // Ok
    printf("%zu\n", sizeof(a ? true : false)); // Why 4?
    return 0;
}

Đầu ra ( GCC ):

1
1
4 // Why 4?

Nhưng ở đây,

printf("%zu\n", sizeof(a ? true : false)); // Why 4?

toán tử bậc ba trả về booleankiểu và boolkiểu sizeof là 1byte trong C.

Sau đó, tại sao lại sizeof(a ? true : false)đưa ra kết quả đầu ra là bốn byte?

6 answers

223
Justin 2017-10-30 22:42.

Đó là bởi vì bạn có #include <stdbool.h>. Tiêu đề đó xác định macro truefalse10, do đó, câu lệnh của bạn trông giống như sau:

printf("%zu\n", sizeof(a ? 1 : 0)); // Why 4?

sizeof(int) là 4 trên nền tảng của bạn.

66
Sourav Ghosh 2017-10-30 22:40.

Đây, booleankiểu trả về toán tử bậc ba ,

OK, còn nhiều thứ nữa!

Trong C, kết quả của này hoạt động ternary là loại int. [ghi chú bên dưới (1,2)]

Do đó, kết quả giống như biểu thức sizeof(int), trên nền tảng của bạn.


Ghi chú 1: Trích dẫn C11, chương §7.18,Boolean type and values <stdbool.h>

[....] Ba macro còn lại thích hợp để sử dụng trong các #ifchỉ thị tiền xử lý. họ đang

true

mở rộng thành hằng số nguyên 1,

false

mở rộng thành hằng số nguyên 0, [....]

Lưu ý 2: Đối với toán tử điều kiện, chương §6.5.15, ( tôi nhấn mạnh )

Toán hạng đầu tiên được đánh giá; có một điểm trình tự giữa đánh giá của nó và đánh giá của toán hạng thứ hai hoặc thứ ba (tùy theo giá trị nào được đánh giá). Toán hạng thứ hai chỉ được đánh giá nếu toán hạng đầu tiên so sánh không bằng 0; toán hạng thứ ba chỉ được đánh giá nếu so sánh đầu tiên bằng 0; kết quả là giá trị của toán hạng thứ hai hoặc thứ ba (tùy theo giá trị nào được đánh giá), [...]

Nếu cả toán hạng thứ hai và thứ ba đều có kiểu số học, thì kiểu kết quả sẽ được xác định bởi các phép chuyển đổi số học thông thường, được áp dụng cho hai toán hạng đó, là kiểu kết quả. [....]

do đó, kết quả sẽ có kiểu số nguyên và vì phạm vi giá trị, các hằng số chính xác là kiểu int.

Điều đó nói rằng, một lời khuyên chung chung, int main()tốt hơn là int main (void)nên thực sự phù hợp với tiêu chuẩn.

58
n. 'pronouns' m. 2017-10-30 23:49.

Toán tử bậc ba là một con cá trích đỏ.

    printf("%zu\n", sizeof(true));

bản in 4 (hoặc bất cứ thứ gì sizeof(int)trên nền tảng của bạn).

Điều sau giả định rằng đó boollà một từ đồng nghĩa với charhoặc một loại tương tự của kích thước 1 và intlớn hơn char.

Lý do tại sao sizeof(true) != sizeof(bool)sizeof(true) == sizeof(int)chỉ đơn giản là bởi vì truekhông một biểu hiện của loại bool. Đó là một biểu hiện của loại int. Nó là #defined như 1trong stdbool.h.

Không có giá trị nào thuộc loại boolC nào cả. Mỗi giá trị như vậy ngay lập tức được thăng hạng int, ngay cả khi được sử dụng làm đối số sizeof. Chỉnh sửa: đoạn này không đúng sự thật, lập luận để sizeofkhông được thăng cấp int. Tuy nhiên, điều này không ảnh hưởng đến bất kỳ kết luận nào.

31
Lundin 2017-10-31 23:47.

Về kiểu boolean trong C

Một kiểu boolean được giới thiệu khá muộn trong ngôn ngữ C, vào năm 1999. Trước đó, C không có kiểu boolean mà thay vào đó được sử dụng intcho tất cả các biểu thức boolean. Do đó, tất cả các toán tử logic như > == !vv trả intvề giá trị 1hoặc 0.

Các ứng dụng được tùy chỉnh để sử dụng các loại sản xuất tại nhà, chẳng hạn như typedef enum { FALSE, TRUE } BOOL;, cũng tổng hợp intcác loại theo kích thước.

C ++ có kiểu boolean rõ ràng và tốt hơn nhiều, boolkhông lớn hơn 1 byte. Trong khi các kiểu hoặc biểu thức boolean trong C sẽ kết thúc bằng 4 byte trong trường hợp xấu nhất. Một số cách tương thích với C ++ đã được giới thiệu trong C với tiêu chuẩn C99. Sau đó C có một kiểu boolean _Boolvà cả tiêu đề stdbool.h.

stdbool.hcung cấp một số khả năng tương thích với C ++. Tiêu đề này xác định macro bool(cách viết giống như từ khóa C ++) mở rộng thành _Bool, một kiểu là kiểu số nguyên nhỏ, có thể lớn 1 byte. Tương tự, tiêu đề cung cấp hai macro truevà cách falseviết giống như từ khóa C ++, nhưng có khả năng tương thích ngược với các chương trình C cũ hơn . Do đó truefalsemở rộng đến 10trong C và loại của chúng là int. Các macro này không thực sự thuộc loại boolean như các từ khóa C ++ tương ứng.

Tương tự, vì mục đích tương thích ngược, các toán tử logic trong C vẫn trả về intngày nay, mặc dù C ngày nay có kiểu boolean. Trong khi trong C ++, các toán tử logic trả về a bool. Vì vậy, một biểu thức chẳng hạn sizeof(a == b)sẽ cho kích thước của một inttrong C, nhưng kích thước của a booltrong C ++.

Về toán tử điều kiện ?:

Toán tử điều kiện ?:là một toán tử kỳ lạ với một vài câu hỏi thường gặp. Đó là một sai lầm phổ biến khi tin rằng nó tương đương 100% với if() { } else {}. Không hẳn.

Có một điểm thứ tự giữa đánh giá của toán hạng thứ nhất và thứ hai hoặc thứ ba. Các ?:nhà điều hành được đảm bảo chỉ đánh giá hệ 2 hoặc toán hạng thứ 3, vì vậy nó không thể thực hiện bất kỳ tác dụng phụ của các toán hạng không được đánh giá. Mã like true? func1() : func2()sẽ không thực thi func2(). Càng xa càng tốt.

Tuy nhiên , có một quy tắc đặc biệt nói rằng toán hạng thứ 2 và thứ 3 phải được thăng hạng ngầm và cân bằng với nhau bằng các chuyển đổi số học thông thường . ( Quy tắc quảng cáo kiểu ngầm định ). Điều này có nghĩa là toán hạng thứ 2 hoặc thứ 3 sẽ luôn lớn ít nhất bằng một int.

Vì vậy, nó không quan trọng truevà tình falsecờ là loại inttrong C bởi vì biểu thức sẽ luôn cho ít nhất kích thước của một intvấn đề.

Ngay cả khi bạn viết lại biểu thức cho nó vẫn sẽ trả về kích thước của một !sizeof(a ? (bool)true : (bool)false) int

Điều này là do quảng cáo kiểu ngầm thông qua các chuyển đổi số học thông thường.

21
chqrlie 2017-10-31 23:02.

Câu trả lời nhanh:

  • sizeof(a ? true : false)đánh giá là 4bởi vì truefalseđược định nghĩa <stdbool.h>theo 10tương ứng, do đó, biểu thức mở rộng thành sizeof(a ? 1 : 0)một biểu thức số nguyên có kiểu int, chiếm 4 byte trên nền tảng của bạn. Vì lý do tương tự, sizeof(true)cũng sẽ đánh giá 4trên hệ thống của bạn.

Tuy nhiên, lưu ý rằng:

  • sizeof(a ? a : a)cũng đánh giá là 4vì toán tử bậc ba thực hiện các thăng hạng số nguyên trên các toán hạng thứ hai và thứ ba của nó nếu đây là các biểu thức số nguyên. Điều này cũng tất nhiên sẽ xảy ra cho sizeof(a ? true : false)sizeof(a ? (bool)true : (bool)false), nhưng đúc toàn bộ biểu hiện như boolcư xử như mong đợi: sizeof((bool)(a ? true : false)) -> 1.

  • cũng lưu ý rằng toán tử so sánh đánh giá các giá trị boolean 1hay 0, nhưng có intloại: sizeof(a == a) -> 4.

Các toán tử duy nhất giữ bản chất boolean asẽ là:

  • toán tử dấu phẩy: cả hai sizeof(a, a)sizeof(true, a)đánh giá thành 1tại thời điểm biên dịch.

  • toán tử gán: cả hai sizeof(a = a)sizeof(a = true)có giá trị là 1.

  • các toán tử tăng dần: sizeof(a++) -> 1

Cuối cùng, tất cả những điều trên chỉ áp dụng cho C: C ++ có ngữ nghĩa khác nhau liên quan đến boolkiểu, giá trị boolean truefalse, toán tử so sánh và toán tử bậc ba: tất cả các sizeof()biểu thức này đều được đánh giá là 1trong C ++.

1
u__ 2017-11-06 01:42.

Đây là một đoạn trích từ đó là những gì được bao gồm trong nguồn

#ifndef __cplusplus

#define bool    _Bool
#define true    1
#define false   0

#else /* __cplusplus */

Có macro truefalseđược khai báo là 1 và 0 tương ứng.

tuy nhiên trong trường hợp này kiểu là kiểu của các hằng chữ. Cả 0 và 1 đều là các hằng số nguyên phù hợp với một int, vì vậy kiểu của chúng là int.

sizeof(int)trong trường hợp của bạn là 4.

Related questions

MORE COOL STUFF

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett đã bất chấp những lời khuyên hẹn hò điển hình khi cô gặp chồng mình.

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Michael Sheen là một diễn viên phi lợi nhuận nhưng chính xác thì điều đó có nghĩa là gì?

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Ngôi sao của Hallmark Colin Egglesfield chia sẻ về những cuộc gặp gỡ với người hâm mộ ly kỳ tại RomaDrama Live! cộng với chương trình INSPIRE của anh ấy tại đại hội.

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Bạn sẽ phải phủi sạch đầu đĩa Blu-ray hoặc DVD để xem tại sao Northern Exposure trở thành một trong những chương trình nổi tiếng nhất của thập niên 90.

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

8 công dụng tuyệt vời của Baking Soda và Giấm

8 công dụng tuyệt vời của Baking Soda và Giấm

Bạn biết đấy, hai sản phẩm này là nguồn điện để làm sạch, riêng chúng. Nhưng cùng với nhau, chúng có một loạt công dụng hoàn toàn khác.

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Thủy điện rất cần thiết cho lưới điện của Hoa Kỳ, nhưng nó chỉ tạo ra năng lượng khi có nước di chuyển. Bao nhiêu nhà máy thủy điện có thể gặp nguy hiểm khi các hồ và sông cạn kiệt?

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Tóc tỉa từ các tiệm và các khoản quyên góp cá nhân có thể được tái sử dụng như những tấm thảm thấm dầu và giúp bảo vệ môi trường.

Xem đoạn giới thiệu cho bộ phim chuyển thể đầy khói lửa, có sự góp mặt của ngôi sao Edward Norton từ phim Motherless Brooklyn của Jonathan Lethem

Xem đoạn giới thiệu cho bộ phim chuyển thể đầy khói lửa, có sự góp mặt của ngôi sao Edward Norton từ phim Motherless Brooklyn của Jonathan Lethem

Edward Norton đã muốn đưa cuốn tiểu thuyết Motherless Brooklyn của Jonathan Lethem's Joycean 1999 lên màn ảnh kể từ khi nó được xuất bản. Bây giờ, 20 năm sau, một đoạn giới thiệu đã xuất hiện cho câu chuyện sôi nổi, đưa câu chuyện của Lethem trở lại những năm 1950 với rất nhiều gương mặt quen thuộc.

Cách dễ dàng chọn không tham gia trọng tài ràng buộc thẻ Apple

Cách dễ dàng chọn không tham gia trọng tài ràng buộc thẻ Apple

Có thích thú khi sử dụng Thẻ Apple mới của bạn không? Trước khi bạn bắt đầu chi tiêu, có một nhiệm vụ bổ sung cần xem xét: chọn không tham gia trọng tài ràng buộc. Bạn sẽ phát hiện ra các điều khoản trọng tài ràng buộc trong nhiều thỏa thuận tài chính vì nó giúp ngăn các ngân hàng và đối tác kinh doanh của họ không phải ra tòa.

Những người chơi Fortnite World Cup không ghi bàn có cảm giác hài hước về điều đó

Những người chơi Fortnite World Cup không ghi bàn có cảm giác hài hước về điều đó

Điểm số tại vòng chung kết Fortnite World Cup Solo hôm nay là rất lớn, với người chiến thắng Bugha ghi được nhiều hơn 26 điểm so với người về thứ hai là Psalm. Nhưng không phải ai cũng có thể giành chiến thắng: Bốn cầu thủ ra về với 0 điểm, nhưng — ít nhất là trên Twitter — họ là những người thể thao tốt về điều đó.

Báo cáo: Cánh cửa tuyển sinh có thể đã mở cho các ứng viên UCLA có mối quan hệ có ảnh hưởng

Báo cáo: Cánh cửa tuyển sinh có thể đã mở cho các ứng viên UCLA có mối quan hệ có ảnh hưởng

Huấn luyện viên trưởng của bộ môn thể dục dụng cụ UCLA Valorie Kondos-Field theo dõi Katelyn Ohashi thi đấu thăng bằng trong trận gặp Stanford tại Pauley Pavilion vào ngày 10 tháng 3 năm 2019 ở Los Angeles, California. Vụ bê bối gian lận tuyển sinh đại học tiết lộ các chi tiết của một quá trình chính thức hóa để đưa những đứa trẻ thất bại của các gia đình giàu có và nổi tiếng vào các trường đại học đáng tin cậy và danh tiếng, sử dụng một "cửa phụ" đắt tiền cho các bậc cha mẹ mà sự giàu có của họ khiến họ không có cơ hội. chỉ cần tài trợ cho một cánh mới trong khuôn viên trường.

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Rothschild's luggage got lost, but luckily she has an incredible closet to shop: Sister Paris Hilton's!

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa. Từ Hollywood đến New York và mọi nơi ở giữa, hãy xem các ngôi sao yêu thích của bạn đang làm gì!

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

Các nhà điều tra đang xem xét liệu nhóm và nghi phạm có biết nhau trước vụ tấn công hay không

Thanh thiếu niên, Gia đình Florida Hội đồng quản trị trường học về Luật 'Không nói đồng tính': 'Buộc chúng tôi tự kiểm duyệt'

Thanh thiếu niên, Gia đình Florida Hội đồng quản trị trường học về Luật 'Không nói đồng tính': 'Buộc chúng tôi tự kiểm duyệt'

Vụ kiện, nêu tên một số học khu, lập luận rằng dự luật "Không nói đồng tính" được ban hành gần đây của Florida "có hiệu quả im lặng và xóa bỏ học sinh và gia đình LGBTQ +"

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Vào năm 2021, tôi khuyến khích bạn suy nghĩ lại mọi thứ bạn biết về khách hàng mà bạn phục vụ và những câu chuyện bạn kể cho họ. Lùi lại.

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Vào ngày sinh nhật thứ 9 của Felix The Cat, tôi nhớ về một trong những mất mát lớn nhất trong cuộc đời trưởng thành của tôi - Sophie của tôi vào năm 2013. Tôi đã viết bài luận này và chia sẻ nó trên nền tảng này một thời gian ngắn vào năm 2013.

Khi bạn không thể trở thành người mà Internet muốn bạn trở thành

Khi bạn không thể trở thành người mà Internet muốn bạn trở thành

Tôi ghét từ "tàu đắm". Mọi người cảm thấy thoải mái trong la bàn đạo đức của riêng mình, và khi làm như vậy, họ thấy mình vượt qua sự phán xét.

Tầm nhìn đám mây phi tập trung của DFINITY Blockchain

Lưu ý của người biên tập: Bạn đang xem tài liệu lỗi thời từ blog DFINITY đang được bảo quản cho mục đích lưu trữ.

Tầm nhìn đám mây phi tập trung của DFINITY Blockchain

Bài đăng này khám phá tầm nhìn về đám mây phi tập trung của nhóm DFINITY và cách nó liên quan đến các nhà cung cấp blockchain truyền thống và đám mây hiện có như Amazon Web Services. Các minh chứng về công nghệ DFINITY được áp dụng bởi một mạng lưới quy mô lớn sẽ được thực hiện vào mùa thu năm 2017, sau đó sẽ được gây quỹ Chính cho quỹ hỗ trợ phi lợi nhuận, với mạng “đám mây mở” dự kiến ​​sẽ ra mắt vào đầu mùa hè năm 2018 .

Language