2021-08-15 C語言基礎知識筆記


2021-08-16

C語言基礎知識:
program 程序,是指令的集合
指令:編寫的執行程序
編譯:將程序轉換成二進制
運行:將二進制運行出結果
源程序:hello.c --> 目標程序:hello.obj --->可執行程序:hello.exe --->run

程序設計步驟:
1.確定數據結構
2.確定算法
3.編碼、寫注釋
4.調試

程序3種結構:(結構化)
1.順序結構:從上到下執行
2.選擇結構:沿着不同路徑執行
3.循環結構:重復執行

C的數據類型:基本類型,構造類型,指針類型,無值類型

C的表達式類型:
賦值表達式=,算數表達式+-*/,關系表達式< > <= >= <>,邏輯表達式 && ! || ,條件表達式 ? ,逗號表達式 1, 2, 3

#include<stdio.h> /*調用標准庫函數*/

標識符:符合一定規則的符號集合。
標識符命名規則:字母、數字、下划線組成,不包括特殊符號如:?.-;必須字母,下划線開頭;不能是關鍵字;區分大小寫。

常量:程序中值不能被改變的量。
1.數值型:
1)整型常量:-1 , 十進制; 017,八進制; 0x12,十六進制。
2)實型常量:-12.2 ,0.0
2.非數值型常量:
1)字符型常量:'A','0'
2)字符串常量:''mnae''
3.定義符號常量:#define p 123
變量:程序運行中值改變的量。變量在內存中占用字節,由變量的數據類型決定。

變量數據類型:
一:
整型:
無符號類型:
1.unsigned short int ; 2byte
2.unsigned int ; 4byte
3.unsigned long int ; 4byte
有符號類型:
1.signed short int ; 2byte
2.signed int ; 4byte
3.signed long int ; 4byte
二:
實型:
float ;4byte -10^38~10^38
double ;8byte -10^308~10^308

算術表達式:+,-,*,/, +, -, %;
不同類型轉換:1/0.2=0.5
相同類型結果類型不變:1/2=0
%左右必須是整數
單精度+0變成雙精度
優先級:先函數 再括號 再乘除 再加減

賦值表達式:=; 變量名=表達式
復合賦值表達式:+=;-=;*=;/=; %=; n+=1--->n=n+1 n*=m+1--->n=n*(m+1)
自增自減:-- ;++ ; int i=1;i-- (i=i+1) 前綴先自我運算后運行語句,后綴先運行語句再自我運算
逗號表達式:表達式1,表達式2,表達式3... 從左到右計算每一個表達式,最后一個表達式的結果是整個表達式的值
賦值語句也叫表達式語句,以;結尾。int i=10;//賦初值語句
i=12; //賦值語句

print(格式控制,輸出項1,輸出項2)
print("a=%d b=%d"a,b); //輸出%需要寫%%
輸出格式:以%開頭,一個格式字符結束,中間插入寬度(數字),左對齊減號,前導數字0

----------------------------------------------------------------------------------------------------------------------------------------
%c 輸出一個字符
%s 輸出一個字符串,遇到'\0'終止
%d 輸出整型數據,%hd短整型,%ld長整型
%o 輸出八進制,不帶前導0, %#o 帶前導0
%x或%X 輸出十六進制不帶前導0
%u 無符號輸出整型數
%f 輸出單精度
%lf 輸出雙精度
%e或%E 以指數形式輸出浮點數 [-1]m.dddddde+/-xxx
%g或%G 由系統決定使用%f還是%e輸出保證寬度最小
%p 輸出變量內存地址
%nd 整數輸出,小於n左邊補空格,右對齊
%n1.n2f 浮點數輸出,n1代表寬度包括小數點,n2代表小數位數,如果小數位數大於n2,截取並四舍五入。
僅僅指定小數位數:%.n2f。
%n1s 不足右邊補空格,右對齊
-% 代表默認左對齊
-----------------------------------------------------------------------------------------------------------------------------------------

盡量不要在print()中做變量運算。
如果print("%*d" ,m,n) m取代*號表示寬度,n是輸出值。

數據輸入函數:
scanf(格式控制,輸入項1,輸入項2)
scanf("%d%f%lf",&k,&a,&h); //必須使用&符號 ,除非變量本身就是地址變量。
scanf("%d%*d%d%d",&x,&h,&k) //輸入1 2 3 4 ,x的值1, h的值3,k的值是4,%*d表示跳過本次輸入的數。
后兩位四舍五入原理:原數乘以100,加0.5,取整,除以100輸出。

選擇結構:
關系運算避免兩個浮點數做相等的比較,兩個浮點數做減法,和一個精度值做比較。
邏輯運算符:&& || !
運算符兩邊有數,是雙目運算符。

if(表達式)語句1

if(表達式)語句1 else 語句2

if()
else if()
else if()
else

條件運算符:?
表達式1?表達式2:表達式3
當表達式1非0,運算表達式2的值作為結果,否則運算表達式3的值作為結果。

switch(表達式)
{ case 常量表達式1:語句1[break;]
case 常量表達式2:語句2[break;]
default : 語句n+1 [break;]
}

代碼示例:

 1 int g;
 2 print("enter g:");scanf("%d",&g);
 3 print("g=%d",g);
 4 switch(g/10)
 5 {
 6     case 10;
 7     case 9: print("A\n");
 8     case 8: print("B\n");
 9     case 7: print("C\n");
10     case 6: print("D\n");
11     default: print(E\n);
12 
13 }

goto語句:
goto 語句符號;

代碼示例:

 1 stop : print("stop");

2 goto stop; 

循環結構:
while(表達式) 循環體
do 循環體 while(表達式);

代碼示例:

1 do 
2 {print("*");k++;
3 }while (k<0);

計算公式:1-2+3-4+5......

 1 #include<stdio.h>
 2 main()
 3 {int n=1,sum=0;
 4 int i=1;
 5 while(n<=100)
 6 {sum=sum+i*n;
 7 n++;
 8 i=-i;
 9 }
10 printf("sum=%d\n",sum);
11 }

計算公式:1-1/2+1/3-1/4+1/5......

 1 #include<stdio.h>
 2 main()
 3 {
 4 int n=1;
 5 double sum=0.0;
 6 int i=1;
 7 while(n<=100)
 8 {sum=sum+i*(1.0/n);
 9 n++;
10 i=-i;
11 }
12 print("sum=%d\n",sum);
13 }

for 循環 :
for(表達式1;表達式2;表達式3)

代碼示例:

1 for(k=2;K<100;k++)
2 {print("program")
3 }

計算判斷素數:2-100之間:

 1 for(i=2;i<100;i++)
 2 {tag=0;
 3     for(k=2;k<i;k++)
 4 {
 5 if(i%k==0)
 6 tag=1
 7 }
 8 if (tag==0)
 9 print("%d",i);
10 }

break:跳出循環,向下繼續運行。
continue:結束本次循環繼續下次循環。

ASCII碼表:字符與數字對照表
常用:
0 :34
1 :35
......
A :65
B : 66
......
a : 97
b : 98
......
(依次增加)

轉義字符:
\n
\t
\r
\\
\'
\"
\0(空值屏幕不可見)

字符串常量:要用 " " 括起來,結尾有'\0'標志。
"a"
"abc"

char a='a';
char a=97;

字符輸出 putchar()
字符輸入 getchar()
空格,tab ,回車 會被接收。

  字母大小寫轉換:

 1   char c;
 2   while((c=getchar())!='\n')
 3   {
 4   if(c>='a'&&c<='z')
 5   {
 6   c=c-'a'+'A';
 7   putchar(c);
 8   }
 9   }
10   putchar('\n');


c語言總是從main()函數開始執行。到main()結束。一個c程序只有一個main()函數。

#include<math.h>
常用數學函數:
pow (底數,指數)求冪
sqrt(數值)開平方
abs(整數值)取整數的絕對值
fabs(實型值)取實型的絕對值
sin(實型值)取得sin值
cos(實型值)取得cos值
exp(實型值)以自然對數e為底的冪

自定義函數:
函數返回值通過return返回

1   double add (double x ,double y)
2   {
3     double s;
4     s=x+y;
5     return s;
6   }
7   double x=10.3,y=13.6,z
8   z=add(x,y);

函數調用,2種傳遞方式:
1.值傳遞 只傳送值 實參不做改變
2.地址傳遞 傳送地址 實參被改變

指針變量:只能放內存地址
訪問變量:直接訪問
訪問指針:間接訪問
定義指針變量:類型名 *指針變量名
double *pd ; //pd基類型為double,只能存放double類型變量地址
指向指針的指針:int **p ,k ,*s=&k ; p=&s ;

指針變量賦空值:int *p; p=NULL; 或 p=0; 或 p='\0';
定義指針中的*:告訴計算機是指針
間址運算符*:通過指針引用存儲單元
*與&是逆運算:* 取值, & 取址
++*p 代表 ++(*p)
*p++ 代表 *(p++)
移動指針:對指針變量加或減去一個整數。使指針變量指向相鄰的存儲單元。
指針比較:if(p<q) 一般用於多個指針指向同一變量的情況。

數組:具有相同類型的變量的集合,這些變量在內存中占有連續的存儲單元。
一維數組:類型名 數組名[整型常量表達式]
int a[8]={1,2,3,4,5,6,7,8}; 當所賦值少於所對應的數組元素個數時,系統自動給后邊補0
通過賦初值定義數組的大小:int a[]={1,2,3,4,5,6,7,8};
直接輸出a與&a[0]相等,說明數組名代表數組的首地址。
通過指針循環移動給數組賦值:

1 int *p,a[10]; 
2 for(p=a;p-a<10;p++);
3 {
4     scanf("%d",p);
5 }

當P指向s[]首地址時:數組元素s[i]有4種表示:s[i] p[i] *(s+i) *(p+i) s固定不可變,P可以變化。

二維數組:類型名 數組名[整型常量表達式1][整型常量表達式2]
int a[3][4];
二維數組賦初值:
int a[3][4]={{1,2,3},{2,3,4},{4,5,6},{7,8,9}};
int a[][3]={{1,2,3},{4,5},{5,7},{3,6}}

對於二維數組,省略只能省略第一個方括號。

int s[][3]={1,2,3,4,5}; 當花括號中的元素個數整除第二維的常量表達式時,整除結果就是第一維的大小,
否則第一維的大小等於整除結果加1。

二維數組實際上是一個一維數組,a[3][4] 中a[0]就代表a[0][0]的地址
int *p ,a[3][4]; p=a[0]是合法的,p=a[0]+1 等於 &a[0][1]
二維數組 數組名a 代表a[0][0]
int i ,j; a[i][j]的地址可以用以下五種表達:&a[i][j] a[i]+j *(a+i)+j &a[0][0]+i+j a[0]+i+j
取值:*(&a[i][j]) *(a[i]+j)
指針數組:int *p[3]; 數組中的元素相當於指針變量。

建立一個行指針引用二維數組元素:int a[2][2]; int (*p)[2];
當二維數組名作為實參時對應的形參必須是一個行指針變量。
在內存中系統會自動在字符串末尾加上一個'\0' ,'\0'不算做字符串的長度。

字符串的標准頭文件:
#include<string.h>

字符數組賦初值:
char str[]={'f','a','d','\0'};
char str[]="hallo";
char str[10]={"hallo"};
在定義指針變量的同時讓指針變量指向str的首地址:
char str[]="from",*p2=str;
通過賦值運算使指針指向一個字符串:char *p ; p="from";

輸入字符串的時候空格和回車會作為分隔符不能讀入:
char str[8];
scanf("%s",str);

當輸入數組元素的地址將從該元素讀入字符:
char str[13];
scanf("%s",str+1);

'\0'對應的數值是0

gets 接收字符串:
char str[25];
gets(str);
此處可以接收空格,回車將被替換成'\0';

puts 輸出字符串:
puts(字符串首地址);

二維字符數組:
char name[10][33];

賦初值下標可以省略:
char c[][12]={"s","f","g","k"};

用指針數組賦初值:
char *p[3]={"s","g","l"};
各個字符串占用的空間不一定是連續的,訪問這些字符串依賴於指針。

字符串復制:strcpy(s1,s2);

字符串連接:strcat(s1,s2);

字符串長度:strlen(s);

字符串比較:strcmp(s1,s2); 不同返回1

指向函數的指針:在c語言中函數名代表該函數的入口地址,因此定義一種指向
函數的指針來存放這種地址。
double (*fp)(int,int *);

局部變量全局變量:
變量定義是指給變量分配確定的儲存空間。
變量說明是指說明變量的性質。
局部變量:也叫內部變量,在函數內部和復合語句中定義的變量。
全局變量:也叫外部變量,在函數外部定義的變量。
儲存類別:自動類,局部變量可以說明為自動或靜態類;
靜態類:全局變量只能是靜態類。

說明符: auto 自動
register 寄存器
static 靜態
extern 外部
在函數內部或復合語句中定義變量時,如果沒有指定存儲類,系統默認為自動類,
auto變量的存儲單元被分配在內存的動態存儲區,當進入函數體時系統自動為auto變量分配存儲單元
退出時自動釋放。
寄存器變量也屬於自動類,與自動類的區別:將變量的值保留在pcu的寄存器中,register變量沒有
地址,不能進行求址運算。
靜態變量:在整個程序運行期間,靜態變量在靜態存儲區占據永久存儲單元。
靜態局部變量沒有賦初值,c編譯程序自動給賦初值0
外部函數extern可以被其他編譯單位中的函數調用,函數的返回值為非整型時,應該在調用語句的函數部分
用extern對所用的函數進行說明。
靜態函數:只限於本編譯單位的函數調用。

宏替換(宏定義):
#define 宏名 替換文本
宏定義在一行寫不下轉下一行,用字符“\”
帶參數的宏替換:
#define 宏名(形參表) 替換文本
#define M(x,y) x*y
a=M(4,5);
終止宏替換:
#undef

文件包含:
#include"文件名"
如果用" "引起來,系統先在源程序所在目錄內查找指定文件,如果沒有找到則按標准方式查找。
#include<文件名>
如果用<> 引起來,系統直接按標准方式查找文件。

動態存儲分配:
malloc函數:malloc(size)
返回值類型:void , 所以需要使用強制類型轉換。
int *p;
p=(int *)malloc(sizeof(int));
print(*p);

free函數:free(p); 指針p必須指向由動態分配函數malloc分配的地址,
free函數將指針所指向的存儲空間釋放。
此函數沒有返回值。

calloc函數:calloc(n,size);
函數返回值:void*
用來給n個同一類型的數據分配連續的存儲空間,每個數據長度為size
char *p;
p=(char *)calloc(10,sizeof(char));
使用calloc函數開辟存儲單元相當於開辟一維數組,函數第一個參數決定數組的大小,
第二個參數決定數組元素的類型。

typedef 數據類型 新的名稱

結構體類型:
struct 結構體標志名
{
類型名1 結構成員表1
......
類型名n 結構成員名n
}變量1,變量2;

給結構體定義別名

1 typedef struct
2 {
3     char name[12];
4     char sex;
5     int year,month,day;
6     float sc[4];
7 }STRUC;
8 STRUC std,per[3],*pstd;

結構體賦初值:

1 struct 
2 {char name[12];
3 char sex;
4 int year,month,day;
5 float sc[4];
6 }std={"liming",'m',1988,2,6,88,66,77,99};

給結構體數組賦初值:

1 struct bookcard
2 {char num[5];
3 float money;
4 }bk[3]={{"no.1",44.6},{"no.2",66,7},{"no.3",43.8}};

結構體變量中數據的引用:
結構體名:std.sex
指針:p->sex
指針:(*p).sex

共用體類型:
union 結構體標志名
{
類型名1 結構成員表1
......
類型名n 結構成員名n
}變量1,變量2;

結構體與共用體不同:
結構體成員變量各自占有自己的存儲空間,共用體中所有成員占有同一個存儲空間,
共用體占用的內存字節與成員中所占字節數最多的那個成員相等。

鏈表:一種重要的數據結構,是動態的進行存儲分配的結構。
鏈表組成:
頭指針:存放一個地址,指向一個元素。
節點:用戶需要的實際數據和鏈接節點的指針。
定義一個節點:

1 struct s
2 {int num;
3 float g;
4 struct s *next;
5 };

用結構體實現鏈表:

 1 #include <stdio.h>
 2 #define NULL 0
 3 struct student
 4 {long num;
 5 float score;
 6 struct student *next;
 7 };
 8 main()
 9 {struct student a,b,c,*head,*p;
10 a.num=101;  a.score=89.1;
11 b.num=102;  b.score=88.4;
12 c.num=103;  c.score=77.5;
13 head=&a;  a.next=&b;  b.next=&c;  c.next=NULL;
14 p=head;
15 do
16 {printf("%ld%5.1f\n",p->num,p->score);
17 p=p->next;
18 }while(p!=NULL);
19 }

在節點p q之間插入節點算法:
新插入節點s:

1 s->next=p->next;
2 p->next=s;

刪除節點s:
假設3個節點p s q

1 p->next=p->next->next;
2 free(s);

位運算:
按位取反:~
左移:<<
右移:>>
按位與:&
按位異或:^
按位或:|

文件指針:是一個指向結構體的指針。
文件類型指針定義形式:FILE *指針變量名;
FILE *fp;
fp=fopen("文件路徑","打開方式");
------------------------------------------
r 只讀
w 只寫
a 追加
rb 只讀打開二進制文件
wb
ab
r+ 打開文本文件
w+ 建立新的文本文件
a+ 打開文本文件
rb+
rw+
ab+
--------------------------------------------
關閉文件:fclose(fp);
判斷文件結束:feof(文件指針); 文件結束返回1
feof(fp);

格式化讀寫函數:從磁盤文件中讀寫字符
fprintf(文件指針,格式字符串,輸出);
fscanf(文件指針,格式字符串,輸入);
fprintf(fp,"%d,%f",i,t); //把字符串寫入文件
fscanf(fp,"%d,%f",&i,&t); //顯示文件內容

fgets(str,n,fp); 從指定文件讀入字符串
返回值:str的首地址
fputs("chiiaa",fp); 向指定文件輸出字符串
返回值:成功為0,失敗EOF

fread(buffer,size,count,fp);
buffer是數據塊指針,他是內存的首地址,輸入的數據准備存入此塊中
fwrite(buffer,size,count,fp);

rewind(fp); 使文件的位置指針回到文件開頭
fseek(fp,offset,origin); 移動文件位置指針到指定位置
ftell(fp); 獲得文件的位置指針的當前位置,調用出錯返回-1L

-------------------------------------------------------------------------------------------------------結束

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM