C語言第十章:結構體、枚舉、預處理指令

1、 構造類型:根據已定義的一個或多個數據類型用構造的方法構造新的類型。
2、 結構體:由若干個相同或者不同的數據類型組成的結構體
爲什麼要有結構類型?
結構體可以把功能相同的數據組織起來,存在一起,用的時候方便,而且在調用函數時,若傳遞參數較多,傳一個結構體相對而言簡單一些,很多系統自帶的函數必須用結構體。

什麼是結構體?
“結構”是一種構造類型,它是由若干“成員”組成的。每一個成員可以是一個基本數據類型或
者又是一個構造類型
格式:struct 結構名{
成員列表
};//此處的分號不可以省略
十二、結構體變量及其定義方法
結構體定義的三種方法
1)、先定義結構體,=然後在定義結構體變量
struct Student{
int sno;
char name[21];
int age;
float score;
};
//注意:
a)、結構體定義完成喲後,計算機不會給結構體分配內存空間
b)、會在定義結構體變量後分配存儲空間

//結構體變量定義格式:
struct 結構體 結構體變量名;
struct Student stu;//這句話表示定義一個Student結構體的變量,變量名是stu
*因爲stu是Student類型 ,stu可以存放學生的 sno 、name、age、score ,也可以定義多個結構體變量

2)、定義結構體的同時,定義結構體變量

格式:struct Car{
int wheel;
float speed;
}car,car1;//結構體變量名

3)、使用匿名結構體定義結構體變量
struct {
int sno;
char name[21];
int age;
float score;
}結構體變量1,結構體變量2 。。;

char [20] =”asdas ” 使用sizeof的話是它的長度 20
使用strlen的話就會出現長度是字符的長度。 5

3、 三種初始化方式
struct Student stu;
stu.sno=201104;
4、 stu.age=22;
5、 //stu.name=”唐順治”; //這是一種方法
6、 strcpy(stu.name, “唐楓”);
7、 stu.score=96.5f;
8、 printf(“學生的姓名 :%s 學號:%d,年齡:%d,成績:%.2f\n”,stu.name,stu.sno,stu.age,stu.score);
9、
10、 struct Student stu1={2011,”張三”,23,56.77f};
11、
12、 //部分初始化
13、 struct Student stub2={.name=”李四”};
4、結構體變量存儲原理
1、結構體對齊的含義:結構體的總長度
2、計算結構體在內存中佔用的字節數的方法
1)、先找模數 是結構體中基本數據類型中佔用字節數最大的那個。
2)、再計算結構體變量的各個成員佔用的字節和(注意他的對齊方式)
計算方法:(避免有時間出現交換順序就字節數不同的情況)

返回指針值的函數稱爲指針型函數 int *sum(int x, int y)
指向函數的指針變量稱爲“函數指針變量”。In t (*p)(int a, int b)

一、 結構體數組
1、 概念:數組的元素是結構體的類型。用來存放結構體相同的結構體變量。
2、 格式:
1)、定義的同時定義數組,struct 結構體{}數組名[長度]; struct Student{}stu[5];
2)、先定義結構體,後定義數組。Struct Student boy[5];
3、結構體數組的初始化
//2、定義的同時進行初始化
struct Student girl[2]={{“ss”,55},{“rr”,33}};
//3、先定義後初始化,整體賦值
struct Student ds[2];
ds[0]=(struct Student){“tsz”,44};
ds[1]=(struct Student){“tangfeng”,44};
//4、先定義結構體數組 ,後初始化
struct Student stu[2];
//1)使用strcpy函數
strcpy(stu[0].name,”tangshunzhi”);
//2、使用scanf
//scanf(“%s”,stu[0].name);
//stu[0].name=”weqw”;

二、 結構體指針
1、 結構體指針:指針變量指向一個結構體變量,結構體指針變量中得值所指向的時結構體的首地址 。
2、 結構體指針間接訪問成員值
1)、一般形式:(*p).成員變量名
2) p->成員變量名 注意:p一定是一個結構體指針
三、結構體的嵌套
a、成員可以是基礎數據類型也可以是一個結構
注意::結構體不可以嵌套自己的變量,但是可以嵌套自己的指針,結構體的定義可以嵌套其他結構體類型的變量。
1、 結構體的嵌套:結構體定義中,結構體的成員又是另外一個結構體變量。
2、 用結構體變量的成員值作爲函數的參數,實質值傳遞
3、 用結構體變量(變量名)作爲函數的參數,實質也是值傳遞

四、枚舉類型(是一種基本數據類型)
1、C語言提供一種類型,這種類型得分變量的取值被限定在一定的範圍之內。
2、格式:enum 枚舉類型名{枚舉值1,枚舉值2.。。。。};
3、enum iColor{kIcolorWhite,kIcolorBlack,kIcolorTHJ}; //注意這種的命名方式。
4、枚舉不可以嵌套定義
5、枚舉變量的使用和定義
1)、先定義枚舉類型,再定義枚舉類型
2)、定義枚舉類型的同時定義變量
//枚舉變量的值:枚舉類型完成以後,系統會自動的給每一個整型初值,默認初值從第一個元素開始值爲0,以後每個元素的值在前一個的基礎上值加1。

什麼 情況下使用枚舉:
當程序中需要給某一個變量值,限定取值範圍的時候,可以使用枚舉

五、typedef 使用方法
//1、基本數據類型
typedef int MALATANG;//MALATANG就是int

//2、用在數組,給數組起別名
typedef  int ARRAY[5];//int a[5];  數組長度是5
ARRAY a1={2,3,5,6,7};//就是長度爲5的數組

for(int i=0;i<5;i++)
{
    printf("%d\t",a1[i]);
}

//3、給結構體起別名
struct Person{
    char *name;
    int age;
};
struct Person p1={"aad",18};
//給struct Person 起個別名  P
typedef struct Person  P;
//第二種起別名的方法
typedef struct Car{
    int wheels;
    int speed;
    }MYCAR;//表示給結構體起個別名
MYCAR car1={1,23};
//給匿名的結構體起個別名MYCAR
typedef struct{
    int hh;
}IPHONE;

//4、給枚舉起別名
//ISEX就是一個別名
typedef enum Sex{kSexMan,kSexWomen} ISEX;

typedef enum Sex S;
S s1;
s1=kSexMan;
printf("%d\n",s1);
//5、給函數指針
//指向函數的指針
int (*p)(int x,int y);
//給函數的中的指針起別名

typedef  int (*FUN)(int x,int y);// FUN就是一個別名

FUN f1;
f1=sum;
int result=f1(3,4);

printf(“sum=%d\n”,result);

六、預處理指令
1、概念:以“#”號開頭的預處理命令,如:#include #define這些預處理命令一般都放在源文件的前面但是也可以放在別的地方。
2、預處理的分類:文件包含、條件編譯、宏定義
3、作用:編譯之前完成它自己的工作
七、宏的概念及無參宏定義方法
1、宏:C語言中我們自定義的特殊標示符,習慣大寫
2、宏的分類:有參宏和無參宏
3、宏的定義:#define 標示符 宏名
注意:預處理指令經常寫在函數之前。
宏不是一個語句,它是一個預處理指令所以不需要分號。
4、宏替換:源程序在編譯之前,由預處理程序對我們寫得源程序進行處理,會把源程序所有出現宏名的地方一律使用宏的字符串去替換。

5、終止宏的話使用  #undef

6、宏使用的注意:
1)、宏是有作用域的
2)、字符串中出現宏名,是不會給替換的
3)、使用#undef可以終止宏
4)、宏可以嵌套

            5)、使用起別名    #define INT 1   INT ;
            6)、注意括號的使用

八、有參宏的定義和使用
1、有參宏 有參宏 #define SUM(a ) a+a
SUM(3)//不僅僅要a+a 替換,而且還要把實參3代入到字符串中使用返回值。

3、 有參宏的注意事項:
1)、宏的形參之間可以出現空格,但是宏名和形參之間不能出現空格。
2)、在帶參宏定義中,形式參數不分配內存單元.
3)、有宏參數時,最好用括號括起來
4)可以用宏來定義多個語句
十、typedef和#define的區別?
Define只是簡單的替換,在編譯之前
Typedef 在編譯的時間進行替換相同的類型,它不是簡單的替換,而是對類型說明符重新命名,被命名的標示符具有類型定義說明的功能。

預處理功能:如宏定義、文件包含、條件編譯

第四節:條件編譯
注意:條件編譯後面的條件表達式中不能識別變量,它裏面只能識別常量和宏定義

第一種形式的格式爲:

if 常量表達式

程序段1

else

程序段2

endif

如常量表達式的值爲真(非0),則對程序段1 進行編譯,否則對程序段2進行編譯。因此可以使程序在不同條件下,完成不同的功能。

第一種形式的格式爲:

ifdef

標識符
程序段1

else

程序段2

endif

它的功能是,如果標識符已被 #define命令定義過則對程序段1進行編譯;否則對程序段2進行編譯。如果沒有程序段2(它爲空),本格式中的#else可以沒有。

第三種形式的格式爲:

ifndef 標識符

程序段1

else

程序段2

endif

第二種形式的區別是將“ifdef”改爲“ifndef”。它的功能是,如果標識符未被#define命令定義過則對程序段1進行編譯,否則對程序段2進行編譯。這與第二種形式的功能正相反。


1、【掌握】static 與 extern對局部變量的作用
static 和 extern都是用來修飾變量(局部的static實際也是全局的)
static修飾的變量 只有你的包含那個變量定義的源代碼文件可以訪問(內部的變量)
extern定義的變量的哪個源文件都可以訪問 只要聲明瞭就可以(外部變量)

1、static對局部變量的作用
1、延長局部變量的生命週期,從程序啓動到程序退出,但是它並沒有改變變量的作用域
2、定義變量的代碼在整個程序運行期間僅僅會執行一次

2、Static對全局變量的作用:
聲明一個內部變量
由於靜態全局變量的作用域侷限於一個源文件內,只能爲該源文件內的函數公用,因此可以
避免在其它源文件中引起錯誤。

3、extern作用
完整定義一個外部變量
完整聲明一個外部變量

發佈了55 篇原創文章 · 獲贊 3 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章