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作用
完整定義一個外部變量
完整聲明一個外部變量