Mr J C99標準之陣列問題

2021-08-21 19:41:11 字數 3266 閱讀 7259

c99標準,2023年12月1日,國際標準化組織(iso)和國際電工委員會(iec)旗下的c語言標準委員會(iso/iec jtc1/sc22/wg14)正式發布了這個標準檔案 。其主要內容為:

對編譯器限制增加了,比如源程式每行要求至少支援到 4095 位元組,變數名與函式名的要求支援到 63 位元組 (extern 要求支援到 31)。

預編譯處理增強了。例如:

支援了可變引數的巨集(variadic macro): #define macro(...) __va_args__

使用巨集的時候,引數如果不寫,巨集裡用 #,## 這樣的東西會擴充套件成空串。(c89標準中會出錯的)

支援 // 行注釋(這個特性實際上在c89的很多編譯器上已經被支援了)

增加了新關鍵字 restrict,inline,_complex,_imaginary,_bool

支援 long long,long double _complex,float _complex 這樣的型別

支援 <: :> %: %:%: ,等等奇怪的符號替代,d&e 裡提過這個支援了不定長的陣列。陣列的長度就可以用變數了。宣告型別的時候呢,就用 int a[*] 這樣的寫法。不過考慮到效率和實現,這玩意並不是乙個新型別。所以就不能用在全域性裡,或者 struct union 裡面,如果你用了這樣的東西,goto 語句就受限制了。

變數宣告不必放在語句塊的開頭,for 語句提倡這麼寫 for(int i=0;i<100;++i) 就是說,int i 的宣告放在裡面,i 只在 for 裡面有效。(vc6.0沒有遵守這條標準,i 在 for 外也有效;但vc2005裡已經預設是i在外面不可見了,但有編譯選項可以設定。)

復合字面量:當乙個類似結構的東西需要臨時構造的時候,可以用 (type_name) 這有點像 c++ 的建構函式

相較於c89標準,c99標準新增了一種結構體/陣列的初始化方式,名叫designated initializers [8]  ,即:

struct w =, [1].a[0] = 2 }; [9] 

字串裡面,\u 支援 unicode 的字元

支援 16 進製的浮點數的描述

所以 printf和scanf 的格式化串增加了支援 "%lld"和"%llu",對應long long int型別和unsigned long long int型別(可以分別簡寫為long long和unsigned long long)。

浮點數的內部資料描述支援了新標準,這個可以用 #pragma 編譯器指定

增加了乙個內建的區域性靜態字元陣列變數 __func__ ,可以用於得到當前函式的函式名 [10]  。

對於非常量的表示式,也允許編譯器做化簡

修改了 /% 處理負數時的定義,這樣可以給出明確的結果,例如在c89中-22 / 7 = -3, -22% 7 = -1,也可 以-22 / 7= -4, -22% 7 = 6。 而c99中明確為 -22 / 7 = -3, -22% 7 = -1,只有一種結果。

取消了不寫函式返回型別預設就是 int 的規定

允許 struct 定義的最後乙個陣列寫做 不指定其長度描述

const const int i; 將被當作 const int i; 處理

增加和修改了一些標準標頭檔案。比如定義 bool 的 ,定義一些標準長度的 int 的 ,定義複數的 定義寬字元的 有點泛型味道的數學函式 跟浮點數有關的 。裡多了乙個 va_copy 可以複製 ... 的引數。裡多了個 struct tmx 對 struct tm 做了擴充套件

輸入輸出對寬字元還有長整數等做了相應的支援

long double_complex;long double_imaginary。

標頭檔案中定義了complex和imaginary巨集,並將它們擴充套件為_complex和_imaginary,因此在編寫新的應用程式時,應該使用標頭檔案中的complex和imaginary巨集。

c99標準中引進了long long int(-263至263 - 1)和unsigned long long int(0到264 - 1)。long long int能夠支援的整數長度為64位。

在這裡,我主要先說我上面紅字標註的問題(我在今天重拾c primer plus遇到的問題):

#include#define months 12 

int main();

int i;

for(i=0;i

這個程式在c99標準下是可以執行的:

從輸出結果可以看出指定初始化專案有兩個重要特性。第一,  如果在一乙個指定初始化專案後跟有不止乙個值,例如在序列[4]=31,30,31 中這樣,則這些數值將用來對後續的陣列元素初始化。也就是說,  把31賦給days[4]之後,接著把30和31分別賦給days[5]和days[6]。第二,如果多次對乙個元素進行初始化,則最後的一次有效。例如,前面把days[1]初始化為28,而後面的指定初始化[1]=29覆蓋了前面的數值,於是days[1]的數值最終為29。

但是對於現在的c語言標準c11,這個是行不通的,我在編譯之後執行,出來的結果是這樣的:

這就讓人非常頭大。

我查詢相關資料發現:① c99中,結構中的最後乙個元素允許是未知大小的陣列,這就叫做柔性陣列成員,但結構中的柔性陣列成員前面必須至少乙個其他成員。柔性陣列成員允許結構中包含乙個大小可變的陣列。sizeof返回的這

種結構大小不包括柔性陣列的記憶體。包含柔性陣列成員的結構用malloc()函式進行記憶體的動態分配,並且分配的記憶體應該大於結構的大小,以適應柔性陣列的預期大小。② c99中,程式設計師宣告陣列時,陣列的維數可以由任一有效的整型表示式確定,包括只在執行時才能確定其值的表示式,這類陣列就叫做可變長陣列、但是只有區域性陣列才可以是變長的。可變長陣列的維數在陣列生存期內是不變的,也就是說,可變長陣列不是動態的。可以變化的只是陣列的大小。可以使用*來定義不確定長的可變長陣列。

在學某語言之前,請先了解一下它的標準。(it's important for youself.)剛學c語言的同學可以看看這個:鏈結檢視

MySQL入門之使用SQL99標準的連線查詢

使用sql99標準的連線查詢 join.on.內連線 只返回滿足連線條件的資料 兩邊都有的才顯示 select e.d.from emp e inner join dept d on e.deptno d.deptno 也可以省略inner關鍵字。select e.d.from emp e inne...

關於c語言c99標準中的不定長陣列

博主我在剛讀大一學習c語言的時候,寫過這樣一段 include intmain void 很明顯,我是想從鍵盤讀入乙個整數n,然後定義乙個大小為n的整性陣列。當時程式的執行環境是vc6.0,這個程式不能通過編譯,理由是定義陣列大小時n必須是const的,查閱書籍教科書上 詢問老師都是同樣的回答。今天...

陣列問題之七

自然數陣列的排序 奇數下標都是奇數或者偶數下標都是偶數 子陣列的最大累加和問題 在陣列中找到乙個區域性最小的位置 陣列中子陣列的最大累乘積 陣列小和定義如下 陣列s 1,3,5,2,4,6 在s 0 的左邊小於等於s 0 的數的和為0,在s 1 的左邊小於或等於s 1 的數的和為1,在s 2 的左邊...