戈韋思網(wǎng)站建設優(yōu)化網(wǎng)站推廣教程排名
文章目錄
- 前述
- 一、數(shù)據(jù)
- 1.1 數(shù)據(jù)類型
- 1.2 數(shù)據(jù)
- 第一種數(shù)據(jù):常量
- 第二種數(shù)據(jù):變量
- 第三種數(shù)據(jù):表達式
- 1、算術運算符及算術表達式
- 2、賦值運算符及賦值表達式
- 3、自增、自減運算符
- 4、逗號運算符及其表達式(‘順序求值’表達式)
- 5、強制類型轉換(顯式轉換)
- 6、隱式轉換
- 第四種數(shù)據(jù):函數(shù)
- 1.3 標識符
- 二、順序結構
- 2.1 什么是順序結構
- 2.2 printf()輸出函數(shù)
- 2.3 scanf()輸入函數(shù)
- 2.4 字符類型數(shù)據(jù)的輸入輸出專屬函數(shù)
- 三、選擇結構(也叫分支結構)
- 3.1 兩類表達式
- (1)關系運算符及關系表達式
- (2)邏輯運算符與邏輯表達式
- 3.2 if語句
- 3.3 switch語句
- 四、循環(huán)結構
- 格式1——while語句
- 格式2——do while語句
- 格式3——for語句
- 兩個控制語句——break continue
- 例題
- 五、數(shù)組
- 5.1 一維數(shù)組的定義和引用(只有一個下標)
- 1、一維數(shù)組的定義格式:
- 2、一維數(shù)組元素的引用格式:
- 3、一維數(shù)組的初始化
- 5.2 二維數(shù)組的定義和引用(有兩個下標)
- 1、二維數(shù)組的定義格式:
- 2、二維數(shù)組的引用
- 3、二維數(shù)組的初始化
- 5.3 字符數(shù)組
- 1、字符數(shù)組的初始化
- 2、字符串
- 3、字符串使用
- (1)字符串存儲(賦值)四種方法
- (2)字符串函數(shù)
- 六、函數(shù)
- 6.1 函數(shù)定義
- 6.2 函數(shù)調用的兩種方式
- 6.3 函數(shù)使用例題分析
- 七、在函數(shù)中的變量
- 7.1函數(shù)的定義與使用
- 7.2 變量的三個屬性
- 1、變量類型
- 2、作用范圍
- 3、存儲類別
- 八、預編譯命令
- 8.1 預編譯命令
- 8.2 宏
- 1、第一種:無參宏定義
- 2、第二種:帶參宏定義
- 九、指針
- 9.1 指針變量定義
- 1、定義的格式:
- 2、指針變量的引用
- 9.2 指向數(shù)組的指針變量
- 1、指向數(shù)組元素的指針變量
- 2、指向一維數(shù)組的指針變量
- 9.3 指向多維數(shù)組的指針變量
- 1、指向多維數(shù)組元素的指針變量
- 2、指向由m個元素組成的一維數(shù)組的指針變量
- 7.4 指向字符串指針的指針變量
- 7.5 指向函數(shù)的指針變量
- 7.6 返回指針的參數(shù)
- 7.7 指針數(shù)組和指向指針的指針變量
- 1、若一個數(shù)組的所有元素均為指針類型(地址),則稱為指針數(shù)組。
- 7.8 空指針
- 九、構造類型
- 9.1 結構體類型
- 1、構造結構體類型
- 2、定義結構體變量
- 3、結構體變量的初始化及引用】】使用結構體變量、結構體數(shù)組、結構體指針變量
- 9.2 共用體類型
- 1、共用體變量的定義
- 2、共用體變量的引用
- 9.3 typedef
- 十、位運算與文件
- 10.1 位運算
- 1、按位與運算(&)
- 2、按位或運算(|)
- 3、按位異或運算(^)
- 4、按位取反運算(~)
- 5、按位左移運算符(<<)
- 6、按位右移運算符(>>)
- 10.2 文件
- 1、文件概念
- 2、文件的打開與關閉
- 3、文件的讀寫
- 4、文件當前位置讀寫函數(shù)
前述
C語言是一門編程語言,在大學中很多專業(yè)都會學習,考研中部分專業(yè)會有涉及,工作中也仍有應用。
以下是chatgpt對c語言的簡單介紹:
C語言是一種廣泛應用于系統(tǒng)編程和應用程序開發(fā)的高級編程語言。以下是對C語言的簡單介紹:
發(fā)展歷史:C語言由貝爾實驗室的Dennis Ritchie在20世紀70年代初開發(fā)而成。它是基于早期的B語言,并在其基礎上進行了改進和擴展。
特點和優(yōu)勢:
- 簡潔而高效:C語言提供了簡潔而高效的語法結構,使得程序編寫和閱讀相對容易。它具有較少的語法規(guī)則和關鍵字,使得程序員可以更自由地控制代碼的行為。
- 高度可移植性:C語言編寫的程序可以在不同的計算機平臺上進行編譯和運行,具有較高的可移植性。這使得C語言成為系統(tǒng)級編程和跨平臺開發(fā)的首選語言之一。
- 強大的底層控制能力:C語言提供了豐富的底層控制能力,可以直接訪問內存和硬件資源。這使得C語言在系統(tǒng)編程、驅動程序開發(fā)和嵌入式系統(tǒng)等領域得到廣泛應用。
- 豐富的函數(shù)庫:C語言擁有豐富的標準函數(shù)庫和第三方函數(shù)庫,可以方便地進行各種操作,如文件處理、字符串處理、數(shù)學計算等。
應用領域:C語言廣泛應用于系統(tǒng)編程、嵌入式系統(tǒng)開發(fā)、驅動程序開發(fā)、操作系統(tǒng)開發(fā)等領域。它也是其他高級編程語言(如C++、Java等)的基礎語言。
需要注意的是,C語言相對較底層,需要程序員自行管理內存和資源,因此對于初學者來說可能有一定的學習曲線。但掌握C語言的基礎知識可以為后續(xù)學習其他編程語言打下堅實的基礎。
一、數(shù)據(jù)
編寫程序的目的是處理數(shù)據(jù),所以先要了解數(shù)據(jù)。計算機中的數(shù)據(jù)不同于我們數(shù)學課上寫的數(shù)可以隨意表示任何數(shù)據(jù),計算機中的整數(shù)和小數(shù)是不一樣的,它們屬于不同的類型:計算中的數(shù)據(jù)是有類型的。
1.1 數(shù)據(jù)類型
數(shù)據(jù)類型四大類:基本類型、構造類型、指針類型、空類型
- 基本類型:字符型 char、整型 int、浮點型(單精度浮點型 float、雙精度浮點型 double)
- 構造類型:數(shù)組型、結構體類型 struct、共用體類型、枚舉類型 enum
- 指針類型
- 空類型
1.2 數(shù)據(jù)
C語言中的常量、變量、表達式、函數(shù)都可以理解為數(shù)據(jù)。
第一種數(shù)據(jù):常量
常量有四類:整型常量、實型常量、字符型常量、字符串常量。
- 整型常量:三種形式(十進制、八進制、十六進制)
- 實型常量:兩種形式(小數(shù)、指數(shù))
- 第一形式 -> 小數(shù)形式:由數(shù)字和小數(shù)點組成。
如:123.456 123. .456 0.456 都是合法的實型常量。 - 第二形式 -> 指數(shù)形式:用"E"或"e"后緊跟一個整數(shù)表示以10為低的冪。
如:1.23E-5
注:
字母E或e之前之后必須都有數(shù)字,且后必須是整數(shù)。
字母E或e的前后及各數(shù)字之間不能有空格。
- 第一形式 -> 小數(shù)形式:由數(shù)字和小數(shù)點組成。
- 字符型常量:四種形式(常規(guī)、轉義、八進制、十六進制)
- 第一形式 -> 普通字符:一對單引號括一個字符
如:‘a(chǎn)’ ‘A’ ‘@’ ‘9’ - 第二形式 -> 轉義字符常量:必須以一個反斜杠“\”作為開頭,常用的轉義字符有
\n 表示換行符
\t 表示制表符
\b 表示退格符
\r 表示回車符 - 第三形式 -> 八進制表示的字符:\ddd 最多可以有三位八進制數(shù)
- 第四形式 -> 十六進制表示的字符:\xhh 最多可以有兩位十六進制數(shù)
- 第一形式 -> 普通字符:一對單引號括一個字符
- 字符串常量:一種形式
定義:用一對雙引號括起來若干個字符
如:“abcdefgh” “123456” “a1b2c3”
注:
每一個字符串尾都有一個字符 ‘\0’
C語言種沒有字符串變量
第二種數(shù)據(jù):變量
變量使用規(guī)則:先定義后使用
定義格式:數(shù)據(jù)類型名 變量名列表;
比如:
int i;int j;int k;
int i, j, k;
int i=1, j=1, k=9; /*賦初值*/
注:
- 變量必須先定義后使用。
- 變量名屬于用戶標識符,遵守用戶標識符命名規(guī)則。
- 在同一“函數(shù)體”{}中 不能定義同名變量。
- 同時定義多變量,必須用逗號分隔。
- 變量可賦初值(初始化),無初值是隨機值。
第三種數(shù)據(jù):表達式
各種表達式
定義:表達式:用運算符將數(shù)據(jù)連接起來的合法式子
運算符:三個屬性:功能、優(yōu)先級、結合性(運算方向(左->右 or 左<-右))
如:
3.5 + 1/2 3.5 + (1/2)
1+2+3 (3.5 * 1)/ 2 = 1.75
1.0/2 = ? 1/2 = ?
1、算術運算符及算術表達式
+ - * / % 【結合性是 左->右】
取余(%):
- 兩邊的運算對象必須是整型
如:7.0%3、4%3. 、不合法的表達式 - 求值方法:先忽略符號不計求出余數(shù),再將所得余數(shù)的符號定成與被除數(shù)相同的符號即可。
如:
17%3 結果為2
17%-3 結果為2
-17% 3 結果為-2
-17% -3 結果為-2
注:
(1)單獨的常量、變量或函數(shù)調用都是C語言的合法表達式
(2)凡是表達式都有一個確定的值
2、賦值運算符及賦值表達式
賦值運算符:= 【14級 左<-右】
格式:變量名=表達式
賦值運算符的功能:將表達式的值賦給“=”左邊的變量
例如:A = 5+8 【先計算,后賦值】
a=b=c=1+2的計算順序是a=(b=(c=(1+2))) 【表達式的值賦值給變量】
注:
- (1)賦值運算符左邊只能是一個變量
- 如:
a+b= 3 4=3 非法表達式
a=6 a+(b=3) 合法的表達式
- 如:
- (2)賦值運算符右邊可以是合法表達式
- a = b = 20 a = (b=10)/(c=2)
- (3)賦值表達式的值就是賦值運算符左邊變量的值(重要)
- (4)實型數(shù)據(jù)賦給整型變量時,實型小數(shù)舍去,整型賦給實型變量時系統(tǒng)自動將整型數(shù)據(jù)轉成實型數(shù)據(jù)。
- 復合賦值運算符: 【結合性:左<-右】
+= -= *= /= %= &= |= ^= >>= <<= - 注:復合賦值運算符的兩個運算符中間不能有空格
如:a+ =3
- 復合賦值運算符: 【結合性:左<-右】
例1. 若有int a = 5,b=8; 則下列表達式的值是多少?用完表達式后變量a和b的值分別為多少?
a+=b/=a
表達式的值:
A的值:
B的值:
3、自增、自減運算符
自增運算符:++ i++ ++i
自減運算符:-- i-- --i
如:
i++; ++i; 等價于:i=i+1
i–; --i; 等價于:i=i-1
【自增自減運算符:結合性2:左<-右,優(yōu)先級2級】
注:
(1)只能用于變量不能用字啊常量或表達式。
如 3++、(a+b)++ 不合法的表達式
如 int a=3; 則表達式的值 變量的值
a)a++ ?3 ?4
b)++a ?4 ?4
c)a-- ?3 ?2
d)–a ?2 ?2
題1. int a=3;求a++*a
#include <stdio.h>int main()
{int a = 3;int b= a++*a;printf("a=%d\n", a);printf("b=%d\n",b);return 0;
}
題2. 若有定義int a=20,b=20,c=20,d=20;則下列表達式的值分別為多少?
A、a++ * 10
B、10 * b++
C、++c / 7
4、逗號運算符及其表達式(‘順序求值’表達式)
格式:表達式1,表達式2,表達式3,……,表達式n;
功能:逗號表達式的值就是表達式n的值,求值順序是從左到右依次求解。
5、強制類型轉換(顯式轉換)
強制類型轉換(顯示轉換)就是手動編寫代碼強制性地修改數(shù)據(jù)類型。
格式:
(類型名) 表達式
或 (類型名) (表達式)
利用強制類型轉換運算符可將一個表達式的值轉換成指定的類型。
如:
float x = 123.456,y;
(1) int(x) 錯
(2) (int) x (int)(x)
(3) (int)x+y (int)(x+y)
進行強制類型轉換,得到的是一個中間值,而原來表達式或變量的類型未發(fā)生改變。
如:
若變量x為int類型,則表達式(float)x的結果是一個單精度類型,但是x還是int型。
6、隱式轉換
隱式類型轉換(隱式轉換)就是自動修改數(shù)據(jù)類型,一般是高精度的數(shù)據(jù)賦值給低精度的數(shù)據(jù)會出現(xiàn)隱式類型轉換。
【隱式轉換是自動完成的】
1.0/2=? 1/2=?
說明:
同一優(yōu)先級的運算符,運算次序由結合方向所決定。
簡單記就是:!>算術運算符 > 關系運算符 > && > || > 賦值運算符
第四種數(shù)據(jù):函數(shù)
函數(shù)(標準函數(shù) 自定義函數(shù))
#include<math.h>
// |-5| 如何表示?abs()
abs(-5)
1.3 標識符
標識符就是名字。這類名字分為三類,一類是關鍵字,一類是預定義標識符(庫函數(shù)名等),一類是用戶自定義標識符(函數(shù)名、變量名)。
- 保留字(關鍵字)【int char float double等 32個(C89)】
C語言的關鍵字是一些具有特殊含義的保留字,它們在C語言中有著特定的用途和功能。使用時需要遵循語法規(guī)則。 - 預定義標識符【main】
預定義標識符:預先定義并具有特殊含義的標識符
scanf printf include等 - 用戶自定義標識符【自定義的函數(shù)名、變量名】
二、順序結構
C語言語句:三類語句
類型1 -> /**/
類型2 -> 定義語句;
類型3 -> 執(zhí)行語句;
2.1 什么是順序結構
定義:從main()開始,由上往下一條一條地執(zhí)行。
三大類語句(注釋、定義、執(zhí)行)->執(zhí)行語句有5類:
- 控制語句(9條)
- 函數(shù)調用語句;
- 表達式語句;
- 空語句;
- 復合語句;
花括號算是一條語句。
順序結構偽代碼:就是第一步干什么,第二步干什么,下一步干什么…
例如:某同學3門功課的平均分? 是順序結構
順序結構的程序設計框架:#include <> int main() { 輸入 76 89 92 //第一步計算 //第二步輸出 //第三步return 0; }
以下是chatgpt對順序結構的解釋:
在C語言中,順序結構是一種基本的程序控制結構,它按照代碼的順序依次執(zhí)行每個語句,沒有任何條件或循環(huán)的控制。順序結構是C語言程序中最簡單、最基礎的結構,也是程序的默認執(zhí)行方式。
順序結構的特點是代碼按照從上到下的順序依次執(zhí)行,每個語句的執(zhí)行不受其他因素的影響。當程序執(zhí)行到一個語句時,會順序執(zhí)行該語句,然后繼續(xù)執(zhí)行下一個語句,直到程序結束。
以下是一個簡單的順序結構示例:
#include <stdio.h>int main() {int a = 10;int b = 20;int sum = a + b; // 第一條語句printf("The sum is: %d\n", sum); // 第二條語句return 0; // 第三條語句 }
在上述示例中,程序按照從上到下的順序執(zhí)行。首先,聲明并初始化變量a和b,然后計算它們的和并將結果存儲在變量sum中。接下來,使用printf函數(shù)打印出sum的值。最后,使用return語句結束程序的執(zhí)行。
順序結構在C語言中非常常見,它使得程序可以按照預定的順序執(zhí)行各個語句,從而實現(xiàn)特定的功能和邏輯。
2.2 printf()輸出函數(shù)
“標準輸入輸出函數(shù)”是以一些庫函數(shù)來實現(xiàn)的
注意:標準函數(shù)/庫函數(shù)使用前必須:#include<頭文件名>再包含的程序文件中最頂部。
printf():“占位符”是以%開始的,被替換。
占位符字符:
- d 帶符號十進制整數(shù)
- u 無符號十進制整數(shù)
- o 無符號的進制整數(shù)
- X或x 無符號十六進制整數(shù)
- c 輸出一個字符,不輸出單引號
- s 輸出一個字符串。輸出時不輸出雙引號
- f 輸出一個實型數(shù)。隱含輸出6位小數(shù)
- E或e 輸出指數(shù)形式的實型數(shù)
在C語言中,printf函數(shù)是一個用于輸出格式化字符串的函數(shù),它可以將指定的數(shù)據(jù)以指定的格式打印到標準輸出(通常是終端窗口)。printf函數(shù)屬于stdio.h頭文件中的標準庫函數(shù),因此在使用之前需要包含該頭文件。
printf函數(shù)的基本語法如下:
#include <stdio.h>int printf(const char *format, ...);
其中,format是一個字符串參數(shù),用于指定輸出的格式。…表示可變參數(shù)列表,用于指定要輸出的數(shù)據(jù)。
printf函數(shù)的使用方法如下:
在程序中包含<stdio.h>頭文件。
在需要使用printf函數(shù)的地方,調用該函數(shù)并傳入相應的參數(shù)。
在format字符串中,可以使用占位符來指定輸出的格式,例如:%d表示輸出整數(shù),%f表示輸出浮點數(shù),%s表示輸出字符串等。
以下是一個簡單的示例,演示了如何使用printf函數(shù)輸出不同類型的數(shù)據(jù):
#include <stdio.h>int main() {int num = 10;float pi = 3.14;char str[] = "Hello, World!";printf("The value of num is: %d\n", num);printf("The value of pi is: %f\n", pi);printf("The string is: %s\n", str);return 0; }
在上述示例中,我們使用printf函數(shù)分別輸出了一個整數(shù)、一個浮點數(shù)和一個字符串。通過在format字符串中使用相應的占位符,我們可以指定輸出的格式,并將要輸出的數(shù)據(jù)作為參數(shù)傳遞給printf函數(shù)。
運行上述程序,將會輸出以下結果:
The value of num is: 10 The value of pi is: 3.140000 The string is: Hello, World!
注意,printf函數(shù)中的format字符串中的占位符必須與傳遞給printf函數(shù)的參數(shù)類型匹配,否則可能會導致輸出結果不正確或程序崩潰。
2.3 scanf()輸入函數(shù)
考點1:“普通/占位符”,輸入時普通字符必須原樣輸入。
int a, b;
scanf("%d,%d", &a, &b);
//輸入:3,5scanf("a=%d,b=%d",&a,&b);
scanf("%d",&a);//編碼時常寫這種
考點2:“占位符”,輸入時4種輸入格式。
int a,b;
scanf("%d%d", &a, &b);
//輸入時,中間用空格或tab間隔或回車,最后是回車
//方式一:空格 方式二:tab 方式三:空格tab 方式四 回車
考點3:“占位符”,輸入時1種輸入。
char ch1,ch2;
scanf("%c%c", &ch1, &ch2);
//輸入時,只能挨著輸入,chr1輸入后不能寫空格
都是字符就需要連續(xù)輸入字符
考點4:“占位符”,輸入時一種輸入。
char ch1, ch2;
int x;
scanf("%c%d%c", &ch1, &x, &ch2);
//輸入時,數(shù)字前可有空格。如:"a 3b"
//實踐:輸入時,數(shù)字前可有空格或tab或回車。數(shù)字后必須直接跟字符。
考點5、地址列表,輸入時&。
int x;
scanf("%d",x);//錯誤 or 正確
2.4 字符類型數(shù)據(jù)的輸入輸出專屬函數(shù)
(1)putchar()
格式:putchar(字符常量或字符變量)
功能:輸出一個字符但不輸出單引號。
如:
putchar('a'); //a
putchar('\n');
putchar(100); //d
putchar('100');//錯誤
(2)getchar()
功能:接收一個從鍵盤輸入的字符。
注:getchar()沒有任何參數(shù),函數(shù)的返回值就是輸入的字符
如:
char a,b;
a=getchar();
b=getchar();
若輸入為:1<回車>
則變量a的值為字符 ‘1’,變量b的值為回車符。
三、選擇結構(也叫分支結構)
3.1 兩類表達式
構成單個條件、聯(lián)合多個條件。
(1)關系運算符及關系表達式
< ??? <= ??? > ??? >= ??? == ??? !=
三要素:功能、優(yōu)先級(6級)、結合性(左->右)
關系表達式的結果是一個邏輯值(0和1,代表真假)
> 4>5
> 5==5
> 7=7
> 1<2<3
> 5>4>3
(2)邏輯運算符與邏輯表達式
&& ??? || ??? !
在C語言中,邏輯表達式的值只有 1 和 0 兩種值。其中,1表示“真”,0表示“假”。
&& ???11級 ??? 左 —> 右
|| ??????12級 ??? 左 —> 右
! ?????? 2級 ????? 左 <— 右
//例題:
> 5||5
> 4<3&&9
> 0&&7
> 5>4>3&&3
做題時要考慮:
- 合法
- 短路
- 優(yōu)先級,同級結合性
3.2 if語句
格式1:
if(表達式)語句序列;
后續(xù)語句;
格式2:
if(表達式)語句序列1;
else語句序列2;
后續(xù)語句;
格式3:
if(表達式)if(表達式)語句序列11;else語句序列12;
else語句序列2;
后續(xù)語句;
3.3 switch語句
格式:
switch(表達式)
{case 常量表達式1 : 語句序列1;case 常量表達式2 : 語句序列2;……case 常量表達式n : 語句序列n;default : 語句序列n+1;
}
- switch后必須用小括號將表達式括起。
- case后是常量整型或字符型,不能有變量和逗號運算符。
- 各case后常量不能出現(xiàn)相同的值。
- case 和 default只是一個入口標號,不起中斷作用。它們的順序可以任意顛倒。switch是按照代碼書寫順序執(zhí)行case,最后執(zhí)行default。
- 執(zhí)行的過程是:程序執(zhí)行到switch時,計算小括號內的表達式的值,若該值與某個case后的值相同時,則程序直接跳到該case語句塊往后執(zhí)行;若沒有一個case后的值與switch后括號內表達式的值相同,當有default時程序直接跳到default所在語句塊執(zhí)行,當沒有default時程序直接跳出switch。switch執(zhí)行時,先用switch后小括號內的表達式的值對比所有的case后的常量,如果兩個值相等,則執(zhí)行該case語句塊,如果該case語句塊中有break則直接跳出switch,如果沒有break,則繼續(xù)檢查下一個case。
- case和default必須出現(xiàn)在switch語句中。
- 多個case可以共用一組執(zhí)行語句
case 'A': case 'B': case 'C':printf("CCC\n");break;
四、循環(huán)結構
1、循環(huán)語句
功能:重復執(zhí)行相同的代碼段。
有三格式
格式1——while語句
while(表達式)
{//循環(huán)體語句序列;
}
//后續(xù)語句:
格式2——do while語句
do
{//循環(huán)體語句序列
}while(表達式);
//后續(xù)語句;
格式3——for語句
for(i=0; ; i++)
{//循環(huán)體語句;if(i == 35){break;}printf("123");
}
//后續(xù)語句
exp1一般是定義并初始化循環(huán)變量。循環(huán)在最初執(zhí)行一次,只執(zhí)行一次
exp2一般是是條件判斷語句
exp3一般是循環(huán)的條件變量的增量(增加或減少)
for執(zhí)行流程:最初執(zhí)行一次并只執(zhí)行一次exp1,然后 exp2->循環(huán)體語句->exp3 往復執(zhí)行。若exp2為假則跳出循環(huán),為真繼續(xù)循環(huán)。
思考:若是沒有exp2怎么辦?相當于是1,永真,就是死循環(huán)。
例題:1+2+3+4+……+100
#include <stdio.h>
int main()
{int i,sum=0;//while// i = 1;// while(i<=100){// //sum += i;// sum = sum +i;// i++;// }// for(i=1; i<=100; i++){// sum += i; //sum = sum +i;// }// printf("%d\n", sum);do{sum += i;i++;}while(1);//scanf("%d", &i);return 0;}
兩個控制語句——break continue
格式:break;
功能:中止退出。范圍:循環(huán)體中和switch體中。
for(i=1; i<4; i++)
{i++;break;
}
printf("%d", i);
格式:continue;
功能:結束當前本輪循環(huán)直接進行下一輪循環(huán)。
范圍:循環(huán)體中。
for(i=1; i<=10; i++)
{//i++;if(i==6 || i==5){continue; }sum += i;//.....
}
printf("%d", i);//5
如果循環(huán)體中的continue前后都有代碼,那么如果執(zhí)行到continue,就相當于只跳過了循環(huán)體的后半部分。如下:
for(i=1; i<4; i++)
{i++;continue;i++;
}
例題
以下程序的運行結果是:15 or 20 or 25 or 30
#include <stdio.h>int main()
{int i,j,m;for(i=5; i>=1; i--){m = 0;for(j=i; j<=5; j++){m = m + i*j;}}printf("%d\n",m);
}
以下程序的運行結果是:20 or 21 or 32 or 43
#include <stdio.h>int main()
{int n = 4;while(n--);printf("%d", --n);
}
以下程序的運行結果是?
#include <stdio.h>int main()
{int i = 5;do{switch(i%2){case 0:i--;break;case 1:i--;continue;}i--;i--;printf("%d", i);}while(i>0);
}
五、數(shù)組
1、一維數(shù)組
2、二維數(shù)組
3、字符串
特點:同一數(shù)組中的所有元素都屬于同一種數(shù)據(jù)類型(int char float)數(shù)組元素用數(shù)組名和相應的下標來確定。
方法:一個數(shù)組元素其實就是一個變量,在數(shù)組中稱為帶下標的變量。
5.1 一維數(shù)組的定義和引用(只有一個下標)
1、一維數(shù)組的定義格式:
類型名 數(shù)組名[常量表達式];
如:
float s[25];
float s[5*5];
int a[10];
char s1[30];
定義數(shù)組有四個注意:
- 數(shù)組名屬于用戶定義標識符。要遵守標識符命名規(guī)則。比如int for[25];是不行的。
- 定義一維數(shù)組時數(shù)組名后必須用一個方括號(將常量表達式括起來,常量表達式的值表示數(shù)組共有多少個元素)。
如:下面定義是非法的
int a(10);
int a{10}; - 定義數(shù)組時方括號中的表達式不能含有變量。另外表達式的值必須要大于 0 且為正整數(shù)。如:
int a[1.5];
int a[-10];
int a[n];
int a[0];
int N=9;int a[N]; - C語言每個數(shù)組在內存中分配空間時是連續(xù)分配的。
2、一維數(shù)組元素的引用格式:
數(shù)組名[下標]
先定義數(shù)組后使用
不能整體用數(shù)組名
注:C語言中不能對數(shù)組進行整體引用,只能單獨引用其中的元素。引用時下標可以是如下形式。
char a[10];
a[0] = 'A';
a[3+7] = 'b';//錯誤
記住:數(shù)組元素下標的值在0和size-1之間。即下標范圍屬于[0, size-1]
3、一維數(shù)組的初始化
格式:
類型名 數(shù)組名[常量表達式]={初值1, 初值2, ……};
注意:
- 定義一維數(shù)組時可以將各元素的初始值依次放在一堆{}中賦值給數(shù)組(必須用{}將初值括起,且初值之間用一個逗號分隔)。
int a[5] = {19, 45, 30, 20, 10, 66}; int a[5] = {11}; - 多則出錯;少則補0。
- 定義賦初值的個數(shù)大于數(shù)組長度,則數(shù)組長度可以省略。
int a[] = {19, 45, 66, 90};//ok
int a[]; - 一個也不給則是隨機值。
int a[5]; - 只能在定義數(shù)組的同時用{}給數(shù)組元素整體賦值。
a[5] = {19, 45, 30, 20, 10, 66};
5.2 二維數(shù)組的定義和引用(有兩個下標)
1、二維數(shù)組的定義格式:
類型名 數(shù)組名[常量表達式1][常量表達式2]
如:
int a[10][10];
char b[3][4];
float s[7][3];
注:
-
數(shù)組名要遵守用戶自定義標識符的命名規(guī)則。
-
定義二維數(shù)組第一個方括號常量表示行數(shù),第二個方括號常量表示列數(shù)。
int a[4*5]; //一維 20個元素個數(shù) int a[4][5];//二維 4行5列 20個元素
-
定義數(shù)組時方括號中的表達式不能有變量,且表達式的值必須是大于 0 的正整數(shù)。
-
在內存中二維數(shù)組元素的存放也是連續(xù)的,先行后列原則。
2、二維數(shù)組的引用
數(shù)組名[行下標][列下標];
注:
- 不能整體引用,只能引用其中的元素
- 引用二維數(shù)組元素時,必須有行下表和列下標兩個下標。從0開始依次加1。
3、二維數(shù)組的初始化
方法1:將初值依序放在一對 {} 中,與一維數(shù)組初始化格式相同。
例如:int a[2][3] = {1,2,3,4,5,6};
方法二:定義二維數(shù)組的同時,按行初始化每一行初值均用一對 {} 括起,采用嵌套的 {} 格式。
例如:int a[2][3]={ {1,2,3}, {4,5,6} };
注意:定義二維數(shù)組的同時給數(shù)組初始化,則可以省略行數(shù),但列數(shù)不能省略。
例如:
int a[][3]= {1,2,3,4,5,6};//對?
int a[2][]= {1,2,3,4,5,6};//錯?
int a[][3];//?
5.3 字符數(shù)組
1、字符數(shù)組的初始化
char s[]={‘a(chǎn)’, ‘b’, ‘c’, ‘d’, ‘e’};
與其它類型數(shù)組的初始化方式一樣,只是其初始值是字符。
2、字符串
因為字符串最后都有一個字符串結束符(‘\0’),所以用字符數(shù)組來存放字符串時一定要有一個元素存放結束符’\0’
- 字符串常量后有一個’\0’。
如:
"abcd"由5個字符組成:‘a(chǎn)’ ‘b’ ‘c’ ‘d’ ‘\0’ - 用字符串給一字符數(shù)組進行初始化有三種情況:
a. 方法一:char a[] = “abcd”;
b. 方法二:char a[] = {“abcd”};
c. 方法三:char a[] = {‘a(chǎn)’,‘b’,‘c’,‘d’,‘\0’};
遇到雙引號就加 ‘\0’
3、字符串使用
(1)字符串存儲(賦值)四種方法
方法1:利用scanf();鍵盤輸入
char a[10];
scanf(“%s”, a);//輸入:ab cd<回車>
scanf(“%s”, &a); //非法
printf(“%s”, a);//輸出時,從當前地址開始輸出,遇到’\0’結束
注:用 %s 格式輸入時,遇到空格符或回車符則自動結束輸入。 scanf(“%s,%s”, a,b); 不能正確讀取數(shù)據(jù)。
方法2:利用gets();鍵盤輸入
功能:讀取字符串賦值給字符數(shù)組??捎锌崭?br /> 注:
-
用gets()輸入字符時,只有遇到回車才讀取字符。
char str1[10]; gets(str1); //輸入:ab cd<回車> //str:ab cd
-
不論用%s還是gets()在輸入時均不需要輸入雙引號。若輸入了雙引號則雙引號也作為字符串的有效字符。
puts()輸出
功能:屏幕上輸出字符數(shù)組中的字符。
注:用該函數(shù)輸出與用%s格式輸出一樣,只是該函數(shù)將’\0’轉成’\n’輸出。
//如;
puts("abc");put("def");
/* 輸出結果:
abc
def
*/
方法3:利用字符數(shù)組初始化
char s[] = "abc";
char s[] = {"abc"};
char s[] = {'a', 'b', 'c', '\0'};
方法4:strcpy()
char a[10];
strcpy(a, "abcd");
方法4:字符串常量賦值給指針
char *s = "hello";
char *buf = "hello world";
(2)字符串函數(shù)
第 1 函數(shù):strcat()
格式:
#include<string.h>
strcat(字符數(shù)組1, 字符數(shù)組2);
功能:“連接”
如:
char a[18] = "jack";
char b[10] = "zhy";
strcat(a,b);
/*
a=>"jackzhy"
b=>"zhy"
*/
第 2 個函數(shù):strcpy():
格式:
#include<string.h>
strcpy(字符數(shù)組1, 字符數(shù)組2);
功能:將字符數(shù)組2中的字符串替換到字符數(shù)組1中。函數(shù)值為字符串數(shù)組1的首地址。
如:
char str1[10] = "123456";
char str2[10] = "abc";
strcpy(str, str2);
// str1=> "abc"
// str2=> "abc"
第 3 個函數(shù):strcmp()
#include<string.h>
strcmp(字符數(shù)組1, 字符數(shù)組2);
功能:函數(shù)返回值相同位置不同字符的ASCII碼差值。
返回值:一個整型數(shù),是一個插值。
// strcmp("abc", "abc") => 0
// strcmp("abc", "abfc") => 'c' - 'f' => -3
// strcmp("abc", "ab") => 'c' - '\0' => 99
注:不能用關系運算符直接進行字符串大小或字符數(shù)組大小的比較。
//這是不行的
"abc" == "abc";
"abc" > "ab";
第4個函數(shù):strlen()
格式:
#include<string.h>
strlen(字符數(shù)組);
功能:求出字符數(shù)組的實際長度(不包括結束符)
char a[10] = "4332567";
printf("%d", strlen(a));//7char a[10] = "abc\018\0"; // \01是8進制
printf("%d", strlen(a));//5char a[10] = "abc\012\0"; // \012是8進制
printf("%d", strlen(a));//4
六、函數(shù)
C語言程序的框架有兩種:
- 一個main() 單框架
- 一個main() + 多個子函數(shù) 復合框架
注:
- 一個源程序文件可由一個或多個函數(shù)組成
- 一個C程序可以由一個或多個源程序文件組成。
- C程序執(zhí)行從main開始,結束于main結束;可調用其它函數(shù)。
- 函數(shù)不能嵌套定義,但可以互相調用,不能調用main()函數(shù)。
函數(shù)的分類:
(1)無參函數(shù)和有參函數(shù)
(2)庫函數(shù)和用戶自定義函數(shù)+main()
6.1 函數(shù)定義
1、函數(shù)定義
函數(shù)返回值類型 函數(shù)名(形式參數(shù)列表)
{
函數(shù)體;
}
說明:
-
函數(shù)體可以沒有語句,但不能沒有花括號,函數(shù)名后必須有一對小括號。
-
定義有參函數(shù)時,形參的定義可以采用傳統(tǒng)方式或現(xiàn)代方式兩種。
//傳統(tǒng)方式: int max(x,y) int x,y; // 不能定義形參以外的其它變量 {//... }//現(xiàn)代方式: int max(int x, int y) {}
-
函數(shù)返回值類型:兩類
// 形式1:非void型(int float double等...) int fun(int x, int y) {return 表達式; }// 形式2:void型 void fun(int x, int y) {//不加return }
6.2 函數(shù)調用的兩種方式
方式一:非void型
變量名 = 函數(shù)名(實參列表);
方式二:void型
函數(shù)名(實參列表);
6.3 函數(shù)使用例題分析
(1)原型聲明
方式一:#include<頭文件> (庫函數(shù))
方式二:聲明的格式 (用戶自定義函數(shù))
函數(shù)類型 函數(shù)名(形參類型1 形參1, 形參類型2 形參2, …);
函數(shù)類型 函數(shù)名(形參類型1, 形參類型2, …);
void sum(int x, int y); /*函數(shù)原型聲明*/int main()
{sum(3, 5);return 0;
}void sum(int x, int y)
{printf("%d", x+y);
}
- 有頭有分號 - 聲明
- 有頭有體無分號 - 定義
- 函數(shù)名(實參) - 調用
(2)函數(shù)調用的過程
在進行函數(shù)調用時系統(tǒng)將實參值對應地(按位置次序對應)傳給形參,是一種值的單向傳遞。
實參與形參之間有一個關系。(順序、類型、個數(shù) 一致)
七、在函數(shù)中的變量
7.1函數(shù)的定義與使用
函數(shù)定義:
函數(shù)返回值類型 函數(shù)名(形式參數(shù)列表)
{函數(shù)體;
}
//這是函數(shù)的定義
函數(shù)聲明:
函數(shù)類型 函數(shù)名(形參類型1 形參1, 形參類型2 形參2, ...);
函數(shù)類型 函數(shù)名(形參類型1, 形參類型2, ...);
//這是函數(shù)的聲明語句
void sum(int x, int y);int main()
{sum(3, 5);return 0;
}void sum(int x, int y)
{printf("%d", x+y);
}
7.2 變量的三個屬性
變量三屬性:
- 類型(用類型去定義變量)
- 作用范圍(根據(jù)位置)
a. 內部(局部)變量
b. 外部(全局)變量 - 存儲類別
a. auto
b. static
c. register
d. extern
1、變量類型
就是數(shù)據(jù)類型,如int、float、double
2、作用范圍
(1)局部變量(內部變量)
定義:在一個函數(shù)內部定義的變量稱為局部變量
- 局部變量只在函數(shù)(它所在的函數(shù))內部有效
- 不同函數(shù)中可以出現(xiàn)同名變量,他們分別是不同函數(shù)的局部變量
- 復合語句中定義的變量只能在此復合語句中有效
- 所有形式參數(shù)是局部變量
(2)全局變量(外部變量)
定義:在函數(shù)外部定義的變量為全局變量
- 全局變量的有效范圍是在本文件內從定義該變量的位置開始到本文件結束。
- 全局變量可以在它的有效范圍內被每個函數(shù)引用(使用)。
- 在同一文件中若全局變量與局部變量同名,局部變量“覆蓋”全局變量。
全局變量也是靜態(tài)變量
3、存儲類別
(1)auto變量(默認)
- auto類別變量用完后釋放所占用空間。
- 局部變量默認為auto類別,無初始化時,初始值為隨機值。
- 使用時間短,一般都為auto類別變量。
(2)static變量
- static從定義到程序運行結束均占用存儲空間。
- 全局變量默認為static類別,無初始化時,初值為0。
- static類別變量只能進行一次初始化。
(3)register類別變量
- register類別只能是局部變量才能被說明。
- 一般不能直接使用。
(4)extern類別變量
- extern類別變量可以加大變量的作用范圍。
- 兩種說明格式
- 格式 1:
定義的同時說明類別:
存儲類別 類型名 變量名; - 格式 2:
分別定義、說明:
類型名 變量名;
存儲類別 變量名;
- 格式 1:
八、預編譯命令
8.1 預編譯命令
文件包含(include)
#include <>
#inclulde “”
8.2 宏
1、第一種:無參宏定義
格式:
#define 宏名 宏內容
功能:用一個指定的標識符(宏名)來代表一串字符串(宏內容)。
如:
#define PI 3.141592
#define N 10
注:
- 宏名我們一般用大寫字母表示,遵守用戶自定義標識符命名規(guī)則。
如:#define PI “abcdefg” - #define 可以在函數(shù)外定義也可以在函數(shù)內定義,但該命令應該在單獨一行上。
- 在進行宏定義時,可以引用已經(jīng)定義的宏名進行層層置換。
- 在進行宏替換時,必須先替換完所有的宏后再運算,同時替換過程中不能亂加括號。
2、第二種:帶參宏定義
#define 宏名(參數(shù)列表) 宏內容
功能:提供了一種更加靈活的替換方式。
如:#define s(x,y) x*y+2
注:
- 在定義有參宏時,參數(shù)列表必須用一對小括號括起且小括號和宏名之間不能有空格。
- 對有參宏名進行替換時,需要將形參改成相應的實參,并且注意分清形參和實參的對
應關系。
九、指針
9.1 指針變量定義
C語言有兩種變量:其中變量(普通變量)存儲內容值;地址變量(指針變量)存儲地址值。
1、定義的格式:
類型名 *指針變量名;
如:
int a, b, *p1, *p2;
float x, y, *p3, *p4;
char s, *p5, *p6;int b, *a;
int* a;
注:
- 定義變量(普通變量、指針變量)都必須在前面有類型名。
- 在定義指針變量時,指針變量名前的“*”表示現(xiàn)在定義的是一個指針類型的變量。星號并不是指針變量名的一部分,只是一個標志。
- 指針變量專門用來存放地址,禁止將一個整型值直接賦值給一個指針變量。
2、指針變量的引用
“&”取地址運算符,通過&運算符可以取出普通變量的地址。
指針運算符,*可以取出指針變量所指向的普通變量的值,(間接引用普通量)。
*指針變量名
如:
int a,b=20,c=30,d=40,*p;
p = &d;
a = *p; //a=d;
- 可以通過賦值使一個指針變量“指向”某一普通變量(指針變量 = &普通變量)
- 在C語言中正確的做法是先讓指針變量指向一個確定的存儲單元后,再通過該指針變量引用它所指向的存儲單元。
- 變量名(普通變量、指針變量)都表示其存儲單元內的值:
p1=p2; /* p1指向了p2所指向的單元 */ - 若指針變量p指向變量a,即將變量a的地址賦給了指針變量p。
- 所有的指針變量在內存中分配的字節(jié)數(shù)相同。sizeof()
說明:int fun(int a[10]) <=> int fun(int *a) <=> int fun(int a[])
若數(shù)組做為形參,則將數(shù)組名做指針變量來處理。
9.2 指向數(shù)組的指針變量
1、指向數(shù)組元素的指針變量
由于數(shù)組元素與普通一樣,所以定義指向數(shù)組元素的指針變量與定義指向普通變量的指針變量完全一樣
2、指向一維數(shù)組的指針變量
注:
(1)C語言中規(guī)定:數(shù)組名代表數(shù)組的首地址,而且是一個地址常量
(2)當指針變量指向數(shù)組中的某一個元素時,指針變量加1后指向數(shù)組中后一個元素,指針變量減1時指向數(shù)組中前一個元素。
舉例指針在數(shù)組中的使用:
(3)若兩個指針變量指向同一個數(shù)組,則這兩個指針變量可以進行大小比較如:
char s[10];
char *p1 = s+3, *p2 = &s[7];
//則 p1 > p2 ===> 0 p1 < p2 ===> 1
// p1 - p2 == -4
(4)在形參中的數(shù)組實際上是一個指針變量,并不是真正的數(shù)組,因為該“數(shù)組名”的值是可以改變的,而真正的數(shù)組名的值是不能改變的。
(5)若形參是數(shù)組或指針變量,則在函數(shù)中可以通過該形參改變實參的值。
9.3 指向多維數(shù)組的指針變量
若a是一個二維數(shù)組,則:
- a+i 是行指針,即指向的是一整行。若對它加1則指向下一行。
- *(a+i)和a[i]一樣,都是一個列指針,即指向一個元素。
- *(a+i)+j 和 a[i]+j一樣,都表示元素a[i][j]的地址。即與 &a[i][j]等價。
- ((a+i)+j)、(a[i]+j)、((a+i))[j] 和 a[i][j] 一樣,都表示元素。
//若有以下定義:
int w[2][3];
//則對w數(shù)組元素的非法引用是:
/*
A:*(w[0]+2)
B:*(w+1)[2]
C:w[0][0]
D:*(w[1]+2)
E:w[1]+2
*/
1、指向多維數(shù)組元素的指針變量
如:
int a[3][4];
int *p = &a[0][3];
//則:
p+1指向元素a[1][0];
p+4指向元素a[1][3];
p-2指向元素a[0][1];
常用于取二維數(shù)組a元素地址的方式:&a[i][j]、a[i][j]、*(a+i)+j 元素地址
2、指向由m個元素組成的一維數(shù)組的指針變量
定義指向由m個元素組成的一維數(shù)組的指針變量的格式:
基類型 (*指針變量名)[m];
如:
int a[5][7];//a是行地址
int (*p)[7];
p=a;
char b[10][80];
char(*r)[80];
r = b+5;
7.4 指向字符串指針的指針變量
符串常量:C語言對字符串常量是按首地址處理字符串常量的
- char str[] = “China”
- char *p = “China”
- str = “Chinese” 錯誤
- p = “Chinese”
7.5 指向函數(shù)的指針變量
函數(shù)名與數(shù)組名一樣,是起始地址,而且是一個地址常量
定義指向函數(shù)的指針變量的方式:
類型名 (*指針變量名)();
有()的標志說明是函數(shù)
一維數(shù)組 列地址
二維數(shù)組 行地址
函數(shù) 函數(shù)地址
區(qū)分:
/*
類型名 (*指針變量名)();
類型名 普通變量名:
類型名 數(shù)組名[];
類型名 *指針變量名:
類型名 函數(shù)名()
{....}
類型名 (*指針變量名)[M];
*/
注:
(1)在定義指向函數(shù)的指針變量時,要注意有兩個小括號必須要有,不需要定義形參。
(2)單獨的函數(shù)名代表該函數(shù)的首地址(函數(shù)的入口地址)
(3)函數(shù)的指針變量只能指向函數(shù)的入口處(函數(shù)的首地址),不能指向函數(shù)中的某條指令。(
另外,對指向函數(shù)的指針變量加1是沒有意義的)。
(4)給指向函數(shù)的指針變量賦值時,只寫函數(shù)名即可,不必寫參數(shù)。
7.6 返回指針的參數(shù)
類型名 函數(shù)名(形參)
{}返回指針的函數(shù)的定義方式為:
類型名 *函數(shù)名(形參)
{return 地址值;
}
7.7 指針數(shù)組和指向指針的指針變量
1、若一個數(shù)組的所有元素均為指針類型(地址),則稱為指針數(shù)組。
格式:
類型名 *數(shù)組名[常量表達式];
int *s[10];
注:
(1)要注意它與定義指向m個元素組成的一維數(shù)組的指針變量之間的區(qū)別
類型名 *數(shù)組名[常量表達式];
類型名 (*指針名)[常量表達式m];
(2)它的每個元素都是一個指針類型(地址),即它的每個元素相當于一個指針變量。
int *a[10]:
int a[10]:
int a[10][10]:
2、指向指針的指針變量
用來存放指針變量地址的指針變量 稱為 指向指針的指針變量。
定義格式:基類型名 **指針變量名;
如:
int a=3;
int *p = &a;
int **k = &p;
/*
則:*k得到變量p(變量a的地址)
*/
7.8 空指針
指針變量可以有空值,即指針變量不指向任何變量,不指向任何有用的存儲單元。
在系統(tǒng)中已將NULL定義為0,即NULL的值為0。
int a,b,c,*p=NULL;
此時p的值為空指針,即p不指向任何有用的存儲單元。盡管NULL的值為0,但我們不能認為p指向了地址為0的存儲單元。
注:
(1)當一個指針變量的值為空指針時,我們不能引用它所指向的存儲單元。
(2)若某指針(地址)的基類型為void型,則有引用時應進行相應的強制類型轉換。
#include <stdio.h>
main()
{int a[]={1,2,3,4,5,6,7,8,9,10,11,12};int *p=a+5,*q=NULL;*q=*(p+5)printf("%d %d\n",*p,*q);
}
輸出:
九、構造類型
9.1 結構體類型
1、構造結構體類型
struct 結構體類型名
{成員1的定義;成員2的定義;......;成員n的定義;
};struct student
{int sn;int age;char sex;int s[3];
};
注:
(1)定義成員的方式與定義普通變量的方式一樣
(2)成員列表必須用一對花括號括起
(3)結構體名可以省略。
2、定義結構體變量
A.先定義結構體類型名再定義結構體變量
main()
{struct student{int sn;int age;char sex;int s[3];}; /*類型定義*/struct student stu1,stu2,st[25];/*變量定義*/
}
B.在定義結構體類型同時定義變量
struct student
{int sn;int age;char sex;int s[3];
}stu1,stu2,st[25];
C.類型、變量同時定義,類型名student省略
struct
{int sn;int age,char sex;int s[3];
}stu1,stu2,st[25];
注:
(1)結構體變量在內存中占用字節(jié)數(shù)為各成員占用字節(jié)數(shù)總和。【有待商榷】
3、結構體變量的初始化及引用】】使用結構體變量、結構體數(shù)組、結構體指針變量
(1)再定義結構體變量的同時可以將各成員的初值按順序放在一對花括號中,來進行對結構體變量的初始化。若初值個數(shù)多于成員個數(shù)則出錯,若初值個數(shù)少于成員個數(shù),則多余成員自動賦0。
struct aa
{int a;char b[10];float c;
} a1={30, "china", 40.5}, a2={60,"hello"};
(2)結構體變量不能整體引用,只能引用它的成員(同數(shù)組相似)
/* 引用結構體成員的方式:
結構體變量名.成員名
其中.為成員運算符
*/
printf("al=%d,%s,%f", a1);//非法/
printf("al=%d,%s,%f", a1.a, a1.b, a1.c);
a1.a=80;
a1.b="xinjiang";//strcpy(a1.b, "abc")
a1.c=60.5;
(3)結構體指針變量
(4)指向結構體數(shù)組的指針
struct student
{int num;char name[20];char sex;float score;
};
struct student stu[3] = {{1001,"zhang",'M',60.5},{1002,"li",'M',100},{1003,"wang",'W',90.9}};
struct student *p=stu;// &stu[0]等價//引用成員:
stu[1].num;(p+1)->num;(*(p+1)).num;
stu[0].name;p->name;(*p).name;
注:
(1)可以用結構體變量的成員作為實參,它與普通變量作為實參的用法是一樣的。
(2)用結構體變量作為實參時,要求形參必須是同一結構體類型的變量,傳遞后形參與實參各對應成員值是一樣的。
(3)也可以用結構體類型的地址(指針變量或數(shù)組)作為實參,要求形參必須是同一結構體類型的指針變量或數(shù)組。只要是地址傳遞,則間可以通過形參來改變實參的值。
9.2 共用體類型
共用體中的所有成員共用同一段內存(所有成員的起始地址都是一樣的)
格式:
union 共用體名
{成員列表;
};
注:
(1)成員列表為定義該共用體的成員,成員定義的方式與普通變量的方式一樣。
(2)成員列表必須用一對花括號括起。
(3)共用體名可以省略。
1、共用體變量的定義
(1)先定義類型,再定義變量
(2)定義類型的同時,定義變量
(3)直接定義變量
union data
{int i;char ch[10];float s;
}
注:
由于共用體類型變量的所有成員公用同一段內存,所以共用體類型變量所占的字節(jié)數(shù)等于該共用體類型中占字節(jié)數(shù)最多的成員所占的字節(jié)數(shù)。
2、共用體變量的引用
注:
(1)不能整體引用共用體變量,只能引用其成員。
(2)同類型成員共享值。
(3)在內存中整型數(shù)據(jù)的二進制數(shù)低8位占用前面一個字節(jié),高8位占用后面一個字節(jié)。
如:
整數(shù)255,在內存中的存儲形式是:
1111 1111 0000 0000
一個字符型數(shù)據(jù)占用一個字節(jié),對于數(shù)組來說前面元素占用前面的字節(jié)。
(4)共用體變量之間可以相互賦值,賦值后兩個變量應使用同一成員。
(5)共用體變量的地址與各成員的地址都相同的。
(6)在定義共用體時,可以對其進行初始化,但只能有一個初值且必須用花括號將初值括起。相當于給第一個成員賦值。
(7)共用體、結構體的成員均可以是共用體或結構體類型
(8)不能用共用體類型變量做為函數(shù)參數(shù)。
(9)計算共用體占用字節(jié)數(shù)。
9.3 typedef
用typedef 定義新類型名
在編程中可以用typedef來定義新的類型名來代替已有的類型名。給已有類型起別名。
格式:
typedef 已有類型名 新的類型名;
如:
typedef int INTEGER;
//以后在定義變量時int和INTEGER是等價的。
INTEGER a[10],b; int a[10],b;
(1)typedef可用于定義各種類型名,但不能定義變量,即只要見到typedef則該語句最后的標識符必定是一個類型名而不是變量名。
(2)typedef只能對已經(jīng)存在的類型新增一個別名,而不是創(chuàng)造新類型。即在ypedef后必須是一個已有的類型。
十、位運算與文件
10.1 位運算
位運算的操作對象只能是整型或字符型數(shù)據(jù)。
C語言提供6種位運算符:
& ??| ??^ ??~?? << ??>>
復合賦值運算符:
&= ??|=?? ^= ??<<=?? >>=
1、按位與運算(&)
兩個相應的二進制位都是1時,它們按位運算后的結果才是1,否則為0。
1&1=1
1&0=0
0&1=0
0&0=0
全1為1;有0為0。
作用:清零。
2、按位或運算(|)
兩個相應的二進制位中只要有一個為1,則它們按位或運算后結果為1。
1|1=1
1|0=1
0|1=1
0|0=0
作用:將特定位 置1。
3、按位異或運算(^)
當兩個相應的位同為1或同為0時,按位異或運算結果為0;兩個相應位一個為1另一個為0時,按位異或運算結果為1。
1^1=0
1^0=1
0^1=1
0^0=0
相同為0,相異為1
4、按位取反運算(~)
按位取反運算符是一個單目運算符。按位取反后0變1,1變0。
注:
對一個數(shù)按位取反得到的值為該數(shù)+1后再乘-1。???
5、按位左移運算符(<<)
格式:數(shù)<<n
功能:將二進制位按位依序左移n位。
對一個十進制數(shù)左移n位后得到的值為該數(shù)乘以2n的積。
6、按位右移運算符(>>)
格式:數(shù)>>n
功能:將二進制位按位依序右移n位。
若該數(shù)為一個負數(shù)并且不能被2n整除則得到的數(shù)為商加-1。
10.2 文件
1、文件概念
- 文件:記錄在外部存儲介質(外存)上的數(shù)據(jù)的集合。
- 文件的分類:
- 文本文件(ASCII碼文件):每個字符存儲在文件中。
- 二進制文件:以二進制存儲。
- C語言對文件的存取是以字符(字節(jié))為單位的。
- 文件類型指針
考試中,記住FILE就是文件類型名,它是一個結構體類型。對一個文件進行操作,通過文件指針進行的,定義如下:FILE *fp, *in, *out;
2、文件的打開與關閉
1、文件的打開(fopen()函數(shù))
格式:fopen(文件名,文件使用方式)
功能:按指定的“使用方式”打開文件,函數(shù)返回打開文件的指針,該指針的基類型為文件類型。文件名和文件使用方式均為字符串。
如:以只讀方式打開文件data.txt,并用指針變量fp指向它。
FILE *fp;
fp = fopen("data.txt", "r");
打開文件的“使用方式”:
“r”:打開已存在的文件
“w”:刷新寫、創(chuàng)建寫
“a”:追加寫、創(chuàng)建寫
“+”:增強
“r+” “w+” “a+”
“rb” “wb” “ab”
“rb+” “wb+” “ab+”
注:
(1)文件使用方式只能用小寫字母,文件名用大寫或小寫均一樣。
如:
FILE *fp;
fp = fopen("c:\\tc\\data.txt", "w");
(2)在“文件使用方式”中若含有字母 b,則打開的是一個二進制文件(bit)。
(3)當fopen“打開”失敗時,函數(shù)返回NULL。
if (fp = fopen(文件名, 文件使用方式)==NULL)
{printf("can not open this file\n");exit(0);
}
2、文件的關閉(fclose函數(shù))
文件使用完后應該關閉該文件。
格式:fclose(文件指針);
如:fclose(fp);
3、文件的讀寫
(1)fputc()
格式:fputc()
功能:把一個字符寫到文件指針所指的文件中。其中字符可以是字符常量也可以是字符變量。若輸出成功則函數(shù)返回輸出的字符,失敗則返回EOF(stdio.h中定義為-1)。
(2)fgetc()
格式:fgetc(文件指針)
功能:從文件指針所指文件中讀取一個字符。若讀取成功則函數(shù)返回讀取的字符,失敗(遇到文件結束)則返回EOF。
char ch;
ch = fgetc(fp);
(3)fgets()
格式:fgets(str, n, fp)
功能:其中str表示一個字符指針,可以是字符數(shù)組名也可以是字符指針變量名。從fp所指文件中讀取n-1個字符(不是n個字符),并在這些字符最后加一個字符串結束符’\0’后賦給str。
函數(shù)返回str的首地址。
(4)fputs()
格式:fputs(str, fp)
功能:向fp所指文件中寫(輸出)str中的字符串,str可以是字符串常量、字符數(shù)組或字符指針變量。在輸出時字符串的結束符’\0’不會輸出。若輸出成功則返回0,失敗返回EOF(stdio.h中定義為-1)。
(5)fread()、fwrite()
格式:
fread(buffer, size, count, fp);
fwrite(buffer, size, count, fp);
其中:
buffer時數(shù)據(jù)的地址
size是每次讀寫的字節(jié)數(shù)
count表示讓函數(shù)進行多少次的讀寫
fp是要進行讀寫的文件指針變量
功能:用來讀寫一個連續(xù)的數(shù)據(jù)塊
注:
- 這兩個函數(shù)以二進制方式進行讀寫。
(6)fprintf()、fscanf()
格式:
fprintf(文件指針, 格式說明符, 輸出列表);
fscanf(文件指針, 格式說明符, 輸入列表);
功能:按格式說明符所指定的格式向文件中讀寫(輸入輸出)數(shù)據(jù)。其中格式說明符和輸入(輸出)列表的用法與scanf和printf函數(shù)相同。
補充:feof(文件指針)
作用是測試文件的當前讀寫位置是否到達文件末尾,若是則返回非0值(真),否則返回0(假)。
while(!feof(fp))
{}
4、文件當前位置讀寫函數(shù)
(1)重新定位指針
格式:rewind(文件指針)
作用:使當前的讀寫位置重新指向文件的開頭。函數(shù)無返回值。
(2)fseek()
格式:fseek(文件指針,位移量,起始點)
功能:將當前的讀寫位置從“起始點”開始按“位置量”所指定的移動字節(jié)數(shù)向后移動。
起始點有:
SEEK_SET 或 0 (表示“文件的開始”)
SEEK_CUR 或 1 (表示“當前位置”)
SEEK_END 或 2 (表示文件末尾)
位移量:要在數(shù)值后加字母l或L。
如:
fseek(fp, 100L, SEEK_SET)
例題分析:
(3)ftell()
格式:ftell(文件指針)
功能:返回當前文件的位置值,用相對于文件頭的位移量表示。若返回-1L表示出錯。