• 问题总会出现,不过解决问题的方法也会出现!!!

C语言基础学习笔记18

学习笔记 小雨 715次浏览 已收录 0个评论

—— ——-

2-结构体数组概念及定义

  1. 结构数组概念

数组的元素也可以是结构类型的。因此可以构成结构型数组。结构数组的每一个元素都是具有相同结构类型的下标结构变量。在实际应用中,经常采用结构数组来表示具有相同数据结构的一个群体。

  1. 结构数组定义

定义格式:

struct 结构名{

成员列表

}数组名[数组长度];

例如:定义一个长度为5的数组,其中每一个元素都是stu结构类型

struct stu{

int num;

char *name;

char sex;

float score;

}boy[5];

定义了一个结构数组boy,共有5个元素,boy[0]~boy[4]。每个数组元素都具有struct stu的结构形式。

3-结构数组的初始化和遍历

  1. 结构数组的初始化

struct stu{

int age;

char *name;

};

  1. 定义的同时进行初始化

struct stu s[2]={{12,”aa”},{18,”bb”}};

  1. 先定义,后初始化,整体赋值

s[1]=(struct stu){23,”ccc”};

  1. 先定义,后初始化

s[1].age=12;

strcpy(stu[1].name,”abcd”);

5-结构指针定义和初始化

  1. 指向结构体变量的指针

一个指针变量当用来指向一个结构变量时,称之为结构指针变量。结构指针变量中的值是所指向的结构变量的首地址。通过结构指针即可访问该结构变量。这与数组指针和函数指针的情况是相同的。

结构指针变量说明的一般形式为:

struct 结构名 *结构指针变量名;

例如,在前面的例题中定义了stu这个结构,如要说明一个指向stu的指针变量pstu,可写为:

struct stu *pstu;//定义了指针只能指向stu结构体类型的结构体变量

当然也可定义stu结构时同时说明pstu。与前面的各类指针变量相同,结构指针变量也必须要先赋值后才能使用。

赋值是把结构变量的首地址赋予该指针变量,不能把结构名赋予该指针变量。

则:pstu=&boy;是正确的

而:pstu=&stu;是错误的

  1. 结构名、结构体变量名、结构体指针

结构名和结构变量是两个不同的概念,不能混淆。结构名只能表示一个结构形式,编译系统并不对它分配内存空间。只有当某变量被说明这种类型的结构时,才对该变量分配存储空间。结构指针变量,就是用来存储结构体变量地址的,就能更方便地访问结构变量的各个成员。

6-结构体指针间接访问成员值

其访问的一般形式为:

(*结构指针变量).成员名

或为:

结构指针变量->成员名

例如:

(*pstu).num

或为:

pstu->num

应该注意(*pstu)两侧的括号不可少,因为成员符“.”的优先级高于“*”。

如去掉括号写作*pstu.num则等效于*(pstu.num),这样,意义就完全不对了。

7-结构体嵌套使用

  1. 成员也可以又是一个结构,即构成了嵌套的结构

//结构体嵌套:结构体定义的里面有其他结构体

//结构体不可以嵌套自己变量,可以嵌套指向自己这种类型的指针

如:

Struct Date{

int month;

int day;

int year;

};

Struct stu{

int num;

char *name;

char sex;

struct date birthday;

float score;

};

C语言基础学习笔记18

  1. 嵌套定义自己的指针

C语言基础学习笔记18

8-结构体变量及成员作为函数参数

  1. 成员属性做函数的参数

结构体成员属性作为函数的参数就是值传递(成员变量是数组除外)。

  1. 结构体名作为函数的参数

在ANSI C标准中允许用结构体变量作函数参数进行整体传送。但是这种传送要将全部成员逐个传送,特别是成员为数组时将会使传送的时间和空间开销很大,严重的降低了程序的效率。因此最好的办法就是使用指针,即用指针变量作函数参数进行传送。这时由实参数向形参的只是地址,从而减少了时间和空间的开销。

9-结构体指针作为函数的参数

C语言基础学习笔记18

C语言基础学习笔记18

10-枚举类型介绍及定义

C语言提供了一种称为”枚举”的类型。在“枚举”类型的定义中列举出所有可能的取值,被说明为该“枚举”类型的变量取值不能超过定义的范围。

应该说明的是,枚举类型是一种基本数据类型,而不是一种构造类型,因为它不能再分解为任何基本类型。

  1. 枚举类型

枚举类型定义的一般形式为:

enum 枚举类型名{枚举值表};

在枚举值表中应罗列出所有的可用值。这些值也称为枚举元素。

例如,该枚举名为weekday,枚举值共有7个,即一周中的七天。凡被说明为weekday类型变量的取值只能是七天中的某一天。

11-枚举变量定义和使用

  1. 枚举类型变量

如同结构和联合一样,枚举变量也可用不同的方式说明,即先定义后说明,同时定义说明或直接说明。设有变量a、b、c被说明为上述的weekday,

可采用下述任一种方式:

enum weekday{sun,mou,tue,wed,thu,fri,sat};

enum weekday a,b,c;

或者为:

enum weekday{sun,mou,tue,wed,thu,fri,sat}a,b,c;

或者为:

enum{sun,mou,tue,wed,thu,fri,sat}a,b,c;

12-typedef关键字介绍

  1. 概念及语法格式

C语言不仅提供了丰富的数据类型,而且还允许由用户自己定义类型说明符,也就是说允许由用户为数据类型取“别名”。

typedef定义的一般形式为:

typedef 原类型名 新类型名;

其中原类型名中含有定义部分,新类型名一般用大写表示,以便于区别。

有时也可用宏定义来代替typedef的功能,但是宏定义是由预处理完成的,而typedef则是在编译时完成的,后者更为方便灵活。

13-typedef使用方法

  1. 使用方法

类型定义符typedef即可用来完成此功能。

  1. 基本数据类型

例如:有整型a、b其说明如下:

int a,b;

其中int 是整型变量的类型说明符。int的完整写法为integer,为了增加程序的可读性,可把整型说明符用typedef定义为:

typedef int INTEGER

这以后就可用INTEGER来代替int作整型变量的类型说明了。

例如:

INTEGER a,b;

它等效于:

int a,b;

用typedef定义数组、指针、结构等类型将带来很大的方便,不仅使程序书写简单而且使意义更为明确,因而增强了可读性。

  1. 数组类型

例如:typedef int ARRAY[5];//int a[5];数组长度为5

ARRAY a1,b1;//int a1[5],b1[5];

  1. 给结构体起别名

struct Person{

char *name;

int age;

};

struct Person p1={“zcz”,18};

//给结构体struct Person起个别名P

typedef struct Person P;

//用别名定义新的变量

P p2={“znmm”,28};

printf{“name:%s,age:%dn”,p2.name,p2.age};

//给结构体定义别名2

typedef struct Car{

int lunzi;

int speed;

}MYCAR;//表示把结构体起个别名

MYCAR car1={1,200};

//给匿名结构体起个别名

typedef struct{

int screenSize;

int ram;

}IPHONE;

//用新类型定义结构体变量

IPHONE iphone={10,5};

  1. 给枚举类型起别名

typedef enum Sex{kSexMan,kSexWomen} ISEX;//ISEX别名

typedef enum{Monday,Tuesday,Wednesday,Thursday}WEEKDAY;//WEEKDAY别名

  1. 给函数指针

//指向函数的指针

int sum(int a,int b){

return a+b;

}

int(*p)(int ,int);//函数指针

//给函数中指针起别名

typedef int (*FUN)(int)(int);//FUN是一个别名

FUN f1,f2;//f1,f2都是函数指针

f1=sum;

printf(“%dn”,f1(67,23));

14-预处理指令的概念及分类

  1. 基本分类

以#号开头的预处理指令。如包含命令#include,宏定义命令#define等。在源程序中这些命令都放在函数之外,而且一般都放在源文件的前面,它们称为预处理部分。

所谓预处理是指在进行编译的第一遍扫描(词法扫描和语法分析)之前所作的工作。预处理是C语言的一个重要功能,它由预处理程序负责完成。当对一个源文件进行编译时,系统将自动引用预处理程序对源程序中预处理部分处理,处理完毕自动进入对源程序的编译。

C语言提供了多种预处理功能。如:宏定义、文件包含、条件编译等。合理地使用预处理功能编写的程序便于阅读、修改、移植和调试,也有利于模块化程序设计。

C语言基础学习笔记18

15-宏的概念及无参定义方法

  1. 宏的概念定义方法

被定义为“宏”的标识符称为”宏名”。在编译预处理时,对程序中所有出现的“宏名”,都用宏定义中的字符串去代换,这称为“宏代换”或“宏展开”。

宏定义是由源程序中的宏定义命令完成的。宏代换是由预处理程序自动完成的。在C语言中,“宏”分为有参数和无参数两种、

无参宏的宏名后不带参数。其定义的一般形式为:

#define 标识符 字符串

其中的“#”表示这是一条预处理命令。凡是以“#”开头的均为预处理命令。“define”为宏定义命令。“标识符”为所定义的宏名。“字符串”可以是常数、表达式、格式串等。

符号常量的定义就是一种无参宏定义。常对程序中反复使用的表达式进行宏定义。

  1. 无参宏使用注意事项
  2. 习惯上宏名用大写字母表示,以便于与变量区别。但也允许用小写字母。
  3. 宏定义时用宏名来表示一个字符串,在宏展开时又以该字符串取代宏名,这只是一种简单的代换,字符串可以含任何字符,可以是常数,也可以是表达式,预处理程序对它不作任何检查。如有错误,只能在编译已被宏展开后的源程序时发现。
  4. 宏定义不是说明或语句,在行末不必加分号,如加上分号则连分号也一起置换。
  5. 宏定义必须写在函数之外,其作用域为宏定义命令起到源程序结束。如要终止其作用域可使用#undef命令。

C语言基础学习笔记18

  1. 宏名在源程序中若用“”括起来,则预处理程序不对其作宏代换。

C语言基础学习笔记18

  1. 宏定义允许嵌套,在宏定义的字符串中可以使用已经定义的宏名。在宏展开时由预处理程序层层代换。

C语言基础学习笔记18

  1. 可用宏定义表示数据类型,使书写方便。

C语言基础学习笔记18

  1. 对“输出格式”作宏定义,可以减少书写麻烦

C语言基础学习笔记18

注意括号问题:

C语言基础学习笔记18

16-有参宏定义和使用方法

  1. 有参宏的定义方法

C语言允许宏带有参数。在宏定义中的参数称为形式参数,在宏调用中的参数称为实际参数。

对带参数的宏,在调用中,不仅要宏展开,而且要用实参去代换形参。

带参数的宏定义的一般形式为:

#define 宏名(形参表)字符串

在字符串中含有各个形参。

带参宏调用的一般形式为:

宏名(实参表);

C语言基础学习笔记18

C语言基础学习笔记18

  1. 有参宏使用注意事项
  2. 带参宏定义中,形参之间可以出现空格,但是宏名和形参表之间不能有空格出现。

C语言基础学习笔记18

  1. 在带参宏定义中,形式参数不分配内存单元,因此不必作类型定义。而宏调用中的实参有具体的值。要用它们去代换形参,因此必须作类型说明。这是与函数中的情况不同的。在函数中,形参和实参是两个不同的量,各有自己的作用域,调用时要把实参值赋予形参,进行“值传递”。而在带参宏中,只是符号代换,不存在值传递的问题。
  2. 在宏定义中的形参是标识符,而宏调用中的实参可以是表达式。

C语言基础学习笔记18

  1. 在宏定义中,字符串内的形参通常要用括号括起来避免出错。在上例中的宏定义中(y)*(y)表达式的y都用括号括起来,因此结果是正确的。

C语言基础学习笔记18

  1. 宏定义也可用来定义多个语句,在宏调用时,把这些语句又代换到源程序内。

C语言基础学习笔记18

17-使用有参宏求最大值

#define Max(a,b)  (a>b) ? a:b

18-typedef和#define的区别

应注意宏定义表示数据类型和用typedef定义数据说明符的区别。宏定义只是简单的字符串代换,是在预处理完成的,而typedef是在编译时处理的,它不是作简单的代换,而是对类型说明符重新命名。被命名的标识符具有类型定义说明的功能。

C语言基础学习笔记18

19-条件编译的概念及优点

  1. 为什么要使用条件编译
  2. 按不同的条件去编译不同的程序部分,因而产生不同的目标代码文件。有利于程序的移植和调试
  3. 条件编译当然也可以用条件语句来实现,但是条件语句将会对整个源程序进行编译,生成的目标代码程序很长,而采用条件编译,则根据条件只编译其中的程序段1或程序段2,生成的目标程序较短。

20- #if-#else条件编译指令

第一种形式的格式为:

#if 常量表达式

程序段1

#else

程序段2

#endif

它的功能是,如常量表达式的值为真(非0),则对程序段1进行编译,否则对程序段2进行编译。因此可以使程序在不同条件下,完成不同的功能。

C语言基础学习笔记18

注意:条件编译后面的条件表达式中不能识别变量,它里面只能识别常量和宏定义

21-#ifdef条件编译指令

1、#ifdef条件编译指令

第一种形式的格式为:

#ifdef 标识符

程序段1

#else

程序段2

#endif

它的功能是,如果标识符已被#define命令定义过则对程序段1进行编译;否则对程序段2进行编译。

第二种形式的格式为:

#ifdef 标识符

程序段1

#else

程序段2

#endif

它的功能是,如果标识符已被#define命令定义过则对程序段1进行编译;否则对程序段2进行编译。如果没有程序段2(它为空),本格式中的#else可以没有,即可写为:

#ifdef 标识符

程序段

#endif

C语言基础学习笔记18

2、#ifndef条件编译指令

第三种形式个格式为:

#ifndef 标识符

程序段1

#else

程序段2

#endif

与第二种形式的区别是将“ifdef”改为“ifndef”。它的功能是,如果标识符未被#define命令定义过则对程序段1进行编译,否则对程序段2进行编译。这与第二种形式的功能正相反。


本博客内容既有转载自网络的内容,也有本作者原创内容,仅供学习与交流之用
如有侵权或者错误之处,请及时在下方留言!
喜欢 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址