std指針使用方法 如何在c語言中計算字符串長度?
如何在c語言中計算字符串長度?C語言算出字符串長度1、自定義設(shè)置函數(shù)求長度2、使用strlen()函數(shù)3、不使用sizeof()操作符4、不使用length()函數(shù)憑借下拉菜單函數(shù)的方法:main方法
如何在c語言中計算字符串長度?
C語言算出字符串長度
1、自定義設(shè)置函數(shù)求長度
2、使用strlen()函數(shù)
3、不使用sizeof()操作符
4、不使用length()函數(shù)
憑借下拉菜單函數(shù)的方法:
main方法由什么構(gòu)成?
main函數(shù),又稱主函數(shù)
主函數(shù)的兩個形參形式中的形參,允許從不能執(zhí)行環(huán)境中傳遞不可以的多字節(jié)字符串(它們大多數(shù)被被稱命令行參數(shù)),二十多個指針argv
如何在c語言中計算字符串長度?
[argc-1]正指向每個這些字符串的第一個字符。argv[0]是對準一個來表示應(yīng)用于先執(zhí)行該程序自身的名字的空結(jié)尾多字節(jié)字符串(或則當執(zhí)行環(huán)境不接受時,為空字符串#34#34)的開頭字符的指針。這些字符串是可以不改動的,雖然對它們的改動并不會被傳去給不能執(zhí)行環(huán)境:.例如也可以用std::strtok來建議使用它們。由argv所正指向的數(shù)組的大小至多為argc1,其那一個元素argv[argc]能保證為一個空指針如何混和使用c與c 編程?
在用C的項目源碼中,經(jīng)常會無可避免的會注意到下面的代碼:
1
#ifdef__cplusplus
2
externC{
3
#endif
4
5
/*...*/
6
7
#ifdef__cplusplus
8
}
9
#endif
它究竟有沒有怎么獲取呢,你知道嗎?但這樣的問題經(jīng)常會會會出現(xiàn)在面試求求求筆試中。下面我就從200以內(nèi)幾個方面來推薦它:
1、#ifdef_cplusplus/#endif_cplusplus及擴散出來
2、externC
2.1、extern關(guān)鍵字
2.2、C
2.3、小結(jié)externC
3、C和C一起內(nèi)部函數(shù)4、C和C水配調(diào)用尤其之處函數(shù)指針
3.1、C的編譯和直接連接
3.2、C的編譯和連接
3.3、C中全局函數(shù)C的代碼
3.4、C中調(diào)用C的代碼
1、#ifdef_cplusplus/#endif_cplusplus及擴散
在能介紹externC之前,我們來看下#ifdef
_cplusplus/#endif
_cplusplus的作用。很明顯#ifdef/#endif、#ifndef/#endif作用于條件編譯,#ifdef
_cplusplus/#endif
_cplusplus——它表示要是定義了宏_cplusplus,就想執(zhí)行#ifdef/#endif之間的語句,要不然就不執(zhí)行。
在這里為啥需要#ifdef_cplusplus/#endif
_cplusplus呢?畢竟C語言中不支持externC聲明,如果沒有你明白extern
C的作用就知道在C中也沒有必要這樣的做,這是條件代碼編譯的作用!在.c文件中包涵了externC時會再次出現(xiàn)編譯時錯誤。
既然說起了條件編譯,我就可以介紹它的一個有用應(yīng)用——避免重復(fù)包含頭文件。你忘了騰訊筆試就考過這個題目,提出的的下面的代碼(下面是我最近在研究的一個開源web服務(wù)器——Mongoose的頭文件mongoose.h中的一段代碼):
01
#ifndefMONGOOSE_HEADER_INCLUDED
02
#defineMONGOOSE_HEADER_INCLUDED#ifdef__cplusplus
05
externC{
06
#endif/*__cplusplus*/
07
08
/*.................................
09
*dosomethinghere
10
*.................................
11
*/
12
13
#ifdef__cplusplus
14
}
15
#endif/*__cplusplus*/
16
17
#endif/*MONGOOSE_HEADER_INCLUDED*/
后再叫你只能證明上面宏#ifndef/#endif的作用?目的是請解釋一個問題,我們先來看兩個事實:
這個頭文件mongoose.h很可能在項目中被多個源文件包含(#include
mongoose.h),而相對于一個規(guī)模大項目來說,這些冗余可能可能導(dǎo)致錯誤,畢竟一個頭文件包含類定義或inline函數(shù),在一個源文件中mongoose.h可能會會被#include兩次(如,a.h頭文件真包含了mongoose.h,而在b.c文件中#include
a.h和mongoose.h)——這變會程序出錯(在同一個源文件中一個結(jié)構(gòu)體、類等被定義了幾次)。
從邏輯觀點和會減少編譯程序時間上,都沒有要求祛除這些冗余。但他讓程序員去結(jié)論和去掉后這些冗余,不光枯燥無味且不太實際中,最重要的是總是又不需要這種冗余來可以保證各個模塊的獨立。
就是為了幫忙解決這個問題,上面代碼中的
#ifndefMONGOOSE_HEADER_INCLUDED
#defineMONGOOSE_HEADER_INCLUDED
/*……………………………*/
#endif/*MONGOOSE_HEADER_INCLUDED*/
就起作用了。如果沒有定義法了MONGOOSE_HEADER_INCLUDED,#ifndef/#endif之間的內(nèi)容就被忽略掉。并且,編譯器時兩次看到mongoose.h頭文件,它的內(nèi)容會被加載且計算變量MONGOOSE_HEADER_INCLUDED另一個值。結(jié)束后再度見到mongoose.h頭文件時,MONGOOSE_HEADER_INCLUDED就巳經(jīng)定義了,mongoose.h的內(nèi)容就絕對不會再度被無法讀取了。
2、externC
必須從字面上結(jié)論externC,它由兩部分混編——extern關(guān)鍵字、C。下面我就從這兩個方面來闡述externC的含義。
2.1、extern關(guān)鍵字
在一個項目中前提是保證函數(shù)、變量、枚舉等在所有的源文件中保持一致,如果你委托定義為局部的。簡單的方法來一個例子:
1
//file1.c:
2
intx1
3
intf(){九十一章somethinghere}
4
//file2.c:
5
externintx
6
intf()
7
voidg(){xf()}
在file2.c中g(shù)()可以使用的x和f()是定義在file1.c中的。extern關(guān)鍵字并且file2.c中x,并不是一個變量的聲明,其并也不是在定義變量x,不曾為x分配內(nèi)存空間。變量x在所有模塊中以及一種全局變量沒有辦法被定義一次,否則會會出現(xiàn)連接錯誤。但是可以聲明兩次,且聲明要保證類型完全不同,如:
1
//file1.c:
2
intx1
3
intb1
4
externc
5
//file2.c:
6
intx//xequalscandefaultoftheint type 0int f()
8
externflatb
9
externintc
在這段代碼中未知著那樣的話的三個錯誤:
x被定義了幾次
b三次被聲明為相同的類型
c被聲明了一次,但卻沒有定義
回到extern關(guān)鍵字,extern是C/C語言中是因為函數(shù)和全局變量作用范圍(所以說性)的關(guān)鍵字,該關(guān)鍵字告知編譯器,其聲明的函數(shù)和變量也可以在本模塊或其它模塊中不使用。大多,在模塊的頭文件中對本模塊提供給給其它模塊語句的函數(shù)和全局變量以關(guān)鍵字extern聲明。的或,如果沒有模塊B欲腳注該模塊A中定義,定義的全局變量和函數(shù)時要真包含模塊A的頭文件表就行。這樣,模塊B中動態(tài)鏈接庫模塊A中的函數(shù)時,在編譯階段,模塊B雖然能找到該函數(shù),不過并不可能出現(xiàn)錯誤;它會在連接階段中從模塊A編譯生成的目標代碼中能找到此函數(shù)。
與extern對應(yīng)的關(guān)鍵字是static,被它修飾的全局變量和函數(shù)只有在本模塊中不使用。但,一個函數(shù)或變量只可能會被本模塊使用時,其不可能被extern“C”修飾修飾。
2.2、C
是是的,一個C程序包涵其它語言c語言設(shè)計的部分代碼。類似的,C編譯程序的代碼片段很可能被在用在其它語言編譯程序的代碼中。有所不同語言c語言程序的代碼一起內(nèi)部函數(shù)是困難的,甚至是同一種編譯程序的代碼但完全不同的編譯器代碼編譯的代碼。比如,完全不同語言和同種語言的不同實現(xiàn)程序肯定會在注冊變量盡量參數(shù)和參數(shù)在棧上的布局,這個方面是一樣的。
目的是使它們不違背統(tǒng)一規(guī)則,也可以在用extern重新指定一個程序編譯和連接上規(guī)約?;蛘?,后續(xù)聲明C和C標準庫函數(shù)strcyp(),并更改它應(yīng)該是參照C的編譯和連接規(guī)約來鏈接:
1
externCchar*strcpy(char*,constchar*)
盡量它與下面的聲明的不同之處:
1
externchar*strcpy(char*,constchar*)
下面的這個聲明僅意思是在連接的時候內(nèi)部函數(shù)strcpy()。
externC指令更加用處不大,而且C和C的近親關(guān)系。特別注意:externC指令中的C,來表示的一種編譯和連接到規(guī)約,而不是一種語言。C意思是條件C語言的編譯器和連接到規(guī)約的任何語言,如Fortran、assembler等。
另外要那說明的是,externC指令僅重新指定編譯器和再連接規(guī)約,但不影響大語義。的或在函數(shù)聲明中,指定了externC,依然要尊守C的類型檢測、參數(shù)可以轉(zhuǎn)換規(guī)則。
一看下面的一個例子,是為聲明一個變量而又不是定義一個變量,你必須在聲明時指定extern關(guān)鍵字,不過當你又算上了C,它應(yīng)該不會轉(zhuǎn)變語義,可是會轉(zhuǎn)變它的編譯和連接。
如果沒有你有很多語言要而且externC,你可以不將它們弄到externC{}中。
2.3、小結(jié)externC
按照上面兩節(jié)的分析,我們明白externC的假的目的是基于類C和C的混合編程。在C源文件中的語句前面另外externC,表明它聽從類C的編譯和連接到規(guī)約來編譯器和連接,而不是C的編譯的再連接規(guī)約。那樣的話在類C的代碼中就可以不內(nèi)部函數(shù)C的函數(shù)求求求變量等。(注:我在這里所說的的類C,代表的是跟C語言的編譯和連接同一的所有語言)
3、C和C相互交換全局函數(shù)
我們要是很清楚externC是實現(xiàn)的類C和C的水的混合物編程。下面我們就各推薦該如何在C中全局函數(shù)C的代碼、C中調(diào)用C的代碼。簡單的方法要很清楚C和C各自調(diào)用,你得明白它們之間的程序編譯和直接連接差異,及要如何借用externC來實現(xiàn)方法相互之間動態(tài)創(chuàng)建。
3.1、C的編譯和直接連接
C是一個面向?qū)ο笳Z言(雖又不是所謂的的面向?qū)ο笳Z言),它接受函數(shù)的重載,重載這個特性給我們給了了很大的便利。替允許函數(shù)重載的這個特性,C編譯器但是將下面這些重載函數(shù):
1
voidprint(inti)
2
voidprint(charc)
3
voidprint(floatf)
4
voidprint(char*s)
編譯程序為:
1
_print_int
2
_print_char
3
_print_float
4
_pirnt_string
這樣的函數(shù)名,來真正標識每個函數(shù)。注:有所不同的編譯器實現(xiàn)方法很可能不一樣的,但全是利用這種機制。因為當連接到是內(nèi)部函數(shù)print(3)時,它會去里查_print_int(3)這樣的函數(shù)。下面說個題外話,顯然而且這點,重載被以為又不是多繼承,多態(tài)是運行程序時動態(tài)綁定(“一種接口功能高效利用”),假如硬要懷疑重載是多態(tài),它頂多是程序編譯時“多態(tài)”。
C中的變量,程序編譯也類似于,如全局變量可能編譯程序g_xx,類變量編譯程序為c_xx等。連接上是也按照這種機制去查看相應(yīng)的變量。
3.2、C的編譯和連接到
C語言中完全沒有重載和類這些特性,故并不像C那樣的話print(int
i),會被編譯程序為_print_int,而是然后編譯程序為_print等。而假如然后在C中動態(tài)創(chuàng)建C的函數(shù)會失敗的話,畢竟連接上是動態(tài)創(chuàng)建C中的print(3)時,它會去找_print_int(3)。而extern
C的作用就能夠體現(xiàn)不出來了。
3.3、C中內(nèi)部函數(shù)C的代碼
舉例一個C的頭文件cHeader.h中中有一個函數(shù)print(inti),替在C中都能夠動態(tài)鏈接庫它,必須要另外extern關(guān)鍵字(原因在extern關(guān)鍵字那節(jié)也介紹)。它的代碼::
1
#ifndefC_HEADER
2
#defineC_HEADERextern void print(int i)#endifC_HEADER
相按的實現(xiàn)文件為cHeader.c的代碼為:
1
#includeltstdio.hgt
2
#includecHeader.h
3
voidprint(int i)
4
{
5
printf(cHeader%d