c语言使用CodeBlocks软件,使用CodeBlocks学习C语言
目錄
正文
一、C語言的優缺點
C語言是面向過程的程序設計語言,一門“死而不僵”的語言,優點是穩定、可靠、通用性極強,但是對大型程序來說面向過程的語言使用起來會比較麻煩。
1.從命令行獲取輸入內容
使用函數scanf("XX0XX1...",&YY0,&YY1,...)。其中&表示獲得數據的地址,獲取數據后放到這個地址中,XX是一般的數據類型比如%d、%o等,YY是要賦值的對象。使用轉換說明%nXX也可以限制接收的個數,比如%7s、只接收7個字符裝入字符串中。
2.輸出內容到命令行
使用函數printf("%m.nXX0",XX1)。m表示占位個數、包括小數點的位置,少于實際長度將顯示全部內容、多出實際長度將用空格填充(正數空格左填充,負數空格右填充),n表示取值個數(數值類型取小數點后邊幾位,字符串表示先取幾位、后填充),之后按照這個格式輸出;XX0是常見數據類型,比如%o八進制、%x十六進制、%e指數形式、%g自動選擇、%u無符號整形、%s字符串(此時的n可以控制字符串輸出的位數),另外可以外加\n換行等轉義字符。
3.C99輸出的奇怪數
-1.#INF00負無窮、1.#INF00正無窮、NaN非數
1.順序、條件、循環語句
一般是順序語句,程序從上到下、從左到右順序執行;條件語句可以跳轉,用if、else進行條件的判斷,不過要注意的是這種特殊情況switch_case。表達式具有某個常量返回值,當符合case的常量時執行后邊的語句塊;如果需要跳出switch,在相應的case語句塊后面加上break即可,否則程序會在符合的地方一直執行下去。
switch(表達式)
{
case 常量: 語句塊
case 常量: 語句塊
default: 語句塊
}
先判斷條件,符合后執行循環體;可以不執行循環體
while(表達式)語句;
先執行循環體,在判斷條件,如果滿足繼續執行循環體;至少執行一次循環體
do 語句 while(表達式);
如果知道循環的具體范圍,多數情況下都用for循環;表達式1做初始化用、表達式2是條件、表達式3一般用做自增自減
for(表達式1;表達式2;表達式3)語句
2.表達式
表達式就是一個可以運算的式子,容易出錯的地方是運算符優先級:
優先級
運算符
0
() [] .
1
! 正+ 負- ~ ++ -- *指針取地址內容
2
* / %
3
加+ 減-
4
<< >> >>>
5
< <= > >= instanceof
6
== !=
7
按位與&
8
^
9
|
10
&&
11
?:
12
= += -= *= /= % = &= |= ^= ~= <<= >>= >>>=
1.常規數據類型
(1)定義和修飾
除下表外其他數據類型修飾字:%o八進制,%x十六進制,%g自動選擇格式不輸出無意義的0
數據類型/數據類型限定字
格式化輸入輸出表示
大小
short或usigned short
%h其他
char
%c
字符型,占2個byte;1個byte占4個bit位
char *
%s
字符串,本身占4個byte
int
%d或%i
整形,占4個byte位
long
%ld
長整形,占4個byte位
unsigned
%u
無符號整形,占4個byte位
float
%f
單精度浮點數,占4個byte位
double
%lf
雙精度浮點數,占8個byte位
long double
%Lf
%n
記錄%n出現之前的所有字符數
static
static的變量只初始化一次;
語句塊外聲明static,表示該變量只在聲明它、包含它的文件可見;
語句塊中聲明static,這個變量在程序徹底結束前都不會丟失數據
const
常量
volatitle
數據是易變的,每次數據都必須從內存中獲取、不允許編譯器做優化
extern
extern聲明的變量不會即刻分配空間
register
希望將變量存儲到寄存器中
(2)整型補充
整型和整型的除法得到的結果不等于理論值,而是對理論值的絕對值向下取整;數值類型的排序使用sort()會方便很多(默認從小到大排列,也可以自定義,需要頭文件algorithm.h),比如sort(a,a+10,cmp);,對象a可以是數組也可以是其他含有數據的容器、cmp是自定義的函數。
(3)字符型補充
字符型變量可以用整形的方式讀出,得到的是它的ASII碼值,小寫字母的ASCII碼減去大寫字母的ASCII碼值為32
① 字符轉義序列
名稱
轉義序列
警報
\a
換行符
\n
回車符
\r
水平制表符
\t
垂直制表符
\v
反斜杠
\\
問號
\?
單引號
\’
雙引號
\”
回退符
\b
換頁符
\f
② 比較實用的函數
函數
頭文件
作用
參數及說明
toupper(‘XX’)
將XX轉大寫
XX是字符
tolower(‘XX’)
將XX轉小寫
XX是字符
getchar()
從命令行接收一個字符
速度上比scanf要快
getch()
同步接收一個字符
解決“一閃而過”的問題
putchar(XX)
在命令行上打印一個字符
速度上比printf要快
sizeof(XX)
獲取數據類型在內存中的字節大小
XX是任意一種數據類型
2.聯合、枚舉
union聯合,它的內存空間是共用的,最終內存的大小取決于最大的那個對象;enum枚舉,同一個作用域內如果對象對應里面的值,相當于得到里面的編號、編號從0開始,枚舉對象可以是里面的任意值。
3.自定義的數據類型
C中的自定義數據類型指的是結構體struct,C++中還包括類;結構體名稱就是類型的名稱,訪問里面元素可以點取,如果是結構體指針,還可以用箭頭獲取;結構體別名可以對結構體提前聲明或定義,也是結構體的另一種名字,有別名的結構體可以像使用內置變量一樣使用它。
(1)定義和初始化
struct
{
屬性序列
}別名0或別名0初始化,別名1或別名1初始化...;
或者
struct 結構體名稱
{
屬性序列;
}別名0或別名0初始化,別名1或別名1初始化...;
或者
typedef struct 結構體名稱
{
屬性序列;
}別名0,別名1,...;
struct 結構體名稱 自定義變量{屬性序列對應的值};
指針pointer可以理解為地址序列的首地址,但是指針自身有一個用來區別其他指針的地址;加*表示讀出地址中的數據、加&表示取地址,進入下一個地址pointer++或者++pointer。
1.指針的賦值
int i=8848;
int *p=&i;
或者
int i=8848;
int *p;
p=&i;
2.分配內存空間
可以用malloc()或者calloc()來分配空間、 calloc()將清空空間中的內容,用realloc()可以重新改變分配空間的大小而盡量不改變其中的內容,最后用free()釋放這些空間;全局的指針malloc后需要顯式調用free來銷毀,比如作為類(C++)或者結構體屬性的變量,局部分配的指針可以由編譯器自動銷毀;其中:
堆:用戶申請的內存空間,如果不注意管理會在程序運行中造成內存泄漏,程序結束后才被系統回收
棧:分配局部變量空間
只讀存儲區:為常量、程序代碼分配空間的地方
3.指針的用途
(1)數組元素是指針
比如char* planets[],這是個很特殊的數組,數組的每個元素都是char*也即字符串,很明顯每個元素的長度可以不同。
(2)指向指針的指針
倘若二級指針p分配有足夠的內存空間,那么訪問i行j列就是*(*(p+i)+j),意思是二級指針p偏移i個單位、取地址得到一級指針,一級指針偏移j個單位、最終取地址中的數據。
(3)指向函數的指針
函數名是它自己的函數指針,函數指針比如double (*f)(double),如果函數也類似這樣的形式、這個函數指針f就可以指向它;函數指針也可以做成數組,比如void (*file_cmd[])(void)={new_cmd,open_cmd,close_cmd},花括號中是定義過的函數,然后就像正常使用函數一樣的使用file_cmd。
(4)受限指針
在一些底層文件上會看到受限指針,比如int* restrict p;,表示被指向的對象只允許p指針對它操作。
const int* p,const在*左邊,表示內容*p不能改變但是p的指向可以再變,這種情況做參數的時候比較常見;
int* const p,const在*右邊,表示p的指向不能改變、一般在定義的時候就初始化了;
const后面的變量不能做左值、也不能做函數返回值,反之可以做左值或返回值;
const的數據可以賦值給非const的數據,如果是指針這會造成安全隱患!(C++中不允許這樣的賦值)
4.引用
C中沒有引用專門的內容,不過有必要補充下。當遞歸含有參數并且這個參數需要統一的時候,C++可以用引用來唯一指代這個對象,避免每一級遞歸都修改參數最終無法統一;C的一個解決辦法是將這個參數定義為全局變量。
1.用法
以一個程序為例,獲取本地時間并格式化輸出;其他更詳細的介紹可以查閱參考文檔。
time_t obj;
time(&obj);
struct tm* bag=localtime(&obj);
char str[30];
strftime(str,30,"%Y-%m-%d %H:%M:%S",bag);
printf("%s\n",str);
C中的字符串變量就是字符串數組,這個數組的末尾裝了空字符’\0’。
1.字符串的書寫
如果字符串過長可以在句子后加\,換行從頭書寫;或者在句后加”,換行再加上”,這是用空白字符串做拼接、是更好的做法。
2.字符串的賦值
C允許對字符串取下標,就像數組一樣;另外注意總需要留出一個位置給空字符。用sizeof()可以求出數組的真實長度。
char p[]="june 14";
char k[]={'j','u','n','e',' ','1','4','\0'};
const char* p=”abc”;
printf("%c\n",p[1]);
printf("%c\n",”abc”[1]);
3.字符數組和字符指針
char data0[]=”june 14”;
char* data1=”june 14”;
前者可以修改”june 14”中的內容,后者不可以,因為它沒有分配內存空間。一種做法是字符指針指向已有的數組,另一種做法是為指針動態分配內存空間。
4.字符串的讀寫
scanf、gets可以實現讀,gets與scanf不同的是它不會跳過空白字符、而且一定要注意輸入的字符個數限制;
printf、puts可以實現寫,puts與printf不同的是會在輸出后自動添加換行符。
5.C語言的字符串庫
#include ,函數的具體使用方法可以查看api文檔
strcpy
字符串復制
strlen
字符串的長度,即字符串數組的實際長度-1
strcat
字符串的拼接
strcmp
字符串比較,返回0表示相等、1表示大于、-1表示小于
1.輸入輸出重定向
將文件作為輸入傳遞給應用程序,或者將程序的輸出保存到文件,比如demo是一個應用程序:
demo
demo >out.dat
>和
2.文件輸入/輸出流
以寫方式打開的文件不管打開是否成功最后都要關閉
(1)比較實用的函數
tmpfile
產生臨時文件
fopen
打開文件
fclose
關閉文件
fflush
清理緩沖區
remove
刪除文件
rename
重命名文件,文件是已經關閉了的
fprintf
對流格式化的輸出,比如對stderr錯誤流輸出
fscanf
從流中讀出數據,成功返回1
feof
返回非零的值表明流中設置了文件末尾指示器
ferror
返回非零值表明設置了錯誤的指示器,也即讀錯誤
tmpnam(null);
返回一個無重復的文件名
(2)文件的讀寫模式
帶有+的模式從讀轉到寫需要使用fflush()或者文件定位函數;二進制的文件讀寫模式在下面的基礎上加上b,意思不變。
r
只讀,文件不存在會出錯
w
只寫,文件不存在會新建
a
追加
r+
讀和寫,從文件頭開始
w+
讀和寫,將覆蓋原有內容
a+
讀和寫,文件存在就追加
(3)掃描集
在類似scanf()的函數中可能會用到,scanf()是一個匹配的函數,會根據輸入和掃描集匹配接收一些值。
掃描集默認各元素默認以空格作分隔;%*屏蔽與它相鄰的后一個元素;%[集合]匹配出現在集合中的情況;%[^集合]匹配不在集合中的情況。
(4)文件內容的定位
fseek
設置文件位置
ftell
以長整型返回當前文件位置
rewind
文件位置設置在起始位置,同時清除錯誤指示器
fgetpos
超大文件中設置文件位置
fsetpos
超大文件中獲取文件位置
(5)字符形式的輸入輸出
fputc、fgetc
輸入輸出,只做函數調用
putc、getc
輸入輸出,像宏一樣調用、速度要快
putchar、getchar
標準輸入輸出
(6)字符串形式的輸入輸出
puts、gets用于標準輸入輸出流,puts會自動添加上換行符;fputs、fgets對流不挑剔,使用范圍會更廣些。
(3) 塊形式的輸入輸出
fread、fwrite主要用于二進制流,比如結構體讀寫,返回值表示的是實際讀入或寫入的數量。
3.字符串輸入/輸出流
可以做格式化輸入輸出或者數據類型轉換,其他類似的函數有atoi()、atof()、atol()、atoll()、itoa()、ltoa(),但是功能并沒有這么強大
sprintf(str,”%ld”,31415926);
將數字輸入到字符串str
snprintf(str,25,”%ld”,31415926);
將數字輸入到字符串str,實際大小不會超過限定的數目
sscanf(str,”%d”,&a);
將數據str給某變量a
1.宏定義
和預處理有關,預處理器:在編譯前處理C程序,主要是宏定義、條件編譯、文件包含,預處理器和編譯器是不同的程序;預處理指令是以#開頭的一些命令,它可以出現在程序的任何地方;預處理指令總是一行一行的定義,如果需要換行用\字符
(1)預定義宏,編譯器中已經定義過的宏
__func__
正在運行的函數的名字
__DATE__,__TIME__
編譯的時間
__FILE__
被編譯的文件名
__STDC__
是否支持C89或C99標準
(2)自定義定義宏
#undef 標識符可以取消某個標識符的定義,之后就可以更新標識符的定義
//標示符后面非注釋的部分都是要替換的內容
#define 標識符 替換列表
//帶參數的情況,為避免出錯,替換列表需要括號,替換列表中的參數每次出現都需要括號;宏沒有參數類型,可以接收任何類型的參數,但是無法用指//針指向一個宏、因為預處理后宏會被刪除掉;盡量避免使用帶有副作用的參數比如++、--,因為這樣的宏更容易出錯
#define 標識符(x1,x2,…,xn) 替換列表
動態參數,__VA_ARGS__表示的就是…的部分
#define TEST(condition,…) ((condition)?printf(“Passed test: %s\n”,#condition):printf(__VA_ARGS__))
(3)#和##運算符
#運算符,將后一個元素轉化成字符串
#define PRINT_INT(n) printf(#n “=%d\n”,n);
//這個調用等價于 printf(“i/j=%d\n”,i/j);
PRINT_INT(i/j);
##運算符,將參數和其他元素連接在一起,可以制作函數模板(C語言沒有重載函數,但是可以得到近似的)
#define MK_ID(n) i##n
//等價于int i1,i2,i3;
int MK_ID(1),MK_ID(2),MK_ID(3);
(4)連接較長的宏
//連接表達式
#define 標識符 (表達式0,表達式1,…,表達式n)
//連接語句
#define 標識符 \
do{ \
語句0; \
語句1; \
…
語句n; \
}while(0)
(5)條件編譯
#ifdef、#ifndef可以判斷這個宏是否被定義過,這樣就可以給這個宏設置一些默認的值
#if 表達式1
表達式1為真時的代碼
#elif 表達式2
表達式2為真時的代碼
#elif 表達式3
表達式3為真時的代碼
…
#else
其他情況的代碼
#endif
(7)其他指令
//編譯器定義過的特殊功能
#pragma 記號
2.數的進制
0x
16進制,比如0x00ff,每一位表示4個bit位
3.運算符
考慮到可移植性,最好僅對無符號數(比如unsigned short)進行移位運算
<<
左移位
>>
右移位
~
按位取反
&
按位與
^
按位異或
|
按位或
|=
設置某一位的值,比如i |= 0x0010把對應位設置為1
&=
清除某一位的值,比如i &= ~0x0010把對應位設置為0
(1)操作二進制某一位
i |= 1<
從右往左、將i的對應位置為1,j從0開始
i &=~(1<
從右往左、將i的對應位置為0,j從0開始
if(i&(1<
測試i的對應位置是否為1,j從0開始
(2)操作位域
顧名思義,就是操作遺傳二進制序列
示例
說明
i = i &~0x0070 | j<<4
先清除4到6位的值,然后將4到6位的值置為j
j = (i>>4) & 0x0007
獲取4到6位的值
1.頭文件、源文件
頭文件指.h文件、源文件指.c文件,頭文件只是聲明、源文件具體來定義
2.將程序分為多個文件
對于較復雜或者龐大的程序來說這是很有用的,頭文件中雖然也可以寫定義的內容,但是最好只寫聲明、將具體的定義交給源文件。
3.引入文件
#include
搜尋系統頭文件所在的目錄
#include “文件名”
先搜尋當前目錄,再搜尋系統頭文件所在的目錄;文件名中可以有相對路徑
#include 標記
這個“標記”是用#define定義的
布爾值:C89中沒有布爾值,一種做法用0和1代替變量的真和假,但是并不直觀;另一種做法是宏定義,#define TRUE 1、#define FALSE 0;C99對此有了進一步的/改進,提供了專門的數據類型_Bool,但是這個布爾值是用整型數據來代替的;除_Bool外,C99提供了一個新的頭文件,更容易的使用布爾變量。
函數
頭文件
說明
assert(條件語句);
#include
異常處理,條件語句為真才能通過“測試”
_findfirst(const char*,struct _finddata_t*);
_findnext(intptr_t,struct _finddata_t*);
_findclose();
#include
獲取某個目錄下的文件名及文件,不是標準庫文件、但是為核心庫提供支持。
ctrl+d
復制行或者選中塊
ctrl+滾輪
放縮內容大小
ctrl+shift+c
注釋行或者選中塊
ctrl+shift+x
反注釋行或者選中塊
ctrl+l
刪除行或者選中塊
ctrl+g
到達指定行
ctrl+j
自動補全框架
ctrl+pgup
到達上一個函數
ctrl+pgdown
到達下一個函數
ctrl+r
替換內容
alt+拖動
拖動選中的內容
alt+鼠標選中
編輯列
f10
全屏
f5
添加/去除斷點
f7
next line
f8
debug
f9
編譯運行
ctrl+b
加書簽
alt+pgup/pgdn
到上/下一個書簽的位置
2.程序的調試方法
可以點擊continue/debug來快速檢測循環內關鍵步驟的執行,另外使用一定的條件語句、減少測試的規模都可以調試數據規模比較大的程序,這是很有意義的;Debug會顯示這個作用域之內的所有變量的值,但是不能直接顯示出指針和表達式的數據
① 確定語法上沒有錯誤,再考慮使用Debug來檢測錯誤
② 聲明用于測試的變量,下劃線加上要測試的對象名字,之后把它們添加到需要測試的地方
③ 在函數開頭、循環開頭添加斷點,可以方便的對這些地方進行測試,不想測試的時候也可以跳出
④ 運行Debug,跟蹤最新變量的變化是否正確
⑤ 測試結束后,刪除所有用于測試的變量
(2)宏定義結合printf
直接使用printf是可以的,但是對測試部分的代碼每次都要刪除添加,比較麻煩;優點是簡單粗暴、適用范圍廣
//DEBUG的值為1表示測試,為0表示取消測試
#define DEBUG 1
//嵌入代碼之中
#if DEBUG
測試用的代碼
#endif
3.命令行的緩沖區大小和窗口大小
緩沖區大小是實際容納內容的大小,如果某一方向的緩沖區大小大于窗口大小對應方向就會出現滾動條;窗口大小就是視覺上看到的窗口的大小。
總結
以上是生活随笔為你收集整理的c语言使用CodeBlocks软件,使用CodeBlocks学习C语言的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 立体匹配十大概念综述---立体匹配算法介
- 下一篇: 三星固态硬盘 SM951 NVME wi