當前位置:首頁 » 編程軟體 » c編譯器函數

c編譯器函數

發布時間: 2025-02-17 01:33:55

❶ window內自帶的c語言編譯器怎麼用

1、首先,輸入【#include】。


注意事項:

盡管C語言提供了許多低級處理的功能,但仍然保持著跨平台的特性,以一個標准規格寫出的C語言程序可在包括類似嵌入式處理器以及超級計算機等作業平台的許多計算機平台上進行編譯。

❷ 如何用C語言編譯器打布爾類型的結果

需要准備的材料分別有:電腦、C語言編譯器。

1、首先,打開C語言編譯器,新建一個初始.cpp文件,例如:test.cpp。

❸ 在C++ 程序中調用被 C 編譯器編譯後的函數,為什麼要加 extern 「C」聲明

因為c++編譯時會進行名變化,而C不會,導致無法找到函數等。
要禁止名變換,使用C++的extern 'C'指示。

詳見
http://dev.csdn.net/article/13/13133.shtm

Item M34:如何在同一程序中混合使用C++和C
許多年來,你一直擔心編製程序時一部分使用C++一部分使用C,就如同在全部用C編程的年代同時使用多個編譯器來生成程序一樣。沒辦法多編譯器編程的,除非不同的編譯器在與實現相關的特性(如int和double的位元組大小,傳參方式)上相同。但這個問題在語言的標准化中被忽略了,所以唯一的辦法就是兩個編譯器的生產商承諾它們間兼容。C++和C混合編程時同樣是這個問題,所以在實體混合編程前,確保你的C++編譯器和C編譯器兼容。
確認兼容後,還有四個要考慮的問題:名變換,靜態初始化,內存動態分配,數據結構兼容。
* 名變換
名變換,就是C++編譯器給程序的每個函數換一個獨一無二的名字。在C中,這個過程是不需要的,因為沒有函數重載,但幾乎所有C++程序都有函數重名(例如,流運行庫就申明了幾個版本的operator<<和operator>>)。重載不兼容於絕大部分鏈接程序,因為鏈接程序通常無法分辨同名的函數。名變換是對鏈接程序的妥協;鏈接程序通常堅持函數名必須獨一無二。
如果只在C++范圍內,名變換不會影響你。如果你你有一個函數叫drawline而編譯器將它變換為xyzzy,你總使用名字drawLine,不會注意到背後的obj文件引用的是xyzzy的。
如果drawLine位於C運行庫中,那就是一個不同的故事了。你的C++源文件包含的頭文件中申明為:
void drawLine(int x1, int y1, int x2, int y2);
代碼體中通常也是調用drawLine。每個這樣的調用都被編譯器轉換為調用名變換後的函數,所以寫下的是
drawLine(a, b, c, d); // call to unmangled function name
obj文件中調用的是:
xyzzy(a, b, c, d); // call to mangled function mame
但如果drawLine是一個C函數,obj文件(或者是動態鏈接庫之類的文件)中包含的編譯後的drawLine函數仍然叫drawLine;沒有名變換動作。當你試圖將obj文件鏈接為程序時,將得到一個錯誤,因為鏈接程序在尋找一個叫xyzzy的函數,而沒有這樣的函數存在。
要解決這個問題,你需要一種方法來告訴C++編譯器不要在這個函數上進行名變換。你不期望對用其它語言寫的函數進行名變換,如C、匯編、Fortran、LISP、Forth或其它。(是的,這「其它」中應該包括COBOL,但那時你將得到什麼?(Yes, what-have-you would include COBOL, but then what would you have? ))總之,如果你調用一個名字為drawLine的C函數,它實際上就叫drawLine,你的obj文件應該包含這樣的一個引用,而不是引用進行了名變換的版本。
要禁止名變換,使用C++的extern 'C'指示:
// declare a function called drawLine; don't mangle
// its name
extern "C"
void drawLine(int x1, int y1, int x2, int y2);
不要以為有一個extern 'C',那麼就應該同樣有一個extern 'Pascal'和extern 'FORTRAN'。沒有,至少在C++標准中沒有。不要將extern 'C'看作是申明這個函數是用C語言寫的,應該看作是申明在個函數應該被當作好象C寫的一樣而進行調用。(使用術語就是,extern 'C'意思是這個函數有C鏈接,但這個意思表達實在不怎麼清晰。不管如何,它總意味著一件事:名變換被禁止了。)
例如,如果不幸到必須要用匯編寫一個函數,你也可以申明它為extern 'C':
// this function is in assembler - don't mangle its name
extern "C" void twiddleBits(unsigned char bits);
你甚至可以在C++函數上申明extern 'C'。這在你用C++寫一個庫給使用其它語言的客戶使用時有用。通過禁止這些C++函數的名變換,你的客戶可以使用你選擇的自然而直觀的名字,而不用使用你的編譯生成的變換後的名字:
// the following C++ function is designed for use outside
// C++ and should not have its name mangled
extern "C" void simulate(int iterations);
經常,你有一堆函數不想進行名變換,為每一個函數添加extern 'C'是痛苦的。幸好,這沒必要。extern 'C'可以對一組函數生效,只要將它們放入一對大括弧中:
extern "C" { // disable name mangling for
// all the following functions
void drawLine(int x1, int y1, int x2, int y2);
void twiddleBits(unsigned char bits);
void simulate(int iterations);
...
}
這樣使用extern 'C'簡化了維護那些必須同時供C++和C使用的頭文件的工作。當用C++編譯時,你應該加extern 'C',但用C編譯時,不應該這樣。通過只在C++編譯器下定義的宏__cplusplus,你可以將頭文件組織得這樣:
#ifdef __cplusplus
extern "C" {
#endif
void drawLine(int x1, int y1, int x2, int y2);
void twiddleBits(unsigned char bits);
void simulate(int iterations);
...
#ifdef __cplusplus
}
#endif
順便提一下,沒有標準的名變換規則。不同的編譯器可以隨意使用不同的變換方式,而事實上不同的編譯器也是這么做的。這是一件好事。如果所有的編譯器使用同樣的變換規則,你會誤認為它們生成的代碼是兼容的。現在,如果混合鏈接來自於不同編譯器的obj文件,極可能得到應該鏈接錯誤,因為變換後的名字不匹配。這個錯誤暗示了,你可能還有其它兼容性問題,早些找到它比以後找到要好。
* 靜態初始化
在掌握了名變換後,你需要面對一個C++中事實:在main執行前和執行後都有大量代碼被執行。尤其是,靜態的類對象和定義在全局的、命名空間中的或文件體中的類對象的構造函數通常在main被執行前就被調用。這個過程稱為靜態初始化(參見Item E47)。這和我們對C++和C程序的通常認識相反,我們一直把main當作程序的入口。同樣,通過靜態初始化產生的對象也要在靜態析構過程中調用其析構函數;這個過程通常發生在main結束運行之後。
為了解決main()應該首先被調用,而對象又需要在main()執行前被構造的兩難問題,許多編譯器在main()的最開始處插入了一個特別的函數,由它來負責靜態初始化。同樣地,編譯器在main()結束處插入了一個函數來析構靜態對象。產生的代碼通常看起來象這樣:
int main(int argc, char *argv[])
{
performStaticInitialization(); // generated by the
// implementation
the statements you put in main go here;
performStaticDestruction(); // generated by the
// implementation
}
不要注重於這些名字。函數performStaticInitialization()和performStaticDestruction()通常是更含糊的名字,甚至是內聯函數(這時在你的obj文件中將找不到這些函數)。要點是:如果一個C++編譯器採用這種方法來初始化和析構靜態對象,除非main()是用C++寫的,這些對象將從沒被初始化和析構。因為這種初始化和析構靜態對象的方法是如此通用,只要程序的任意部分是C++寫的,你就應該用C++寫main()函數。
有時看起來用C寫main()更有意義--比如程序的大部分是C的,C++部分只是一個支持庫。然而,這個C++庫很可能含有靜態對象(即使現在沒有,以後可能會有--參見Item M32),所以用C++寫main()仍然是個好主意。這並不意味著你需要重寫你的C代碼。只要將C寫的main()改名為realMain(),然後用C++版本的main()調用realMain():
extern "C" // implement this
int realMain(int argc, char *argv[]); // function in C
int main(int argc, char *argv[]) // write this in C++
{
return realMain(argc, argv);
}
這么做時,最好加上注釋來解釋原因。
如果不能用C++寫main(),你就有麻煩了,因為沒有其它辦法確保靜態對象的構造和析構函數被調用了。不是說沒救了,只是處理起來比較麻煩一些。編譯器生產商們知道這個問題,幾乎全都提供了一個額外的體系來啟動靜態初始化和靜態析構的過程。要知道你的編譯器是怎麼實現的,挖掘它的隨機文檔或聯系生產商。
* 動態內存分配
現在提到動態內存分配。通行規則很簡單:C++部分使用new和delete(參見Item M8),C部分使用malloc(或其變形)和free。只要new分配的內存使用delete釋放,malloc分配的內存用free釋放,那麼就沒問題。用free釋放new分配的內存或用delete釋放malloc分配的內存,其行為沒有定義。那麼,唯一要記住的就是:將你的new和delete與mallco和free進行嚴格的隔離。
說比做容易。看一下這個粗糙(但很方便)的strp函數,它並不在C和C++標准(運行庫)中,卻很常見:
char * strp(const char *ps); // return a of the
// string pointed to by ps
要想沒有內存泄漏,strp的調用著必須釋放在strp()中分配的內存。但這內存這么釋放?用delete?用free?如果你調用的strp來自於C函數庫中,那麼是後者。如果它是用C++寫的,那麼恐怕是前者。在調用strp後所需要做的操作,在不同的操作系統下不同,在不同的編譯器下也不同。要減少這種可移植性問題,盡可能避免調用那些既不在標准運行庫中(參見Item E49和Item M35)也沒有固定形式(在大多數計算機平台下)的函數。
* 數據結構的兼容性
最後一個問題是在C++和C之間傳遞數據。不可能讓C的函數了解C++的特性的,它們的交互必須限定在C可表示的概念上。因此,很清楚,沒有可移植的方法來傳遞對象或傳遞指向成員函數的指針給C寫的函數。但是,C了解普通指針,所以想讓你的C++和C編譯器生產兼容的輸出,兩種語言間的函數可以安全地交換指向對象的指針和指向非成員的函數或靜態成員函數的指針。自然地,結構和內建類型(如int、char等)的變數也可自由通過。
因為C++中的struct的規則兼容了C中的規則,假設「在兩類編譯器下定義的同一結構將按同樣的方式進行處理」是安全的。這樣的結構可以在C++和C見安全地來回傳遞。如果你在C++版本中增加了非虛函數,其內存結構沒有改變,所以,只有非虛函數的結構(或類)的對象兼容於它們在C中的孿生版本(其定義只是去掉了這些成員函數的申明)。增加虛函數將結束游戲,因為其對象將使用一個不同的內存結構(參見Item M24)。從其它結構(或類)進行繼承的結構,通常也改變其內存結構,所以有基類的結構也不能與C函數交互。
就數據結構而言,結論是:在C++和C之間這樣相互傳遞數據結構是安全的--在C++和C下提供同樣的定義來進行編譯。在C++版本中增加非虛成員函數或許不影響兼容性,但幾乎其它的改變都將影響兼容。
* 總結
如果想在同一程序下混合C++與C編程,記住下面的指導原則:
* 確保C++和C編譯器產生兼容的obj文件。
* 將在兩種語言下都使用的函數申明為extern 'C'。
* 只要可能,用C++寫main()。
* 總用delete釋放new分配的內存;總用free釋放malloc分配的內存。
* 將在兩種語言間傳遞的東西限制在用C編譯的數據結構的范圍內;這些結構的C++版本可以包含非虛成員函數。

❹ C語言中qsort函數怎麼用

qsort函數是編譯器函數庫自帶的快速排序函數。
qsort 的函數原型是:
void qsort(void*base,size_t num,size_t width,int(__cdecl*compare)(const void*,const void*));
它的參數為: 1 待排序數組首地址
2 數組中待排序元素數量
3 各元素的佔用空間大小
4 指向函數的指針,用於確定排序的順序
它在使用的時候需要包含頭文件:stdlib.h
實例:
#include<stdio.h>
#include<stdlib.h>
int comp(const void*a,const void*b)
{
return *(int*)a-*(int*)b;
}
int main()
{
int *array;
int n;
scanf("%d",&n);
array=(int*)malloc(n*sizeof(int));
int i=0;
for(;i<n;i++)
{
scanf("%d",(array+i));
}
qsort(array,n,sizeof(int),comp);
for(i=0;i<n;i++)
{
printf("%d\t",array[i]);
}
return0;
}

❺ c語言如何創建文件夾

在C語言中可以通過調用創建文件夾函數,或者使用系統命令兩種方法創建文件夾。 一、調用庫函數。 C語言庫函數創建文件夾依賴於編譯器,不同編譯器使用的創建文件夾函數不同。 舉例如下: 1、VC/VS編譯器。 函數聲明為 int _mkdir( const char *dirname ); 頭文件為direct.h。 功能為創建dirname文件夾,並返回結果,如果成功則返回0,否則返回-1。 2、TC編譯器。 聲明形式為 int mkdir(char *pathname); 頭文件為dir.h。 功能為創建pathname文件夾,並返回結果,如果成功則返回0,否則返回-1。 3、gcc編譯器。 聲明形式為int mkdir(const char *pathname, mode_t mode); 其中函數頭文件為sys/stat.h, 參數類型mode_t頭文件為sys/types.h。 與其他編譯器的創建文件夾函數不同,gcc創建文件夾多了一個參數mode, 指定被創建文件夾的許可權。 函數功能為創建文件夾名為pathname, 許可權值為mode的文件夾。 如果成功則返回0,否則返回-1。 二、通過系統命令調用。 在C 語言中可以通過system函數調用系統命令,具體命令格式取決於操作系統。 比如在Linux/Unix下,可以使用: system("mkdir ./XXX"); 來創建XXX文件夾。 而在windows下需要使用dos命令,比如: system("mkdir .\\XXX");

熱點內容
c創建sqlite資料庫 發布:2025-03-04 20:29:45 瀏覽:891
我的世界手游版怎麼做伺服器 發布:2025-03-04 19:52:22 瀏覽:943
浪潮存儲知識 發布:2025-03-04 19:50:07 瀏覽:577
網上開戶賬號密碼是什麼 發布:2025-03-04 19:48:40 瀏覽:497
pcftpps3 發布:2025-03-04 19:39:55 瀏覽:494
怎麼配置輸入引腳 發布:2025-03-04 19:38:21 瀏覽:40
aes加密後的數據長度 發布:2025-03-04 19:37:40 瀏覽:922
linux保存時間 發布:2025-03-04 19:37:34 瀏覽:692
手機如何做密碼門 發布:2025-03-04 19:37:34 瀏覽:444
java與c應用 發布:2025-03-04 19:36:51 瀏覽:993