05-資料型別

Icer_Newer發表於2023-03-14

資料型別

1.字元型

字元型變數用於儲存一個單一字元,在 C 語言中用 char 表示,其中每個字元變數都會佔用 1 個位元組。在給字元型變數賦值時,需要用一對英文半形格式的單引號(' ')把字元括起來。

記憶體中只能儲存二進位制數,如何儲存字元,需要將字元轉換為二進位制儲存在記憶體中,對應編碼使用ASCII表
字元變數實際上並不是把該字元本身放到變數的記憶體單元中去,而是將該字元對應的 ASCII 編碼放到變數的儲存單元中。char的本質就是一個1位元組大小的整型。

1.1 ASCII表

ASCII ((American Standard Code for Information Interchange): 美國資訊交換標準程式碼)是基於拉丁字母的一套電腦編碼系統,主要用於顯示現代英語和其他西歐語言。它是最通用的資訊交換標準,並等同於國際標準ISO/IEC 646。ASCII第一次以規範標準的型別發表是在1967年,最後一次更新則是在1986年,到目前為止共定義了128個字元。

Bin
(二進位制)
Oct
(八進位制)
Dec
(十進位制)
Hex
(十六進位制)
縮寫/字元
解釋
0000 00000000x00NUL(null)
空字元
0000 00010110x01SOH(start of headline)
標題開始
0000 00100220x02STX (start of text)
正文開始
0000 00110330x03ETX (end of text)
正文結束
0000 01000440x04EOT (end of transmission)
傳輸結束
0000 01010550x05ENQ (enquiry)
請求
0000 01100660x06ACK (acknowledge)
收到通知
0000 01110770x07BEL (bell)
響鈴
0000 100001080x08BS (backspace)
退格
0000 100101190x09HT (horizontal tab)
水平製表符
0000 1010012100x0ALF (NL line feed, new line)
換行鍵
0000 1011013110x0BVT (vertical tab)
垂直製表符
0000 1100014120x0CFF (NP form feed, new page)
換頁鍵
0000 1101015130x0DCR (carriage return)
Enter鍵
0000 1110016140x0ESO (shift out)
不用切換
0000 1111017150x0FSI (shift in)
啟用切換
0001 0000020160x10DLE (data link escape)
資料鏈路轉義
0001 0001021170x11DC1 (device control 1)
裝置控制1
0001 0010022180x12DC2 (device control 2)
裝置控制2
0001 0011023190x13DC3 (device control 3)
裝置控制3
0001 0100024200x14DC4 (device control 4)
裝置控制4
0001 0101025210x15NAK (negative acknowledge)
拒絕接收
0001 0110026220x16SYN (synchronous idle)
同步空閒
0001 0111027230x17ETB (end of trans. block)
結束傳輸塊
0001 1000030240x18CAN (cancel)
取消
0001 1001031250x19EM (end of medium)
媒介結束
0001 1010032260x1ASUB (substitute)
代替
0001 1011033270x1BESC (escape)
換碼(溢位)
0001 1100034280x1CFS (file separator)
檔案分隔符
0001 1101035290x1DGS (group separator)
分組符
0001 1110036300x1ERS (record separator)
記錄分隔符
0001 1111037310x1FUS (unit separator)
單元分隔符
0010 0000040320x20(space)
空格
0010 0001041330x21!歎號
0010 0010042340x22"雙引號
0010 0011043350x23#井號
0010 0100044360x24$美元符
0010 0101045370x25%百分號
0010 0110046380x26&和號
0010 0111047390x27'閉單引號
0010 1000050400x28(
開括號
0010 1001051410x29)
閉括號
0010 1010052420x2A*星號
0010 1011053430x2B+加號
0010 1100054440x2C,逗號
0010 1101055450x2D-減號/破折號
0010 1110056460x2E.句號
0010 1111057470x2F/斜槓
0011 0000060480x300字元0
0011 0001061490x311字元1
0011 0010062500x322字元2
0011 0011063510x333字元3
0011 0100064520x344字元4
0011 0101065530x355字元5
0011 0110066540x366字元6
0011 0111067550x377字元7
0011 1000070560x388字元8
0011 1001071570x399字元9
0011 1010072580x3A:冒號
0011 1011073590x3B;分號
0011 1100074600x3C<小於
0011 1101075610x3D=等號
0011 1110076620x3E>大於
0011 1111077630x3F?問號
0100 00000100640x40@電子郵件符號
0100 00010101650x41A大寫字母A
0100 00100102660x42B大寫字母B
0100 00110103670x43C大寫字母C
0100 01000104680x44D大寫字母D
0100 01010105690x45E大寫字母E
0100 01100106700x46F大寫字母F
0100 01110107710x47G大寫字母G
0100 10000110720x48H大寫字母H
0100 10010111730x49I大寫字母I
010010100112740x4AJ大寫字母J
0100 10110113750x4BK大寫字母K
0100 11000114760x4CL大寫字母L
0100 11010115770x4DM大寫字母M
0100 11100116780x4EN大寫字母N
0100 11110117790x4FO大寫字母O
0101 00000120800x50P大寫字母P
0101 00010121810x51Q大寫字母Q
0101 00100122820x52R大寫字母R
0101 00110123830x53S大寫字母S
0101 01000124840x54T大寫字母T
0101 01010125850x55U大寫字母U
0101 01100126860x56V大寫字母V
0101 01110127870x57W大寫字母W
0101 10000130880x58X大寫字母X
0101 10010131890x59Y大寫字母Y
0101 10100132900x5AZ大寫字母Z
0101 10110133910x5B[開方括號
0101 11000134920x5C\反斜槓
0101 11010135930x5D]閉方括號
0101 11100136940x5E^脫字元
0101 11110137950x5F_下劃線
0110 00000140960x60`開單引號
0110 00010141970x61a小寫字母a
0110 00100142980x62b小寫字母b
0110 00110143990x63c小寫字母c
0110 010001441000x64d小寫字母d
0110 010101451010x65e小寫字母e
0110 011001461020x66f小寫字母f
0110 011101471030x67g小寫字母g
0110 100001501040x68h小寫字母h
0110 100101511050x69i小寫字母i
0110 101001521060x6Aj小寫字母j
0110 101101531070x6Bk小寫字母k
0110 110001541080x6Cl小寫字母l
0110 110101551090x6Dm小寫字母m
0110 111001561100x6En小寫字母n
0110 111101571110x6Fo小寫字母o
0111 000001601120x70p小寫字母p
0111 000101611130x71q小寫字母q
0111 001001621140x72r小寫字母r
0111 001101631150x73s小寫字母s
0111 010001641160x74t小寫字母t
0111 010101651170x75u小寫字母u
0111 011001661180x76v小寫字母v
0111 011101671190x77w小寫字母w
0111 100001701200x78x小寫字母x
0111 100101711210x79y小寫字母y
0111 101001721220x7Az小寫字母z
0111 101101731230x7B{開花括號
0111 110001741240x7C|垂線
0111 110101751250x7D}閉花括號
0111 111001761260x7E~波浪號
0111 111101771270x7FDEL (delete)刪除
#include <stdio.h>

int main()
{
	char ch = 'a';
	printf("sizeof(ch) = %u\n", sizeof(ch));

	printf("ch[%%c] = %c\n", ch); //列印字元
	printf("ch[%%d] = %d\n", ch); //列印‘a’ ASCII的值

	char A = 'A';
	char a = 'a';
	printf("a = %d\n", a);		//97
	printf("A = %d\n", A);	//65

	printf("A = %c\n", 'a' - 32); //小寫a轉大寫A
	printf("a = %c\n", 'A' + 32); //大寫A轉小寫a

	ch = ' ';
	printf("空字元:%d\n", ch); //空字元ASCII的值為32
	printf("A = %c\n", 'a' - ' '); //小寫a轉大寫A
	printf("a = %c\n", 'A' + ' '); //大寫A轉小寫a

	return 0;
}

字元0在記憶體中儲存的是48,數字0在記憶體中儲存的是0

  • 字元所對應的最大ASCII碼值為127,就可以表示所有的字元,所以就可以使用char型別進行儲存單個字元,所以char型別又稱為字元型

1.2 字元變數的輸入

#include <stdio.h>

int main()
{
	char ch;
	printf("請輸入ch的值:");

	//不要加“\n”
	scanf("%c", &ch);
	printf("ch = %c\n", ch); //列印ch的字元

	return 0;
}

1.3 跳脫字元

有特使含義的字元,反斜槓+字母表示一個字元

跳脫字元 含義 ASCII碼值(十進位制)
\a 警報 007
\b 退格(BS) ,將當前位置移到前一列 008
\f 換頁(FF),將當前位置移到下頁開頭 012
\n 換行(LF) ,將當前位置移到下一行開頭 010
\r 回車(CR) ,將當前位置移到本行開頭 013
\t 水平製表(HT) (跳到下一個TAB位置) 009
\v 垂直製表(VT) 011
\ 代表一個反斜線字元"" 092
' 代表一個單引號(撇號)字元 039
" 代表一個雙引號字元 034
? 代表一個問號 063
\0 數字0 000
\ddd 8進位制跳脫字元,d範圍0~7 3位8進位制
\xhh 16進位制跳脫字元,h範圍09,af,A~F 3位16進位制
#include <stdio.h>

int main()
{
	printf("abc");
	printf("\refg\n"); //\r切換到句首, \n為換行鍵

	printf("abc");
	printf("\befg\n");//\b為退格鍵, \n為換行鍵

	printf("%d\n", '\123');// '\123'為8進位制跳脫字元,0123對應10進位制數為83
	printf("%d\n", '\x23');// '\x23'為16進位制跳脫字元,0x23對應10進位制數為35

	return 0;
}

1.4 字元與數值轉換

#include <stdio.h>

int main(){

  char ch_1 = 'a'; // 在記憶體中儲存的是97 ascii碼
  
  //列印字元的ascii碼  使用%d
  printf("%d\n",'a'); // 97
  printf("%d\n",'\n'); // 10   
  

  // 列印ascii數值對應的字元 %c
  printf("%c\n",ch_1); // 'a'

  char ch = '8'; // 定義字元8
  // 將字元8轉化為數字8
  // 用字元8-字元0就可以
  

  // 大寫和小寫轉換 a - 97 A - 65  ascii相差32
  char ch_2 = 'A';
  ch_2 = ch_2 + 32 ; 
  ch_3 = ch_2 + ' ';
  printf("%c\n",ch_2);  // a 

  // sizeof()
  printf("%d\n",sizeof(ch_2)); // 1個位元組--資料型別長度
  printf("%d\n",sizeof('a');  // 4位元組-- 'a'-->97-->int型別-->4個位元組

  return 0;
}

1.5 讀取多個字元

#include <stdio.h>

int main(){
  
  char ch = 0;
  scanf("%c",&ch); // 此時鍵盤輸入a,ch被賦值a;鍵盤輸入abc回車,ch也被賦值a,只能讀一個
  printf("%c\n",ch);

  // 讀取兩個字元--鍵盤輸入兩個字元
  char ch_1 = 0;
  char num = 0; 
  scanf("%c".&ch_1);   // 此時阻塞,等待輸入,輸入a回車, ch_1得到a  num得到\n
  scanf("%c",&num);
  printf("%c\n",ch_1);
  printf("%c\n",num);
  print("%d\n",ch_1);  // 97
  printf("%d\n",num);  // 10
  
  // 要連續輸入兩個字元給兩個變數,必須將中間輸入的回車\n吃掉,多加一個scanf()
  char ch_1 = 0;
  char num = 0; 
  scanf("%c".&ch_1);   // 此時阻塞,等待輸入,輸入a回車,b回車, ch_1得到a  num得到b
  printf("%c\n",ch_1);
  scanf("%c",&ch_1)
  scanf("%c",&num);
  printf("%c\n",num);
  print("%d\n",ch_1);  // 97
  printf("%d\n",num);  // 10
  system("pause");
  return 0;
}

2.浮點型

實型變數也可以稱為浮點型變數,浮點型變數是用來儲存小數數值的。在C語言中, 浮點型變數分為兩種: 單精度浮點數(float)、 雙精度浮點數(double), 但是double型變數所表示的浮點數比 float 型變數更精確。

由於浮點型變數是由有限的儲存單元組成的,因此只能提供有限的有效數字。在有效位以外的數字將被捨去,這樣可能會產生一些誤差。

不以f結尾的常量是double型別,以f結尾的常量(如3.14f)是float型別。
float佔4個位元組,double佔8個位元組

#include <stdio.h>

int main()
{
   
  // 浮點型資料列印的時候,預設輸出6位小數
  float a = 3.1415926456;
  double b = 3.1415926456;
  printf("%f\n",a);
  printf("%f\n",b);  // a b 都輸出6位小數
  
  // 輸出多位小數  %m.nf -- m表示資料寬度,  .n 表示輸出幾位小數
  printf("%.8f\n",a)
  
  // float有效精度7位,double有效精度是15位
  printf("%.8f\n",b);   // a = 3.14159274   b = 3.14159264; 

  //傳統方式賦值
  float a = 3.14f; //或3.14F
  double b = 3.14;

  printf("a = %f\n", a);
  printf("b = %lf\n", b);

  //科學法賦值
  a = 3.2e3f; //3.2*1000 = 3200,e可以寫E
  printf("a1 = %f\n", a);

  a = 100e-3f; //100*0.001 = 0.1
  printf("a2 = %f\n", a);

  a = 3.1415926f;
  printf("a3 = %f\n", a); //結果為3.141593


  system("pause")       
  return 0;
}

3.限定符

限定符 含義
extern 宣告一個變數,extern宣告的變數沒有建立儲存空間。extern int a;//變數在定義的時候建立儲存空間
const 定義一個常量,常量的值不能修改。const int a = 10;
Volatile 防止編譯器最佳化程式碼
register 定義暫存器變數,提高效率。register是建議型的指令,而不是命令型的指令,如果CPU有空閒暫存器,那麼register就生效,如果沒有空閒暫存器,那麼register無效。
volatile int sum;
for(int i = 0;i < 100;i++){
  sum = i
}

// 結果等價於是: sum = 99,編譯器會將上述程式碼進行最佳化,但是有時候在描述硬體的時候不想
// 編譯器進行最佳化,所有加上volatile關鍵字進行修飾  

register將變數定義在暫存器,一些變數經常使用,定義在暫存器中,方便進行計算

4.字串常量

  • 字串常量使用雙引號引起來
  • 字串是記憶體中一段連續的char空間,以'\0'(數字0)結尾。
  • 字串常量是由雙引號括起來的字元序列,如“china”、“C program”,“$12.5”等都是合法的字串常量。
  • "abc" -- 在記憶體中實際上是四個字元 abc\0,\0得存在實際上是為了方便對字串進行操作,比如進行字串列印
    字串常量與字元常量的不同:

    每個字串的結尾,編譯器會自動的新增一個結束標誌位'\0',即 "a" 包含兩個字元'a'和’\0’。
#include <stdio.h>

int main()
{
    string str = "abc";
    printf("%s\n",str);
    system("pause");
    return 0;
}
  • 字元0('0') -- 在記憶體儲存ascii碼 -- 48
  • \0 -- 在記憶體中儲存0
  • 數字0 -- 在記憶體中儲存0
  • 數字0和\0等價

5.輸入輸出函式

5.1 printf()和putchar()

printf是輸出一個字串,putchar輸出一個char。

#include <stdio.h>

int main()
{
    char ch = 'a';
    printf("%c\n",ch); // 使用%c列印一個字元
    putchar(ch);  // 使用putchar函式列印字元
    system("pause");
    return 0;
}
列印格式 對應資料型別 含義
%d int 接受整數值並將它表示為有符號的十進位制整數
%hd short int 短整數
%hu unsigned short 無符號短整數
%o unsigned int 無符號8進位制整數
%u unsigned int 無符號10進位制整數
%x,%X unsigned int 無符號16進位制整數,x對應的是abcdef,X對應的是ABCDEF
%f float 單精度浮點數
%lf double 雙精度浮點數
%e,%E double 科學計數法表示的數,此處"e"的大小寫代表在輸出時用的"e"的大小寫
%c char 字元型。可以把輸入的數字按照ASCII碼相應轉換為對應的字元
%s char * 字串。輸出字串中的字元直至字串中的空字元(字串以'\0‘結尾,這個'\0'即空字元)
%p void * 以16進位制形式輸出指標
%% % 輸出一個百分號

printf附加格式:

字元 含義
l(字母l) 附加在d,u,x,o前面,表示長整數
- 左對齊
m(代表一個整數) 資料最小寬度
0(數字0) 將輸出的前面補上0直到佔滿指定列寬為止不可以搭配使用-
m.n(代表一個整數) m指域寬,即對應的輸出項在輸出裝置上所佔的字元數。n指精度,用於說明輸出的實型數的小數位數。對數值型的來說,未指定n時,隱含的精度為n=6位。
#include <stdio.h>
int main()
{
	int a = 100;
	printf("a = %d\n", a);//格式化輸出一個字串
	printf("%p\n", &a);//輸出變數a在記憶體中的地址編號
	printf("%%d\n");

	char c = 'a';
	putchar(c);//putchar只有一個引數,就是要輸出的char
	long a2 = 100;
	printf("%ld, %lx, %lo\n", a2, a2, a2);

	long long a3 = 1000;
	printf("%lld, %llx, %llo\n", a3, a3, a3);

	int abc = 10;
	printf("abc = '%6d'\n", abc);  // 列印寬度6
	printf("abc = '%-6d'\n", abc); // 左對齊6位寬度
	printf("abc = '%06d'\n", abc); // 不足6位前面補0
	printf("abc = '%-06d'\n", abc); // err,左對齊,左補0衝突

	double d = 12.3;
        // m.n m--表示寬度 .m表示小數位數
	printf("d = \' %-10.3lf \'\n", d); // '12.300   '

	return 0;
}

5.2 scanf()和getchar()

  • getchar是從標準輸入裝置讀取一個char。
  • scanf透過%轉義的方式可以得到使用者透過標準輸入裝置輸入的資料。
#include <stdio.h>

int main()
{
	char ch1;
	char ch2;
	char ch3;
	int a;
	int b;

	printf("請輸入ch1的字元:");
	ch1 = getchar();
	printf("ch1 = %c\n", ch1);   // 輸入a 回車

	getchar(); //測試此處getchar()的作用,將上面的回車吃掉

	printf("請輸入ch2的字元:");
	ch2 = getchar();            // 輸入b回車
	printf("\'ch2 = %ctest\'\n", ch2);

	getchar(); //測試此處getchar()的作用 // 吃掉回車
	printf("請輸入ch3的字元:"); // 輸入c 


	scanf("%c", &ch3);//這裡第二個引數一定是變數的地址,而不是變數名
	printf("ch3 = %c\n", ch3);

	printf("請輸入a的值:");
	scanf("%d", &a);
	printf("a = %d\n", a);

	printf("請輸入b的值:");
	scanf("%d", &b);
	printf("b = %d\n", b);

	return 0;
}

相關文章