一文詳解C語言char類型中的存儲(chǔ)
char是如何存儲(chǔ)的
字符型(char)用于儲(chǔ)存字符(character),如英文字母或標(biāo)點(diǎn)。但是char類型在內(nèi)存中并不是以字符的形式儲(chǔ)存,而是以ASII碼的形式儲(chǔ)存,也可以說char類型儲(chǔ)存的實(shí)際上是整數(shù)。所以char類型也被歸類為整形家族。
int main()
{
char c = 'A';
printf("%d\n", c);
printf("%c\n", c);
return 0;
}
從上面的代碼可以看出,因?yàn)閏har類型儲(chǔ)存的是整形,所以可以以正數(shù)的形式打印出
打開內(nèi)存窗口,也可以看出char是以整數(shù)的形式存儲(chǔ):
既然知道char實(shí)際上是整形,所以也可以用int類型對(duì)char類型賦值
int main()
{
char c = 65;
printf("%d\n", c);
printf("%c\n", c);
return 0;
}
以
%d輸出就是輸出存儲(chǔ)在內(nèi)存中的整形,以%c輸出就會(huì)輸出初始化時(shí)整數(shù)對(duì)應(yīng)的ASKII碼字符
其實(shí)關(guān)于由int類型對(duì)char賦值,以及對(duì)于char類型之間的運(yùn)算,其實(shí)都會(huì)經(jīng)歷一個(gè)操作叫做:整形提升,整形提升的詳細(xì)介紹在另一篇文章里??點(diǎn)擊跳轉(zhuǎn)
char的類型
當(dāng)聽到char的類型這句話時(shí),第一反應(yīng)應(yīng)該會(huì)是:“char的類型不就是char嘛”
其實(shí)不然,char類型實(shí)際上分區(qū)為有符號(hào)的signed char和無符號(hào)的unsigned char
你可能對(duì)有無符號(hào)可能會(huì)陌生,對(duì)于有無符號(hào)我在另一篇文章里詳細(xì)介紹了??點(diǎn)擊跳轉(zhuǎn)
對(duì)于char的有無符號(hào)位比較特殊的是:
char與signed char不一定等價(jià)char默認(rèn)是signed char還是unsigned char取決于編譯器- 在常見的編譯器里,
char類型都默認(rèn)為signed char
char的取值范圍
char類型占1個(gè)字節(jié),也就是8個(gè)比特位
所以char在內(nèi)存中以00000000開始,逐漸遞增,到011111111,在增加到100000000,最后到11111111,如下圖:

對(duì)于signed char來說:
00000000為0,逐漸遞增到011111111為127,因?yàn)榈谝晃皇欠?hào)位,所以再+1后的100000000為負(fù)數(shù)。
從最下面的開始算,11111111為-1,向上逐漸遞減,到100000001時(shí),為-127,所以100000000為-128。
所以,有符號(hào)的char的取值范圍是:-128 ~ 127
對(duì)于unsigned char來說:
當(dāng)二進(jìn)制最高好比特位的數(shù)為0時(shí),無符號(hào)的char與有符號(hào)的char相同,當(dāng)制最高好比特位的數(shù)為1時(shí),因?yàn)槭菬o符號(hào)的char,所以
100000000為128,直到11111111為255
所以,無符號(hào)的char的取值范圍是:0 ~ 255
下面這幅圖可以形象地表示出char類型數(shù)據(jù)范圍

其實(shí),這個(gè)圖還可以體現(xiàn)出
char類型的“循環(huán)”
在給char類型賦值為超過它的取值范圍的值時(shí),在char中的會(huì)按照?qǐng)D中的循環(huán)方向進(jìn)行存儲(chǔ)值,這其實(shí)是由于整形提升導(dǎo)致的,但是通過照著這個(gè)圖會(huì)比分析整形提升的過程更方便得出實(shí)際char中的值
int main()
{
char c = 129;
printf("%d", c);
return 0;
}
這個(gè)程序輸出是-127,而不是129

此代碼中,char類型默認(rèn)是有符號(hào)的char,它的取值范圍是-128 ~ 127,但是給c賦值為129,超出了取值范圍
所以照著圖就可以看出:129超了127兩位,在圖里127向后走兩位就是-127
無符號(hào)整形也是如此。
例題
例1
//輸出什么?
#include <stdio.h>
int main()
{
char a= -1;
signed char b=-1;
unsigned char c=-1;
printf("a=%d,b=%d,c=%d",a,b,c);
return 0;
}
在這里char和signed char是一個(gè)意思,有符號(hào)的char取值范圍是-128 ~ 127,-1在這個(gè)范圍中,所以a,b 都輸出 -1
無符號(hào)的范圍是0 ~ 255,-1不在這個(gè)范圍里,根據(jù)起面的循環(huán)圖,c中存放的是255

例2
//輸出結(jié)果是什么?
int main()
{
char a[1000];
int i;
for(i=0; i<1000; i++)
{
a[i] = -1-i;
}
printf("%d",strlen(a));
return 0;
}
答案是:255
因?yàn)?code>strlen是遇到\0就結(jié)束,也就是遇到0就結(jié)束
a[i]的值從-1,-2,-3到-128,再到127,126……0
這之間一共有255個(gè)數(shù),所以結(jié)果是255
例3
//輸出結(jié)果是什么?
#include <stdio.h>
unsigned char i = 0;
int main()
{
for(i = 0;i<=255;i++)
{
printf("hello world\n");
}
return 0;
}
答案是:死循環(huán)
因?yàn)檫@里的i是無符號(hào)的char,范圍是0 ~255,隨著for循環(huán)的進(jìn)行,當(dāng)i==255時(shí),再加1,i變?yōu)?,仍然小于255,所以是死循環(huán)
附:關(guān)于轉(zhuǎn)義字符的內(nèi)容
void main()
{
//char a = '\'',b='\\',c='\r';// \是轉(zhuǎn)義符
//cout << a << endl;
//cout << b<< endl;
//cout << c << endl;
//int x = 'avb';
//int y = 'a';
//int z = 'v';
//int f = 'b';
//int h = y*z*f;
}
char a = ‘’’,b=’\’,c=’\r’; \是轉(zhuǎn)義符
通過轉(zhuǎn)義符可以得到某些特殊的字符的本身
如果只是簡(jiǎn)單賦值如:char ch=‘’‘;想得到一個(gè)單引號(hào)字符,這樣的操作是無法通過編譯的。
例如我們想要在字符串中輸入一個(gè)特殊的名字如:“c++“hm”
如果簡(jiǎn)單的寫為:char str[30]={" llj “c++ "hm "};這樣是無法得到正確的答案的
我們需要使用轉(zhuǎn)義符
char str[30]={" llj \“c++ \"hm "}
這樣使用轉(zhuǎn)義符,就可以把某些界限符的意義轉(zhuǎn)為其他含義,如’ ‘是字符的界限符,” “是字符串的界限符。
再舉一個(gè)例子:int x='4';那么x的值為字符4對(duì)應(yīng)的ascii值
但是如果寫為 int x=’\4’;那么x的值就為4。
int x="\1\2\3\4\5\6\7"[2];
上面x的值為3;
首先整個(gè)字符串通過轉(zhuǎn)義變?yōu)榱?ldquo;1234567”這樣七個(gè)字符,而后面的[2]則是代表著下標(biāo)訪問第二個(gè)數(shù)據(jù),所以得到的剛好是第三個(gè)字符3;之所以能訪問是因?yàn)?,在這個(gè)字符串中\(zhòng)1\2\3等每個(gè)數(shù)都為一個(gè)字節(jié),那么下標(biāo)2,相當(dāng)于第三個(gè)數(shù),也就是第三個(gè)字節(jié)的內(nèi)容。
總結(jié)
到此這篇關(guān)于C語言char類型中的存儲(chǔ)的文章就介紹到這了,更多相關(guān)C語言char類型存儲(chǔ)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++將二叉樹轉(zhuǎn)為雙向鏈表及判斷兩個(gè)鏈表是否相交
這篇文章主要介紹了C++將二叉樹轉(zhuǎn)為雙向鏈表及判斷兩個(gè)鏈表是否相交的方法,文中還給出了求兩個(gè)鏈表相交的第一個(gè)節(jié)點(diǎn)列的實(shí)現(xiàn)方法,需要的朋友可以參考下2016-02-02
C++實(shí)現(xiàn)LeetCode(38.計(jì)數(shù)和讀法)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(38.計(jì)數(shù)和讀法),本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07
求斐波那契(Fibonacci)數(shù)列通項(xiàng)的七種實(shí)現(xiàn)方法
本篇文章是對(duì)求斐波那契(Fibonacci)數(shù)列通項(xiàng)的七種實(shí)現(xiàn)方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
C++實(shí)現(xiàn)數(shù)字轉(zhuǎn)換為十六進(jìn)制字符串的方法
這篇文章主要介紹了C++實(shí)現(xiàn)數(shù)字轉(zhuǎn)換為十六進(jìn)制字符串的方法,涉及C++操作數(shù)字與字符串轉(zhuǎn)換的相關(guān)技巧,需要的朋友可以參考下2015-06-06
visual?studio?2022?編譯出來的文件被刪除并監(jiān)視目錄中的文件變更(示例詳解)
這篇文章主要介紹了visual?studio?2022?編譯出來的文件被刪除?并監(jiān)視目錄中的文件變更,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-08-08
C++深入詳解單例模式與特殊類設(shè)計(jì)的實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了C++單例模式和特殊類的設(shè)計(jì),單例模式這種類型的設(shè)計(jì)模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對(duì)象的最佳方式,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-06-06







