[英]Assert that the value literals have no type is false?
我在主題,文章和SO答案中都讀到#define
值沒有類型,因此我下定了決心,認為類型是容器變量的屬性,而不是值本身的屬性:
const char cVALUE = 100; // 'cVALUE' is char with value 100, wich type is '100'?
const short sVALUE = 100; // 'sVALUE' is short with value 100, wich type is '100'?
const int iVALUE = 100; // 'iVALUE' is int with value 100, wich type is '100'?
#define VALUE 100 // wich type is 'VALUE'?
但是, 值后綴呢?
#define VALUE_L 100l // 'VALUE_L' is long?
#define VALUE_UL 100ul // 'VALUE_UL' is unsigned long?
#define VALUE_LL 100ll // 'VALUE_LL' is long long?
#define VALUE_ULL 100ull // 'VALUE_ULL' is unsigned long long?
在上面的代碼中,類型似乎附加在值上,因此所有這些原始值都是類型化的值,與我之前閱讀的內容相反。 但是還有更多! 文本文字甚至具有限定詞,例如:
#define TEXT "Text" // '"Text"' is an array of some kind of chars.
上面#define
的文本值具有類型(字符類型,如果您使用的是MSVC,我認為該字符類型可能會隨着項目設置->字符集的變化而變化,不知道是否可以在其他IDE中使用)還具有const
cualifier,它是LValue而不是RValue,數字和文本文字之間的所有這些行為差異都困擾着我。
因此,假設字符類型為char
,則文字"Text"
的類型為const char *
, const char * const
或const char[5]
? 還是至少在上下文中推斷出正確的類型之前根本沒有類型?
並且,在C ++ 11標准中,文本文字也可以使用一些設置字符集的前綴進行類型化:
#define TEXT L"Text" // wide string with char type wchar_t
#define TEXTu8 u8"Text" // UTF-8 string with char type char
#define TEXTu u"Text" // UTF-16 string with char type char16_t
#define TEXTU U"Text" // UTF-32 string with char type char32_t
在考慮了所有這些內容之后,我感到非常困惑,因此我懇求一些建議:
#define
)沒有類型,但可以用文字指定類型? 換句話說:斷言值文字沒有類型是否為假? 100
),可以始終視為int類型嗎? 在C和C ++中,預處理器和編譯器是兩個單獨的實體。
處理#define
和其他預處理指令的預處理器沒有類型系統。 它操縱字符串。 這些字符代表的任何值都留給編譯器本身。
考慮
#define Y x[
即使字符串x[
在C中沒有任何意義,這也是合法的預處理程序指令。但是您可以將其用作
char Y 10];
聲明和數組x
的char
。
實際上,C預處理程序可以在源文件中用於非C語言。例如,它經常用於FORTRAN源。 由於FORTRAN沒有標准的預處理程序。
首先,您的問題:
斷言值文字沒有類型是否為假?
是。
沒有后綴且沒有小數的值文字(例如100),可以始終視為int類型嗎?
我認為默認情況下,您輸入int
。
即使是考慮文字前綴,Wich還是文字文字的類型和稱謂?
如果我沒記錯的話,默認類型是char []
。
第二,一些背景:
值文字有一個類型-只是沒有明確指定它,並且並非所有類型都可以用這種方式指定。
通過聲明一個常量,您可以顯式指定類型,並為編譯器提供更多信息。
考慮到:
#define VALUE1 102
會告訴您您的值是一個int文字。
通過聲明一個const,您可以說:
static const int VALUE1 = 102;
static const float VALUE1 = 102;
static const double VALUE1 = 102;
static const unsigned int VALUE1 = 102;
進行define
的正確/更好的方法(正確是define
constant用於常量的相對術語)將是:
#define VALUE1 (int(102))
#define VALUE1 (float(102))
// etc ...
此時,最好添加常量。
它們是正確的,因為預處理器沒有類型。 您的例子
#define VALUE_L 100l
這並不意味着VALUE_L
具有long
類型。 您可以使用預處理器將該文本插入字符串文字的中間,例如this 。
宏沒有類型。 預處理器可以創建令牌,編譯器隨后可以將令牌解釋為具有類型,但這是切線的,因此不必執行任何此類操作。
同樣, L""
文字是C ++ 03和wchar_t
。 文字""
類型為const char[1]
,是左值。 它們是左值的原因是因為傳統上它們是用const char*
指向的,並且指針必須指向左值,否則它在有用之前將變得無效,並且傳統的C數組不能為右值。
為什么常識中的文字值(和#defines)沒有類型,但是可以用文字指定類型? 換句話說:斷言值文字沒有類型是否為假?
不是。 文字均具有C ++ 11標准第2.14節中指定的類型。 在解釋文字之前,將替換預處理器宏。
沒有后綴且沒有小數的值文字(例如100),可以始終視為int類型嗎?
沒有; 十進制文字是int
, long int
或long long int
一個可以表示該值的值。 如果需要,八進制或十六進制文字也可以不帶符號。 在2011年之前,因為它不是標准類型,所以沒有考慮long long
。
因此100
將具有int
類型,因為它足夠小,可以用int
表示。
甚至考慮其前綴,文本文字的類型和限定符是什么?
沒有前綴,它是const char
數組,足夠容納所有字符和零終止符。 因此, "Text"
類型為char const[5]
。
使用前綴,字符類型將更改為您在問題中提供的類型。 數組大小仍然足夠大,可以容納包括終止符在內的所有字符。
#define
是預處理器的指令,該預處理器僅執行復制和粘貼樣式替換。 預處理器不知道或不關心代碼的含義,並且沒有類型的概念。
預處理之后,編譯器處理表達式,語句,類型等。 每個表達式(除非它是重載函數的名稱或地址)都具有僅依賴於該表達式而不依賴於代碼上下文的類型。
(C ++ 11的braced-init-list沒有類型,從技術上講也不是表達式,盡管它們可以出現在許多相同的上下文中。)
因此,# #define VALUE 100
對預處理器有意義,但那時類型的概念甚至不適用。 但是此后幾乎所有正確使用VALUE
都將其用作表達式,並且這些表達式都具有int
類型。
是的,數字后綴和字符串前綴確實會影響文字表達式的類型。 100
的類型為int
,但100UL
的類型為unsigned long
。
字面上的"Text"
總是具有類型const char [5]
但確切的含義,表示char
可以取決於你的編譯器。 在大多數情況下,該文字將立即使用隱式的數組到指針轉換為const char*
類型衰減。 (此外,為了與const
發明之前的古代C代碼向后兼容,C ++允許從字符串文字中初始化char*
變量,但最好不要這樣做。)
同樣,文字L"Text"
具有const wchar_t [5]
類型,依此類推。
#define
告訴預編譯器用定義替換所有實例,因此類型在變量中不是顯式的,但可以通過查看其表示的文字值來確定。
int
整數,否則可以將其制成long
等,例如436234636L。 當預處理器看到文本#define VALUE 100
,它將存儲字符串VALUE
[或類似的東西],並將“替換”存儲為100。每當預處理器以后找到VALUE
,它將替換為100
。 因此, VALUE
沒有類型。 C語言中的文本100
確實具有類型-它是一個int
,因為這就是語言規則所說的。
請記住,預處理程序替換發生在正確的編譯之前,因此預處理程序替換可以執行所有“怪異”的事情,這些事情在沒有宏的情況下很難(有時是不可能)。
同樣,預處理器只是將TEXT
替換為"Text"
,此時它沒有類型。 類型僅存在於適當的編譯器中。 因此,如果您有:
#define TEXT "Text"
void myfun(int x)
{
...
}
...
myfun(TEXT);
預處理器將產生
...
myfun("Text");
只有在正確編譯代碼后,編譯器才會發現“嗯,這是一個文本字符串,它不是預期的整數”,並給您帶來一些錯誤。
至於"Text"
的“類型”,它確實取決於確切的上下文。 在大多數情況下,安全的做法是將其視為const char *
,但是在某些情況下,也可以將其視為char [5]
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.