资源预览内容
第1页 / 共37页
第2页 / 共37页
第3页 / 共37页
第4页 / 共37页
第5页 / 共37页
第6页 / 共37页
第7页 / 共37页
第8页 / 共37页
第9页 / 共37页
第10页 / 共37页
亲,该文档总共37页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
第3章 指针、函数、及其他数据类型 指针 函数 结构体 共用体 枚举3.1 指针指针是一种非常重要的数据类型,利用指针变量可以表示各 种数据结构,方便地引用数组和字符串,像汇编语言一样 处理内存地址。指针极大地丰富了语言的功能,运用指 针编程是语言最主要的风格之一。3.1.1 指针的基本概念指针变量的定义数据类型符 *指针变量名;int *p; double *pd; int *p1, *p2; int *p1, p2; 3.1.1 指针的基本概念int *pn; pn= *pn=2;3.1.1 指针的基本概念指针的运算指针是一个内存地址值,它是一个无符号的整数,可以进 行加法和减法运算,但不允许进行乘法、除法和两个指针 值的相加运算。指针类型的变量在内存中都和int类型所 占的大小想相同,可以使用sizeof来查看大小int a5 = 1, 2, 3, 4, 5; int *p1 = p1+; 3.1.1 指针的基本概念void指针类型void *p;上面的定义中,p仍然是一个指针变量,有自己的内存空 间,占用4个字节,但是没有指定它指向哪种类型的变量 。在这种情况下,不能对指针变量进行运算,否则会导致 编译错误。3.1.1 指针的基本概念指针的类型转换(TYPE *)p 强制类型转换的结果是生成一个新的指针,该指针的类型 为TYPE *,所指向的类型为TYPE,其他属性都不变,所 指向的地址仍为原来的地址。 3.1.1 指针的基本概念指向指针的指针数据类型符 *指向指针的指针变量名; int a,b; int *p; int *pp; p= 2 问上面的语局同什么语句相同? *pp= int *p; p=a; p= 对数组元素的引用既可以使用下标法,也可以使用指针的表 示方法,如: p+n与a+n表示数组元素an的地址,即3.2 函数 函数的定义与声明 函数的调用与参数传递 变量的作用域 变量的存储类型 外部函数和内部函数 函数的递归 函数指针3.2.1 函数的定义与声明函数对应于程序的模块,需要先定义后使用。定义也叫函数的声明,函数的声明需 要注意的是函数句尾有一个分号,并且形式参数可以只写数据类型返回值类型符 函数名(形式参数列表) 定义部分;执行语句部分; return语句的格式为: return 表达式; return(表达式);3.2.2 函数的调用与参数传递函数调用的一般格式为: 函数名(实际参数列表) 函数参数传递是调用函数和被调用函数在调用发生时进行通信的方法。基本的参数 传递机制有: 值传递:被调用函数中的任何操作都不会影响到实参变量的值地址传递:被调用函数队形式参数的任何擦操作做都被处理成间接寻址, 通过对地质访问,会影响实际参数变量通过指针的方式实现了地质的传递,但这种地质传递方式实际上也是值 传递,只不过传递的是地址值3.2.3 变量的作用域局部变量是在函数内部定义的变量或函数的形式参数。 int func (int a,int b) int i; int main() int i, j; 3.2.3 变量的作用域全局变量是在函数外部定义的变量 int x, y; void func() int main() /* int y; */ 现在全局变量x,y在两个函数中都可以使用,需要注意的是,如果在函数内部定义变量 和全局变量名相同,又或者是函数参数中有和全局变量名相同,则会使用局部变 量.3.2.3 变量的作用域如果需要在未定义前使用全局变量,声明全局变量:extern 数据类型符 全局变量名;使用全局变量可以减少函数调用过程中实际参数和形式参数 之间数据传递带来的时间消耗。但也会带来了一些问题 全局变量破坏了函数的封装性 全局变量使函数代码的可读性降 3.2.4 变量的存储类型定义一个变量的完整形式应为:存储类型说明符 数据类型符 变量名;存储类型说明符有四种: auto(自动变量) extern(外部变量) static(静态变量) register(寄存器变量) 变量的存储类型变量在内存中的存储方式可以分为两种,静态存储和动态存储 静态存储:变量在定义的时候就分配存储单元并一直保持到整个程序的结束全局变 量即属于静态存储的方式 动态存储:在程序执行过程中,使用它时才分配存储单元,使用完立即释放.函数的形 式参数,在定义的时候不会分配内存空间,只要被调用的时候,才进行内存的分配, 如果一个函数被反复调用,则会反复地进行存储单元的分配与释放 通常把由于变量的存储方式不同而产生的特性成为变量的生存期,生存期表示了变 量存在的时间,也叫生命周期. 生命周期和作用域是从时间和空间两个不同的角度来描述变量的特性C语言中存储类型分为四种变量的存储类型一 自动变量 默认的情况下,所有的局部变量都是自动变量 auto int a int a 是相同的关键字可以省略 二 外部变量 全局变量的存储方式,都是外部变量,使用extern关键字声明,全局是从作用域角度说 的,外部是从存储方式说的.所谓的外部就是,该类型的变量可以在所有构成程序 的源文件中使用 三 静态变量 static关键声明,重要的是,他对于修饰局部变量和全局变量含义是不一样的 extern int a 全局变量,可以在多个源文件中使用 static extern int a 也是全局变量,但是只是本文件的全局变量,不能再其它文件中使 用,静态全局变量 static 修饰局部变量,特点是,该变量位于静态存储区,在整个程序运行期间始终占用 着被分配的空间.也就是说,在函数调用后,他的值依然存在,并可能会影响下一次 函数的调用 四 寄存器变量 变量一般是存放在内存中的,但是对于一些频繁使用的变量,为了提高存取时间, 可将其放入在CPU的寄存器中.叫寄存器变量.register int i.一般来说没必要这 么声明,编辑器会优化变量的声明,并自动识别,转换成寄存器变量3.2.5 外部函数和内部函数当一个程序由多个源文件组成时,可以指定一个文件中的函 数能被其他文件调用,也可以指定该函数只能被本文件使 用。从这个意义上讲,函数可以分为: 外部函数:默认就是外部函数 extern关键字 内部函数:static关键字来声明3.2.5 外部函数和内部函数如果一个函数可以被其他源文件调用,该函数就称为外部函 数。定义外部函数时,在函数前面加关键字extern 。extern int add(int a,int b) return a+b; 3.2.5 外部函数和内部函数如果一个函数只能被本文件中的其他函数调用,该函数就称 为内部函数。定义内部函数时,在函数前面加关键字 static。static int add(int a,int b) return a+b; 3.2.6 函数的递归所谓递归,就是函数自己调用自己,或在自己调用的下一级 函数中调用自己。函数的递归之所以能实现,就是因为函 数在每次调用时都在栈中有形参和局部变量的拷贝,他们 与函数的其他调用过程无关。 采用递归的方法解决实际问题时,必须满足一定的条件: 可以把要解决的问题转化为一个新的问题,而新问题的 解决方法与原问题相同,只是所处理的对象有规律地递 增或递减; 要有递归结束的条件,即在适当的地方结束递归调用, 否则将进入死循环。3.2.7 函数指针函数指针是指向函数的指针变量。 因而“函数指针”本身首先应是指针变量,只不 过该指针变量指向函数。这正如用指针变量可指向整型变量、字符型、数组一 样,这里是指向函数。如前所述,C在编译时,每一个函数都有一个入口地址 ,该入口地址就是函数指针所指向的地址。有了指向函数的指针变量后,可用 该指针变量调用函数,就如同用指针变量可引用其他类型变量一样,在这些概 念上是一致的。函数指针有两个用途:调用函数和做函数的参数。 函数指针变量的定义格式为: 函数的返回值类型 (*函数指针变量名)(函数的形式参数) void (*p)(int x);int func(int x); /* 声明一个函数 */ int (*f) (int x); /* 声明一个函数指针 */ 定义一个指针变量f,它指向某一个函数,这种函数返回值类型是int,并且参数类型是 int类型,这里只是定义,并未赋值f=func; /* 将func函数的首地址赋给指针f */ 赋值时函数func不带括号,也不带参数,由于func代表函数的首地址,因此经过 赋值以后,指针f就指向函数func(x)的代码的首地址。 (*f)(9) 通过函数指针调用了func函数指针函数指针也可以作为函数的参数使用 tpyedef关键字 typedef 类型 别名 例typedef int int32;int32 a=9; 上面的int32就变成了一种类型,它指代的是int类型 typedef void (*pt)(int,int) 上面的含义是定义一个函数指针类型 pt void add(int,int); void sub(int,int); void fun(pt,int,int); 定义一个函数,其中一个参数是指针类型pt3.3 结构体、共用体和枚举前面介绍的数据类型(如字符型、整型、数组和指针等)只 能描述事物某一方面的属性。而现实世界中的事物往往具 有多方面的属性,为此C语言提供几种用户可以自定义的 数据类型:结构体、共用体和枚举。3.3.1 结构体结构类型体的定义struct 结构体名 数据类型符 成员1; 数据类型符 成员2; 数据类型符 成员n; ;3.3.1 结构体结构体变量的定义先定义结构体,然后像定义基本数据类型变量一样,定 义结构体类型的变量 在定义结构体的同时定义结构体变量,适用于定义局部 使用的结构体变量 直接定义结构体变量,即在定义结构体的同时定义结构 体变量,但不给出结构体名 3.3.1 结构体结构体变量的初始化struct 结构体名 结构体变量名 = 初始数据表;struct student a = 23, “Zhang Xing“, M, 28, “1002 Xin Jian Road“ ;3.3.1 结构体指向结构体的指针struct 结构体名 *结构体指针名struct student *p;3.3.1 结构体结构体变量成员的引用结构体变量名.成员名a.id (*结构体指针变量).成员名(*p).id 结构体指针变量-成员名 p-id 3.3.1 结构体嵌套结构体struct student int id;char name20;char sex;unsigned int age;struct addr address; ; 结构体变量名.嵌套结构体变量名.结构体成员名 student.address.zipcodestruct address char city32; char address100;unsigned long zipcode; char tel8; ;3.3.1 结构体应用实例3.3.2 共用体共用体又称为联合体,它也是由不同类型的数据构成的。共 用体和结构体的主要区别是:共用体存储时采用了覆盖技 术,不同数据类型的成员占用同一段内存空间。这样在某 一时间点上,共用体中只能存储其某一成员的信息。3.3.2 共用体共用体类型的定义 union 共用体名 数据类型符 成员1; 数据类型符 成员2; 数据类型符 成员n; ; 共用体变量的定义 union 共用体名 共用体变量名; 3.3.3 枚举枚举是一个被命名的整型常量的集合,其中列举出所有可能 的取值。枚举类型的定义 enum 枚举名 枚举常量1,
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号