帶你重新溫習一遍C語言,這些基礎C語言知識你都瞭解嗎?

目錄

1. 常量、變量、數據類型

2. 運算符與表達式

3. 基本語句

4. 選擇結構

5. 循環結構

6. 數組

7. 函數

8. 指針

9. 編譯預處理和動態存儲分配

10. 結構體與共用體

11. 文件

12. 綜合運用 — 學生成績管理系統設計


1. 常量、變量、數據類型

  • 源程序有一個或者多個函數構成,每個函數完成相對獨立的功能。
  • 一個C語言程序中有且只有一個main函數,程序執行從main函數開始,從main函數結束。
  • 函數體:函數後面用{}括起來的部分。
  • 每個執行語句後面加上“;”,預處理、函數頭、}後面不加“;”。
  • 註釋:/*......*/。
  • 預處理:以#開頭。
  • 區分大小寫。
  • 運行過程

(1)標識符

  • 只能有數字、字母、下劃線組成,第一個字符必須使字母或下劃線,區分大小寫。
  • 標識符分類:關鍵字(如for、while等)、預定義標識符、用戶標識符。

(2)常量

  • 在程序運行中其值不能被改變的量。
  • 整型常量、字符型常量、實型常量、字符串常量、符號常量。
  • 整型常量

   十進制常量(123)、八進制常量(o15)、十六進制常量(ox2A),默認類型爲int(有符號基本整型)、無符號整型常量其後加U或u(123u)、長整數其後加L或l。

  • 實型常量

  十進制小數形式:小數點兩邊必須都有數字。(13.23)

  指數形式e:前必須有數字,後面必須爲整數。(1.23e4)

  默認類型:double。

  後面加上F或f爲float類型。

  • 字符常量

  用單撇號括住:‘a’、‘+’等。轉義字符如下:

  • 字符串常量

用雙撇號括住:“123456”等。字符串常量佔用內存字節數等於字符串中的字節數加1,最後一個字節存放‘\0’

  • 符號常量

由預定義命令定義的常量。如:#define R 3

(3)變量

  • 值可以改變的量,在使用前必須先定義。
  • 如:int i,j;
  • 整型變量

  • 實型變量

  • 字符變量

用來存放字符常量。

用關鍵字char定義。

定義形式:char cr;

賦值:cr=‘m’;

(4)類型的自動轉換與強制轉換

  • 當表達式中類型不一致時,編譯器會進行類型轉換。
  • 優先級:char<int<float<double
  • 賦值運算時右別向左別進行轉化。
  • 強制類型轉換:(類型)(表達式)

2. 運算符與表達式

(1)運算符

   所有單目運算符、條件運算符、賦值運算符、拓展運算符都是從右向左結合,其餘爲從左向右結合。+(加)、-(減)、*(乘)、/(除)、%(餘),其中%兩端必須爲整數。雙目運算符兩側數值類型一致才能進行運算。如果不一致則系統會進行轉換。

  • 自增運算符++

++i、--i:在使用i之前,先進行加1或減一。

i++、i--:在使用i之後,使i的值加1或減1。

自左向右結合

  • 位運算

3. 基本語句

(1)printf函數

  提供的標準輸出函數,形式printf(格式控制,輸出列表)

printf("%d\n",sum);

(2)scanf函數

  形式:scanf(格式控制,地址表列)

#include<stdio.h>
main()
{
	int sum;
	scanf("%d",&sum);
	printf("%d\n",sum);
}

(3)字符輸出函數和字符輸入函數

  • 字符輸出函數:putchar()向終端輸出一個字符
  • 字符輸入函數:getchar()向終端輸入一個字符

4. 選擇結構

  • if語句
#include<stdio.h>
main()
{
	int i=1,j=2;
	if(i>=j)
	printf("%d\n",i);
	else
	printf("%d\n",j);	
}
  • 條件表達式

   表達式1?表達式2:表達式3;

#include<stdio.h>
main()
{
	int sum;
	sum=2>3?2:4;
	printf("%d\n",sum);	
}
  • switch語句

switch(表達式){

case 常量表達式:語句1

case 常量表達式:語句2

case 常量表達式:語句n

default:語句n+1

}

5. 循環結構

  • while循環語句

while(表達式)

循環體

先對表達式進行判斷,後執行語句,知道表達式爲0時,退出循環體。

  • do...while循環

do{

循環體

}

while(表達式);

  先執行循環體一次,然後判斷循環條件是否成立。當表達式爲假時,退出循環。

  • for(語句1;語句2;語句3)

  語句1:賦值;語句2:判斷;語句3:運算

  • break和continue語句

   break:用於從循環體跳出,該語句只能出現在循環體內及switch語句內,不能用於其它語句。

   continue:結束本次循環。

6. 數組

(1)一維數組

  一維數組是指數組中的每個元素只帶有一個下標的數組。

  定義方式:類型說明符  數組名[常量表達式]

  必須先定義後使用,數組名定名規則與變量名相同,常量表達式爲數組長度。

  • 一維數組的引用

例如:int tab[3]={0,1,2};

tab[0]=0

tab[1]=1

tab[2]=2

  • 一維數組初始化

   使數組中的元素都爲0:

例如:int tab [3]={0,0,0};或int tab[3]={0};

   對數組賦值:

例如:int tab[3]={1,2,3};也可以寫成:int tab[]={1,2,3};

(2)二維數組

  在C語言中,二維數組元素的排列順序爲按行排放。

  一般形式:數據類型  數組名[常量表達式][常量表達式]

  如:int a[3][3]

  • 二維數組初始化

例如:int a[3][3]={{0,1,2,3},{2,3,4,5},{4,5,6,7}};

           int a[2][3]={1,2,3,4,5,6};

(3)字符數組

  初始化:

  數組的輸入輸出:

%c:將字符逐個輸入或輸出

%s:將整個字符串輸入或輸出

(4)字符串處理函數

  •   puts():將一個字符串輸出到終端(以‘\0’結束)
  •   gets(字符數組):從終端輸入一個字符串到字符數組,並且得到一個函數值。
  • strcpy函數

   strcpy(字符數組1,字符串2):將字符串2複製到字符數組1中。

  • strcat函數

   strcat(字符數組1,字符數組2)

  • strlen函數

   strlen(字符數組):計算字符數組的長度。

  • strcmp函數

   strcmp(字符數組1,字符數組2)

7. 函數

(1)函數概述

  一個C程序主要有一個主函數和其它若干函數組成的,並且只有一個主函數。

  用戶角度函數分爲:標準函數、自定義函數。

  函數形式看:無參函數、有參函數。

(2)函數定義形式

  如:求出給定任意兩個正整數的和。

#include<stdio.h>
int add(int m,int n);
main()
{
int sum,m,n;
printf("請輸入兩個整數爲:"); 
scanf("%d%d",&m,&n);	
sum=add(m,n);
printf("求和結果爲:%d\n",sum);
}

int add(int m,int n){
	int sum;
	sum=m+n;
	return sum;
}
請輸入兩個整數爲:75 25
求和結果爲:100

--------------------------------
Process exited after 4.032 seconds with return value 16
請按任意鍵繼續. . .

(3)函數參數與返回值

  • 形式參數與實際參數

   在定義函數時,函數後面的括號中的變量稱爲形式參數。(形參)

   在主調函數中,函數後面的括號中的變量稱爲實際參數。(實參)

   形式參數與實際參數數目應該保持一致。

  • 函數返回值

   函數返回值是通過return語句獲得的。

   函數返回值應當屬於確定的某一個值,在定義函數時指定返回類型。

   對於不帶回值的函數應當用void定義函數爲無類型,此時函數體中不得出現return函數。

  • 函數調用:函數語句、函數表達式、函數參數

(4)函數遞歸調用

#include<stdio.h>
int age (int n);
main(){
printf("最終年齡爲:%d\n",age(5));	
}

int age (int n){
	int m;
	if(n==1)
	m=10;
	else
	m=age(n-1)+2;
	return m;
}
最終年齡爲:18

--------------------------------
Process exited after 0.08125 seconds with return value 15
請按任意鍵繼續. . .

(4)數組作爲函數參數

  • 數組元素作爲函數實參
  • 數組名可以作爲函數參數

(5)全局變量與局部變量

  • 全局變量:在函數之外定義的變量,作用範圍從定義變量開始到本文件結束。
  • 局部變量:在函數內部定義的變量,只能在本函數內部使用。

(6)變量的存儲類別

  • auto變量

   系統默認類型。

  • register變量

   寄存器變量也是自動變量,可以提高機器的運行效率。它是將變量編譯保存到CPU內存中去。

  • 靜態存儲的局部變量

   用static進行聲明。在整個運行過程中不釋放存儲單元。初值爲0或空字符。在其它函數中不能調用。

  • 外部變量extern

   在一個文件中引用後面定義的外部變量則用extern進行聲明。

  • 用static聲明外部變量

   如果希望全局變量只能被本文件引用,則引用static來進行說明全局變量。

8. 指針

(1)地址與指針

  •   在C語言中將地址可以稱爲指針,一個變量的地址稱爲變量的指針。一個專門存放另一個變量地址的指針稱爲指針變量。
  •   取地址運算符&,返回操作數的地址。
  • 數組的地址可以用數組名來表示。
  • 函數名可以表示函數的地址。
  • 指針變量

一般形式:類型說明符  *指針變量名

例如:int *p,m;

          char *k;

          double *t;

p=&m;表示用賦值語句使一個指針變量指向整型變量。

  • 指針變量的引用

指針運算符 * :返回該地址中的變量值。

&和*互爲逆運算。

  • 指針變量作爲函數參數

指針變量既可以作爲形參,也可以作爲實參。

指針變量作爲實參時,也是值傳遞。

#include<stdio.h>
void sw1(int *p1,int *p2);
main(){
	int a=5,b=10;
	printf("輸出:a=%d,b=%d\n",a,b);
	sw1(&a,&b);
	printf("輸出:a=%d,b=%d\n",a,b);	
}

void sw1(int *p1,int *p2){
	int temp;
	temp=*p1;
	*p1=*p2;
	*p2=temp;	
}
輸出:a=5,b=10
輸出:a=10,b=5

--------------------------------
Process exited after 0.08376 seconds with return value 15
請按任意鍵繼續. . .

(2)數組與指針

  • 指向數組元素指針

   C語言中數組名爲數組的首地址,也就是數組中第0號元素的值,p=&a[0]等價於p=a

  • 通過指針引用數組元素

如果有 int a[10],*p=a;

p+i和a+i都是數組元素a[i]的地址。

*(p+i)和*(a+i)都是數組元素a[i]的值。

p[i]=*(p+i)

例如:一個整型數組,輸出其全部值?

#include<stdio.h>
main(){
	int tab[5]={1,2,3,4,5},*p=tab,i;
	printf("用數組輸出值:"); 
	for(i=0;i<5;i++){
		printf("%d",tab[i]);
	}
	printf("\n用指針輸出值:"); 
	for(i=0;i<5;i++){
		printf("%d",p[i]);
	}
	
}
用數組輸出值:12345
用指針輸出值:12345
--------------------------------
Process exited after 0.1296 seconds with return value 1
請按任意鍵繼續. . .


  • 用數組名作爲函數參數
  1. 形參與實參都用數組名。
  2. 實參用數組名,形參用指針變量。
  3. 實參與形參都用指針。
  4. 實參爲指針,形參爲數組名。

(3)字符串與指針

  • 表示形式

例如:char str[]="hello";

用字符指針指向一個字符串:char *p="hello";

等價於:char *p;

              p="hello";

  • 字符指針變量和字符數組的區別

賦值方式不同:

  1. 字符數組可以在其定義時候進行整體賦值,但在賦值語句中不能完成整體賦值。
  2. 字符指針變量可以在定義的時候賦值,也可以在賦值語句中完成。

編譯時不同:

  1. 在程序中指針變量的值可以改變,而數組名不可以改變。

(4)返回指針函數

   返回指針函數定義的格式爲:函數類型   *函數名([形參表])

例如:int *b(int m,int n)

  • 指針數組

   在一個數組中,其元素均爲指針數組類型,這樣的數組稱爲指針數組。

   一維指針數組定義的形式:類型名 *數組名[數組長度]

例如:int *a[4]

表示數組共有四個元素,每個元素都指向整型數組。

9. 編譯預處理和動態存儲分配

(1)宏定義

  • 不帶參數的宏定義

   定義形式:#define 宏名 替換文本

例如:#define PI 3.14

可以用#undef命令終止宏定義的作用域。

同一個宏名不能重複定義。

在進行宏定義時,可以引用已經定義好的宏。

  • 帶參數的宏定義

   定義形式:#define 宏名(參數表)字符串

例如:#define m(y) y*y

(2)文件包含#include

  文件包含命令行的一般形式爲:#include“文件名”或#include<文件名>

(3)動態存儲函數

  函數原型:void *malloc(unsigned int size)

  系統自動在內存動態存儲區中,分配長度爲size的一段連續空間。

  若執行成功:函數返回值指向被分配域的起始地址指針。

  若執行失敗:函數返回值爲空指針。

10. 結構體與共用體

(1)typedef

  一般形式:typedef 類型名 標識符

  類型名:已有定義的類型標識符。標識符:用戶自己定義標識符。

例如:typedef int A

int a;等價於A a;

(2)結構體數據類型

一般形式:struct 結構體名{

成員列表

};

  • 先聲明結構體類型再定義變量名

  如已經定義了結構體struct student,可以定義:

struct student student1,student2;
  • 在聲明類型的同時定義變量
struct student{

char name[20];
int age;
char sex;

}student1,student2;
  • 直接定義結構體類型變量
struct{
成員列表
}變量名列表;

(3)結構體變量的引用

  結構體變量不能作爲一個整體而對其進行操作,只能對其中結構體變量中的各個成員分別進行輸入與輸出。

  結構體變量名.成員名

  如果結構體某個成員又是一個結構體類型,則可以使用若干個成員運算符,一級一級的找到最低的一級成員。

  結構體變量成員可以和普通變量一樣進行各種運算。

(4)結構體數組

struct student{
char name[20];
int num;
}stu[2]={{"song hong",123},{"li hang",124}};

(5)指向結構體類型數據的指針

結構體變量名.成員名==*(結構體指針變量名).成員名==結構體指針變量->成員名

在使用指針變量指向結構體數組時,只要把結構體數組中的每個元素當做普通變量即可。

(6)鏈表

  1. 鏈表是一種常見的數據結構,它可以動態的存儲單元分配的一種結構。
  2. 鏈表最後一個結點的指針域置成'\0'值,標誌着鏈表結束。
  3. 每個鏈表都用一個頭指針變量來指向鏈表的開始,稱爲head指針。存放鏈表第一個結點的地址。
  4. 每個結點由兩個域組成:數據域和指針域。
  5. 鏈表基本操作:創建、檢索、插入、刪除、修改。
  6. 順序訪問鏈表中各節點的數據域。
  7. 還有刪除節點和插入節點。

(7)共用體

  幾個不同的變量共佔同一段內存的結構。

  定義形式:

union 共用體名{

成員變量

}變量列表;

11. 文件

C語言把文件分爲:ASC\amalg文件(文本文件)和二進制文件,文件是一個字節流或者二進制流。文件存取方式:順序存取、直接存取。

FILE *fp

fp是指向FILE結構體類型的指針變量。

(1)fopen函數

  格式:fopen(文件名,文件使用方式)

  當出現錯誤時候,函數返回值爲NULL。

(2)fclose函數

  格式:fclose(文件指針)

  當執行關閉操作時候,成功返回爲0,失敗爲非0。

(3)fread和fwrite函數

  格式:

fread(buffer,size,count,fp);
fwrite(buffer,size,count,fp); 
  • buttfer:指針變量。
  • size:讀寫的字節數。
  • count:用來指定每讀寫一次,輸入或者輸出數據塊數。
  • fp:文件數據類型指針。

(4)格式化讀寫函數

  格式:

fscanf(文件指針,格式字符串,輸入列表);
fprintf(文件指針,格式字符串,輸出列表);

  作用在磁盤文件上的數據。

(5)fputs函數

  把字符串輸入到文件中去。

fputs(str,fp);
  • str:輸出字符。
  • fp:文件指針。

(6)rewind函數

rewind(fp);

  使文件的位置指針重新返回到文件的開頭。

(7)fseek函數

fseek(文件指針類型,位移量,起始點);

  起始點:

文件開頭:0

文件當前位置:1

文件結尾:2

12. 綜合運用 — 學生成績管理系統設計

實現過程:https://blog.csdn.net/fanjufei123456/article/details/104003332

要求:

1、成績錄入:輸入學生的學號、姓名及三門課的成績;

2、成績查詢:(至少一種查詢方式)。按學號查詢學生記錄,或查詢不及格學生的記錄;

3、成績統計:計算學生的平均分;根據學生的平均分高低,對學生的數據進行排序後輸出;對學生單科成績排序,輸出學生姓名與該科成績;

4、退出系統:退出整個系統(即主菜單);

#include <stdio.h>
 
#include<stdlib.h>
 
typedef struct student
 
{
 
int num;
 
char name[13];
 
int score[3];
 
double aver;
 
}STU;
 
void ave(STU s[],int n)
 
{ double a[1000];
 
int i;
 
for(i=0;i<n;i++)
 
a[i]=(s[i].score[0]+s[i].score[1]+s[i].score[2])/3.0;
 
printf("學號\t姓名\t\t分數1\t分數2\t分數3\t平均分\n");
 
for(i=0;i<n;i++)
 
printf("%d\t%s\t\t%d\t%d\t%d\t%.1f\n",s[i].num,s[i].name,s[i].score[0],s[i].score[1],s[i].score[2],a[i]);
 
}
 
void search(STU s[],int n, int a)
 
{
 
int i,k=0;
 
for(i=0;i<n;i++)
 
{
 
if(s[i].num==a)
 
{ printf("學號\t姓名\t分數1\t分數2\t分數3\t\n");
 
printf("%d\t%s\t%d\t%d\t%d\n",s[i].num,s[i].name,s[i].score[0],s[i].score[1],s[i].score[2]);
 
k=k+1;
 
break;
 
}
 
}
 
if(k==0)
 
printf("\t沒有查詢到相關信息");
 
}
 
void average(STU s[],int n)
 
{ int i,j;
 
STU ss[10000];
 
STU *p=ss;
 
for(i=0;i<n;i++)
 
s[i].aver=(s[i].score[0]+s[i].score[1]+s[i].score[2])/3.0;
 
for(i=0;i<n;i++)
 
ss[i]=s[i];
 
for(i=0;i<n-1;i++)
 
{
 
for(j=i+1;j<n;j++)
 
{
 
if(ss[i].aver<ss[j].aver)
 
{
 
STU temp=*(p+i);
 
*(p+i)=*(p+j);
 
*(p+j)=temp;
 
}
 
}
 
}
 
printf("學號\t姓名\t平均分\n");
 
for(i=0;i<n;i++)
 
printf("%d\t%s\t%.1f\n",(p+i)->num,(p+i)->name,(p+i)->aver);
 
}
 
void grade(STU s[],int n)
 
{int i,j,k;
 
STU ss[10000];
 
STU *p=ss;
 
for(i=0;i<n;i++)
 
ss[i]=s[i];
 
printf("請輸入k的值查詢,k=0時按分數1,k=1時按分數2,k=2時按分數3:");
 
scanf("%d",&k);
 
for(i=0;i<n-1;i++)
 
{
 
for(j=i+1;j<n;j++)
 
{
 
if(ss[i].score[k]<ss[j].score[k])
 
{
 
STU temp=*(p+i);
 
*(p+i)=*(p+j);
 
*(p+j)=temp;
 
}
 
}
 
}
 
printf("姓名\t分數\n");
 
for(i=0;i<n;i++)
 
printf("%s\t%d\n",(p+i)->name,(p+i)->score[k]);
 
}
 
main()
 
{ int N,i;
 
STU s[10000];
 
int num1;
 
int menu;
 
printf("請輸入學生個數:");
 
scanf("%d",&N);
 
for(i=0;i<N;i++)
 
{
 
printf("請輸入學號 姓名 分數1 分數2 分數3\n");
 
scanf("%d%s%d%d%d",&s[i].num,s[i].name,&s[i].score[0],&s[i].score[1],&s[i].score[2]);
 
}
 
printf("\n\n");
 
printf("*************學生成績管理系統*************\n\n");
 
printf("1--------輸出平均分\n");
 
printf("2--------按學號查詢成績\n");
 
printf("3--------按平均分排序後輸出\n");
 
printf("4--------對學生單科成績排序後輸出\n");
 
printf("5--------退出程序\n");
 
printf("\n\n");
 
while(1)
 
{
 
printf("\n請輸入菜單號:");
 
scanf("%d",&menu);
 
switch(menu)
 
{
 
case 1: ave(s,N);break;
 
case 2: printf("請輸入要查詢的學號:");
 
scanf("%d",&num1);
 
search(s,N,num1);
 
break;
 
case 3: average(s,N);break;
 
case 4: grade(s,N);break;
 
case 5: exit(0);
 
default:
 
printf("菜單號輸入錯誤\n");
 
break;
 
}
 
}
 
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章