天天看點

偷學C語言第一天

目錄

從“Hello world!”開始

代碼解釋

#include

stdio

.h

<>

main()函數

/**/

printf()

return

C程式結構

寫的第一個C語言Bug

資料類型

辨別符 

變量和常量

變量

常量

多學一點

比特位和位元組

符号位(signed&unsigned)

從“Hello world!”開始

#include <stdio.h>
int main(){
	/*第一個C程式*/
	printf("Hello world!\n");
	return 0;
}           

代碼解釋

#include

是在程式編譯之前要處理的内容,稱為編譯預處理指令。編譯預處理指令還有很多,它們都以“#”開頭,并且不用分号結尾,是c語言的程式語句。我猜測“include”這個東東就類似于Java中的導包,舉個通俗的例子,我們要做某件事情,别人是做這件事情的專家,那麼專業的事情就交給專業的人去做,是以我們得先把專家請過來,#include<stdio.h>就相當于你先把“stdio.h”這個可以完成标準輸入輸出的專家請過來,在需要輸入輸出時直接調用它裡面的函數即可。

stdio

stdio是C編譯系統提供的一個檔案名,stdio是“standard input & output”的縮寫,即有關标準輸入輸出的資訊。

.h

h即head,表示頭檔案,因為這些檔案都是放在程式各檔案的開頭。

<>

表示系統自帶的庫,也可以寫成" " 表示使用者自定義的庫,如果寫成" "并且自定義的庫裡面沒有這個檔案系統會自動查找自帶的庫,如果還是沒有就會報錯。

main()函數

與Java相同,mian()函數是C語言程式入口,既然是入口,那在一個C程式中就隻能有一個main()函數,可沒有後門噢(~_~)。int是函數的傳回值類型,也就說你這個函數在執行完成之後,要傳回給調用者什麼玩意,當然也可以不傳回,此時可以指定傳回值類型為void或者直接省掉。

#include <stdio.h>
void main(){
	printf("Hello world!\n");
}           

在撸碼時我發現以下寫法都不會報錯,原來C并不是那麼嚴謹,可能我剛開始學C,了解的還不夠,這個問題先記在小本本上,高手也可以在評論區留言幫我解惑,不勝感激{>_<}~

#include <stdio.h>
main()
{
 double d = 3.1415926;
 printf("Hello world!\n");
 return d;
}

#include <stdio.h>
int main()
{
	printf("Hello world!\n");
}


#include <stdio.h>
void main()
{
 printf("Hello world!\n");
}

#include <stdio.h>
main()
{
 printf("Hello world!\n");
}           

/**/

C語言的注釋,是給開發人員看的,計算機不會理會注釋。

printf()

print是列印的意思,f即format,是以printf是格式化列印,也叫格式化輸出。詳情請看:printf函數文檔

return

使用return關鍵字結束程式,并傳回我們指定的資料。

C程式結構

從上述案例中我們可以總結出,一個C語言程式包含:預處理器指令、函數、變量、語句、注釋,除此之外,後面我們還會學到表達式。

寫的第一個C語言Bug

#include<stdio.h>
int main()
{
	printf("
     *********
   |:H:a:p:p:y:|
 __|___________|__
|^^^^^^^^^^^^^^^^^|
|:B:i:r:t:h:d:a:y:|
|                 |
*******************
                  ,;,,;
                 ,;;'(    生
       __      ,;;' ' \   ┇
    /'  '\'~~'~' \ /'\.)  日
 ,;(      )    /  |.      ┇
,;' \    /-.,,(   ) \     快
     ) /       ) / )|     ┇ 
     ||        ||  \)     樂
     (_\       (_\n");
return 0;
}           

緣起:鐵哥們今天過生日,作為程式員的我想搞個特别的生日祝福,于是就有了上面的程式,printf既然可以輸出“Hello world”,那我讓它多輸出點東西應該沒問題吧,結果:

偷學C語言第一天

小朋友,你是不是有很多問号?哈哈哈~ 經過一番百度,原來需要用“\n”來換行,用“\”作為上一行和下一行的“連接配接符”(我們暫且叫它連接配接符),"\n"是C語言的轉義字元,在字元串中反斜杠 + 字元是轉義字元,表示特殊含義。但反斜杠如果後邊不帶任何字元(直接換行),表示我們希望 C 語言将該行以及下一行看做是一個整體。來看看修改後的代碼:

#include<stdio.h>
int main()
{
	printf("\n\
     *********\n\
   |:H:a:p:p:y:|\n\
 __|___________|__\n\
|^^^^^^^^^^^^^^^^^|\n\
|:B:i:r:t:h:d:a:y:|\n\
|      小馬       |\n\
*******************\n\
                  ,;,,;\n\
                 ,;;'(    生\n\
       __      ,;;' ' \   ┇\n\
    /'  '\'~~'~' \ /'\.)  日\n\
 ,;(      )    /  |.      ┇\n\
,;' \    /-.,,(   ) \     快\n\
     ) /       ) / )|     ┇ \n\
     ||        ||  \)     樂\n\
     (_\       (_\n");
return 0;
}           
偷學C語言第一天

雖然有警告,但是沒有報錯了,而且也能正常列印出顔文字了。

PS:下面的轉義字元表不用刻意去記,常用自然會用。

轉義字元 意義 ASCII碼值(十進制)
\a 響鈴(BEL) 007
\b 倒退(BS) ,将目前位置移到前一列 008
\f 換頁(FF),将目前位置移到下頁開頭 012
\n 換行(LF) ,将目前位置移到下一行開頭 010
\r 回車(CR) ,将目前位置移到本行開頭 013
\t 水準制表(HT)  009
\v 垂直制表(VT) 011
\' 單引号 039
\" 雙引号 034
\\ 反斜杠 092

常用ASCII碼對照表

資料類型

在C語言中,資料類型指的是用于聲明不同類型的變量或函數的一個廣泛的系統。變量的類型決定了變量存儲占用的空間,以及如何解釋存儲的位模式。通俗地講,我們的資料是存儲在記憶體中的,記憶體就好像是一幢摩天大樓,裡面被分成了大大小小的房間,我們的資料就被存儲在這些房間裡,房間的編号就是記憶體位址,房間的大小及内部布局就是由資料類型決定的。

常用的資料類型包括基本類型、指針類型、數組類型、結構類型等。(數組類型和結構類型統稱為構造類型或聚合類型,函數的類型指的是函數傳回值的類型。) 

偷學C語言第一天

關于标準整數類型的存儲大小和值範圍的細節

類型 存儲大小 值範圍
char 1 位元組 -128 到 127 或 0 到 255
unsigned char 1 位元組 0 到 255
signed char 1 位元組 -128 到 127
int 2 或 4 位元組 -32,768 到 32,767 或 -2,147,483,648 到 2,147,483,647
unsigned int 2 或 4 位元組 0 到 65,535 或 0 到 4,294,967,295
short 2 位元組 -32,768 到 32,767
unsigned short 2 位元組 0 到 65,535
long 4 位元組 -2,147,483,648 到 2,147,483,647
unsigned long 4 位元組 0 到 4,294,967,295

關于标準浮點類型的存儲大小、值範圍和精度的細節

類型 存儲大小 值範圍 精度
float 4 位元組 1.2E-38 到 3.4E+38 6 位小數
double 8 位元組 2.3E-308 到 1.7E+308 15 位小數
long double 16 位元組 3.4E-4932 到 1.1E+4932 19 位小數

各種類型的存儲大小與系統位數有關,但目前通用的以64位系統為主。 為了得到某個類型或某個變量在特定平台上的準确大小,C為我們提供了sizeof運算符,代碼示例:

#include<stdio.h>
void main()
{
	int i = 666;//i是變量
	/*sizeof的三種使用方式:
	  sizeof(對象)
	  sizeof 對象
	  sizeof(類型)
	*/
	printf("整型的存儲大小是:%d\n",sizeof(i));
    printf("整型的存儲大小是:%d\n",sizeof i);
    printf("整型的存儲大小是:%d\n",sizeof(int));
}           

PS:我們可以為基本資料類型加上一些限定符,比如表示長度的 short 和 long。比如 int 經過限定符修飾之後,可以是 short int,long int,還可以是 long long int(這個是 C99 新增加的)。 

辨別符 

 辨別符是用來辨別變量、函數,或任何其他使用者自定義項目的名稱。辨別符的命名規範如下:

  • 隻能是英文字母(A~Z、a~z)、數字(0~9)、下劃線(_)組成。
  • 第一個字母必須是字母或下劃線開頭。
  • 辨別符區分大小寫。
  • 不能使用關鍵字命名。

變量和常量

變量

變量就是可以改變的資料。我們讓CPU幫我們處理的資料都被它放在了記憶體裡(可以了解為一個個坑位,一個蘿蔔一個坑),每個記憶體都有記憶體位址(坑位編号),而我們需要給變量取名再把它放進記憶體裡,這樣做的好處就是我們可以通過直呼其名的方式擷取變量在記憶體中儲存的資料。

聲明變量的文法:資料類型 變量名;

/*示範變量*/
#include<stdio.h>
void main()
{
	/*先聲明變量*/
	int i ;
    /*再給變量指派,業内稱該操作為給變量初始化*/
    i = 666;
	float f = 3.14F;
	double d = 31415926E-7;
	
	printf("i = %d\n",i);
	printf("f = %3.3f\n",f);
	printf("d = %.7f\n",d);
}           

PS:C語言關鍵字就是C語言自己内部使用的名字,這些名字都具有特殊意義,不允許外部使用。傳統的 C 語言(ANSI C)有 32 個關鍵字:auto、break、case、char、const、continue、default、do、double、else、enum、extern、float、for、goto、if、int、long、register、return、short、signed、sizeof、static、struct、switch、typedef、union、unsigned、void、volatile、while;1999年,ISO 釋出 C99,添加了 5 個關鍵字:inline、restrict、_Bool、_Complex、_Imaginary;2011年,ISO 釋出 C11,添加了 7 個關鍵字:_Alignas、_Alignof、_Atomic、_Static_assert、_Noreturn、_Thread_local、_Generic。

常量

就是恒量,不變的量,正所謂“強者恒強”~

常量的分類

  • 整型常量

    整型常量可以是八進制、十進制、十六進制,字首指定基數,字尾指定類型,比如:30UL表示無符号長整型30,0x4b表示十六進制的4b。

    注:字首“0x”/"0X"表示十六進制、"0"表示八進制,不帶字首預設十進制;字尾u/U表示無符号(unsigned),l/L表示長整型(long)。

  • 浮點常量(實型常量)

    浮點常量有兩種表示形式,即小數形式和指數形式。當使用小數形式表示時,必須包含整數部分、小數部分,或同時包含兩者。當使用指數形式表示時,必須包含小數點、指數,或同時包含兩者。帶符号的指數是用e或E引入的。

  • 字元常量

    字元常量被括在單引号中,像這樣的'a',字元常量可以是一個普通的字元(例如 'a')、一個轉義序列(例如 '\t'),或一個通用的字元(例如 '\u02C0')。

  • 字元串常量

    字元串字面值或常量是被括在雙引号 "" 中的,字元串你可以了解為文本,例如“Hello world!”。

  • 定義常量(宏定義)

    在C中我們可以通過 #define 預處理器和const關鍵字定義常量。關于兩者的差別,可以看看這篇:const和#define的差別,詳細!

#include<stdio.h>

/*定義常量方式一:
格式:#define 辨別符 常量值

它的功能就是把程式中所有出現的該定義的辨別符都替換為随後的常量。
*/
#define MAX 800
int main()
{
	/*整型常量*/
	int i = 888;
	/*單浮點型常量,浮點型預設是double,使用f/F字尾可以指定為float類型*/
	float f = .5F;
	/*雙浮點型常量*/
	double d = 314.15926E-2;
	/*字元常量*/
	char c = 'a';
	/*字元串常量:C語言中用'\0'這個特殊的轉義字元标記字元串的結束位置,
	這樣以來,當作業系統讀取到這個轉義字元時,就能知道字元串到此為止了。
	*/
	char chs[] = "學習使我快樂{>_<}";
	/*定義常量方式二:
	  格式:const 類型 辨別符 = 常量值;
	*/
	const int CAPACITY = 16;
	
	
	/*printf 函數文檔:https://fishc.com.cn/thread-66471-1-1.html*/
	printf("i = %d\n",i);
	printf("f = %.1f\n",f);
	printf("d = %8.7f\n",d);
	printf("c = %c\n",c);
	printf("chs = %s\n",chs);
	printf("MAX = %d\n",MAX);
	printf("CAPACITY = %d\n",CAPACITY);
}           

多學一點

比特位和位元組

  • 比特位(bit)是CPU能讀懂的最小機關,用"b"表示,隻能存放二進制的0和1。
  • 位元組(Byte)是記憶體結構的最小尋址機關,用"B"表示。
  • 一位元組等于八位:1Byte==8bit。是以一位元組可以存儲最大的數是:11111111。

符号位(signed&unsigned)

signed(帶符号位)和unsigned(不帶符号位)叫做類型限定符,用于限定char和任何整型變量的取值範圍。帶符号位的變量可以表示負數,最高位用1表示負數,0表示正數;而不帶符号位的變量隻能表示正數,它的存儲空間也就相應擴大一倍。預設所有的整型變量都是 signed的,也就是帶符号位的。

我們看個例子:

#include<stdio.h>
#include<math.h>
int main()
{
	/*預設是有符号的,即signed*/
	short i = -1;
    /*無符号的變量隻能接受整數,如果硬要把負數指派給它,編譯器
	會提示你“[-Woverflow]”,運作代碼将會出現奇葩的結果
	*/
	unsigned short j = -1;
	/*計算int類型可以存儲的最大值 ------ 這行代碼是有問題的*/
	int maxIntError = pow(2,32)-1;
	/*計算int類型可以存儲的最大值 ------ 這行代碼才是正确的*/
	unsigned int maxInt = pow(2,32)-1;
	
	printf("i = %d\n",i);
	printf("j = %d\n",j);
	printf("maxIntError = %d\n",maxIntError);
	printf("maxInt = %u\n",maxInt);
}           

繼續閱讀