step1.day12 Linux下使用C语言编程基础总结
一:系統準備
1.VMware軟件安裝,用來在現在操作系統下模擬Linux系統而不必重裝系統
2.Linux系統安裝,推薦使用Ubuntu14.02版本,較為穩定
注意:安裝步驟,選擇稍后安裝虛擬機,完成必要的配置步驟后添加鏡像安裝
打開VMware workstations→在主頁中選擇“創建新的虛擬機”→典型→稍后安裝系統→選擇Linux系統及版本→
選擇安裝名稱和路徑→指定硬盤大小→自定義硬件配置→選擇安裝鏡像→完成后啟動此虛擬機開始安裝→
安裝中按順序要求填寫用戶名、語言、時區、管理員密碼和創建用戶等。
建議選擇已經配置好的系統,避免學習環境安裝而浪費大量時間,且安裝系統后的軟件升級和配置需求很多其他知識,需要循序漸進
下載配置好的系統,在虛擬機中選擇打開虛擬機,選擇文件夾后雙擊.Ubuntu.vmx后即可使用
二、Linux系統下學習C語言的大致框架
1.搭建環境、熟悉Linux下常用命令及vim編輯器
2.C語言發展及基礎知識,包含數據類型、變量、常量和運算符和優先級
3.輸入輸出語句
4.分支、循環語句(即控制語句)
5.數組和字符串
6.指針和數組即字符串
7.函數。
C語言的基礎知識大致如此,編程語法和其他編程語言類似,邏輯思維能力需要多敲代碼練習
三、Linux系統的基礎知識
1.Linux是1991年由林納斯托瓦斯創建,Linux內核具備以下5種功能①設備管理②文件管理③進程管理④內存管理⑤網絡管理
2.Linux文件系統和Windows不同,Linux的層級目錄是通過文件系統組織管理,是倒置樹結構,沒有盤符感念,一切皆文件。
3.Linux文件系統各個目錄功能根據FHS(filesystem hierarchy standar)
/ 根目錄
/bin 用戶命令和二進制文件
/sbin 系統二進制文件
/boot 系統啟動相關文件
/etc 系統啟動時候用到的配置文件
/dev 設備文件(通過此文件訪問設備驅動)
/home 用戶家目錄
/lib 可執行程序需要連接的庫文件
/mnt/hgfs/share 共享目錄
4. shell命令
Linux @ Ubuntu : ~
用戶名 間隔符 主機名 間隔符 家目錄
whoami 查看用戶名
hostnamec 查看主機名
$ 符號表示普通用戶
#符號表示超級用戶
su root 從普通用戶切換到root超級用戶,輸入密碼不會顯示
sudo passwd root 進行修改超級用戶密碼
exit 從root退回去Linux用戶或退出terminal
用戶界面下打開terminal Ctrl+alt+T
terminal狀態下打開多個terminal Ctrl+shift+n
①ls命令
ls 顯示當前目錄文件列表
ls -l 查看文件屬性(ll)
ls -a查看所有文件包含隱藏文件(以. .. 開頭文件)
ls -lh 把文件大小轉換為響應數量級
ls -R 遞歸顯示文件(文件下文件目錄)
ls -i 顯示文件的iNode號
文件類型: b s p - l c d
塊設備驅動文件 套接字文件 管道文件 普通文件 連接文件 字符設備驅動文件 目錄文件
權限: rwx rwx r-x (r 4 讀 w 2 寫 x 1 執行)
用戶 組 其他用戶
ls -l下 數值(如果是目錄,代表子目錄個數,如果是文件,代表副本個數)
②cd 命令 切換目錄
cd 相對路徑/絕對路徑
cd cd~ 回到家目錄
cd - 回到上一次操作目錄
cd ../ 返回上一級目錄 cd ../ ../返回上上級目錄
cd /mnt/hgfs 以絕對路徑方式切換目錄
③pwd 顯示當前工作路徑
④clear 清屏命令(實際是翻頁)Ctrl+l
⑤touch 穿件文件命令 touch hello.c
文件不存在即是創建,存在即是修改時間戳
⑥mkdir 創建目錄
mkdir hello 創建hello目錄
mkdir -m 0664 test 創建一個權限為664的目錄
cd test失敗的原因可能是test/: Permission denied
mkdir -p hello/test 遞歸創建目錄及子目錄
⑦rm 刪除命令
rm 文件名 rm *.c *是通配符
rm -rf 刪除目錄 -r遞歸刪除 -f強制刪除
⑧chmod 修改權限 chmod 0664 hello 修改hello文件的權限為664
⑨cp 拷貝命令
cp hello.c hello/ 拷貝hello.c文件到hello目錄下
cp hello/ test/ -r (-a)拷貝目錄
⑩mv 移動或者重命名
mv hello/ test/ 移動hello目錄到hello目錄下,如果沒有權限 mv前+sudo(cd前不能+sudu,需切換至root后cd)
mv hello.c hello1.c 重命名
? echo 打印
echo 1111 向屏幕終端打印1111
echo 1111 >test.c 向test.c文件中寫入1111(重定向,覆蓋之前內容)
echo 1111 >>test,c 向test.c文件中追加寫入1111(不覆蓋,追加寫入)
? cat 1.c 將1.c文件的內容在終端上顯示
5.vim編輯器命令
在terminal終端上鍵入vi test.c,即創建一個test.c的文件,如果文件存在則是打開
①命令行模式 下的命令
按Esc進入命令行: yy 拷貝
nyy 拷貝n行
dd 剪切
ndd 剪切n行
p 粘貼
u 撤銷
gg=G 對其(或者鼠標左鍵選擇后按=)
/要查找的字符 查找字符串
/^要查找的字符 查找字符串并高亮每行第一次出現的位置
/字符串$ 查找字符串 顯示并高亮每行以這個字符串結尾的位置
n 下一個
N上一個
底行模式下 :nohl 取消高亮
插入模式:按a 光標當前位置后插入 A 光標當前行位插入
i 光標當前位置插入 I 光標當前行首插入
o 當前位置下一行插入行 O 光標擋墻行上插入行
底行模式 按空格或者:進入,
:w 保存
:wq 保存并退出
:x 保存并退出
:wqa 保存并退出所有
:q 退出未修改文件
:q! 強制退出
:n 跳轉到N行
:nohl 取消高亮
:set nu 顯示行號
:set nonu 取消顯示行號
:set mouse= 可以拷貝(按住shift鼠標選中后右鍵可拷貝)
:set mouse=a 取消拷貝
:60,65y 起止行號拷貝 剪切等
:%s/舊/新/g 替換所有行
:vsp 1.c 垂直現在文件打開另一個1.c
:sp 1.c 水平現在文件打開另一個1.c
二、C語言基礎知識
編程即是內存申請、內存管理和內存應用的過程
1.一個hello world 程序
#include <stdio.h> //包含printf的頭文件
// <> 在系統的/usr/include下找頭文件
// "" 在當前目錄下找頭文件
int main()//c代碼的入口函數
{
printf("hello world\n"); //printf是一個打印函數,\n 1.換行 2.刷新緩沖區域
return 0;
}
編譯代碼分四步
1.預處理:頭文件展開、宏替換 gcc -E hello.c -o hello.i 不可執行
2.編譯:將預處理后文件生產匯編文件 gcc -S hello.i -o hello.s 不可執行
3.匯編:將編譯文件生產可執行文件 gcc -C hello.s -o hello.o 可執行但沒有庫文件
4.連接:將c代碼中用到的庫文件連接到可執行程序中 可以執行
2.計算機的組成(輸入輸出設備、控制器、運算器、存儲設備、總線)
哈佛結構:指令和數據分開存儲的架構,效率高 常用DSP ARM
馮諾依曼結構:指令和數據不分開存儲、分時操作,效率低一些,用于早起的x86架構處理器
3.存儲器的類型
①cache 高速緩存(i-cache指令緩存 d-cache數據緩存)
②iROM 只讀存儲器(可存儲可執行存放啟動代碼)
③IRAM 隨機存儲器 可執行掉電丟失數據
④DRAM/DDR 內存 可執行掉電丟失數據
⑤flash 硬盤
Nor flash Nand flash Emmc 機械硬盤
4.數據表示(計算機內只能以0 1 形式存儲數據)
進制:二進制0b 八進制 0 十進制 十六進制0x (幾進制就是逢幾進一),進制的相互轉換(8進制占3位,16進制占四位轉換)
計算機中,數據以補碼形式儲存,正數源碼反碼補碼一致,負數源碼最高位是符號位,反碼除符號位其他翻轉,補碼是反碼+1
補碼的補碼是源碼 -128 10000000(特殊記住)
1bit
1byte = 8bit
1KB =1024byte
1M =1024kb
1G =1024Mb
1T =1024Gb
1Pb =1024Tb
5 .字符:根據ASCII表,不同字符有對應的0~255編碼,特殊字符如‘a’‘A’‘0’'\0'等
6.C語言中的數據類型
①基本類型
字符 char unsigned char 1字節
整形 short (2字節) int(4字節) long(4字節) long long(8字節)
實型 float(4字節) double(4字節) long double(12字節)
枚舉 enum
②構造類型:數組 結構體 共用體
③指針類型
④空類型 void
注意:數據類型間可以強制轉換,但是可能存在損失精度的風險,一般不轉化
大端小端問題:定義一個int類型,強制轉換為char類型,取出的數值是高位是小端,取出的是低位是大段
大端:高位存在低字節
小端:高位存在高字節
7.C語言中的變量聲明(內存申請)
<儲存類型><變量類型><變量名>
存儲類型:auto register static const volatile extern
變量類型即是數據類型
變量名:①以字母數組下劃線組成,且以字母或者下劃線開頭
②:不能是32個關鍵字
③ 大小寫區分
④見名知意
8.C語言中的常量
①.整形常量
②實型常量
③字符常量
④字符串常量
⑤標識常量 define(宏)
#define M 5+1 預處理階段原樣展開。不計算
#define S(a) #a 字符串化
#define S(a,b) a##b 字符串拼接
9.c語言中的運算符
()在前,單算移關與,異或邏條賦,逗號(按照優先級)
注意:使用異或(加法)可以在不定義新的變量下 實現數值交換
a^=b
b^=a
a^=b
a=a+b
b=a-b
a=a-b
注意:使用移位和或運算,實現高低位翻轉(偶數位與1,左移一位 | 奇數位與1 右移1位),相鄰一位對調 2位對調 4位對調
條件運算符?: a>b?a:b
10.C語言中的輸入輸出語句
①printf 格式化輸出 %d %s %u %p %o %x %c %e %g %# %f %lf
%4d 打印數占4個字符單元 前面補空
%04d 打印數占4個字符單元,前面補0
%-4d 左對齊
%ld long
%ld double
%.2f 顯示小數點后兩位
%Lf long double
②scanf
scanf("%d%c%s%f",&a,&b,&c,&d);
scanf("%d",&a);
scanf("%c",&b);
1.scanf在使用的時候它不會讀取最后一個\n 的字符,可以使用%*c來吃掉一個字符。
2.scanf如果需要連續輸入兩個(多個)整數,scanf("%d%d",&a,&b); 它會吃掉空格,回車,tab
3.scanf雙引號是什么格式,終端輸入就是什么格式,scanf("%d,%d",&a,&b); -->1231,123
4.scanf在連續輸入的時候,它會把空格,tab,回車作為結束,如果不想以空格或tab作為結束,
scanf("%[^\n]",c) //只把\n作為結束符,可以讀取\n之外的所有字符
5.如果scanf按照如下方式來實現
scanf("%d\n",&a);
printf("%d\n",a);
scanf("%d\t",&a);
printf("%d\n",a);
scanf("%d ",&a);
printf("%d\n",a);
輸入一個整數之后,在額外輸入一個字符(任意的),它就會結束了
③getchar
函數原型:int getchar(void);
功能:輸入一個字符
參數:@ 無;
返回值:成功返回字符的ascii,失敗返回-1;
1.getchar的用法
char a;
a = getchar();
printf("%c\n",a);
2.getchar吃掉字符
int a;
char b;
scanf("%d",&a)
b = getchar();
3.在函數內部定義的變量默認是隨機值,全局變量默認的值是0;
④putchar()
函數原型:int putchar(int c);
功能:輸出一個字符
參數:@c:想要輸出的字符(ascii)
返回值:成功返回字符的ascii,失敗返回-1;
一般用法:
putchar(a);
putchar('\n');
putchar('A');
putchar('\n');
putchar(65);
putchar('\n');
⑤gets()
函數原型:gets(char *s);
功能:讀取多個字符
參數:@s 數組的名字
注意:
gets會將緩沖區中所有的字符全部讀入,不管內存是否越界。
gets會在最后的位置補充\0
char a[50];
gets(a);
⑥puts()
函數原型:int puts(const char *s);
功能:輸出多個字符
參數:@s 數組的名字
注意:puts只能用于輸出多個字符(字符串),puts會自動補充\n
用法:
char a[50];
puts(a);
puts("hello world");
puts(""); ---->自動輸出一個換行
area.c:(.text+0x130): undefined reference to `sqrt'
collect2: ld returned 1 exit status
該錯誤是未有鏈接文件,需gcc area.c -lm
注意,自行定義的頭文件格式位.h文件
#ifndef __HEAD_H__
#define __HEAD_H__
int add(int a,int b);
#endif
11.C語言中的控制語言
①if 、if/else 、if/elseif........
②switch/case/default(case語句執行到遇到break,沒有break則執行到最后,default語言在case都不執行時候執行,也是遇到break或到最后 )
③循環for(語句1;語句2;語句3),循環三要素 初始條件 判斷條件 結束條件
for循環執行順序為,語句1,語句2,循環體,語句3,語句2.。。。。。。
while()先判斷后執行
do while 先執行后判斷
④continue 結束本次循環進行下一次循環,break,結束當前循環體
⑤goto 無條件跳轉語言,只能在本函數內部跳轉,需要一個標簽(一般最為錯誤的統一處理口)
⑥return 結束函數或將行數返回值返回給調用者
12.C語言中的數組
①.數組為構造類型,是基本類型的多個元素組合
②.數組內元素數據類型必須一致
③.數組在內存上連續
④.數組不進行越界檢查
⑤.數組名是數組首地址(a+1 &a+1 &a[0]+1,移動步長為對應類型大小)杜絕a++ ,可以a+1
char a[5],方括號內必須是常量
⑥數組賦值:①初始全部賦值,部分賦值(未賦值元素為0,)
②數組大小根據賦值數確定大小int a[] = {1,2,3,4}
先定義后賦值需要借助循環賦值
sizeof函數可以測量數組長度 sizeof(a)/sizeof(a[0])
⑦冒泡排序
for(i=0;i<N-1;i++)
for(j=0;j<N-i-1;i++)
⑧選擇排序:記錄最小或者最大值的下標,下標變了才交換
a[-1],是數組前一個元素,不定值,不建議使用,數組不進行越界檢查
⑨.二維數組 行號可以省略,列不可省略,二維數組名字也是常量,也不可a++
⑩.一維字符數組(以‘\0’結束就是字符串數組,字符串數組可以%s輸入或者輸出)
?.二維字符串數組,字符串的集合
13 C語言中的指針
地址:在計算機中,地址是以字節為單位進行編號,管理內存,每一個內存區域都有一個編號,這個編號叫做地址
指針:指針就是指向地址的
指針變量:存放地址的變量就叫做指針變量
內存分類:
①堆區:需要手動申請和釋放(malloc/free函數)
②棧區:用戶的函數、局部變量,是由操作系統自行申請和釋放的
③.bss:全局未初始化的變量以及static修飾的變量
④.data:存放用戶的數據
⑤.ro:存放字符串常量
⑥。text:文本段
1.指針的定義 :<存儲類型><數據類型>*<變量名>
char *p;
short *t;
int *q; //*這里的*是一個標識符,//代表定義的是指針類型的變量
sizeof(char *); //4 p+1 移動1字節
sizeof(int *); //4 q+1 移動4字節
sizeof(short *);//4 t+1 移動2字節
指針均占4個字節,指針加1,移動相應數據類型步長
2.和指針相關的符號
* //取出地址中的內容
& //取地址符
3.一維數組和指針
int a[3];
int *p = a;
數組訪問:a[i] <=====>p[i] <====> *(a+i) <====>*(p+i)
注意:
p++ //可以
a++ //不行,原因a是數組名,它是常量不能做加減操作。
4.指針和字符串
char *p = "hello world"; 定義一個指針,指向字符串常量,*p內容不可以修改
*p = 'a'; //錯誤的
p++; //可以
char buf[] = "hello world"; //在棧上存放
char *a;
char str[];
buf[0] = 'a' //可以
buf++; //錯誤的
a = "hello world"; //可以
str = "hello world";//錯誤
5.指針和二維數組,
注意:將數組名賦值給一級指針時候報錯,類型不匹配,需要將數組名賦值給 (同步長數組指針)
6指針數組:int *p[3],一個數組,數組元素為指針
7.二級指針:指向一級指針的指針,通常用著傳參函數中的套用函數傳參
8.數組指針 int (*p)[3] 它是一個指針,指向的是一個數組。這個數組(每一行有三個成員)
數組指針和二維數組和相互對應的。數組指針和二維數組相對對應
int a[3][3] = {1,2,3,4,5,6,7,8,9};
int (*p)[3];
p = a;
a[i][j]<====>*(a[i]+j)<=====>*(*(a+i)+j)<======>
p[i][j]<====>*(p[i]+j)<=====>*(*(p+i)+j)
a+1 //移動一行,3(一行的成員個數)* sizeof(int)
&a[i]+1 //移動一行,3(一行的成員個數)* sizeof(int)
&a+1 //移動整個數組,3(三行)*3(一行的成員個數)* sizeof(int)
a[i]+1 //移動一個成員的大小,sizeof(int);
&a[0][0]+1 //移動一個成員的大小,sizeof(int);
9.sizeof和strlen的區別
1.sizeof是關鍵字,strlen是函數。
2.sizeof可以求類型的大小,strlen求字符串成員的個數
3.sizeof(buf) = 10(不包含'\0'); strlen(buf) = 5(數組長度);
14.C語言中的數據存儲類型
定義變量
<存儲類型> <變量類型><變量名>;
auto :自動 auto int a;
定義局部變量的時候,int a;前面其實是省略了auto。
當函數執行的時候變量會被申請,當函數執行完的時候
變量會被銷毀。
非自動類型的變量:全局變量或者static修飾的變量。
static :1.延長變量的生命周期
void swap()
{
static int a=3; //int a=3;
printf("%d\n",a++);
}
2.限制作用域(只能在本文件內使用)
static int a;
static void hello()
{
printf("hello");
}
register :寄存器
register int a = 5;
定義寄存器類型的變量,但是由于芯片內部的寄存器的個數是有限制的。
所以在使用的時候注意使用的次數。寄存器類型的變量要比普通的變量
讀寫的效率高。
extern :外部的,可以在其他文件中調用
extern int a;
extern int add(int a,int b);
const :它修飾的是一個只讀的變量,修飾的不是常量。
const int a = 5;
a = 100; =>error: assignment of read-only variable ‘a’
const char *p; => const *p; //p指向的內容不可修改
char const *p; => const *p; //p指向的內容不可修改
char * const p;=> const p; //p指向的地址不可以修改
const char *const p; //指向的地址和內容都不可修改
char const *const p; //指向的地址和內容都不可修改
注意:把數據類型去掉后,const修飾的是誰,它就是一個只讀的。
volatile :字面含義(易變的)
(volatile unsgined int *)0x50000000
假如剛開始0x50000000中保存的是0x12345678;
如果這里不加volatile,編譯會對其進行優化,下代碼中只要用到
0x50000000地址中的值的時候,它取得都是0x12345678這個值。但是
在操作系統運行的時候,可能會去修改0x50000000地址中的值。代碼
是不能取出到最新值的。
volatile告訴編譯器不對代碼進行優化,每次在用這個地址中的值的
時候,都要重新從這個地址中來取數據,所以加了volatile之后就能保證
取到的都是最新的數據。
15.C語言中的函數(函數是c語言最基本的組成單元)
函數就是一個實現特定功能的代碼集合,函數封裝要遵從高內聚低耦合
函數三要素:①功能唯一 ②輸入 ③輸出
函數類型
<存儲類型><返回值類型><函數的名字>(參數列表)
{
語句;
return;
}
注意:函數的使用要:先聲明后使用,先使用的先聲明
函數的參數:
1.參數的成員的個數一般小于等于4(效率高)
2.函數的中的參數的名字叫做形式參數,形式參數(函數內部的變量)當函數被調用的時候分配內存,在函數執行結束的時候,形參所占的內存
就會被釋放。
3.實參數:在main中定義的變量,int a = 5; int b =100 =>a就是實參,add(a,b);實際參數可以的變量,常量,表達式,地址。
參數傳遞分為:
值傳遞:不可以交換數據
地址傳遞:可以交換數據
傳遞數據:不是將整個數據都傳遞過去了,它是將數據的首地址傳遞過去了。
傳遞數組:
int func(int buf[100],int n)
{
sizeof(buf);
}
傳遞的是數組的首地址,在函數中sizeof(buf) == 4;
傳遞函數:傳遞的是函數的首地址
int func(int (*fn)(int ));
int func(int fn(int ));
函數使用中,會用到嵌套函數(函數內部調用其他函數)
遞歸函數(自己調用自己)
指針函數(返回值是指針的函數)
函數指針(即函數名) int (*p)(int a, int b)
函數指針數組(數組元素是函數指針的數組) int(*p[3])(int a, int b)
函數指針數組指針:是一個指針,這個指針指向函數指針數組
16 typedef 關鍵字 類型重命名,定義變量時候,將變量名去掉,改為想定義的名稱即可
typedef int INT_32; int
typedef int INT_ARR[3]; int a[]
typedef int INT_ARR_2[3][2]; int a[][]
typedef int * INT_P; int *p
typedef int * INT_A[3]; int *p[3]
typedef int (*ARR_P)[3]; int (*p)[3]
typedef int FUNC (int a,int b);
typedef int (*FUNC_P)(int a,int b);
?
添加新的知識點:1.float和double類型數據不能判斷是否等于0(根據float的存儲方式,永遠不等于0)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 2、#define PI 3.1415? ?這里的PI是文本替換,是(字符串類型而非常量)
轉載于:https://www.cnblogs.com/huiji12321/p/11153752.html
總結
以上是生活随笔為你收集整理的step1.day12 Linux下使用C语言编程基础总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LeetCode 1004.最长连续1的
- 下一篇: WCF 使用证书认证 方法