swift在使用函數(shù)時需注意哪些問題 C語言可以面向對象編程嗎?
C語言可以面向對象編程嗎?c,客觀-c肯定能做到。標準c,一般的說法是沒有.我說的是我自己的想法,如果我寫過面向對象的代碼,類這個術語對用戶來說并不陌生!類基本上是面向對象編程的精髓。一個類只不過是成
C語言可以面向對象編程嗎?
c,客觀-c肯定能做到。標準c,一般的說法是沒有.我說的是我自己的想法,如果我寫過面向對象的代碼,類這個術語對用戶來說并不陌生!類基本上是面向對象編程的精髓。一個類只不過是成員數(shù)據(jù)和成員方法的集合,我們可以通過一個指針來訪問成員和方法。抽象、繼承、多態(tài)和重載是類的基本特性。一般來說,C語言是面向過程的函數(shù)式編程。用標準c解決問題,不外乎定義結構、公共體、枚舉、基本數(shù)據(jù)類型等。,然后定義一堆函數(shù)來訪問和操作這些數(shù)據(jù)。如果你把這些東西分成適當?shù)奈募?,授予適當?shù)臋嘞蕖語言的每個源文件相當于一個類。抽象、多態(tài),并通過使用c99的無類型指針很好地實現(xiàn)。實現(xiàn)繼承比較困難,實現(xiàn)思路是用指針訪問父對象的成員。重載,C實現(xiàn)更簡單!唐 我不認為我。;我在這一段虛張聲勢。Objective-c,swift,這兩種編程語言,如果想了解一點的話??梢钥吹竭@個理論的影子。當然,這兩種語言都有專門的編譯器。和C實現(xiàn)的面向對象編程是不一樣的,綜上所述,用C實現(xiàn)面向對象和編程很難,這不是開發(fā)者要考慮的。建議不要往這個方向編程。如java、C、swift等,都可以是面向對象的編程:
1.編譯器的問題已經被別人解決了;
很多基本功能,根據(jù)系統(tǒng)類庫已經提供,我們不 I don'我不必寫信。
swift開發(fā)前景?
Swift前景光明,技術更先進。
因為減少了重復語句和字符串操作所需的代碼量,所以代碼較少;它的使用簡化了方法和函數(shù)的調用。
Swift更快。根據(jù)流行的GeekBench性能工具的創(chuàng)造者的調查,2014年12月,Swift在使用Mandelbrot算法的計算密集型任務的性能上已經逼近C的性能。
c語言可以泛型編程嗎?如何實現(xiàn)?
泛型編程是一種非常常見的編程方法。主要目的是實現(xiàn)靜態(tài)綁定,使函數(shù)可以接受不同類型的參數(shù),并在編譯時確定正確的類型。
許多語言都支持泛型編程。例如,在C中,可以使用函數(shù)模板和類模板來實現(xiàn)泛型編程。在單一繼承的語言中,如Java、Objective-C或C#,也可以使用similar和NSObject類型進行編程。在具有類型推理功能的編程語言(如Swift)中,可以直接使用泛型編程。
但C語言是高級語言編程的基礎語言,如何用C語言實現(xiàn)泛型編程確實是個問題。首先,C語言沒有支持函數(shù)重載,不支持模板類型,所以真的很難實現(xiàn)。
0x01通用指針簡介(void *)
Void *是C語言中的一種類型。眾所周知,在大多數(shù)編程語言中,void類型表示所謂的空類型,比如一個函數(shù)返回一個空類型void,這是非常常見的用法。
注意:void的返回值并不意味著沒有返回值,而是意味著返回一個空類型,這也是為什么你仍然可以在這些函數(shù)中使用return語句的原因。只有某些語言中的構造函數(shù)和析構函數(shù)沒有返回值。在這些函數(shù)中,不允許使用return語句。它們是顯著不同的。Objective-C是一種獨特的語言,它的類初始化方法是一種普通的方法,返回值是instancetype(當前類的指針類型)。
Void *可能有點不為人知。void *可以表示C語言中任何類型的指針。說到底,對于一個存儲單元的地址來說,它存儲的所謂數(shù)據(jù)類型只是每次取的字節(jié)數(shù)不一樣,這些存儲單元的地址本身并沒有什么不同。下面會更好的體現(xiàn)這句話的意思。
void *的大小永遠是一個字,就像普通的指針一樣。具體大小因機器字長而異,例如32位機器為4字節(jié),64位機器為8字節(jié)。
我還沒有 t在16位8086機上驗證了指針的大小,因為8086的地址是20位。有興趣的可以回去試試。
個人認為指針大小還是16位,因為20位是物理地址,物理地址是從段地址和偏移地址計算出來的。匯編后,C語言中的指針可能只是變成了相對于段地址的偏移地址。畢竟對于8086來說,數(shù)據(jù)永遠在DS段,而代碼永遠在CS段。(斜體表示未經核實的陳述)
在C語言中,其他常用類型的指針可以自動轉換為void * type,而void * type只能強制轉換為其他常用類型的指針,否則會出現(xiàn)警告或錯誤。
關于所謂的void *指向數(shù)組有一個特別大的坑,這里直接用代碼解釋。
void Swap(void *array,int x,int y,int mallocsize) {
void *temp malloc(mallocsize)
memcpy(temp,數(shù)組mallocsize*x,mallocsize)
memcpy(數(shù)組mallocsize*x,數(shù)組mallocsize*y,mallocsize)
memcpy(數(shù)組mallocsize*y溫度、內存大小)
免費(臨時)
}
這是一個經典的交換函數(shù),借助臨時變量temp,不過這個函數(shù)是通用的,memcpy的用法后面會介紹。需要注意的是,如果array指向一個數(shù)組,你可以 t直接用amparray[x]或者array x來獲取指向x元素的地址,因為void *類型的默認指針偏移量是1,和char *一樣,對于大多數(shù)類型都會造成錯誤。因此,在使用泛型類型時,我們必須知道它的原始長度。我們需要一個名為mallocsize的int類型參數(shù)來告訴我們這個值,并在計算指針偏移量時乘以它。這相當于C編程中的模板類型定義或者Java中的泛型參數(shù)。
同時要注意void *類型的指針,它可以 不要在任何時候被取消參考(或者老師過去叫什么 "獲取內容 "在課堂上?),原因很明顯:void類型的變量是不合法的。因此,如果要解引用,必須先將其轉換成普通指針。當在數(shù)組中使用時,還應該注意解引用操作符優(yōu)先于加法操作符,所以應該加上括號,如下所示:
int a *(數(shù)組mallocsize * x)
這段代碼完美體現(xiàn)了C語言編程的丑陋。
0x02 sizeof運算符簡介
Sizeof運算符相信學過C語言的朋友都很熟悉,但知道sizeof是運算符的人不多,返回的類型是size_t類型。sizeof運算符返回類型占用的空間量。這里唯一的要點是,如果你找到一個指針類型或數(shù)組名的大小(事實上,數(shù)組名是一個指針常量),返回的結果總是一個單詞(見上文)。求一個結構類型的sizeof不是簡單的結構中各種類型的sizeof之和,而是涉及到內存對齊的問題。我不 這里不想介紹了。詳情請訪問:如何理解struct的內存對齊?-智虎。
0x03 memcpy功能簡介
Memcpy是一個經常和void *一起使用的函數(shù),它的函數(shù)原型是:
void * memcpy(void *,const void *,size_t)
頭文件屬于string.h,可以看到,這個函數(shù)本身是以void * type作為參數(shù)和返回值的,其實很好理解。這是一個賦值和復制記憶的過程。將第二個參數(shù)指向的內存復制到第一個參數(shù),復制的字節(jié)數(shù)由第三個參數(shù)指定。當然,第三個參數(shù)通常由sizeof運算符獲得,它書上沒有例子。我還沒有 我沒有研究過返回值,也沒有研究過。;我沒用過。如果有知道的朋友可以評論一下。
用0x04 C語言實現(xiàn)泛型編程
話雖如此,我們還沒有 t還沒有提到泛型編程。但是,如上所述,一般的思路是使用void * type作為泛型指針,然后使用類似于mallocsize的參數(shù)來指定占用的內存大小。占用的內存大小是通過sizeof運算符獲得的。如果需要賦值,可以使用memcpy函數(shù)來完成。下面是一個直接的例子,這是一個通用的快速排序來說明這些問題:
#ifndef Compare_h
#定義比較_h
#包含ltstdio.hgt
#包含JCB.h
int IsGreater(void *x,void *y)
int IsGreaterOrEqual(void *x,void *y)
int IsSmaller(void *x,void *y)
int IsSmallerOrEqual(void *x,void *y)
#endif /* Compare_h */
//
// Compare.c
//作業(yè)調度程序
//
//魯創(chuàng)作于2017/11/16。
//版權?2017魯饒威。保留所有權利。
//
#包含比較. h
int IsGreater(void *x,void *y) {
return *(int *)x gt *(int *)y
}
int IsGreaterOrEqual(void *x,void *y) {
return *(int *)x gt *(int *)y
}
int IsSmaller(void *x,void *y) {
return *(int *)x lt *(int *)y
}
int IsSmallerOrEqual(void *x,void *y) {
return *(int *)x lt *(int *)y
}
//
// QuickSort.h
//作業(yè)調度程序
//
//魯創(chuàng)作于2017/11/16。
//版權?2017魯饒威。保留所有權利。
//
#ifndef QuickSort_h
#定義快速排序_h
#包含ltstdio.hgt
#包含ltstdlib.hgt
#包含ltstring.hgt
#包含比較. h
void QuickSort(void *array,int left,int right,int mallocsize)
#endif /* QuickSort_h */
//
// QuickSort.c
//作業(yè)調度程序
//
//魯創(chuàng)作于2017/11/16。
//版權?2017魯饒威。保留所有權利。
//
#包含快速排序. h
void Swap(void *array,int x,int y,int mallocsize) {
void *temp malloc(mallocsize)
memcpy(temp,數(shù)組mallocsize*x,mallocsize)
memcpy(數(shù)組mallocsize*x,數(shù)組mallocsize*y,mallocsize)
memcpy(數(shù)組mallocsize*y,temp,mallocsize)
免費(臨時)
}
int QuickSortSelectCenter(int l,int r) {
返回(左側)/2
}
int quick sort partition(void * array,int l,int r,int mallocsize) {
int left l
int右r
void *temp malloc(mallocsize)
memcpy(temp,數(shù)組mallocsize*right,mallocsize)
while(左左右){
while(IsSmallerOrEqual(array mallocsize * left,temp) ampamp left lt right) {
左邊的
}
if(左lt右){
memcpy(數(shù)組mallocsize*right,數(shù)組mallocsize*左,mallocsize)
正確
}
while(IsGreaterOrEqual(array mallocsize * right,temp) ampamp left lt right) {
正確
}
if(左lt右){
memcpy(數(shù)組mallocsize*left,數(shù)組mallocsize*right,mallocsize)
左邊的
}
}
memcpy(數(shù)組mallocsize*left,temp,mallocsize)
向左返回
}
void QuickSort(void *array,int left,int right,int mallocsize) {
if (leftgtright) {
返回
}
中間中心快速排序選擇中心(左,右)
交換(數(shù)組、中心、右側、mallocsize)
center QuickSortPartition(數(shù)組,左,右,mallocsize)
快速排序(數(shù)組,左,中心-1,mallocsize)
快速排序(數(shù)組,中心1,右側,mallocsize)
}
這里有個懸念,明明可以直接比較,何必用很多函數(shù)來完成,也就是關于Compare.h使用的問題,答案會在下面揭曉。
0x05泛型的協(xié)議問題
剛才那個問題涉及到一個通用的協(xié)議問題,我借用了Objective-C的一個概念在這里詳細闡述。就像那個問題一樣,既然我的快速排序是泛型的,那我怎么保證傳入的實際泛型參數(shù)一定是可比較的呢?比如很明顯int,float,double是可以比較的,我們也理解char使用ASCII編碼方案的比較,字符串類型甚至可以比較。但是如何比較其他語言中的對象呢?這是一個問題。在C中,我們可以重載運算符,所以我們仍然可以使用比較運算符,并使用運算符來重載函數(shù)。但是Java和Objective-C呢?而如果傳入的泛型參數(shù)沒有實現(xiàn)對應的運算符重載函數(shù)呢?這個時候就會一個協(xié)議。簡單地說,如果一個類型想要成為一個排序泛型函數(shù)的泛型參數(shù),你必須實現(xiàn)一個可比較的協(xié)議。這個協(xié)議在Swift語言中叫做Comparable,這樣在編譯的時候,編譯器就會知道這個泛型參數(shù)是可以比較的,從而完成我們的操作,否則就會出錯。這是泛型中的協(xié)議問題。
0x06摘要
C語言的泛型編程以void *為泛型類型,本質上是一個泛型指針。
C語言中的泛型編程需要知道泛型類型變量的內存大小,這可以通過sizeof獲得并傳遞給泛型函數(shù)。
在C語言的泛型編程中,要注意數(shù)組的偏移量。void *的默認偏移量是1,對于大多數(shù)類型來說是錯誤的,需要自己編程轉換。
Memcpy函數(shù)用于在C語言的泛型編程中復制和賦值泛型變量。
在C語言的泛型編程中,我們也需要注意協(xié)議問題,但是在C中,我們只能自己編寫函數(shù)來定義,可以使用其他語言現(xiàn)成的接口或協(xié)議。