Linux c語言
- 一、Linux基礎
- 1.1、Linux環境搭建
- 1.2、Linux基礎
- 1.3、終端命令
- 二、vi編輯器
- 2.1、vi編輯器
- 2.2、GCC編譯工具
- 2.3、存盤器
- 三、C語言基礎
- 3.1、基本c語言程式結構
- 3.2、進制之間的轉換
- 3.3、關鍵字
- 3.4、資料型別
- 3.5、識別符號
- 3.6、分格符
- 3.7、運算子
- 3.8、資料型別
- 3.9、變數
- 3.10、輸入輸出
- 3.11、轉換、三目運算子
- 四、 判斷、回圈、跳轉
- 4.1、if els
- 4.2、switch
- 4.3、while
- 4.4、for
- 4.5、goto
- 五、陣列
- 5.1、一維陣列
- 5.2、二維陣列
- 5.3、一維字符陣列
- 5.4、二維字符陣列
- 六、指標
- 6.1、指標
- 6.2、二級指標
- 6.3、指標與一維陣列
- 6.4、指標與二維陣列
- 六、函式
- 6.1、函式
- 6.2、陣列的傳參
- 6.3、指標函式
- 6.4、函式指標
- 6.5、遞回函式
- 七、結構體
- 跳轉:下一篇、Linux c高級
統一宣告:
博客轉載 聲 明 : 本博客部分內容來源于網路、書籍、及各類手冊,
????????內容宗旨為方便查詢、總結備份、開源分享,
????????部分轉載內容均有注明出處,如有侵權請聯系博客告知并洗掉,謝謝!
百度云盤提取碼:統一提取碼:ziyu
一、Linux基礎
1.1、Linux環境搭建
1.4.1、Linux環境搭建
如果沒有Linux環境先安裝虛擬機和Ubuntu
轉載 最新超詳細VMware虛擬機下載與安裝 鏈接:https://blog.csdn.net/qq_40950957/article/details/80467513
轉載 VMware虛擬機安裝Linux系統(詳解版) 鏈接:http://c.biancheng.net/view/714.html
Ubuntu系統 下載 鏈接:https://cn.ubuntu.com/download
Ubuntu低版本可能不能上網下載,可以推薦我配置好的 Ubuntu 64_20.04 可上網高版本,直接解壓打開使用VM打開即可,

Ubuntu 64_20.04 阿里云鏈接:https://www.aliyundrive.com/s/DWUDBP5KZsU
Ubuntu 64_20.04 百度云鏈接:https://pan.baidu.com/s/1OEYYSHQ1eTVJE-iHjWb7WQ
1.2、Linux基礎
打開ubuntu
普通用戶:farsight 密碼:1
超級用戶:root 密碼:1
/:根目錄
~:家目錄 == /home/farsight
$:命令提示符 普通用戶 #超級用戶
打開終端:
直接點擊圖示 terminal
快捷鍵:ctl+alt+t //打開新終端
右鍵:open terminal //再打開
ctrl+shift+n //打開
ctrl+shift+t //并列打開,打開一個標簽
調節字體:ctrl+shift+‘+’ //調大字體
ctrl+‘-’ //調小字體
1.3、終端命令
終端命令:
pwd:顯示當前所在的路徑
ls :查看當前目錄下的檔案
ls -a:顯示隱藏檔案
ls -l:顯示目錄的詳細資訊
drwxrwxr-x 11 farsight farsight 4096 Jul 31 2020 desktop
d:目錄檔案,檔案夾
rwx rwx r-x:檔案權限
11 :檔案的硬鏈接數
farsight:用戶組名
farsight:用戶名
4096:檔案大小 以 位元組為單位
Jul 31 2020:檔案創建時間
desktop:檔案名
clear :清屏操作 快捷鍵:ctl+‘l’
mkdir+檔案名 :創建一個新的目錄檔案
mkdir -p:遞回創建
cd :跳轉
. :當前目錄
.. :上級目錄
touch:創建一個普通檔案,一般加后綴
更新時間戳
mv 檔案名1 檔案名2 //將檔案重命名為檔案名2
mv 檔案名1 路徑 //移動檔案到路徑下
檔案路徑不同,起到移動的作用,檔案名在移動后的路徑下沒有,檔案路徑相同,重命名
rm:洗掉普通檔案
-r:洗掉目錄檔案
mdir:安全洗掉空檔案,非空時警告
man 手冊
man 1:普通命令
man 2:系統呼叫
man 3:庫函式
絕對路徑:從根目錄出發,一直到指定的目錄
相對路徑:相對于當前位置
gedit test//類似于文本檔案
cat:查看檔案內容
-b:加行號顯示
-s:合并多空行
cp 檔案名1 檔案名2 //復制普通檔案1到檔案2
-r 檔案名1 檔案名2//復制目錄檔案1到目錄檔案2
練習:
1、用相對路徑的方式,切換到上一級的上一級目錄
cd ./../../ cd .. cd ..
2、用絕對路徑的方式,切換到根目錄下的usr下的include目錄
cd /usr/include
3、在家目錄下創建一個school,再在該目錄下創建兩個目錄 class1 class2
mkdir -p school/class1 school/class2
4、在class1中創建兩個普通的檔案
touch day1.txt test.txt
二、vi編輯器
2.1、vi編輯器
vi編輯器:
剛進入時在命令列模式下:
進入插入模式(進行編輯):
i o a I O A
i:從游標的當前位置開始編輯
a:從游標的后一個位置開始編輯
o:從游標的后一行位置開始編輯
I:從游標當行 第一個位置開始編輯
O:從游標當行 前一行位置開始編輯
A:從游標當行 最后一個位置開始編輯
回到命令列模式:Esc
進入底行模式:shift+“:”
:w //進行保存
:q //退出
:wq //保存并退出
:x //保存并退出
:q!//強制退出
:wq!//強制保存并退出
命令列模式下:
dd //洗掉游標所在行
ndd //洗掉游標向下的n行
yy //復制游標所在行
nyy //復制游標向下的n行
p //粘貼到游標所在的下一行或下一個
P //(大寫P)粘貼到游標所在的前一行或前一個
r //改變游標所在的字符,只改變一次
R //改變游標所在的字符,Esc退出
x //剪切或洗掉游標所在的一個字符
X //剪切或洗掉游標所在的前一個字符
s //洗掉游標所在的字符,并進入插入模式
S //洗掉游標所在的行,并進入插入模式
u //撤銷
ctrl+r //反向撤銷
底行模式:
:s/str1/str2 //將str1替換成str2 替換游標所在行的第一個
:s/str1/str2/g //將str1替換成str2 替換游標所在行的所有
:%s/str1/str2/g //將str1替換成str2 替換全文
:%s/str1/str2 //將str1替換成str2 替換全文第一個
:n,ms/str1/str2 //將str1替換成str2 替換n到m行的第一個
:n,ms/str1/str2/gc //將str1替換成str2 替換n到m行的第一個
:n,my //復制n到m行
:n,md //洗掉n到m行
:set number //顯示行號
:set nonumber //隱藏行號
vi/vim 檔案不存在時會自動創建
2.2、GCC編譯工具
GCC編譯工具:
gcc test.c //默認生成a.out可執行檔案
gcc test.c -o test //將生成可執行檔案命名為test
gcc -o test.c test
編譯運行的四個步驟:預處理、編譯、匯編、鏈接
預處理:處理頭檔案、宏定義等,不進行錯誤檢查
gcc -E test.c -o test.i
編譯:將預處理的檔案進行處理,檢查錯誤,生成匯編檔案
gcc -S test.i -o test.s
匯編:將匯編檔案編譯生成機器語言 二進制檔案
gcc -c test.s -o test.o
鏈接:生成可執行檔案
gcc test.o -o test
2.3、存盤器
存盤器:用來存放程式和資料,
程式和資料在計算機中都是以二進制的形式存放存盤器中
存盤容量的大小是以位元組為單位度量,經常用KB、MB、GB、TB
1KB = 1024B 1GB = 1024KB 1TB = 1024G
(1)存盤器分為記憶體儲器(主存盤器)和外存盤器(輔助存盤器)
記憶體 在計算機中,直接和運算器、控制器交換資訊
容量小、存取速度快
外存 間接和cpu聯系,存放一些必須使用但又不急于使用的程式和資料
程式必須調入記憶體中才能執行
程式:系統可以識別的指令,存盤在 磁盤上 ,執行時 從磁盤 到記憶體 再到暫存器 最后被cpu執行
三、C語言基礎
3.1、基本c語言程式結構
#include<stdio.h> //預編譯命令
int main(void)//主函式名 int 函式回傳型別
{
return 0;//回傳值 必須和函式資料型別匹配
}
return 0;//默認 正常結束
return -1;// 例外結束
數值資料:
數制的數:按位權展開的多項式的和
3.2、進制之間的轉換
(1)十進制
基數:10 (0 1 2 3 4 5 6 7 8 9)
位權:數字權位的大小
eg:123 = 1*10^2+2*10^1+3*10^0
3 10^0 位權:1
2 10^1 10
1 10^2 100
(2)二進制
一般形式:0b111000
基數:2 (0 1)
位權:101 = 1*2^0+0*2^1+1*2^2 = 5
xx1 : 2^0 位權:1
x0x : 2^1 位權:2
1xx : 2^2 位權:4
1 2 4 8 16 32 64 128 256 512 1024
二進制轉十進制:每一位數乘位權 相加
十進制轉二進制:a:短除法 b:湊數法
(3)八進制:
一般形式:01101000
基數:8 (0 1 2 3 4 5 6 7 )
位權:1 8 64 512
eg:0101
八進制轉十進制:1*8^0+0*8^1+1*8^2+0*8^3 = 65
十進制轉八進制:a:短除法 b:湊數法
八進制轉二進制:a:一位八進制 轉成 三位二進制
eg:0234 0b 010 011 100
b:先轉成十進制 再轉成二進制
(4)十六進制
一般形式:0x110101
基數:16 (0 1 2 3 4 5 6 7 8 9 A B C D E F)
位權:1 16 256
十六進制轉十進制:按位權相加
十六進制轉二進制:a:一位十六進制 轉成 四位二進制
eg:0x234 0b 0010 0011 0100
二進制轉十六進制:四位二進制轉成一位十六進制
eg: 0b0001 1001 0100 0x194
二進制:0b
八進制:0
十六進制:0x
位(bit):計算機中存盤資料的最小單位
位元組(Byte):存盤容量的度量單位,資料處理的基本單位
1個位元組的存盤空間 稱為 一個存盤單元
1Byte = 8 bit
ubuntu 32位 ----4位元組
計算機中非數值資料
printf("hello!\n");
ASCII碼:
0 null('\0')
10 '\n'
48 '0'
65 'A'
97 'a'
122 'z'
32 空格
‘A’--->'a' 'A'+32
'9'--->9 '9'-'0' '9'-48
詞法符號:程式設計語言中有若干字符組成的有意義的 最小語法單位
3.3、關鍵字
按作用分類:關鍵字、識別符號、分隔符、運算子、標點符號
關鍵字:32個
auto:宣告自動變數 一般不使用
double:宣告雙精度的變數或函式
int:宣告整型的變數或函式
struct:宣告結構體變數或函式
break:跳出當前回圈
if:條件陳述句 肯定分支
else:條件陳述句 否定分支
long:宣告長整型的變數或函式
switch:用于多分支
case:開關陳述句分支
enum:宣告列舉型別
register:宣告暫存器變數
typedef:用來給資料型別取別名
char:宣告字符型的變數或函式
extern:看成參考
return:子程式中回傳陳述句(可以帶引數,也可以不帶)
union:宣告聯合資料型別
const:宣告只讀變數
float:宣告浮點型的變數或函式
short:宣告短整型的變數或函式
unsigned:宣告無符號型別的變數或函式
continue:結束當前回圈,開始下一輪回圈
for:一種回圈陳述句
signed:宣告有符號型別的變數或函式
void:宣告函式無回傳值或無引數,宣告無型別的指標
default:開關陳述句的其他分支
goto:無條件的跳轉
sizeof:計算資料型別的長度
volatile:宣告變數在程式中可以被隱含的改變
do:回圈陳述句中的回圈體
while:回圈陳述句中的回圈條件
static:宣告靜態變數
3.4、資料型別
基本資料型別:char、short、int、long、float、double
存盤型別(有符號、無符號):signed、unsigned、static、register、extern、const、volatile、auto
陳述句:if、else、for、while、do、goto、switch、case、default、break、continue、return
構造:union、struct、enum、
求位元組:sizeof
取別名:typdef
空型別:void
3.5、識別符號
程式員按照命名規則自行定義的詞法符號
命名規則:
1、由字母、數字、下劃線(_)組成
2、不能和關鍵字重名
3、只能由字母或下劃線開頭
識別符號的命名方式:
見名知意
駱駝命名法:混合大小寫字母構成變數名或函式名
小駝峰:
常用于變數
eg:myFirstName
大駝峰(帕斯卡命名法):
常用于類名、函式名
eg:DataBaseUser
下劃線命名法:
eg:print_students_count();
linux下嚴格區分大小寫!
3.6、分格符
空格 ‘ ’ 32
換行 ‘\n’ 10
制表符 '\t' 9
注釋:1、/*提示資訊,注釋一段內容*/
2、//注釋一行內容
3、#if 0
中間內容被注釋
#else
中間內容正常執行
#endif
#if 1
中間內容正常執行
#else
中間內容被注釋
#endif
3.7、運算子
運算子:算數、關系、邏輯、位
根據運算元不同,分為單目運算子、雙目運算子、三目運算子(?:)
算術運算子:+ - * / % ++ --
注:i++和++i的區別
關系運算:< > >= <= != ==(判斷是否相等)
int a = 3;
int b = 4;
(a>b) 0
(a<b) 1
(a!=b) 1
(a==b) 0
邏輯運算子:&&(與) ||(或) !(非)
邏輯:0 為假,非0 為真
&&:兩邊為真才為真,只要有一邊為假就為假
||:只要有一邊為真,就為真
兩邊為假才為假
!:真偽互換
位運算:&(按位與) |(按位或) ~(按位取反) ^(異或) <<(左移) >>(右移)
異或:相異為1 相同為0
左移:右邊補0 右移:左邊補0
1110 0101 << 2 1001 0100 1110 0101 >> 2 0011 1001
位運算的一般用法:對指定位清0 置1
//位運算的位置從0 開始計數
(1)對指定位清0
eg:對i的第2位清0 i=i & ~(1<<2)
(2)對指定位置1
eg:對i的第5位置1 i=i | (1<<5)
賦值運算子:= += -= *= /= %= ^=
int a = 3;
int b = 4;
a += b ===> a = a+b
a -= b ===> a = a-b
a *= b ===> a = a*b
其他運算子:自增 自減
a++ ==> a=a a+1
++a ==> a+1 a=a
a-- ==> a=a a-1
?: & * [] sizeof()
標點符號:
, ; () {}
3.8、資料型別
資料型別:
基本資料型別:(在沒有寫明時,默認有符號)
int 整型:在記憶體中占4位元組
unsigned int范圍:0~2^32-1
0000 0000 0000 0000 0000 0000 0000 0000
1111 1111 1111 1111 1111 1111 1111 1111
//10000 0000 0000 0000 0000 0000 0000 0000 -1
signed:(有符號數,將資料的第一位看做符號位,0表示正數,1表示負數)
signed int 范圍:-2^31~2^31-1
0000 0000 0000 0000 0000 0000 0000 0000 //+0
0111 1111 1111 1111 1111 1111 1111 1111 //+2^31-1
1000 0000 0000 0000 0000 0000 0000 0000 //-2^31
1111 1111 1111 1111 1111 1111 1111 1111//-(2^31-1)
char字符型:在記憶體中占1位元組(特殊的整型)
字符:用單引號引起來的一個字符(ASCII碼) 'a' '1'
unsigned: 無符號 正整數
unsigned char范圍:0~255
1111 1111
0000 0000
signed:(有符號數,將資料的第一位看做符號位,0表示正數,1表示負數)
signed char范圍:
0 000 0000 //+0
0 111 1111 //+127
1 000 0000 //-128(-0無意義)
1 111 1`在這里插入代碼片`111 //-127
short:短整型 在記憶體中占2位元組
long:長整型 在記憶體中占4位元組 (32位作業系統) (64位中占8位元組)
long long:長長整型 在記憶體中占8位元組
float:單精度浮點型(實型) 在記憶體中占4位元組
用于展示小數,有效位數6~7位
double:雙精度浮點型(實型) 在記憶體中占8位元組 有效位數15~16位
3.9、變數
區域變數:
在函式內部(花括號{}內部定義的變數)
作用域:模塊(函式內部) (從定義開始位置,到函式結束)
生命周期:模塊(函式)呼叫后結束
如果未初始化,系統隨機賦值
全域變數:
在函式外部(花括號{}外部定義的變數)
作用域:整個程式 (從定義開始位置,到程式結束)
生命周期:程式結束
系統默認初始化為0
正數:
原碼:資料的二進制
反碼:還是原碼
補碼:還是原碼
負數:
原碼:資料的二進制
反碼:符號位不變,其他位取反
補碼:反碼+1(原碼取反加1)
變數的存盤形式(以補碼的形式存盤)
常量: 在程式運行中 始終不變的
(1)整型常量(十進制數、八進制數、十六進制數)
(2)實型常量a:小數形式 eg:3.14
b:指數形式 eg:12.34*10^3 ===> 12.34e3 e、E表示指數的底數10
注:e前面要有數字 e后面必須是整數
(3)字符常量:計算機內部按照ASCII碼進行存盤和處理
a:普通的字符:用單引號界定
eg:'a' 'A' '3' '#'
b:轉義字符: 用\將字符 原本的含義 賦予新的含義
eg:'\n'
(4)符號常量:一般用在程式的開頭,用預處理指令定義
#define 符號名 常量資料
eg:#define PI 3.14159
PI 就是符號常量 程式中,定義后的任意地方,都可用PI表示3.14159
注:符號名 符合命名規則 一般大寫
變數:在程式中可以改變的資料(用戶自定義)
必須先定義才使用
定義的一般形式:<存盤型別><資料型別><變數名>
存盤型別:(4G虛擬記憶體空間)
auto static register extern
auto:自動型別 堆疊區
auto int a;====> int a;
static:靜態存盤, 靜態存盤區(全域變數區)
只要程式一直運行,static修飾的變數就一直存在
register:暫存器型別,存放在暫存器的存盤空間
效率高、可加快程式運行的速度
extern:外部參考(全域區)
賦值:
初始化:
int a = 10;
一般:int a;
a = 10;
3.10、輸入輸出
格式輸出函式:(加頭檔案 #include <stdio.h>)
printf("字符"); //原樣輸出
printf("%格式控制符",指定的資料);//以固定的格式輸出指定的資料
%d %c %s %f %p %%
%c //字符型別
%d //十進制整數
%x //十六進制無符號整數
%o //八進制無符號整數
%u //無符號十進制整數
%s //字串
%e //指數形式浮點小數
%f //小數形式浮點小數
轉義字符:用\將字符原本的意義改變 賦予新的含義
\n //換行
\t //水平制表符
\0 //空
\v //垂直制表符
\f //換頁
\b //退格
\\ //代表一個反斜線字符‘\’
\' //代表一個單引號字符
\“ //代表一個雙引號字符
\ddd //1到3位八進制數所代表的任意字符
\xhh //1到2位十六進制數所代表的任意字符
格式修飾符:
m %md //輸出指定域寬,數字的長度>m,原樣輸出,小于m,左補空格
n %.nf //限制浮點數的小數位數(四舍五入)
# %#x //顯示進制前的提示符0x 0
格式輸入函式:
scanf("格式控制符",輸入位置的地址);
格式控制符:%d %c %s %f
修飾符:m //指定域寬
l //雙精度或長整型
h //短整型
* //抑制符
scanf 輸入資料結束的標志:
空格 回車 tab
非法輸入
m 指定域寬(123 m=2 12)
字符輸入函式:getchar()
輸入單個字符
變數名 = getchar();
清除垃圾字符
字符輸出函式:putchar()
輸出單個字符
putchar(變數名);
putchar(字符);//字符用‘’
putchar(ASCII);
字串輸入函式:gets()
gets(字串的首地址);
以換行作為結束標志,空格能輸入
//scanf把空格作為結束的標志之一
字串輸出函式:puts()
puts(字串的首地址);
puts("字串");
//后面會自動換行
使用scanf函式時,可能會產生垃圾字符,清除垃圾字符的方法:
getchar();
%*c //使用抑制符
3.11、轉換、三目運算子
強制轉換(不會四舍五入):
顯示:(資料型別) 運算式
注:高->低 會丟失資料 一般不使用
eg:(double) a;//將a轉換成double型別
(int)(x+y);//將x+y的值轉換成int型別
隱式:自動進行的
低型別->高型別
有符號->無符號
char、short->int->unsigned->long->float->double
低 高
三目運算子:
a>b?a:b //判斷a是否大于b,大于運算式的值為a,否則為b
逗號運算子:優先級最低 從左到右依次運算 運算式的值是最后一個
四、 判斷、回圈、跳轉
4.1、if els
if 陳述句的基本形式
(1)單分支 (if陳述句)
if (運算式)
(2)雙分支結構(if-else)
if(運算式) //運算式為真,執行陳述句塊1
{
陳述句塊1;
}
else //if運算式為假,執行陳述句塊2
{
陳述句塊2;
}
if(運算式) //運算式為真,執行陳述句塊1
{
陳述句塊1;
}
else if(運算式) //運算式為真,執行陳述句塊2
{
陳述句塊2;
}
else //if運算式為假,執行陳述句塊
{
陳述句塊;
}
注:else 必須和if搭配使用,它會自動向上尋找最近的if
else if必須和if搭配使用
練習1:在鍵盤上輸入一個字符,判斷是大寫字母還是小寫字母,是數字還是其他字符
2:猜硬幣的小游戲
4.2、switch
switch(運算式)//運算式的結果一般為整型常量或字符常量
{
case 常量運算式1:陳述句塊;break;
case 常量運算式2:陳述句塊;break;
case 常量運算式3:陳述句塊;break;
case 常量運算式4:陳述句塊;break;
...
default:陳述句塊;break;
}
練習:模擬簡單的計算器,進行兩個數的四則運算
4.3、while
while(運算式)//運算式為真,執行下面陳述句,為假時結束回圈
{
陳述句塊;
}
練習:求1+3+5+7.....的和,若累加數大于750時,程式終止并輸出結果,
do//先執行一遍陳述句,再進行判斷
{
陳述句塊;
}
while(運算式)//運算式為真,執行上面的陳述句,為假時結束回圈
練習:求1~1000之間,滿足用3除余2,用5除余3,用7除余2的數
4.4、for
for(運算式1;運算式2;運算式3)
{
陳述句塊;
}
(1)先執行運算式1,只執行一次
(2)執行運算式2,若其值非零(真),則執行for中指定的回圈體中的陳述句;
執行第(3)步,若其值零(假),則結束回圈,轉到第(5)步,若其值零
(3)執行運算式3
(4)轉回執行第(2)步,繼續執行
(5)結束回圈,執行for下面的陳述句
練習:1-3+5-7.....-99+101
for陳述句的其他形式
運算式的省略
(1)如果在for陳述句前給回圈控制變數賦了初值,則運算式1可以省略,分號不能省略
i=1;
for(;i<=100;i++)
{
s=s+i;
}
(2)如果運算式3省略,則應在for陳述句的回圈體內 修改回圈控制變數
for(i=1;i<=100;)
{
s=s+i;
i++;
}
(3)如果運算式1和運算式3都省略,則for陳述句相當于while陳述句
i=1;//在for陳述句前給回圈控制變數賦了初值
for(;i<=100;)
{
s=s+i;
i++;//在for回圈陳述句內 修改回圈控制變數
}
等價于
i=1;
while(i<=100)
{
s=s+i;
i++;
}
(4)如果三個運算式都省略,則可能死回圈,在回圈控制體中遇到break退出
1、break陳述句:switch陳述句中使用,跳過后面的陳述句
回圈體內使用,跳出一層回圈
2、continue陳述句:在回圈陳述句內使用,跳出本次回圈,進入下一次回圈
3、return陳述句:結束整個函式
return 0;//默認規定, 0表示正常結束
return -1;//默認規定, -1表示例外結束
回圈嵌套:
輸出4*4整數矩陣
練習:列印*
**
***
****
*****
用回圈控制變數i控制輸出行
每行上*個數隨行控制變數i變化
i=1,執行一次putchar('*');
外回圈控制行:for(i=1; i<=5; i++)
內回圈: for(j=1; j<=i; j++)
putchar(’*‘);//輸出一行’*‘
練習1:求n的階乘,n從鍵盤輸入
練習2:回圈從鍵盤輸入字符,并統計其中數字字符的個數,用換行符結束回圈
練習3:列印九九乘法表
練習4:利用*列印一個菱形
*
***
*****
*******
*********
*******
*****
***
*
4.5、goto
goto陳述句:直接跳轉
使代碼的可讀性差,一般不使用,需要先定義標志
loop://名字自己定義
goto loop;
五、陣列
5.1、一維陣列
一維陣列:
陣列是一定有順序關系的若干變數的集合 在空間中連續存盤
(批量處理 資料型別相同的 一堆資料)
一般形式:
<存盤型別><資料型別> 陣列名[個數]
存盤型別:auto static register extern
資料型別:char short int double float long
陣列名:符合識別符號的命名規則 一般由數字、字母、下劃線組成,以字母或下劃線開頭
個數:元素個數 不能用變數定義
int a[10];//定義了10個整型元素的陣列 陣列名為a
char b[10];//定義了10個字符型元素的陣列 陣列名為b
初始化:<存盤型別><資料型別> 陣列名[個數] = {元素值,元素值,元素值,元素值,....}
完全初始化:int a[5] = {1,2,3,4,5};
部分初始化:int a[10] = {1,2,3,4,5};
只給部分元素賦初值
當{}中值的個數少于元素個數時,只給前面a[0]~a[4]賦初值,后面5個自動賦值為0
預設初始化:int a[] = {1,2,3,4,5};
使用:陣列名 [下標]
a[9];//注,下標表示0~9 ,下標的上限為元素個數減1
遍歷陣列:
for(i=0; i<n; i++)
{
printf("%d\n",a[i]);
}
陣列越界:
編譯系統不會檢查陣列越界的錯誤,但可能回出現段錯誤
求陣列元素個數:
sizeof(陣列名)/sizeof(資料型別)
sizeof(a)/sizeof(int);//sizeof(a)/sizeof(a[0]);
陣列清零:
(1)int a[10] = {0};
(2)memset 或 bzero
頭檔案#include <string.h>
函式原型:void *memset(void *s, int c, size_t n);
void bzero(void *s, size_t n);
使用:memset(a, 0, sizeof(a));
bzero(a, sizeof(a));
練習5:定義了10個整型元素的陣列,賦值0~9,逆序列印
練習6:定義了10個整型元素的陣列,隨機輸入各元素的值,并找出其中的最大值
練習7:將1~1000中所有的11的倍數存在陣列中,列印輸出
冒泡排序:
for(i=0; i<9; i++)//外層回圈實作排序資料9趟比較
for(j=0; j<9-i; j++)//內回圈陳述句采用逐個比較 交換的方式將最大數交換至資料末尾
{
if(a[j] > a[j+1])
{
a[j] = a[j]^a[j+1];
a[j+1] = a[j]^a[j+1];
a[j] = a[j]^a[j+1];
}
}
資料交換:
temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
5.2、二維陣列
二維陣列:
一般形式:
<存盤型別><資料型別> 陣列名[個數][個數]
//<存盤型別><資料型別> 陣列名[行][列]
存盤型別:auto static register extern
資料型別:char short int double float long
陣列名:符合識別符號的命名規則 一般由數字、字母、下劃線組成,以字母或下劃線開頭
個數:元素個數 不能用變數定義
int a[3][4];
初始化:
<存盤型別><資料型別> 陣列名[個數][個數] = {元素值,元素值,元素值,元素值,....}
int a[3][3] = {1,2,3,4,5,6,7,8,9};
(1)若對全部元素賦初值,則一維的長度可以省略
int a[][3] = {1,2,3,4,5,6,7,8,9};
//int a[3][] = {1,2,3,4,5,6,7,8,9}; 不能省略二維的長度
(2)對部分元素賦初值,未賦初值的部分自動取0
int a[3][3] = {{1},{2},{3}};//對每一行的第一列元素賦初值
1 0 0
2 0 0
3 0 0
int a[3][4];
//二維陣列可以分解為多個一維陣列
//一維陣列名:a[0]、a[1]、a[2]
//三個一維陣列 每個陣列中都包含4個元素
按行賦值:
int a[3][3] = {{1,2,3},{5,4,7},{6,8,9}};
練習1:求4名同學的3門學科,單科成績的平均分,所有科目總的平均分
練習2:從鍵盤上讀入3行4列12整數構成的矩陣,轉入二維陣列a中,將轉置后的結果放在陣列b中,輸出結果
1 2 3 4 1 5 9
5 6 7 8 ====》 2 6 10
9 10 11 12 3 7 11
4 8 12
5.3、一維字符陣列
一維字符陣列:
char a[5] = {'h','e','l','l','o'};
char a[] = {"hello"};
注:字符陣列,不等于字串
字串:“hello”
可以當成字串一次性輸入、輸出 gets、puts
字符陣列:char a[]={"hello"};//注意不要越界,字串后'\0'
練習3:單詞的逆序 hello world逆序===》dlrow olleh
練習2:從鍵盤輸入字串,求字串中空格數
5.4、二維字符陣列
二維字符陣列:
char a[][10] = {“good","better","wonderful"};//注意字符和字串區別
求行數:int n = sizeof(a)/sizeof(a[0]);
求一行元素個數:int column_num = sizeof(a[0])/sizeof(char);
字串相關函式
(1)字串輸入函式 gets()
格式:gets(字符陣列名)
功能:從標準輸入設備鍵盤輸入一個字串,并存到指定的字符陣列中
本函式正常執行后得到一個函式回傳值,即字符陣列的首地址
頭檔案#include <stdio.h>
char ch[15];
gets(ch);//輸入字串中含有空格時,輸出仍為全部字串,以回車作為輸入結束
puts(ch);
(2)字串輸出函式 puts()
格式:puts(字符陣列名)
功能:將字符陣列中的字串輸出到顯示幕
(3)求字串長度函式 strlen()
頭檔案#include <string.h>
函式原型:size_t strlen(const char *s);
//計算字串有效長度 不包括'\0'
用法:int len = strlen(字符陣列名);
(4)字串連接函式 strcat()
頭檔案#include <string.h>
函式原型:char *strcat(char *dest, const char *src);
用法:strcat(字符陣列名1,字符陣列名2);
功能:把字符陣列2中的字串連接到字符陣列1后,并洗掉字符陣列1結束標志'\0'
函式回傳值:字符陣列1首地址
注:字符陣列1應定義足夠長度
(5)字串拷貝函式 strcpy()
頭檔案:#include <string.h>
函式原型:char *strcpy(char *dest, const char *src);
用法:strcpy(字符陣列名1,字符陣列名2)
功能:將字符陣列2中的字串拷貝到字符陣列1中,字串2結束的標志'\0'也一同拷貝
注:字符陣列1應定義足夠長度
(6)字串比較函式 strcmp
頭檔案:#include <string.h>
函式原型:int strcmp(const char *s1, const char *s2);
用法:strcmp(字符陣列名1,字符陣列名2);
功能:按照 兩個陣列中字串的排列順序 逐次比較 對應字符的ASCII碼值,回傳比較結果
a:字串1 = 字串2 ,回傳0
b:字串1 > 字串2 ,回傳1
c:字串1 < 字串2 ,回傳-1
練習:輸入5個國家英文名稱,按字母順序排序輸出
China italy Germany French Spain
六、指標
6.1、指標
地址:記憶體中 以位元組為單位 開始編號
變數在記憶體單元上的編號,地址是常量
1Byte = 8 bit
指標:本質 記憶體單元的地址
指標變數: 專門用來存放地址的變數
指標的位元組大小不會因為資料型別的改變而改變,都是4位元組,與作業系統有關
一般形式:<存盤型別><資料型別> *<變數名>
int *p;//*表示p是一個指標變數,前面的int型別 表示p可以指向一個整型資料
(1)指標的存盤型別指 指標變數本身的存盤型別
(2)指標的資料型別指 指標目標 的資料型別
初始化:<存盤型別><資料型別> *<變數名> = <地址量>
int a = 10;
int *p = &a;
賦值:
int a = 10;
int *p;
p = &a;
使用:
&:取變數的地址
*:取地址中的內容 //單獨使用
兩個互為逆運算 *p == *(&a) == a
野指標:只是定義了指標,沒有目標地址,會非法訪問記憶體(段錯誤)
練習1:利用指標 輸入兩個整數 按先大后小的順序輸出
指標變數的運算:
本質:地址的運算
(1)算術運算:(+ - ++ --)
int *p;
p+n;//p+n*sizeof(p的資料型別)---->向高地址偏移了n個資料
p++;//p=p+1
++p;
p-n;//p-n*sizeof(p的資料型別)---->向低地址偏移了n個資料
p--;//p=p-1
--p;
q-p;//前提是p、q資料型別一致,結果是兩個指標之間的元素個數
//(q-p)/sizeof(資料型別)
注:p+n只是單純的運算,p的指向不變
p++指向改變,指向了下一個資料,p的內容發生了改變
(2)關系運算(>= <= < > == !=)
前提:指標的型別相同
p > q:比較的是指標變數存放地址的高低
void *指標:是一種不確定的資料型別的指標,它可以指向任意的資料型別
但是在使用時需強制型別轉換
為了防止野指標,int *p = NULL;
//int *p;
//p = NULL;//賦值 p指向NULL
if(q == NULL)
{
print(”q = NULL“);
return -1;
}
6.2、二級指標
二級指標:
指向指標的指標
多級指標:
指標的迭代
const 指標
const 被修飾的部分只讀,限制更改
int a = 10;
int b = 90;
(1)const int *p = &a;//限制*p,p指向的內容不能改變
int const *p = &a;//一樣
//*p = 88;error
(2) int * const p = &a;//限制p,p的指向不能改變
//p=&b ;//error
(3)const int * const p = &a;//同時限制*p和p,p指向的內容和p的指向都不能改變
int const* const p = &a;//同時限制*p和p,p指向的內容和p的指向都不能改變
//*p = 88;error
//p=&b ;//error
6.3、指標與一維陣列
指標和一維陣列:
陣列名可代表陣列的首地址,陣列在記憶體中是連續的
陣列名的意義:int a[10];
1:a 代表 陣列 首元素的首地址(地址是常量)
2:a 代表 整個陣列 eg:sizeof(a)求整個陣列的大小
int a[10] = {1,2,3,4,5,6,7,8,9,10}
int *p;
p = &a[0];//p=a;
a[0] <==> *p <==> *a <==> p[0]
a[5] <==> *(p+5) <==> *(a+5) <==> p[5]
a[i] <==> *(p+i) <==> *(a+i) <==> p[i]
指標和陣列名都可以表示地址
注意區別:指標是變數 陣列名是常量
練習2:用兩個指標將陣列元素列印成 6,7,8,9,10,1,2,3,4,5,
int a[10] = {1,2,3,4,5,6,7,8,9,10}
int a[10] = {6,7,8,9,10,1,2,3,4,5}
指標和字符陣列:
char ch[5] = {'h','e','l','l','o'};
char ch[6] = "hello" //本質是陣列,改變的是陣列中的內容
char *p = "hello";
char *q = "hello";
//*p = 'w';段錯誤
字串常量,將字串的首地址直接給指標p,內容不能更改
練習1:用指標的方式完成strcat()函式功能
練習2:用指標的方式完成strcpy()函式功能
6.4、指標與二維陣列
指標和二維陣列:
[]:單獨使用,有降級的作用
二維陣列名:代表一行的首地址
二維陣列名+1 偏移一行
陣列指標:
本質是指標,指向一維陣列的首地址
int a[3][2] = {{1,2},{3,5},{4,89}};
int (*p)[2];//陣列指標 p的型別 int (*)[2] 指向整數 步長以兩個整數為單位
列數:一維陣列最多能存放的元素個數
特點:指向一片連續的空間,方便操作
a[m][n] <==> *(a[m]+n) <==>(*(a+m))[n] <==> *(*(a+m)+n)
p[m][n] <==> *(p[m]+n) <==>(*(p+m))[n] <==> *(*(p+m)+n)
二維陣列中:
a[i][j]<==>p[i][j]<==>*(*(p+i)+j)<==>*(*(a+i)+j)
指標陣列:
本質是陣列(一維陣列),陣列中存放的是指標
int *p[3];
p//陣列指標名 不能自加
p[0]//指標陣列中的第一個元素,是一個指標,能自加
*p[1]//對陣列中的第二個元素取內容
char a[3][15] = {"you","are","a good person"};
char *p[3] = {"to","be","a better man"};
printf("%s\n",a[0]);//you
printf("%s\n",a[1]+1);//re
printf("%c\n",*(a[2]+5));//d
printf("%c\n",*(*(a+2)+5));//d
printf("%s\n",p[2]);//a better man
printf("%s\n",p[2]+9);//man
printf("%c\n",*(p[2]+10));//a
練習3:通過指標實作,輸入字串,洗掉指定的字符//eg:abbcdef 洗掉b acdef
練習4:通過指標實作,輸入字串,洗掉指定的字串//eg:abbccdef 洗掉bc adef
練習1:有5個字串,首先將它們按照字串中的字符個數由小到大排列,再分別取出每個字串的第三個字母合并成一個新的字串輸出(若少于三個字符的輸出空格),要求:利用字串指標和指標陣列實作,
六、函式
6.1、函式
函式:
函式:完成特定功能的代碼塊,可重復呼叫----建立公用模塊、消除重復作業、提高程式開發效率
一般形式(定義):
<資料型別><函式名>(<形式引數說明>)
{
代碼塊;//實作功能
return<運算式>;//運算式的型別與函式資料型別一致
}
資料型別:指的是函式回傳的資料型別,可以為空(void),省略時默認int型別
函式名:符合識別符號的命名規則,最好見明知意
形式引數說明:想要傳入函式的資料型別
<資料型別><函式名>(<形參1>,<形參2>,<形參3>,<形參4>.....)
int fun(int a,int b,int c)
{
int sum = a+b+c;
return sum;
}
函式呼叫:
<函式名>(<實際引數>)
<函式名>(<實參1>,<實參2>,<實參3>,<實參4>.....)//實參個數與形參個數一致
fun(1,2,3);//int a = 1,int b = 2,int c = 3;
//fun(1,2);//error 實參個數與形參個數一致
函式宣告:
提前打招呼,宣告這個程式中有這個函式,具體的功能實作代碼在后面
1.當功能函式放在主函式(main)前面,宣告、定義在一起
2.當功能函式放在主函式(main)后面時使用,宣告陳述句放在頭檔案下面,主函式上面
int fun(int a,int b,int c);
int fun(int ,int ,int );
//宣告時可以省略形參的名字,保留資料型別
1.函式型別
和回傳值緊密聯系
回傳值的資料型別 和 函式的資料型別 必須一致!
由函式功能 決定 回傳值 的型別有無
主函式內的回傳值:(程式員默認規定)
return 0;//程式正常結束
return -1;//程式非正常結束
沒有回傳值
void func()
{
//1.直接不寫回傳值
return;//2.只有return
}
回傳值的使用:
1:定義變數來接收 //int ret = sum(1,2,3);
2:直接使用 //printf("%d\n",sum(1,2,3));
2:函式的引數
實際引數(實參):
具體傳進函式內部的引數(變數的值)
型別和形參一致
個數和形參一致
形式引數(形參)
定義時:需要傳進函式的引數的 形式說明
被呼叫時:程式會定義形參為區域變數,將實參的值賦值給形參變數
3:函式的功能實作代碼
具體的代碼,實作函式的功能
//main 函式為人機互動的介面
4:寫一個函式
(1)思考函式的功能--函式名
(2)思考引數
(3)思考回傳值(資料型別)
(4)實作的代碼
函式的傳參:
1、賦值傳遞(復制傳遞、值傳遞)
將實參的值拷貝給形參,實參和形參時兩個空間的變數
改變形參的值不會改變實參
2、地址傳遞(指標傳遞)
將實參的地址 給 形參(形參指標)
形參通過地址來操作實參變數
3、全域變數(不需要傳參)
全域變數整個程式都能使用
練習1:將10進制轉成2進制
6.2、陣列的傳參
char ch[64] = {0};
(1)定義指標
void func(char *s)// func(ch) ch *s = ch;
eg:
int a[10] = {0};
fun(a); //int *p = a;
void fun(int *p) //int *p = a;
{
}
int a[3][10] = {0};
fun(a); //int (*p)[] = a;
void fun(int (*p)[])//int (*p)[] = a;
{
}
(2)定義成陣列 (不建議使用)
void func(char s[]);//在函式的形參中,s表示的指標,而不是陣列
eg:
int a[10] = {0};
fun(a); //int p[10] = a;
void fun(int p[10]) //int p[10] = a;
{
}
int a[3][10] = {0};
fun(a); //int p[][] = a;
void fun(int p[][10])//行可以省略
{
}
兩種方式形式不同,但意義都是指標
練習2:求2的4次方
練習3:洗掉字串中重復的字符
大小端存盤:
大端存盤:低資料位存放到高地址中,高資料位存放到低地址中
小端存盤:低資料位存放到低地址中,高資料位存放到高地址中
練習1:洗掉一個字串中所有的空格
6.3、指標函式
指標函式:
int *func();
本質是函式,特殊之處在于回傳值為指標(地址)
注意:回傳的地址是否有效(是否能使用),不能回傳區域變數的地址
能回傳的地址:
1、全域變數的地址
2、static修飾的地址
3、回傳能傳入引數的地址(主函式中的地址,傳入被調函式中)
4、字串常量的地址
5、malloc申請空間
練習2:輸入三個整數,按先大后小的順序輸出
練習3:用函式呼叫實作字串的復制
6.4、函式指標
int (*func)();
本質是指標,用來存放函式的地址,指向函式的入口地址(函式名)
<資料型別>(*<函式指標名>)(<形參>);
int (*p)(int a,int b);
<資料型別>:函式指標 所指向的 函式的回傳值的 資料型別
<函式指標名>:符合識別符號的命名規則,最好見明知意
<形參>:與函式指標 所指向的函式的形參 一致(相當于宣告),形參名可以省略
目的:指標可以指向很多同型別的函式(引數 回傳值一致),呼叫的地方不變,使函式更加通用
優點:可用一個指標呼叫多個同型別函式
練習4:實作兩個整數的加、減、乘、除運算
用戶通過輸入1、2、3、4分別進行兩個整數的加、減、乘、除運算,并輸出結果
練習5:約瑟夫環 有n個人圍成一圈,從第一個人開始開始報數(從1到3報數),
凡是報到3的人退出圈子,最后留下來的讓你使原來的第幾號
函式指標陣列:
int (*arr[4])(int,int);
//陣列里 指標指向 引數為兩個int型別的函式地址
練習7:將n個數輸入時順序的逆序排列,用函式實作
6.5、遞回函式
一個函式的函式體中直接或間接呼叫了該函式本身
函式調自己,注意設定邊界條件(終止條件)
分為兩個階段:遞推、回歸
三要求:
1、遞回終止條件,即遞回函式的出口
2、不斷的遞回呼叫本身
3、遞回函式的主體內容,即遞回函式需要做的事情
練習8:求n!
練習9:斐波那契數列 F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2) (n≥2,n∈N*)
0 1 1 2 3 5 8 13 21 34.......
extern:外部變數的宣告(函式外部,檔案外部)
對 一個在其他地方定義的變數,進行一次重復參考,(不會產生新的變數)
擴大了作用域
static:靜態資料
1、修飾區域變數,延長生命周期
2、修飾全域變數,限制作用域 (和extern互斥,不能在其他檔案中使用)
3、修飾函式,限制作用域
const:
1、修飾指標,根據位置不同,限制的內容不同
const int *p;
int * const p;
const int *const p;
2、修飾變數,將變數常量化,不能在后面被改變(需要初始化)
3、修飾形參,表明只是輸入引數,不能在函式內部改變
typedef:取別名
為現有型別取別名
七、結構體
結構體的定義說明了它的組成成員,以及每個成員的資料型別
定義形式一般如下:
struct 結構型別名
{
資料型別 成員名1;
資料型別 成員名2;
資料型別 成員名3;
......
資料型別 成員名n;
};//分號不能少!
結構體的初始化的一般形式如下:
strcut 結構型別名 結構變數 = {初始化資料1,.....初始化資料n};
結構體變數說明的一般形式:
strcut 結構型別名 結構變數;
在程式中使用結構體中成員的方法:
結構變數名.成員名稱
跳轉:下一篇、Linux c高級
跳轉:下一篇、Linux c高級
跳轉:開頭
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/298471.html
標籤:其他
