原則:此文盡量短小精悍,實(shí)用,需要擴(kuò)充閱讀都是以鏈接形式出現(xiàn)
1.編譯
#cc program.c
生成a.out文件
這個(gè)名字是編譯器默認(rèn)的輸出名。如果要修改可執(zhí)行文件的名字可以加-o參數(shù):gcc -o myexec main.c
這樣就把main.c編譯連接生成的可執(zhí)行文件命名為myexec
gcc編譯器的編譯自定義格式
#cc -o hello hello.c
#gcc -o hello hello.c
使用gcc 編譯器就會(huì)為我們生成一個(gè)hello的可執(zhí)行文件
擴(kuò)充閱讀:Linux編譯器GCC的使用
http://blog.csdn.net/21aspnet/article/details/1534108http://blog.csdn.net/21aspnet/article/details/167420補(bǔ)充說明:如果你實(shí)在基礎(chǔ)很差,那么需要在windows下借助VS2010這樣的可視化工具來調(diào)試了,這樣可以很清晰的看出內(nèi)存中的指針
http://blog.csdn.net/21aspnet/article/details/67237582.執(zhí)行
#./a.out
編譯多個(gè)源文件
#cc a.c b.c c.c
3.產(chǎn)生目標(biāo)文件
#cc -c program.c
產(chǎn)生program.o的目標(biāo)文件以后供鏈接用
產(chǎn)生多個(gè)目標(biāo)文件
#cc -c program.c a.c b.c
4.鏈接幾個(gè)目標(biāo)文件
#cc a.o b.o c.o
5.轉(zhuǎn)義字符
\\代表\
代表\\
注意不是代表\\
\'代表'
\"代表"
\n換行
\r回車
擴(kuò)充閱讀:C語(yǔ)言 格式控制符 和 轉(zhuǎn)義字符
http://blog.csdn.net/21aspnet/article/details/15354596.注釋
方法一 /* */
方法二 //
7.保留字
http://blog.csdn.net/21aspnet/article/details/15392528.整型
singed 有符號(hào)
unsigned是無符號(hào)的意思,也就是說如果你的編譯系統(tǒng)給int分配的存儲(chǔ)單元的長(zhǎng)度是2個(gè)字節(jié)的話,有符號(hào)的int 取值范圍是-32768(即2^15)——32767(即2^15-1),而無符號(hào)的unsigned int就是0-65535(2^16-1)
類型
最小范圍
char
0-127
signed char
-127-127
unsinged char
0-255
int
-32767-32767
long int
-2147483647-2147483647
unsinged int
0-65536
int a=8;
int a=012;//8進(jìn)制是0開頭
int a=0x0a;//16進(jìn)制是0x開頭
3種輸出printf("%d",a);都是10
9.枚舉類型
enum A{a,b,c,d};
10.浮點(diǎn)
float double long double
11.指針
指針只能指向地址!
指針的指針是為了取得“地址”,因?yàn)橹羔樦皇侵赶颉爸黧w”
int a;
int *b=&a;
int **c=&b;
a=1;
*b=2;
指針要對(duì)應(yīng)級(jí)別,一級(jí)b對(duì)應(yīng)一級(jí)&a,二級(jí)c對(duì)應(yīng)二級(jí)&b。
如果傳值原代碼塊無星
main()
{
swap(a,b,c)
}
swap(int a,int *b,int **c)
{
a=*b+**c;//這樣不能改變值
*b=a+**c;//可以改變值
}
函數(shù)里要改變?cè)抵挥兄羔?div style="height:15px;">
printf("%d",*b);//輸出2
printf("%d",a);//輸出2
//指針和字符串
char * ch="abc";
char * cp=ch;
printf("%s",cp);//輸出abc
//指針和字符
char ch=‘a(chǎn)’;
char * cp=&ch;
printf("%c",*cp);//輸出a
擴(kuò)展閱讀:
把指針說透
http://blog.csdn.net/21aspnet/article/details/317866C指針本質(zhì)
http://blog.csdn.net/21aspnet/article/details/1539652還看不懂的建議去看:《徹底搞定C指針》
http://download.csdn.net/source/349113112.typedef
typedef int k;
k k1=10;
此聲明定義了一個(gè) int 的同義字,名字為k。注意 typedef 并不創(chuàng)建新的類型。它僅僅為現(xiàn)有類型添加一個(gè)同義字。你可以在任何需要 int 的上下文中使用k
int a=0;
typedef int * p;
p b=&a;
不可以p *b 因?yàn)閜=int *
13.const常量
const int a=15;//必須聲明時(shí)賦值
int const a=15;//必須聲明時(shí)賦值,const在前在后都可以
聲明好以后再賦值會(huì)報(bào)錯(cuò)
const int a;
a=15
其次:在函數(shù)中聲明為const的形參在函數(shù)被調(diào)用時(shí)會(huì)得到實(shí)參的值
int ax(const int aa)
{
int a=aa;
return a+1;
}
擴(kuò)充閱讀:
http://blog.csdn.net/21aspnet/article/details/16019714.define常量
#defined MMX 50
printf("%d",MMX);
15.鏈接屬性
external外部
internal內(nèi)部
none無
16.變量類型
取變量的值可以直接=變量
給變量賦值一定要&
auto 變量
是用堆棧(stack)方式占用儲(chǔ)存器空間,因此,當(dāng)執(zhí)行此區(qū)段是,系統(tǒng)會(huì)立即為這個(gè)變量分配存儲(chǔ)器空間,而程序執(zhí)行完后,這個(gè)堆棧立即被系統(tǒng)收回.在大括號(hào){}內(nèi)聲明.
static 變量
是C程序編譯器以固定地址存放的變量,只要程序不結(jié)束,內(nèi)存不被釋放.
static int a=5;
擴(kuò)充閱讀:static
http://blog.csdn.net/21aspnet/article/details/1535573external 變量
外部變量 定義在程序外部,所有的函數(shù)和程序段都可以使用.
頭文件f1.h
int a=5;//定義
主文件f2.c
#include "f.h" //引用,注意不能<"f.h">
extern int a;//聲明
printf("%d",a);
static external 變量
靜態(tài)外部變量和外部變量差別在于,外部變量生命可以同時(shí)給多個(gè)文件使用,而靜態(tài)外部變量則只能給聲明此變量的文件使用.
register 變量
寄存器變量,是由寄存器分配空間,訪問速度比訪問內(nèi)存快,加快執(zhí)行速度.寄存器大小有限.
注意:register int a=1;只能函數(shù)內(nèi) 而不能函數(shù)外,由于寄存器的數(shù)量有限(不同的cpu寄存器數(shù)目不一),不能定義任意多個(gè)寄存器變量
extern 和static可以函數(shù)外
擴(kuò)充閱讀:寄存器register介紹
http://blog.csdn.net/21aspnet/article/details/257511擴(kuò)充閱讀:變量屬性
http://blog.csdn.net/21aspnet/article/details/256007217.語(yǔ)句
if...else...
while循環(huán)
i=0;a=0;
while(i<10)
{
a=a+i;
i++;
}
break:退出大循環(huán)
continue:退出本次循環(huán)
fo循環(huán)
for(int i=0;i<2;i++)
{
}
do....while
switch
switch(ch){
case "A":
i+1;
break;
case "B":
i+2;
break;
default:
i=0;
}
goto跳轉(zhuǎn)
goto AA;
AA:if...else
18.操作符
+-*/%
19.位移和位操作符
<<左移
>>右移
&位與
|位或
^位非
擴(kuò)展閱讀:
http://blog.csdn.net/21aspnet/article/details/16003720.邏輯運(yùn)算符
&& ||
21.條件運(yùn)算符
a>5?b-6:c/2
a大于5就執(zhí)行b-6否則執(zhí)行c/2
22.++
K++ :k不變
++K :K+1
23.布爾值
C語(yǔ)言中沒有布爾類型。任何一個(gè)整型的變量都可以充當(dāng)布爾變量,用0表示False,其它數(shù)(默認(rèn)為1)表示True。
a = 1;
if(a) {printf("a is T\n");}else{printf("a is F\n");}//輸出T
a = 2;
if(a) {printf("a is T\n");}else{printf("a is F\n");}//輸出T
a = -1;
if(a) {printf("a is T\n");}else{printf("a is F\n");}//輸出T
a = 0;
if(a) {printf("a is T\n");}else{printf("a is F\n");}//輸出F
if(!a) {printf("a is T\n");}else{printf("a is F\n");}//輸出T
如果你想像Pascal一樣使用true和false,那么你可以包含頭文件stdbool.h。這樣你可以定義變量為bool類型并賦值為true或false。例如:
#include "stdbool.h"
bool a = true;
if (a) printf("a is true");
也可以使用
#define False 0
#define True 1
24.數(shù)組
int a[]={1,2,3,4,5}
a[0]//用序號(hào)輸出數(shù)組元素,默認(rèn)下標(biāo)從0開始
求數(shù)組長(zhǎng)度:printf("%d\n",sizeof(a)/sizeof(a[0]));
int *ap=a+2;
ap[0];//輸出3
int a[]={1,2,3,4,5,6};//自動(dòng)計(jì)算數(shù)組長(zhǎng)度
循環(huán)數(shù)組可以用2種方法
int i;
for(int i;i<6;i++)
{
a[i];這樣輸出
或者*(a+i);因?yàn)?(a)指向數(shù)組第一個(gè)元素的指針
}
指針訪問數(shù)組
int *p=a;注意不是&a;
可以三種方法輸出
p[i];方法一就是數(shù)組元素
*(p+i);方法二
for()
{
printf("%d",*p);//方法三
p++;
}
如果 int const p=a;
用上述代碼linux下一樣可以編譯
指針的本質(zhì)
int a[]={1,2,3,4,5} ;
int b[]={6,7,8,9,10} ;
int *p;p=b;
int i;
for(i=o;i<10;i++)
{
prinft("d%",*p);
p++;
}
輸出678910 12345
如果改為p=a;
輸出12345后面其實(shí)是其他未知地址
但是如果改為
p=a;
for(i=-5;i<5;i++)
{
prinft("d%",*p);
p++;
}
輸出678910 12345
由此可以看到指針不是孤立的!
多維數(shù)組
int a[2][3]={1,2,3,4,5,6};
a[0][0]=1;
a[0][1]=2;
a[0][2]=3;
int a[2][3]={
{1,2,3},
{4,5,6}
};
多維數(shù)組只有第一維可以缺省,其余維都要顯示寫出
int a[][3]={1,2,3,4,5,6};
//聲明指針數(shù)組,每個(gè)指針元素都初始化為指向各個(gè)不同的字符串常量
char const keyword[]={
"do";
"doo";
"doooo";
"do";
"doo";
"do";
"doooooo";
}
//聲明矩陣,每一維長(zhǎng)度都是9,不夠用0補(bǔ)齊
char const keyword[][9]={
"do";
"doo";
"doooo";
"do";
"doo";
"do";
"doooooo";
}
擴(kuò)展閱讀:C語(yǔ)言中字符數(shù)組和字符串指針分析
http://blog.csdn.net/21aspnet/article/details/153992825.字符串
類型一:字符串
char day[15] = "abcdefghijklmn";//定義一
char day[] = "abcdefghijklmn";//定義一
char * str="abcdefghijklmn";//定義二
windows下VS2010調(diào)試窗口看區(qū)別
char str[20]="0123456789";//str是編譯期大小已經(jīng)固定的數(shù)組
int a=strlen(str); //a=10;//strlen()在運(yùn)行起確定
int b=sizeof(str); //而b=20;//sizeof()在編譯期確定
sizeof 運(yùn)算符是用來求內(nèi)存容量字節(jié)的大小的。而strlen是用來求字符串實(shí)際長(zhǎng)度的。
下面2種聲明完全一樣
類型二:字符數(shù)組
char msg[]={'a','b','c'}
char msg[]={abc}
char *ans;
ans=strchr(day,'c');
printf("%s",ans);//輸出從c開始的部分
printf("%d",*ans);//輸出找到的指針
ans=strrchr(day,'c');
printf("%s",ans);//輸出找到的指針
printf("%d",*ans);//輸出找到的指針
char temp[100]="hello";
char *t="world";
strcat(temp,t);
輸出 temp
要注意的是 第一個(gè)參數(shù)數(shù)組長(zhǎng)度要=自身原長(zhǎng)+合并字符長(zhǎng)
類型三:字符串?dāng)?shù)組
char *a[4]={"this","is","a","test"};
char **p=a;
擴(kuò)展閱讀:C語(yǔ)言字符串處理庫(kù)函數(shù)
http://blog.csdn.net/21aspnet/article/details/153997026.結(jié)構(gòu)
注意結(jié)構(gòu)一定要};結(jié)束
聲明一
struct simple{
int a;
int b;
};
使用
struct simple s1;
s1.a=1;
聲明二
typedef struct {
int a;
int b;
};simple
使用
simple s1;
s1.a=1;
注意:方法二比一少寫一個(gè)struct
結(jié)構(gòu)初始化
typedef struct {
int a;
int b;
};simple{1,2}
使用
simple.a;//輸出1
指向結(jié)構(gòu)的指針
struct data {
int a;
int b;
};data1{1,2}
struct data *p;
p=&data1;
(*p).a;//輸出1
p->b;//輸出2
擴(kuò)展閱讀:
結(jié)構(gòu)的成員訪問
http://blog.csdn.net/21aspnet/article/details/150259typedef struct 用法詳解和用法小結(jié)typedef的四個(gè)用途和兩大陷阱27.內(nèi)聯(lián)函數(shù)
首先要聲明
inline int 函數(shù)名(參數(shù))
后面要有一個(gè)真實(shí)的函數(shù)體
inline int 函數(shù)名(參數(shù))
{
}
只有三二行的代碼,建議使用內(nèi)聯(lián)!這樣運(yùn)行速度會(huì)很快,因?yàn)榧尤肓薸nline 可以減少了,跳入函數(shù)和跳出函數(shù)的步驟!
28.宏
#define SQUARE(x) x*x
程序中寫SQUARE(3) 實(shí)際等于3*3
29.函數(shù)
int a=1;
int b=2;
ext1(a,b);
ext1(int x.int y)
{
int temp=x;
x=y;
y=temp;
prinft("x=%d,y=%d",x,y)
}
30.動(dòng)態(tài)內(nèi)存分配
動(dòng)態(tài)內(nèi)存分配是為了鏈表,否則只能用數(shù)組
使用malloc和free分配和釋放
#include <malloc.h>//malloc
#include <stdlib.h>//exit’
int * p;
p=malloc(100);
if(p==NULL)
{
printf("Out of memory!\n");
exit(1);
}
實(shí)際中p=malloc(sizeof(int));獲得足夠1個(gè)整數(shù)的內(nèi)存
實(shí)際中p=malloc(10*sizeof(int));獲得足夠10個(gè)整數(shù)的內(nèi)存
擴(kuò)展閱讀:C語(yǔ)言內(nèi)存動(dòng)態(tài)分配
http://blog.csdn.net/21aspnet/article/details/14696831.鏈表
//先定義一個(gè)結(jié)構(gòu)體
typedef struct node{
int data;//數(shù)據(jù)域
struct node * next;//指針域 ,是struct node的成員,又指向struct node類型的的數(shù)據(jù),這里存放下個(gè)結(jié)點(diǎn)的地址
}Node;
建立鏈表
//返回類型是之前定義的結(jié)構(gòu)體
Node * creat()
{
//需要先定義3個(gè)節(jié)點(diǎn)
Node * head=NULL;//頭結(jié)點(diǎn)
Node *p=NULL;//指向原鏈表的最后一個(gè)結(jié)點(diǎn)
Node *s=NULL;//指向新節(jié)點(diǎn)
head=(Node*)malloc(sizeof(Node));//動(dòng)態(tài)分配內(nèi)存空間
head->next=NULL;//開始頭結(jié)點(diǎn)也就是尾結(jié)點(diǎn)
p=head;//p一開始指向頭結(jié)點(diǎn)
//用while循環(huán)
int c=1;//為0是退出循環(huán)的條件
int d=0;
while(c)
{
//使用scanf接受用戶數(shù)據(jù)數(shù)據(jù)
scanf("%d",&d);
if (d!=0)//繼續(xù)輸入
{
s==(Node*)malloc(sizeof(Node));//定義新節(jié)點(diǎn)s,和定義head一樣
s->data=d;//給新節(jié)點(diǎn)賦值
p->next=s;//將第一個(gè)結(jié)點(diǎn)鏈接在第二個(gè)結(jié)點(diǎn)后面
p=s;//p繼續(xù)指向當(dāng)前節(jié)點(diǎn)
}
else
{
c=0;//用戶輸入0結(jié)束 輸入
}
}
p->next=NULL;//結(jié)束輸入時(shí)將最后結(jié)點(diǎn)定義為尾結(jié)點(diǎn)
return head;
}
//輸出結(jié)點(diǎn)
output(Node * head)
{
//新定義一個(gè)指針用于遍歷
//其實(shí)如果head->data會(huì)是0;單鏈表巧妙的從第二個(gè)結(jié)點(diǎn)開始,頭結(jié)點(diǎn)沒用,但是并不代表沒用值!
Node * p=head->next;
while(p!=NULL)
{
printf("%d",p->data);
p=p->next;//注意while循環(huán)里一定要讓P指針不斷往下指向
}
}
//查找制定元素的順序
searchdata(Node * head)
{
int t=0;
printf("請(qǐng)輸入您要查找的值:\n");
scanf("%d",&t);
Node * p=head->next;
int k=0;
while(p!=NULL)
{
k++;
if(p->data==t)
{
printf("%d是第%d個(gè)元素:\n",t,k);
break;
}
p=p->next;
}
if(p==NULL)
{
printf("沒找到");
}
}
//元素之間插入值
insertdata(Node * head)
{
Node *s=NULL;//指向新節(jié)點(diǎn)
s=(Node*)malloc(sizeof(Node));//動(dòng)態(tài)分配內(nèi)存空間
int t=0;
int i=0;
printf("請(qǐng)輸入您要查找的值:\n");
scanf("%d",&t);
printf("請(qǐng)輸入您要插在那個(gè)元素后面:\n");
scanf("%d",&i);
Node * p=head->next;
while(p!=NULL)
{
if(p->data==i)
{
s->data=t;
s->next=p->next;//注意是先指向新節(jié)點(diǎn),再改舊節(jié)點(diǎn)
p-next=s;
printf("插入成功:\n");
break;
}
p=p->next;
}
if(p==NULL)
{
printf("沒找到\n");
}
}
擴(kuò)展閱讀:
鏈表的C語(yǔ)言實(shí)現(xiàn)
http://blog.csdn.net/21aspnet/article/details/146968單鏈表功能大全
http://blog.csdn.net/21aspnet/article/details/15905332.scanf
int d=0;
注意是scanf("%d",&d)
這里千萬(wàn)要注意如果寫為scanf("d%",&d)一樣可以編譯通過,但是會(huì)引起隱含的bug!!!
注意是&d而不是d,因?yàn)槭歉淖冏兞康牡刂穼?duì)應(yīng)的內(nèi)容,而不是直接取其值
33.union
聯(lián)合也叫共同體,和結(jié)構(gòu)struct很像
struct可以定義一個(gè)包含多個(gè)不同變量的類型,每一個(gè)變量在內(nèi)存中占有自己獨(dú)立的內(nèi)存空間,可以同時(shí)存儲(chǔ)不同類型的數(shù)據(jù)。
uniion也可以定義一個(gè)包含多個(gè)不同變量類型,但這些變量只共有同一個(gè)內(nèi)存空間,每次只能使用其中的一種變量存儲(chǔ)數(shù)據(jù)。
問題是這樣做有什么意義?
union{
int a;
float b;
char c;
}a;
a.b=10.123; printf("%d",a.a);
雖然沒有初始化a,一樣可以使用!union相當(dāng)于pascal中的變體記錄。就像c++中的重載這么方便。
34.register寄存器
register int a=1;
但是如果int *b=&a;這樣會(huì)報(bào)錯(cuò),因?yàn)椴豢梢匀〉郊拇嫫髯兞康牡刂贰?div style="height:15px;">
但是使用VS2010調(diào)試時(shí)可以用&a.
37. size_t