前言:
1.初學習了c語言,感徑訓是很不錯的,哈哈~~,下面讓我來分享下我目前對c的認識
題外:后面有關于c語言風格培養的《高質量的c-c++編程》PDF版鏈接,有需要自拿,哈哈~~,
一.初識c語言
1.1計算機語言的發展程序:由需求促進發展,由不成熟逐漸成為流行,
早期的科學家通過數字1和0的組合控制硬體計算機的運行,后來在需求下,人們創建了助記符(匯編語言).但還是不能滿足需求,于是B語言出現,再后來高級語言C,c++,java等相繼出現,但不同地方語言規范不同,為消除這種交流障礙,促進語言的融洽,1989年,ANSI(美國國家標準協會)制定了一套c語言規定(c89),1990年,國際標準化組織(IOS)也制定了一套規定(c90).1999年,ANSI/IOS(C9X委員會)聯合委員會共同制定了c99;2011年,C9x發布了(C11)標準,至此C語言成為世界流行語言,目前使用較多的是c89/c90(2個幾乎等同),
1.2什么是c語言?
c語言是一種面向程序的計算機編程語言,廣泛用于底層C語言的設計目標 是提供一種 能簡易編譯,處理低級存盤器,產生少量機器碼以及不需要任何運行環境支持便能運行的編程語言,
選擇C語言的理由:流行性,高效性,可移植性高,強大而靈活,面向程式員,
1.流行性:c是一門流行語言,其融合了計算機科學理論和實踐的控制特性,便于用戶完成自頂向下的規劃,結構化編程和模塊化設計,使得c語言撰寫的程式更易懂,更可靠,
2.高效性:c是高效的語言,c語言具有通常匯編語言才有的微調控控能力,可以根據具體情況一獲得最大運行速度,最有效的使用記憶體 ,
3.可移植性高:c是可移植的語言,我們知道不同作業系統其運行方式不同,而我們想在不同系統運行c程式,需要我們在少量更改程式的條件下,仍能運行c程式,這必然要求我們的語言可移植性高,而在這些語言中,c語言嶄露頭角,其可移植性非常高
4.強大而靈活:許多作業系統,如UNIX系統大部分也是通過c語言撰寫的,另外很多程式編譯器,解釋器也是用c語言撰寫的,
5.面向程式員:c語言的強大,可以清晰的讓程式員簡潔的表達自己的想法與意圖,
簡單的c程式
#include <stdio.h>
int main ( )
{
printf ( "helloworld!" ) ;
return 0 ;
}
據說在業界能這句話能給你的編程之旅帶來好運!你好世界!
三.c語言的語法規則
3.1 c中的資料型別:整形,浮點型,字符型及其所占空間大小
整型 名字 int (普通整形), short (int)可以省略(int) 短整形 long 長整形 long long 更長的整形 unsigned int 無符號(—)整形(只能為正) signed int 有符號整型(可正可負)
浮點型: 名字 float 單精度浮點數型 double 雙精度浮點型
3.1.2 每種資料型別的在記憶體中的大小
補充:
1.sizeof(型別) 1.它是運算運算子 ,不是函式 2.它用于測定資料在記憶體中的位元組(byte)大小,字串結束標志‘\0’也要被計算記憶體,
2.strlen(字符陣列名) 1.它是函式 ,不是運算子, 2.它用于測定字符陣列長度,在測定長度時以==‘\0’==為字串結束標志,
3.位元組(byte)
計算機的單位:
記憶體單位 名字 補充 bit 位元 計算機最小記憶體單元 byte 位元組 1byte=8bit kb 1kb=1024byte mb 1kb=1024kb gb 1kb=1024mb tb 1kb=1024gb pb 1kb=1024tb
我們知道計算機能識別的機器語言(二進制語言)(一定順序的1/0),而對于每個二進制1/0在記憶體中都要占有一定的空間,我們規定每個 這樣的1/0所占的空間為1bit(計算機中的最小記憶體空間),而計算機中的資料是按位元組,分配空間的,即認為1byte為運行時的記憶體單元,
01000100 占用8個記憶體空間(8個bite位)
而對于資料型別我們規定:
型別 記憶體大小 整型(int) 4個位元組(32bite位) 短整形(short) 2個位元組(16個bite位) long long型 8個位元組,
型別 記憶體大小 字符型 一個位元組(8個bite位),
型別 記憶體大小 單精度型(float) 4個位元組(32個bite位) 雙精度型(double) 8個位元組(64個bite位),
==另外c語言規定:sizeof(long) >=======sizeof(int)=4;具體long型所占位元組大小,依據不同編譯器結果不同,
3.2變數,常量
3.2.1.變數:可以隨時改變的量(資料).如:年齡,身高等;
3.2.2.常量:不能改變的量(資料),如:圓周率,血型等,
3. 2.3定義變數的方式:
資料型別+自定義資料名稱+初始化+陳述句結束標志“;”(分號)
初始化依據條件可以不進行初始化,
如 年齡是整形 資料
身高是浮點型 資料
字母是字符型 資料
int age= 19 ;
float length= 170f ;
char a= 'w' ;
3.2.4變數的使用:
#include <stdio.h>
int main ( )
{
int age= 19 ;
float length= 170f ; //c默認浮點型資料為double型,如果非要float,只需要在后面加f;
char name[ ] = "***" ; //名字是由多個字符組合成的,因此在c中我們定義字符陣列來表示字串;
printf ( "年齡=%d\n" , age) ;
printf ( "長度=%f\n" , length) ;
printf ( "名字=%s" , name) ; //以字串的形式列印字符陣列name中的每個元素;
return 0 ;
}
3.2.5變數的分類
區域變數:
定義 在==**一對{}**內的變數都是 區域變數==,無論是main函式還是普通函式,
全域變數:
==不定義 ==在main函式和其它函式內的都是**全域變數, **
注意
當全域變數與區域變數沖突時,遵從“區域變數優先原則 ”
3.2.6變數的作用域與生命周期————有效使用變數
區域變數:
1.作用域:在所創建位置的一對**{}內 **的==任何地方 ==都可以使用:
2.生命周期: 區域變數自創建的一對{}始 ,到出這對{}為止 ,這段時間為其生命周期; **
right:
a創建于最外面的{} ,所以main函式內 的任何地方都可以使用,
a創建于里面的{} ,所以里面{}內的任何地方 都可以使用,
error
思考
#include <stdio.h>
int main ( )
{
{
int a= 1 ;
printf ( "%d\n" , a) ;
}
printf ( "%d\n" , a) ;
return 0 ;
}
#include<stdio.h>
int main()
{
int a = 1;
{
int a=1;
printf("%d\n", a);
}
printf("%d\n", a);
return 0;
}
全域變數: 1.作用域:自創建到程式結束的任何地方都可以使用, 2.生命周期:自創建到程式結束為其生命周期,
3.2.7常量:
1.字面常量:血型,名字等
2.const修飾常變數(一旦const就不可更改 ):
#include<stdio.h>
int main()
{
const int a=19;
a=22;//變數一旦const就不可更改,重新賦值,
printf("%d",a);
return 0;
}
3.#define定義的識別符號常量
注意
1.define定義的宏常量不占用記憶體,它只會傻瓜式的語言替換,
分析 :
結果并不是20 ,而是12 的原因是:t=x+2*2;
4.列舉常量
當一個變數的所有可能 都可知 的情況下,我們常定義列舉常量;如性別,資料型別等
====c語言規定:列舉常量中的第一個常量在數值上是0,其它依次加1,如果人為的初始化第一個常量,其它常量任然依次加1. *
3.3字符與字串+轉義字符+注釋;
3.3.1.字符與字串:
字符:‘w’像這種由一對==‘ ’==所參考的字符,
字串:”name“像這種用一對” “所參考的連續字符,稱為字串,
因為c語言中沒有字串型資料,因此我們用字符陣列定義字串;
3.3.2.轉義字符:
補充:
1.在計算機中,為了方便字符型與實型資料間的運算,我們人為的規定每個字符 對應的一個十進制數,為此我們制定了ASII表
注意
常用轉義字符:‘\n’,’\t’,’\ddd’,’\xdd’;
注意
3.3.3.注釋
1.在c程式中我們想解釋自己的程式時,我們常使用“//”; 2.在c程式中我們想保留部分程式,不讓其起作用時,
注意
3.4 c語言的3種結構:順序,選擇,回圈,
3.4.1順序:一步一步執行代碼,
3.4.2選擇結構(分支陳述句):
注意
3.4.2.1 if陳述句
1.if陳述句的2種 形式
第一種
if(運算式){陳述句體}
else 陳述句體
第二種
if(運算式){陳述句體}
else if(運算式) {陳述句體}
…
else 陳述句體
注意
1.我們規定else 與最近的 if 匹配. 2.注意if陳述句體中的關鍵字 break,continue;
看題
#include <stdio.h>
int main ( )
{
int a = 0 ;
int b = 2 ;
if ( a == 1 )
if ( b == 2 )
printf ( "hehe\n" ) ;
else
printf ( "haha\n" ) ;
return 0 ;
}
思考這題的輸出結果
==答案:
什么都不輸出思考注意中的第一點
2 .switch陳述句:
1.switch陳述句的形式
switch(整形運算式)
{
case 整形常量運算式:陳述句;
…
}
注意
1.switch中的整形運算式不可以 為浮點型資料 ,但可以為,列舉型別(可以當作是整形常量),字符型資料 (計算機在碰到字符新資料時會將它自動轉化為整形 進行運算)(圖一 ) 2.case 中的必須為整形常量 ,或者是列舉型別(列舉也看以看作是一種特殊常量) 3.switch中的關鍵字 break 是用于分開陳述句塊 的,且不能使用 關鍵字continue ;(圖二 ) 4.當執行的case沒有break作為跳出switch時,其會==,默認==繼續執行下面的case,直到再次遇到break;(圖三) 5…雖然switch中的default 是默認選項 的意思,但使用時多留意其前面是否有 break ;再次體現第三點 的重要性 (圖四) 6.default 可以放在switch陳述句體內的任意位置
看圖——>
圖一
圖二
圖三
**
圖四
問題
#include <stdio.h>
int main ( )
{
int n = 1 ;
int m = 2 ;
switch ( n)
{
case 1 :
m++ ;
case 2 :
n++ ;
case 3 :
switch ( n)
{ //switch允許嵌套使用
case 1 :
n++ ;
case 2 :
m++ ;
n++ ;
break ;
}
case 4 :
m++ ;
break ;
default :
break ;
}
printf ( "m = %d, n = %d\n" , m, n) ;
return 0 ;
}
答案:
分析:(1)-》(2)-》(3)-》(4)-》(5)
(1)先執行外面的swtich,n為1,執行case 1,后m=3.因為其后無break,進行執行case, (2)執行case 2-》m=3,n=2. (3)執行case 3->,執行內嵌的switch中的case 2-》m=4,n=3,遇到break,跳出內部switch (4)執行case 4-》m=5.遇到break,跳出外部switch; (5)m=5,n=3;
3.4.3回圈結構:while,do while,for回圈;
1.while陳述句形式
while(運算式){陳述句體}
當運算式 為真 是,執行陳述句體.
2.do …while陳述句形式
do{陳述句體}while(運算式);
先 執行陳述句體 ,后判斷運算式
3.for陳述句形式
for(運算式1,運算式2,運算式3)
運算式1:
運算式1為初始化部分 ,用于初始化回圈變數 的,
運算式2:
運算式2為條件判斷部分 ,用于判斷回圈時候終止 ,
運算式3:
運算式3為調整部分 ,用于回圈條件的調整 ,
注意
1.while的執行條件 始終比回圈體 多一次 , 2.do while陳述句注意陳述句結束 要有分號"";“ ,且其回圈體 始終與運算式 執行次數一致, 3.brake只能跳出一層 回圈(當內回圈結構時,只能跳出內部一層回圈結構) 4.continue只能跳出本次 回圈,
練一練
列印9*9乘法表
for()形式
int main ( )
{
int i = 0 ;
int j = 0 ;
for ( i = 0 ; i < 10 ; i++ )
for ( j = 1 ; j <= i; j++ )
{
printf ( "%d*%d=%-2d" , i, j, i * j) ;
if ( j == i) printf ( "\n" ) ;
}
return 0 ;
}
分析:通過i控制行,j控制列.
while形式
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
int main ( )
{
int i = 1 ;
int j = 0 ;
while ( i < 10 )
{
j = 1 ;
while ( j <= i)
{
printf ( "%d*%d=%-3d" , i, j, i * j) ;
j++ ;
}
printf ( "\n" ) ;
i++ ;
}
return 0 ;
}
分析:外層回圈控制行,層控制列
do while形式
int main ( )
{
int i = 1 ;
int j = 0 ;
do
{
j = 1 ;
do
{
printf ( "%d*%d=%-3d" , i, j, i * j) ;
j++ ;
} while ( j <= i) ;
printf ( "\n" ) ;
i++ ;
} while ( i< 10 ) ;
return 0 ;
}
分析:外層回圈控制行,層控制列
3.5函式
背景:在一個main函式中,我們可以通過代碼的形式完成某些目的,但是這樣,main函式就會變得很長,為了盡可能的減少main函式的代碼長度,我們創建函式來完成這部分作業,
函式形式:
回傳值型別+函式名+(形參1,形參2,…)
#include <stdio.h>
int add ( int x, int y)
{
return x+ y;
}
int main ( )
{
int a = 0 ;
int b = 0 ;
int c = 0 ;
scanf ( "%d%d" , & a, & b) ;
c= add ( a, b) ;
printf ( "%d\n" , c) ;
return 0 ;
}
函式宣告形式:
回傳值型別+函式名+形式型別+”;“
#include <stdio.h>
int main ( )
{
int add ( int x, int y) ; //函式宣告
int a = 0 ;
int b = 0 ;
int c = 0 ;
scanf ( "%d%d" , & a, & b) ;
c= add ( a, b) ;
printf ( "%d\n" , c) ;
return 0 ;
}
int add ( int x, int y)
{
return x+ y;
}
注意
1.自定義的函式要有回傳值. 2.自定義的函式可以放在main函式的前面,或者后面(在后面的時候,要在main函式中提前宣告), 3.實參傳遞資料到形參時,引數型別要相同,不然會丟失部分資料,
3.7陣列
背景:如果我們想存盤一組數,我們一個怎么辦呢?這時候即需要c中的陣列;
3.7.1陣列的定義:
陣列元素型別+陣列名+【資料數量】;
int arr[ 10 ] = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 } ;
3.7.2陣列下標:
int arr[ 10 ] = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 } ;
陣列長度是10,下標從0~9 ;
3.7.3陣列的使用
#include <stdio.h>
int main ( )
{
int i = 0 ;
int arr[ 10 ] = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 } ;
for ( i= 0 ; i< 10 ; i++ )
{
printf ( "%d " , arr[ i] ) ;
}
printf ( "\n" ) ;
return 0 ;
}
注意
1.陣列下標小于陣列長度,且其最大值為陣列長度-1; 2.陣列名是陣列的首地址;
看題
下面程式有問題嗎?
#include <stdio.h>
int main ( )
{
int i = 0 ;
int arr1[ 10 ] = { 0 } ;
char arr2{ 10 } = { 0 } ;
char arr3[ 10 ] = { '0' } ;
printf ( "%d\n" , arr1[ 0 ] ) ;
printf ( "%c\n" , arr2[ 0 ] ) ;
printf ( "%c\n" , arr3[ 0 ] ) ;
return 0 ;
}
分析:
**arr1[0]被初始化為0;****arr2[0]被初始化為0;**arr3[0]被初始化為字符’0’; 0 對于int 型 就是數字 0,但對char ,在ASII表中是 空 的意思,即沒有任何意義, 字符=='0’對于char 型是 字串結束標志==,
3.8運算子
3.8.1算術運算子:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-WAlUqaiO-1626946061239)(初識c語言.assets/image-20210721180222696.png)]
注意
除法的2種情況: /的前后都是 整形資料 時,對結果取整 , /的前后存在 浮點數 時,結果就是浮點數 ,(圖一)
#include <stdio.h>
int main ( )
{
int a = 0 ;
int b = 0 ;
int c2 = 0 ;
float c2 = 0 ;
scanf ( "%d%d" , & a, & b) ;
c1= a/ b;
c2= a/ b;
printf ( "%d\n" , c1) ;
printf ( "%f\n" , c2) ;
return 0 ;
}
**
3.8.2位移運算子:
<<,左位移運算子
>>右位移運算子
它們移動的是補碼
補碼補充
1.計算機在記憶體中處理資料,都是按資料的補碼 形式進行運算的,最后以原碼 的形式表現資料, 2.正數與0的,原碼,反碼,補碼是一樣的, 3.負數的原碼 是按正數 編時的二進制原碼 ;反碼 是原碼除符號位 ,其它位取反 ;補碼 是反碼+1 ,
題目
#include<stdio.h>
int main()
{
int a=-1;
int b=-1;
printf("%d\n",a<<2);
printf("%d\n",b>>2);
return 0;
}
3.8.3位運算子:&,|,^
注意
運算子 功能 運算規則 & 按位與 對應位均為1時,才位1,否則為0 | 按位或 對應位存在1時就為1 ^ 按位與或 對應位相同為0,相異為1 << 左移 補碼左移若干位,超出丟棄(不包括1),剩下補0,每左移一位,相當于多乘2; >> 右移 補碼右移若干位,正數左補0,負數左補1,右邊溢位丟,
3.8.4賦值運算子:=,+=,-=,*=,/=,&=,|=,<<=,>>=
3.8.5單目運算子:
單目運算子表
單目操作福 功能 ! 邏輯反操作 - 負值 + 正值 & 取地址 sizeof 就型別長度(以位元組為單位) ~ 對一個數的補碼按位取反 – 前置:先自減,后應用;后置:先應用,后自鍵 ++ 前置:先自增,后應用;后置:先應用,后自增 * 間接訪問運算子(解應用運算子) (型別) 強制型別轉換
3.8.6關系運算子:
>,>=,<,<=,==,!=;
3.8.7邏輯運算子(雙目運算子 ):
邏輯運算子 功能 && 且,只有當2邊邏輯都為真是才為真 || 或,一邊為真即為真
3.8.8條件運算子
3.8.9逗號運算式:
exp1,exp2,exp3…
注意
逗號運算式的運算結果 以最后一項為準,
看圖
3.8.10下標參考[],函式呼叫(),結構體成員->.
3.9關鍵字
關鍵字 功能 auto 存盤類別說明關鍵字(區域變數) break 終止一層回圈 case swtich陳述句中的case char 字符資料型別說明關鍵字 const 將變數定義為長量 continue 結束本次回圈,直接執行下次回圈 default switch陳述句中,當沒有滿足case的情況,默認執行default陳述句 do do {}while();陳述句中的關鍵字 double 雙精度資料型別說明關鍵字 else 與最近if匹配的else分支陳述句 enum 列舉變數的說明關鍵字 extern 提前告知變數,函式等出現在別的檔案中 float 單精度資料型別說明關鍵字 for for的說明關鍵字 goto C語言中提供了可以隨意濫用的 goto陳述句和標記跳轉的標號, if 分支陳述句說明關鍵字 int 整形資料說明關鍵字 long 更大整形說明關鍵字 return 回傳某種型別的值,結束函式 short 短整形說明關鍵字 signed 有符號型說明關鍵字 sizeof 測定資料占記憶體空間的大小,單位位元組 static 靜態成員說明關鍵字(具體說明看下面) struct 結構體說明關鍵字 switch swtich分支陳述句關鍵字 typedef 重新定義資料型別別名 :typedef unint unsigned int union 聯合說明關鍵字 unsigned 無符號整形說明關鍵字 void 空型別說明關鍵字 while while陳述句說明關鍵字 register volatile
注意
在定義變數,函式名時不能使用關鍵字
3.9.1static:
1.修飾區域變數:延長 區域變數生命周期 ,不改變 其作用域 (圖一) 2.修飾全域變數:改變全域變數的外聯性(可被其它檔案使用,extern),使全域變數只能被本模塊使用, 3.修飾函式:改變函式的外聯性(可被其它檔案使用,extern),使函式只能被本模塊使用,
圖一
圖二
圖三
3.10#define定義宏常量和宏
#define+“空格”+宏常量名+常量 #define+“空格”+宏名+運算式
3.11指標
3.11.1記憶體:
記憶體是電腦上特別重要的存盤器,計算機中程式的運行都是在記憶體中進行的 ,所以為了有效的使用記憶體,就把記憶體劃分成一個個小的記憶體單元,每個記憶體單元的大小是1個位元組,為了能夠有效的訪問到記憶體的每個單元,就給記憶體單元進行了編號,這些編號被稱為該記憶體單元的地址,
3.11.2記憶體是怎么被編號的?
我們知道32位計算機有32根物理地址線(通過地址線,尋找相應地址的資料),在通電時,每根電信號被轉化為1/0,而這樣的32跟地址線,可形參232 種不同的32為位二進制編碼,二232 位元組換算成G時為4G,在32為系統4G記憶體足夠了,因此以這 232 種二進制(其實是將二進制轉化為16進制,編號記憶體的)為編號剛好,(另外通過增加地址線的方法,可以增加記憶體)
3.11.3地址的存盤
3.11.4指標變數:
3.11.5指標的大小:
前面我們知道,32系統下的32為地址線,通過32位二進制編號記憶體,所以在記憶體中我們存盤一個地址時需要4個 位元組的記憶體單元,即32位 下指標大小為4位元組 ,同理64位系統下,指標大小為8位元組
3.11.6補充
我們在定義變數時,隨機 存盤在記憶體中,當程式結束時,變數記憶體釋放,每次運行,變數都隨機存盤于記憶體中,
3.12結構體
前言
對于人這個抽象概念,我們很模糊,但我們具體到某個人時,他的名字,性別等,做為他的具體屬性被我們知道,
因此我們定義結構體,用于對具有共同屬性的一類事物的 抽象
3.12.1結構體定義:
struct+結構體名
{
屬性1;
屬性2;
…
};
注意
1.定義結構體不可丟關鍵字struct 2.結構結尾的分號不能丟
3.12.2結構體陣列:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ODXlbe3k-1626946061259)(https://gitee.com/wonderland-nordlin/photo/raw/master/照片/.keep/image-20210721222910635.png)]
感言:
1.對目前c語言的有些地方學的不深,不敢過多描述,哈哈,
2.在這段學習中,我會了一些小游戲,由其是關機程式,賊有意思!哈哈,后面會補上的,
3.《高質量的c-c++編程》PDF版鏈接:鏈接:https://pan.baidu.com/s/1yW6FgsZDqeOtVzePrdZk_Q
提取碼:2021