程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C語言知識補遺

C語言知識補遺

編輯:關於C語言

函數前使用extern沒有意義;extern用在變量前表示變量是一個外部鏈接符號。(函數天然是一個外部鏈接符號)

——與此相關的,指定函數的調用風格(__cdecl, __stdcall, __fastcall)等,或者生成動態連接庫時(__declspec(dllimport)、__declspec(dllexport)),或者指定編譯語言類型時(C, C++)時,都只需要在 聲明體(.h文件) 中說明,不需要在實現體(.c文件)中說明。

同時,static對於函數和變量的意義也不同。

非可移植的內存分配技巧:(要求平台的malloc庫實現時采用連續分配,用途:概要訪問,隱式存儲)

struct name {

    int    namelen;

    char namestr[1];

};

#include <stdlib.h>

#include <string.h>

struct name *makename( char *newname )

{

    struct name *ret = malloc(sizeof(struct name)-1 + strlen(newname) + 1);

    if (ret != NULL) {

        ret->namelen = strlen(newname);

        strcpy(ret->namestr, newname);

    }

    return ret;

}

C99引入了許多C++中已有的特性:結構體越來越像 類 了——可以創建無名的臨時 結構體變量

結構體的sizeof值是內存占用范圍,“空洞”也計算在內

如何計算field在struct中的字節偏移量?

非可移植方案:#define offsetof(struct, f)  (size_t)  (  (char*) (struct*)0->f - (char*) (struct*)0  )

不要使用內建的==或!= 來比較結構體變量——編譯器對齊操作可能會導致結構體的稀疏,出現空洞

在需要指針型的地方,如何傳入一個常量?

如intf(int *)函數,怎樣傳入一個常量?     ——在C99中,可以使用“復合字面量”:f(   (int[]){5}   );    類似Java??

函數名本質上也是一個地址,類似數組名; 函數指針本質上也是一個可以參與 賦值、算術 的變量。  () 是唯一可以用於函數指針的後綴運算符。

不同的是,函數名、函數指針的地址實際上是代碼區或者說ROM的地址,而數據變量名、數據指針的地址實際上是數據區RAM的地址,二者不能通用。例如,空的函數指針為void (*)(),空的數據變量指針為void *;

NULL沒有想象中的省力——在函數參數傳入時,仍然需要使用類型轉換。

一般來說,NULL僅僅是一個提示:這裡是一個指針0,沒有其他意義。所以,在不需要指針的地方(如ASCII空字符:)不要用它。

使用規則:

1、在需要空指針常量時,用0或NULL都是等價的;

2、在函數調用傳入0時,根據原型在0或NULL前添加強制轉換;

為什麼需要NULL?因為NULL(表示空指針)在某些平台上實現為0,而在另一些平台上用特殊值來實現——為什麼C標准不把它統一定義為0?因為在某些平台上用特殊值來觸發自動的硬件陷阱,可以捕捉到空指針非法訪問的錯誤,統一用0實現空指針是一種不幸的倒退。

數組並非C語言一級元素,下標也並非一級運算符,而是定義在指針算術運算基礎上——因此,a[i] 等價於 *( (a) + (i) ),也等價於 i[a]。

通過定義不同類型(主要是維數)的指針p,關聯數組a後,可以對p實現++或--不同粒度的重載。

一本C語言的習題匯編:

C Programming FAQs, Steve Summit, 人民郵電2008

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved