[英]Use of sizeof operator in C
我寫了一個代碼來打印C語言中不同數據類型的大小。
#include<stdio.h>
int main()
{
printf("%d", sizeof(int));//size of integer
printf("%d", sizeof(float));
printf("%d", sizeof(double));
printf("%d", sizeof(char));
}
這不起作用,但是如果我將%d
替換為%ld
,則可以。 我不明白為什么我必須花long int
才能打印出較小的數字。
這兩個都是錯誤的,您必須使用%zu
來打印size_t
類型的值,即sizeof
返回的值。
這是因為不同的值具有不同的大小,因此您必須將它們匹配。
像您一樣不匹配是不確定的行為,因此任何事情都可能發生。
這是因為尺寸不匹配。 通過使用%zu
或%u
並強制轉換為unsigned
,可以解決此問題。
當前,您的實現是不確定的行為。
printf("%u", (unsigned)sizeof(int));//size of integer
printf("%u", (unsigned)sizeof(float));
printf("%u", (unsigned)sizeof(double));
printf("%u", (unsigned)sizeof(char));
由於stdout
是新行緩沖的,所以不要忘記在最后打印\\n
來顯示任何內容。
sizeof
的返回類型為size_t
。 從標准來看
6.5.3.4 The sizeof and _Alignof operators
5這兩個運算符的結果值均由實現定義,其類型(無符號整數類型)為size_t,由
<stddef.h>
(及其他標頭)定義。
size_t
是實現定義的。 在我的Linux中,size_t定義為__SIZE_TYPE__
。 關於這個主題,可以在這里找到詳細信息。
在您的情況下,發生的情況是size_t實現的時間長於int
。
我不明白為什么我必須花很長的時間才能打印出較小的數字。
因為size_t
可能表示比int
可以支持的值大得多的值; 在我的特定實現中,最大大小值為18446744073709551615
,這絕對不適合int
。
請記住, sizeof
的操作數可以是帶括號的類型名稱或對象表達式:
static long double really_big_array[100000000];
...
printf( "sizeof really_big_array = %zu\n", sizeof really_big_array );
size_t
必須能夠表示實現允許的最大對象的大小。
您說它不起作用 ,但是您不說它能做什么。 此意外行為的最可能原因是:
%d
期望為int
值。 sizeof(int)
類型為size_t
,該類型是無符號的,並且在許多平台上大於int
,從而導致未定義的行為。 轉換說明符和傳遞的參數的類型必須一致,因為不同的類型以不同的方式傳遞給vararg函數,例如printf()
。 如果傳遞size_t
並且printf
需要一個int
,它將從錯誤的位置檢索該值並產生不一致的輸出(如果有的話)。
您說如果我放%ld
它會起作用 。 此轉換可能有效,因為size_t
恰好與平台的long
相同,但這只是一個巧合,在64位Windows上, size_t
大於long
。
要解決此問題,您可以:
%zu
或 int
。 首先是正確的修復程序,但是某些C庫不支持%zu
,最著名的是VS2013之前的Microsoft C運行時庫。 因此,我建議使用第二種方法,以便攜帶更方便,並且對於明顯較小的類型和對象也足夠:
#include <stdio.h>
int main(void) {
printf("%d\n", (int)sizeof(int));
printf("%d\n", (int)sizeof(float));
printf("%d\n", (int)sizeof(double));
printf("%d\n", (int)sizeof(char));
return 0;
}
另請注意,您不會輸出換行符:根據環境的不同,在輸出換行符或調用fflush(stdout)
之前,輸出對用戶不可見。 甚至有可能在程序退出時未將輸出刷新到控制台,從而導致您觀察到的行為,但是這種環境並不常見。 建議在有意義的輸出末尾輸出換行符。 在您的情況下,不這樣做會導致所有大小都像4481
這樣的數字序列聚集在一起,這可能與您期望的一樣,也可能不是。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.