苍井空一区二区-苍井空在线视频网站免费-苍狼导航精品导航-藏经阁av无码综合亚洲-操逼黄色视频网站-操逼无码视频

首頁 > 職業資格  > 

C語言字符型基礎知識

2023-06-18   來源:萬能知識網

C語言字符型基礎知識

在學習中,大家都背過各種知識點吧?知識點在教育實踐中,是指對某一個知識的泛稱。相信很多人都在為知識點發愁,下面是小編為大家整理的C語言字符型基礎知識,僅供參考,希望能夠幫助到大家。


【資料圖】

C語言字符型基礎知識

1. 字符型數據

文字處理是計算機的一個重要應用領域,這個應用領域的程序必須能夠使用和處理字符形式的數據。在C語言中,字符型數據包括字符和字符串兩種,例如"a"是字符,而"Windows" 是字符串。

字符型數據在計算機中存儲的是字符的ASCII碼(ASCII碼表見附錄A),一個字符的存儲占用一個字節。因為ASCII碼形式上就是0 到255之間的整數,因此C語言中字符型數據和整型數據可以通用。例如,字符"A"的ASCII碼值用二進制數表示是1000001,用十進制數表示是65,在計算機中的存儲示意圖見圖3-6。由圖可見,字符"A"的存儲形式實際上就是一個整型數65,所以它可以直接與整型數據進行算術運算、混合運算,可以與整型變量相互賦值,也可以將字符型數據以字符或整數兩種形式輸出。以字符形式輸出時,先將ASCII碼值轉換為相應的字符,然后再輸出;以整數形式輸出時,直接將ASCII碼值作為整數輸出。

2.字符型常量

字符常量亦被稱為字符常數。C語言中字符常量是括在一對單引號內的一個字符。 例如:"x"、"B"、"b"、"$"、"?"、" "(表示空格字符)、"3"都是字符常量,注意其中"B"和"b"是不同的字符常量。

除了以上形式的字符常量外,對于常用的但卻難以用一般形式表示的不可顯示字符,C語言提供了一種特殊的字符常量,即用一個轉義標識符""開頭,后續需要的轉義字符來表示。常用的轉義字符序列的字符常量見表3-4。

轉義字符是一種特殊形式的字符常量,其意思是將轉義符""后的字符原來的含義進行轉換,變成某種另外特殊約定的含義。

例如,轉義字符" "中的n已不代表字符常量"n",由于n前面是轉義符"",所以n就轉義成換行。轉義字符"15"是"ddd"形式的轉義字符,其中"015"是八進制字符串,它表示了ASCII碼表中編碼為十進制13的字符,也就是回車。轉義字符"x1f"是"xdd"形式的轉義字符,其中"1f"是十六進制字符串,它表示了ASCII碼表中編碼為十進制31的字符,也就是▼。

可見,用轉義字符方法可以表示任何可顯示或不可顯示的字符。在實際應用中,轉義字符的使用很多,例如:例3-2中有以下程序行:

printf("a=%f,b=%f ",a,b);

其中的" "就是轉義字符換行。幾乎每個程序中都會有一個或若干個這樣的程序行。要注意其使用。

3. 字符型變量

字符型變量用于存放字符常量,即一個字符型變量可存放一個字符,所以一個字符型變量占用1個字節的內存容量。說明字符型變量的關鍵字是char,使用時只需在說明語句中指明字符型數據類型和相應的變量名即可。例如:

char s1, s2; /* 說明 s1,s2 為字符型變量 */

s1="A"; /* 為s1賦字符常量"A" */

s2="a"; /*為s2賦字符常量"a" */

4. 字符串常量

字符串常量是用一對雙引號括起來的字符序列。這里的雙引號僅起到字符串常量的邊界符的作用,它并不是字符串常量的一部分。例如下面的字符串都是合法的字符串常量:

"I am a student. ","ABC"," ","a"

注意不要把字符串常量和字符常量混淆,如"a"和"a"是根本不同的數據,前者是字符串常量,后者是字符常量。如果字符串常數中出現雙引號,則要用反斜線"""將其轉義,取消原有邊界符的功能,使之僅作為雙引號字符起作用。例如,要輸出字符串:

He says:"How do you do."

應寫成如下形式:

printf ("He says:"How do you do."");

C語言對字符串常量的長度不加限制,編譯程序總是自動地在字符串的結尾加上一個轉義字符""(即ASCII碼是0,所對應的字符是空),作為字符串常量的結束標志。對字符串操作時,這個結束標志是非常重要的。例如輸出字符串時,遇到這個結束標志才終止輸出。

可見,字符常量與字符串常量的區別有兩個方面:從形式上看,字符常量是用單引號括起的單個字符,而字符串常量是用雙引號括起的一串字符;從存儲方式看,字符常量在內存中占一個字節,而字符串常量除了每個字符各占一個字節外,其字符串結束符""也要占一個字節。例如:字符常量"a"占一個字節,而字符串常量"a" 占2個字節,如圖3-7示意圖所示。

C語言沒有專門的字符串變量,如果需要處理字符串,一般用字符型數組來實現。關于字符數組及其它字符數據處理問題在本書第八章作詳細介紹。

5. 字符數據的應用舉例

例3-3:計算字符"A"與整型數據25的和。

/* L3_3.C */

Main()

{ char a; /* 說明a為字符型變量 */

int b; /* 說明b為整型變量 */

a="A"; /* 為a賦字符常量"A" */

b=a+25; /* 計算65+25并賦值給字符變量b */

printf("%c,%d,%c,%d ",a,a,b,b); /* 分別以字符型和整型兩種格式輸出a、b */

}

程序運行的輸出結果如下:

A,65,Z,90

上述程序中a變量的值是"A",實際存放的是"A"的ASCII碼65,它可直接與十進制整型常量25相加,所得整型數據90賦值給變量b,而90是大寫字符"Z"的ASCII碼,所以可以將a、b變量分別以字符型和整型兩種格式輸出。可見字符型數據和整型數據是可以通用的。

C語言的最大特點是:功能強、使用方便靈活。

C編譯的程序對語法檢查并不象其它高級語言那么嚴格,這就給編程人員留下“靈活的余地”,但還是由于這個靈活給程序的調試帶來了許多不便,尤其對初學C語言的人來說,經常會出一些連自己都不知道錯在哪里的錯誤。

1.書寫標識符時,忽略了大小寫字母的區別。

2.忽略了變量的類型,進行了不合法的運算。

3.將字符常量與字符串常量混淆。

4.忽略了“=”與“==”的區別。

5.忘記加分號。分號是C語句中不可缺少的一部分,語句末尾必須有分號。

6.多加分號。 復合語句的花括號后不應再加分號,否則將會畫蛇添足。

7.輸入變量時忘記加地址運算符“&”。

8.輸入數據的方式與要求不符。代碼①scanf("%d%d",&a,&b);輸入時,不能用逗號作兩個數據間的分隔符②scanf("%d,%d",&a,&b);C規定:如果在“格式控制”字符串中除了格式說明以外還有其它字符,則在輸入數據時應輸入與這些字符相同的字符。

9.輸入字符的格式與要求不一致。在用“%c”格式輸入字符時,“空格字符”和“轉義字符”都作為有效字符輸入。

10.輸入輸出的數據類型與所用格式說明符不一致。

11.輸入數據時,企圖規定精度。

12.switch語句中漏寫break語句。

13.忽視了while和do-while語句在細節上的區別。

14.定義數組時誤用變量。

15.在定義數組時,將定義的“元素個數”誤認為是可使的最大下標值。

16.初始化數組時,未使用靜態存儲。

17.在不應加地址運算符&的位置加了地址運算符。

18.同時定義了形參和函數中的局部變量。

運算符

分為以下幾類:

1、算術運算符:用于各類數值運算。包括加(+)、減(-)、乘(*)、除(/)、求余(%)、自增(++)、自減(--)共七種。

2、賦值運算符:用于賦值運算,分為簡單賦值(=)、復合算術賦值(+=,-=,*=,/=,%=)和復合位運算賦值(&=,|=,^=,>>=,<<=)三類共十一種。

3、逗號運算符:用于把若干表達式組合成一個表達式(,)。

4、關系運算符:用于比較運算。包括大于(>)、小于(<)、等于(==)、>=)、小于等于(<=)和不等于(!=)六種。

5、邏輯運算符:用于邏輯運算。包括與(&&)、或(||)、非(!)三種。

6、條件運算符:這是一個三目運算符,用于條件求值(?:)。

7、位操作運算符:參與運算的量,按二進制位進行運算。包括位與(&)、位或(|)、位非(~)、位異或(^)、左移(<<)、右移(>>)六種。

8、指針運算符:用于取內容(*)和取地址(&)二種運算。

9、求字節數運算符:用于計算數據類型所占的字節數(sizeof)。

10、特殊運算符:有括號(),下標[],成員(→,.)等幾種。

另外,按參與運算的對象個數,C語言運算符可分為:單目運算符 (如 !)、雙目運算符 (如+,- )和三目運算符 (如 ? : )。

算術運算符和算術表達式

一、基本的算術運算符

(1)+(加法運算符或正值運算符,如2+5)。

(2)-(減法運算符或負值運算符,如4-2)。

(3)*(乘法運算符,如3*8)。

(4)/(除法運算符,如11/5)。

/的運算分為兩種情況:

a、“除”的左右兩邊都為整數時,所得結果必然是整數(注意:僅取整數部分,不是四舍五入)

比如:5/2的值為2,不是2.5,1/2的值為0。

b、“除”的左右兩邊至少有一個是實型數據(即小數)時,所得結果為實型數據。

比如:5/2.0的值為2.5,7.0/2.0的值為3.5.

(5)%(模運算符或稱求余運算符,%兩側均應為整型數據,如9%7的值為2)。

需要說明的是:當運算對象為負數時,所得結果隨編譯器不同而不同,在vc中,結果的符號與被除數相同,比如:13%-2值為1,而-15%2值為-1。

二、 算術表達式和運算符的優先級與結合性

算術表達式是用算術運算符和括號將運算量(也稱操作數)連接起來的、符合C語言語法規則的表達式。運算對象包括函數、常量和變量等。

在計算機語言中,算術表達式的求值規律與數學中的四則運算的規律類似,其運算規則和要求如下。

(1)在算術表達式中,可使用多層圓括號,但括號必須配對。運算時從內層圓括號開始,由內向外依次計算各表達式的值。

(2)在算術表達式中,對于不同優先級的運算符,可按運算符的優先級由高到低進行運算,若表達式中運算符的優先級相同,則按運算符的結合方向進行運算。

(3)如果一個運算符兩側的操作數類型不同,則先利用自動轉換或強制類型轉換,使兩者具有相同類型,然后進行運算。

三、 自增自減運算符

作用:使變量的值增1或減1。

如:++i,--i (在使用i之前,先使i的值加1、減1)。

i++,i-- (在使用i之后,使i的值加1、減1)。

(1)只有變量才能用自增運算符 (++)和自減運算符(--),而常量或表達式不能用,如10++或(x+y)++都是不合法的。

(2)++和--的結合方向是“自右向左“,如 -i++ ,i的左邊是負號運算符,右邊是自增運算符,負號運算和自增運算都是 “自右向左“結合的,相當于 -(i++)。

在循環語句中常用到自增(減)運算符,在指針中也常用到該運算符,考生要弄清楚“i++”和“++i”及“i--”和“--i”的區別,特別弄清楚表達式的值和變量的值。

一、位運算符

在計算機中,數據都是以二進制數形式存放的,位運算就是指對存儲單元中二進制位的運算。C語言提供6種位運算符。

二、位運算

位運算符 & |~<< >> ∧ 按優先級從高到低排列的順序是:

位運算符中求反運算“~“優先級最高,而左移和右移相同,居于第二,接下來的順序是按位與 “&“、按位異或 “∧“和按位或 “|“。順序為~ << >> & ∧ | 。

例1:左移運算符“<<”是雙目運算符。其功能把“<< ”左邊的運算數的各二進位全部左移若干位,由“<<”右邊的數指定移動的位數,高位丟棄,低位補0。

例如:

a<<4

指把a的各二進位向左移動4位。如a=00000011(十進制3),左移4位后為00110000(十進制48)。

例2:右移運算符“>>”是雙目運算符。其功能是把“>> ”左邊的運算數的各二進位全部右移若干位,“>>”右邊的數指定移動的位數。

例如:

設 a=15,

a>>2

表示把000001111右移為00000011(十進制3)。

應該說明的是,對于有符號數,在右移時,符號位將隨同移動。當為正數時,最高位補0,而為負數時,符號位為1,最高位是補0或是補1 取決于編譯系統的規定。

例3:設二進制數a是00101101 ,若通過異或運算a∧b 使a的高4位取反,低4位不變,則二進制數b是。

解析:異或運算常用來使特定位翻轉,只要使需翻轉的位與1進行異或操作就可以了,因為原數中值為1的位與1進行異或運算得0 ,原數中值為0的位與1進行異或運算結果得1。而與0進行異或的位將保持原值。異或運算還可用來交換兩個值,不用臨時變量。

如 int a=3 , b=4;,想將a與b的值互換,可用如下語句實現:

a=a∧b;

b=b∧a;

a=a∧b;

所以本題的答案為: 11110000 。

C語言中標識符的命名規則如下:

標識符只能由字母、數字、下劃線組成;

標識符的第一個字母必須是字母和下劃線;

標識符區分大小寫字母,如If和if是兩個完全不同的標識符。

合法標識符如下:

A6, b_3 , _mn

非法的標識符如下:

ab#12 , 8m , tr3:4 , yes no

標識符不能與程序中具有特殊意義的關鍵字相同,不能與用戶編制的函數名、C語言庫函數相同,在程序中各種標識符盡量不要重復,以便區分。選擇變量名和其他標識符時,應注意做到 “見名知義”。

標識符分為如下三類:

1、關鍵字

關鍵字是具有特定含義的,專門用來說明c語言特定成分的一類標識符,不能用作用戶的標識符。

auto

break

case

char

union

do

double

else

enum

extern

goto

if

int

long

short

signed

static

sizof

struct

switch

unsigned

void

for

while

typedef

continue

float

return

typedef

default

2、預定義標識符

預定義標識符在c語言中也有特定的含義,但可以用作用戶標識符,預定義標識符分為兩類:

(1)、庫函數名字,比如(printf,scanf,sin,isdigit等)

(2)、編譯處理命令名,比如(define,include)

3、用戶標識符

用戶根據需要自己定義的標識符稱為用戶標識符。無論如何自定義標識符,都必須符合標識符的三條命名規則。

C語言

char *strchr(const char* _Str,int _Val)

char *strchr(char* _Str,int _Ch)

頭文件:#include

功能:查找字符串s中首次出現字符c的位置

說明:返回首次出現c的位置的指針,返回的地址是被查找字符串指針開始的第一個與Val相同字符的指針,如果s中不存在c則返回NULL。

返回值:成功則返回要查找字符第一次出現的位置,失敗返回NULL

參數編輯

haystack

輸入字符串。

needle

如果 needle 不是一個字符串,那么它將被轉化為整型并且作為字符的序號來使用。

before_needle

若為 TRUE,strstr() 將返回 needle 在 haystack 中的位置之前的部分。

返回: 返回字符串的一部分或者 FALSE(如果未發現 needle)。

例子:

1

2

3

4

5

6

7

$email="[email protected]";

$domain=strchr($email,"@");

echo$domain;//打印@example.com

$user=strchr($email,"@",true);//從PHP5.3.0起

echo$user;//打印name

?>

函數公式編輯

實現:

1

2

3

4

5

6

7

8

char*strchr(char*s,charc)

{

while(*s!=""&&*s!=c)

{

++s;

}

return*s==c?s:NULL;

}

范例

舉例1:(在Visual C++ 6.0中運行通過)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

#include

#include

int main(void)

{

char string[17];

char *ptr,c="r";

strcpy(string,"Thisisastring");

ptr=strchr(string,c);

if(ptr)

printf("Thecharacter%cisatposition:%s ",c,ptr);

else

printf("Thecharacterwasnotfound ");

return0;

}

運行結果:

The character r is at position: ring

請按任意鍵繼續. . .

舉例2:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

// strchr.c

#include

#include

int main()

{

char temp[32];

memset(temp,0,sizeof(temp));

strcpy(temp,"Golden Global View");

char *s = temp;

char *p,c="v";

p=strchr(s,c);

if(p)

printf("%s",p);

else

printf("Not Found!"); return 0;

}

運行結果:Not Found!Press any key to continue

舉例3:

1

2

3

4

5

6

7

8

9

10

11

#include

#include

void main()

{

char answer[100],*p;

printf("Type something: ");

fgets(answer,sizeof answer,stdin);

if((p = strchr(answer," ")) != NULL)

*p = "";//手動將 位置處的值變為0

printf("You typed "%s" ",answer);

}

fgets不會像gets那樣自動地去掉結尾的 ,所以程序中手動將 位置處的值變為,代表輸入的結束。

函數說明

語法

指針名=(數據類型*)realloc(要改變內存大小的指針名,新的大小)。

新的大小可大可小(但是要注意,如果新的大小小于原內存大小,可能會導致數據丟失,慎用!)

頭文件

#include有些編譯器需要#include,在TC2.0中可以使用alloc.h頭文件

功能

先判斷當前的指針是否有足夠的連續空間,如果有,擴大mem_address指向的地址,并且將mem_address返回,如果空間不夠,先按照newsize指定的大小分配空間,將原有數據從頭到尾拷貝到新分配的內存區域,而后釋放原來mem_address所指內存區域(注意:原來指針是自動釋放,不需要使用free),同時返回新分配的內存區域的首地址。即重新分配存儲器塊的地址。

返回值

如果重新分配成功則返回指向被分配內存的指針,否則返回空指針NULL。

注意

當內存不再使用時,應使用free()函數將內存塊釋放。

相關函數

1

malloc、calloc、free、_alloca

應用舉例

舉例1

從這個例子可以看出realloc函數的功能。

運行環境:ubuntu 12.04 GCC 4.6.3

運行結果:

malloc 0x904f008

realloc 0x904f008

0 1 2 3 4 5 6 7 8 9

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

#include

#include

int main()

{

inti;

int*pn=(int*)malloc(5*sizeof(int));

printf("malloc%p ",pn);

for(i=0;i<5;i++)

pn[i]=i;

pn=(int*)realloc(pn,10*sizeof(int));

printf("realloc%p ",pn);

for(i=5;i<10;i++)

pn[i]=i;

for(i=0;i<10;i++)

printf("%3d",pn[i]);

free(pn);

return 0;

}

舉例2

:(在TC2.0中運行通過)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

//realloc.c

#include

#include

main()

{

char*p;

clrscr();//clearscreen

p=(char*)malloc(100);

if(p)

printf("MemoryAllocatedat:%x",p);

else

printf("NotEnoughMemory! ");

get);

p=(char*)realloc(p,256);

if(p)

printf("MemoryReallocatedat:%x",p);

else

printf("NotEnoughMemory! ");

free(p);

get);

return 0;

}

內存分配編輯

如果有足夠空間用于擴大mem_address指向的內存塊,則分配額外內存,并返回mem_address。

這里說的是“擴大”,我們知道,realloc是從堆上分配內存的,當擴大一塊內存空間時, realloc()試圖直接從堆上現存的數據后面的那些字節中獲得附加的字節,如果能夠滿足,自然天下太平。也就是說,如果原先的`內存大小后面還有足夠的空閑空間用來分配,加上原來的空間大小= newsize。那么就ok。得到的是一塊連續的內存。

如果原先的內存大小后面沒有足夠的空閑空間用來分配,那么從堆中另外找一塊newsize大小的內存。

并把原來大小內存空間中的內容復制到newsize中。返回新的mem_address指針。(數據被移動了)。

老塊被放回堆上。

例如

1

2

3

4

5

6

7

8

9

#include

voidmain()

{

char*p,*q;

p=(char*)malloc(10);

q=p;

p=(char*)realloc(q,20);//A行,通過realloc擴大p的空間,并把新的地址賦值給p。

//…………………………

}

在這段程序中我們增加了指針q,用它記錄了原來的內存地址p。這段程序可以編譯通過,但在執行到A行時,如果原有內存后面沒有足夠空間將原有空間擴展成一個連續的新大小的話,realloc函數就會以第二種方式分配內存,此時數據發生了移動,那么所記錄的原來的內存地址q所指向的內存空間實際上已經放回到堆上了!這樣就會產生q指針的指針懸掛,即指針指向了一塊沒有分配給用戶使用的內存,如果再用q指針進行操作就可能發生意想不到的問題。所以在應用realloc函數是應當格外注意這種情況。

返回情況

返回的是一個void類型的指針:調用成功。(這就要求在你需要的時候進行強制類型轉換)

返回NULL:當需要擴展的大小(第二個參數)為0并且第一個參數不為NULL時。此時原內存變成“free(游離)”的了。

返回NULL:當沒有足夠的空間可供擴展的時候。此時,原內存空間的大小維持不變。

特殊情況

如果mem_address為NULL,則realloc()和malloc()類似。分配一個newsize的內存塊,返回一個指向該內存塊的指針。

如果newsize大小為0,那么釋放mem_address指向的內存,并返回NULL。

如果沒有足夠可用的內存用來完成重新分配(擴大原來的內存塊或者分配新的內存塊),則返回NULL。而原來的內存塊保持不變。

現存的數據然后就被拷貝至新的位置,而老塊則放回到堆上.重要的信息就是數據可能被移動

#include

#include

int main(int argc, char* argv[])

{

char *p,*q;

p = (char *)malloc(10);

q = p;

p = (char *)realloc(p,10);

printf("p=0x%x/n",p);

printf("q=0x%x/n",q);

return 0;

}

輸出結果:realloc后,內存地址不變

p=0x431a70

q=0x431a70

例2:

#include

#include

int main(int argc, char* argv[])

{

char *p,*q;

p = (char *)malloc(10);

q = p;

p = (char *)realloc(p,1000);

printf("p=0x%x/n",p);

printf("q=0x%x/n",q);

return 0;

}

輸出結果:realloc后,內存地址發生了變化

p=0x351c0

q=0x431a70

1 #include

2 #include

3 #include

4

5 int main(int argc, char **argv){

6

7 char *p, *p2, *pnew;

8 int offset = 0;

9

10 p = (char *)malloc(10);

11 if(!p){

12 printf("malloc p error ");

13 }

14 strcpy(p, "Hello,");

15 p2 = strchr(p,",");

16 offset = p2-p+1;

17

18 pnew = (char *)realloc((void *)p, 20);

19

20 if(pnew){

21 p = pnew;

22 p2 = pnew + offset;

23 strcpy(p2," world");

24 }

25 printf("string is: %s ",p);

26 return 0;

27 }

執行結果:string is: Hello, world

使用總結

1. realloc失敗的時候,返回NULL

2. realloc失敗的時候,原來的內存不改變,不會釋放也不會移動

3. 假如原來的內存后面還有足夠多剩余內存的話,realloc的內存=原來的內存+剩余內存,realloc還是返回原來內存的地址; 假如原來的內存后面沒有足夠多剩余內存的話,realloc將申請新的內存,然后把原來的內存數據拷貝到新內存里,原來的內存將被free掉,realloc返回新內存的地址

4. 如果size為0,效果等同于free()。這里需要注意的是只對指針本身進行釋放,例如對二維指針**a,對a調用realloc時只會釋放一維,使用時謹防內存泄露。

5. 傳遞給realloc的指針必須是先前通過malloc(), calloc(), 或realloc()分配的

6.傳遞給realloc的指針可以為空,等同于malloc。

1.什么是進制

進制是一種計數的方式,常用的有二進制、八進制、十進制、十六進制。任何數據在計算機內存中都是以二進制的形式存放的。

我對進制的個人理解,二進制數是以2為計算單元,滿2進1位的數;八進制數是以8為計算單元,滿8進1位的數。

對于任何一個數字,我們都可以用不同的進制來表示,比如,十進制數12,用二進制表示為1100,用八進制表示為14,用十六進制表示為0xC。

2.進制的轉換規則

遵循滿進制值進1位,個位數變為0的原理,下面我們以十進制數18為例,對1-18中每一個數值轉換各種進制做一個詳細說明

轉二進制:

①小于2,無需進1位,1的二進制值是1

②為二進制值1后面一個數,由于1+1滿2,需要進1位,個位數變為0,所以2的二進制值是10

③為二進制值10后面一個數,由于11的個位數1小于2,無需進1位,所以3的二進制值是11

④為二進制值11后面一個數,由于11的個位數1+1滿2,需要進1位,而二進制值11的位數1+1又滿2,所以位數加1,最終轉換結果為100

轉換思路:

二進制值11+1 ->10+(1+1)(個位等于2,進1位,個位數變為0) ->(1+1)+0(位數滿2,進1位) -> 100

以此類推,最終十進制數18的二進制轉換結果是10010

轉八進制:

1-7小于8,無需進1位,1-7的八進制由1-7表示

8為八進制值7后面一個數,由于7+1滿8,需要進1位,個位數變為0,所以8的八進制值是10

以此類推,最終十進制數18的八進制轉換結果是22

轉十六進制:

十六進制中,個位數1-15分別為1 2 3 4 5 6 7 8 9 a b c d e f (a=10....f=15)

16為十六進制值c后面1個數,由于c+1滿16,需要進1位,個位數變為0,所以16的十六進制是10。

最終十進制數18的十六進制轉換結果是12

詳細結果如下圖所示(C語言把數字前面加0x的數認為是十六進制數)

3.C語言中int類型進制的聲明以及占位符

雖然以下3個變量的賦值方式不同,但實際賦值結果都是18

//二進制類型數字加0b

int number1 = 0b10010;

//八進制類型數字加0

int number2 = 022;

//十六進制類型數字加0x

int number3 = 0x12;

八進制占位符:%o

十六進制占位符:%x

4.內存存儲數據細節

我們知道,int類型數據占據4個字節,1個字節是8bit。并且任何數據在計算機內存中都是以二進制的形式存放的,所以內存需要用32個0或1來描述1個int類型數據。

由于18的二進制數是10010,我們將一個int類型變量賦值18,本質上是將這個變量的內存地址對應的32個bit位修改為:

0000 0000 0000 0000 0000 0000 0001 0010(未滿31位,后面的數字用0填充:為什么是31而不是32呢,后面會介紹)

假設我們定義兩個變量

int number1 = 12; int number2 = 13;

計算機會根據內存地址以由大到小的順序進行分配內存空間,具體如下圖所示:

5.進制的轉換公式

二進制轉十進制

0b1100 ->0*2的0次方 + 0*2的1次方 + 1*2的2次方 + 1*2的3次方 = 12

十進制轉二進制

67 ->64+2+1 ->2的6次方+ 2的1次方 + 2的0次方 = 0b1000011

6.進制的其他知識

①.n位二進制能保存的整數范圍公式:2的n次方-1

例如,3位的二進制數最大值為111,對應的十進制數字為7;5位的二進制數最大值為11111,對應的十進制數字為(2*2*2*2*2)-1 = 31。

②.負數的二進制保存規則是最左邊的數字是1。例如,0000 0000 0000 0000 0000 0000 0001 0010 表示正整數,1111 1111 1111 1111 1111 1111 1110 1101表示負數

由此,我們就能推測出,int類型能保存的最大整數是2的(32-1)次方-1 = 2147483647。為什么要用32-1,很簡單,32個bit中,必須抽1個bit位用來描述這個數字是正數還是負數。

C語言函數

包含文件:string.h

函數名: strstr

函數原型:

1

extern char *strstr(char *str1, const char *str2);

語法:

1

* strstr(str1,str2)

str1: 被查找目標 string expression to search.

str2: 要查找對象 The string expression to find.

返回值:若str2是str1的子串,則返回str2在str1的首次出現的地址;如果str2不是str1的子串,則返回NULL。

例子:

1

2

3

char str[]="1234xyz";

char *str1=strstr(str,"34");

cout << str1 << endl;

顯示的是: 34xyz

函數實現

1.Copyright 1990 Software Development Systems, Inc.

1

2

3

4

5

6

7

8

9

10

11

12

char *strstr(const char *s1,const char *s2)

{

int len2;

if(!(len2=strlen(s2)))//此種情況下s2不能指向空,否則strlen無法測出長度,這條語句錯誤

return(char*)s1;

for(;*s1;++s1)

{

if(*s1==*s2 && strncmp(s1,s2,len2)==0)

return(char*)s1;

}

return NULL;

}

2.Copyright 1986 - 1999 IAR Systems. All rights reserved

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

char *strstr(constchar*s1,constchar*s2)

{

int n;

if(*s2)

{

while(*s1)

{

for(n=0;*(s1+n)==*(s2+n);n++)

{

if(!*(s2+n+1))

return(char*)s1;

}

s1++;

}

return NULL;

}

else

return (char*)s1;

}

3. GCC-4.8.0

1

2

3

4

5

6

7

8

9

10

11

char *strstr(const char*s1,const char*s2)

{

const char*p=s1;

const size_tlen=strlen(s2);

for(;(p=strchr(p,*s2))!=0;p++)

{

if(strncmp(p,s2,len)==0)

return (char*)p;

}

return(0);

}

應用舉例

// strstr.c

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

#include

#include

main()

{

char *s="GoldenGlobalView";

char *l="lob";

char *p;

clrscr();

p=strstr(s,l);

if(p)

printf("%s",p);

else

printf("NotFound!");

get);

return0;

}

//功能:從字串” string1 onexxx string2 oneyyy”中尋找”yyy”

(假設xxx和yyy都是一個未知的字串)

1

2

3

4

5

6

7

char *s=”string1onexxxstring2oneyyy”;

char *p;

p=strstr(s,”yyy”);

if(p!=NULL)

printf(“%s”,p);

else

printf("notfound ");

說明:如果直接寫語句p=strstr(s,”one”),找到的是onexxxstring2oneyyy

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

char *mystrstr(char*s1,char*s2)

{

if(*s1==0)

{

if(*s2)

return (char*)NULL;

return (char*)s1;

}

while(*s1)

{

int i=0;

while(1)

{

if(s2[i]==0)

return s1;

if(s2[i]!=s1[i])

break;

i++;

}

s1++;

}

return (char*)NULL;

}

C語言的一些誤用和知識總結

具體如下:

1.關于自增自減(即++i,i++)

要想給一個數加一或減一我們可以:

i += 1;

j -= 1;

而C語言還允許用++和--運算符,其實這里有誤導,因為++和--可以作為前綴和后綴,這樣的話他們就有可能改變操作數的值,下面讓我們來看看:

i = 1;

printf("i is %d ",++i); /* prints i is 2 */

printf("i is %d ",i); /* prints i is 2 */

計算表達式i++的結果是i,但是會引發i隨后進行自增:

i = 1;

printf("i is %d ",i++); /* prints i is 1/ */

printf("i is %d ",i); /* prints i is 2 */

第一個printf 顯示了i自增前的原始值,第二個printf顯示了i變化后的新值;當然 -- 類似我就不舉例了~

但在同一個表達式中多次使用++和--往往很難理解我們看看下面的例子:

i = 1;

j = 2;

k = ++i + j++;

i,j,k最終值分別是2,3,4而++i是2 j++是2;

總結:不管是++i還是i++執行這條語句后i的值都加一了只是(++i)的值加一了而(i++)沒變,

2.typedef與#define

2.1.typedef

C語言除了直接使用標準的類型名(如 int char float double)和自己聲明的結構體、共用體、指針、枚舉類型外,還可以用typedef聲明新的類型名來代替現有的類型名。

typedef unsigned char u8;

typedef unsigned int u16;

u8 count;

u16 time;

typedef struct

{

u8 month;

u8 day;

u16 year;

}DATE;

DATE brithday;

總結一下,聲明新的類型名的方法:

1.先按定義變量的方法寫出定義體(如 unsigned int i)

2.在變量名換成新的變量名(如將 i換成u16)

3.在最前面加上typedef (typedef unsigned int u16)

4.然后用新類型名去定義變量

2.2#define

2.1.1不帶參數的宏定義

define 標識符 字符串

define PI 3.1415926

注意:

1.它的作用是在本程序中用指定的標識符PI來代替3.1415926

2.宏定義是用宏來代替字符串也就是做簡單的置換,不做正確性檢查如果寫成

define PI 3.l4l6926

即把1寫成了字母l但是預處理照常代入不做任何語法檢查!!

2.1.2帶參數的宏定義

define 宏名(參數) 字符串

define S(a,b) a*b

area = S(a,b);

define MAX(x,y) (x)>(y) ? (x):(y)

3.typedef和#define的區別

一般來說typedef 因為它能正確處理指針類型

typedef char *String1;

define String2 char *

String1 s1,s2;

String2 s3,s4;

s1,s2,s3 被定義為了char* 但s4卻被定義為了char型

3. static 變量

static變量大致分為三種用法

1. 用于局部變量中,成為靜態局部變量. 靜態局部變量有兩個用法,記憶功能和全局生存期.

2. 用于全局變量,主要作用是限制此全局變量被其他的文件調用.

3. 用于類中的成員.表示這個成員是屬于這個類但是不屬于類中任意特定對象

靜態局部變量

靜態局部變量屬于靜態存儲方式,它具有以下特點:

(1)靜態局部變量在函數內定義 它的生存期為整個源程序,但是其作用域仍與自動變量相同,只能在定義該變量的函數內使用該變量。退出該函數后, 盡管該變量還繼續存在,但不能使用它。

(2)允許對構造類靜態局部量賦初值 例如數組,若未賦以初值,則由系統自動賦以0值。

(3) 對基本類型的靜態局部變量若在說明時未賦以初值,則系統自動賦予0值。而對自動變量不賦初值,則其值是不定的。 根據靜態局部變量的特點, 可以看出它是一種生存期為整個源程序的量。雖然離開定義它的函數后不能使用,但如再次調用定義它的函數時,它又可繼續使用, 而且保存了前次被調用后留下的值。 因此,當多次調用一個函數且要求在調用之間保留某些變量的值時,可考慮采用靜態局部變量。雖然用全局變量也可以達到上述目的,但全局變量有時會造成意外的副作用,因此仍以采用局部靜態變量為宜。

舉例如下:

void fun()

{

static int a = 1;

a++;

}

在第一次進入這個函數的時候,變量a被初始化為1!并接著自增1,以后每次進入該函數,a就不會被再次初始化了,僅進行自增1的操作;在static發明前,要達到同樣的功能,則只能使用全局變量:

int a = 1;

void fun()

{

a++;

}

靜態全局變量

全局變量(外部變量)的之前再加上static 就構成了靜態的全局變量。全局變量本身就是靜態存儲方式, 靜態全局變量當然也是靜態存儲方式。 這兩者在存儲方式上并無不同。這兩者的區別雖在于,非靜態全局變量的作用域是整個源程序, 當一個源程序由多個源文件組成時,非靜態的全局變量在各個源文件中都是有效的。 而靜態全局變量則限制了其作用域, 即只在定義該變量的源文件內有效, 在同一源程序的其它源文件中不能使用它。由于靜態全局變量的作用域局限于一個源文件內,只能為該源文件內的函數公用, 因此可以避免在其它源文件中引起錯誤。從以上分析可以看出, 把局部變量改變為靜態變量后是改變了它的存儲方式即改變了它的生存期。把全局變量改變為靜態變量后是改變了它的作用域, 限制了它的使用范圍。因此static 這個說明符在不同的地方所起的作用是不同的。

static的類成員變量

static關鍵字有兩種意思,你看上下文來判斷

1.表示變量是靜態存儲變量,表示變量存放在靜態存儲區.

2.表示該變量是內部連接(這種情況是指該變量不在任何{}之內,就象全局變量那樣,這時候加上static),也就是說在其它的.cpp文件中,該變量是不可見的(你不能用)。

static 函數 —— 內部函數和外部函數

當一個源程序由多個源文件組成時,C語言根據函數能否被其它源文件中的函數調用,將函數分為內部函數和外部函數。

1 內部函數(又稱靜態函數)

如果在一個源文件中定義的函數,只能被本文件中的函數調用,而不能被同一程序其它文件中的函數調用,這種函數稱為內部函數。

定義一個內部函數,只需在函數類型前再加一個“static”關鍵字即可,如下所示:

static 函數類型 函數名(函數參數表)

{……}

關鍵字“static”,譯成中文就是“靜態的”,所以內部函數又稱靜態函數。但此處“static”的含義不是指存儲方式,而是指對函數的作用域僅局限于本文件。

使用內部函數的好處是:不同的人編寫不同的函數時,不用擔心自己定義的函數,是否會與其它文件中的函數同名,因為同名也沒有關系。

2 外部函數

外部函數的定義:在定義函數時,如果沒有加關鍵字“static”,或冠以關鍵字“extern”,表示此函數是外部函數:

[extern] 函數類型 函數名(函數參數表)

{……}

調用外部函數時,需要對其進行說明:

[extern] 函數類型 函數名(參數類型表)[,函數名2(參數類型表2)……];

詞條內容僅供參考,如果您需要解決具體問題
(尤其在法律、醫學等領域),建議您咨詢相關領域專業人士。

推薦詞條

主站蜘蛛池模板: A三级观看视频 | 99国产| 夜夜导航 | 日韩灭亚洲精品 | 日本一级免费看 | 国产哺乳奶水91PORNY | 97视频播放 | 2025在线国产视频 | 性色精品视频网站在线观看 | 国产第三页 | 一区二区三区免费中文字幕 | 伊人网综合在线 | 亚洲一卡一卡二 | 国产脚交 | 国产日韩精品欧美一区视频 | 欧美精品秘 入口九色 | 97色偷偷9999www| 日韩无砖专 | 91一区二区三区视频 | 免费的短视频app大全下载安装 | 99精品视频免费热播在线观看 | 美女视频黄8频a美女大全 | 国产一区二区三区不卡观 | 日本道精品一区二区三区 | 国产又黄又粗又硬的视频 | 国产又粗又大又爽又黄的 | 亚洲欧美视频一区二区 | 亚洲人成网7777 | 哺乳挤奶网站XXXX国产 | 91无人区乱码一二三四区别详解 | 偷拍 自偷 亚洲 在线 | 韩国三a级做爰片免费观看 国产福利萌白酱 | 午夜成人爽爽爽视频在线观看 | 91PORNY九色蝌蚪首页 | 91日本免费高清 | 国产午夜在线视频观看 | 日本乱伦视频网站 | 97精品视频在线观看 | 日本精品在线观看 | 亚洲欧美日韩精品专区卡通 | 97中文字幕在线精品视频 |