- while循环和for循环先判断表达式,后执行语句;do-while循环先执行语句后判断表达式
- C语言中,“函数”是个重要的概念,是模块化编程的基础
- C语言的库函数十分丰富,大致可分为“标准库函数”和“第三方库函数”两类
- 包括main函数在内,函数的定义都是平行的,不允许把一个函数定义在另一个函数内,不同函数放置的位置没有关系
- 函数定义有4个要素:参数列表,返回类型,函数名和函数体
返回类型用于指明函数输出值的类型,如果没有输出值,返回类型为void。如果在函数定义时没有注明返回类型,默认为int。
函数调用有两种类型
一是“先定义,后调用”,这要求函数定义和调用语句在同一个文件内,编译器能从函数的定义中提取函数参数列表、输出类型等接口信息。
二是“函数声明+函数调用”,大多数情况下,函数的定义与函数的调用并不在一个文件内,即使在一个文件中也有可能调用在前定义在后,这时需要在调用之前先对函数声明,告诉编译器有这么一个函数存在。实参向形参的数据传递是单向的“值传递”。实参和形参在内存中被分配到不同的单元,发生函数调用时,只是将实参的“值“传给形参,在函数中即使改变了形参的值也不会影响实参原来的值
函数和变量一样,也必须“先定义,后使用”
要调用在主函数后面定义的函数,必须在调用函数之前提前声明此函数的原型,否则无法识别函数。原型可不写出形参名。
调用函数之前,一定要使编译器知道函数原型,这样编译器才知道有哪些函数名,该函数需要些什么样类型的参数,返回什么样类型的数值。
函数原型声明的基本形式如下:
返回类型 函数名(数据类型 形参,数据类型 形参……);
或
返回类型 函数名(数据类型,数据类型……)值得注意的是:数组占据的内存空间是连续的,这样,很容易计算数组占据的内存大小和每个元素对应的内存首地址。
一维数组声明的基本格式为:
类型 数组名[数组元素个数];
一维数组的初始化形式一般为:类型 数组名[宽度] = { 初值列表 };
如:int a[10]={10,9,8,7,6,5,4,3,2,1};
中可以省略数组宽度。编译器将通过给出的数据个数来定义数组的宽度
int a[ ]={10,9,8,7,6,5,4,3,2,1};用一个已经初始化的数组给另一个数组赋值,即使元素类型相同,数组大小相同,这样的用法也是不允许的。
一维数组地址的引用
数组名[下标表达式]
数组名 ± 整数
如&a[0]、&a[i]、&a[2*i-1]
a、a+i、a+2*i-1
- C语言中用数组名表示数组的首地址,即第1个元素的地址。比如 a,实际上就是&a[0]。
- 地址加减整数,就是求当前元素后面或前面第几个元素的地址。
- 指针:一个变量的地址
- 指针变量:专门存放地址的变量
- 指针可以视为一个普通变量,通常所说的定义一个指针实际上是声明一个指针变量
声明一个指针变量时,需要向编译器提供:
指针的类型,原则上指针类型应与其指向的数据类型一致
指针变量名
声明一个指向int型数据的指针pInt:
int* pInt;
- 在一行语句中同时声明两个指针变量,指针变量前都要加星号
- 声明一个指针后,编译器并不会自动完成其初始化,此时,指针的值是不确定的,也就是说,该指针指向哪块内存单元是完全随机的,因此,指针变量的初始化十分重要。
如果在指针变量声明之初确实不知道该将指针指向何处,最简单的方式:
int* pInt=NULL如果要让指针变量确切地指向某个变量,需要使用&取地址操作符。
- 指针变量也是变量,占据一定的内存空间,有地址,因此可以用一个指针指向它,这称为指向指针的指针,或二级指针
- 指针类型,指的是声明指针变量时位于变量名前的“类型”,而指针所指向的类型,指的是为指针初始化或赋值时的变量类型。
指针变量的值是指针本身存储的数值,这个值将被编译器当作一个地址,而不是一个一般的数值。在32位程序里,所有类型的指针的值都是一个32位整数,因为32位程序里内存地址长度为32位。指针所指向的内存区就是从指针的值所代表的那个内存地址开始,长度为sizeof(指针所指向的类型)的一片内存区。一个指针的值是A,即是说该指针指向了以A为首地址的一片内存区域;反之,说一个指针指向了某内存区域,即是说该指针的值是这块内存区域的首地址。
指针变量的赋值运算
p=&a; (将变量a的地址赋值给p)
p=array; (将数组array首地址赋值给p)
p=&array[i]; (将数组元素地址赋值给p)
p1=p2; (指针变量p2赋值给p1)
不能把一个整数赋值给p,也不能把p的值赋值给整型变量
- “指针+整数”用于将指针向后移动“sizeof(指针类型)”个内存单元,而“指针-整数”用于将指针向前移动“sizeof(指针类型)”个内存单元。
- 对指针的算术运算使得指针以某类型为单位在内存中前后移动,但编译器并不会检查这种移动的有效性,即不会检查目的地址是否可用,如果移动失误,很有可能会修改一些本不该修改的内存单元,给程序带来致命打击。
一个类型为 T 的指针的移动
以 sizeof(T)为移动单位
对两个毫无关联的指针比较大小是没有意义的,因为指针只代表了“位置”信息,但是如果两个指针所指向的元素位于同一个数组(或同一块动态申请的内存中),指针的大小比较反映了元素在数组中的先后关系。
指针变量所支持的另一种运算是两个同类型指针相减,返回值是个有符号整数,其值可用下列公式计算:
(指针1的值 - 指针2的值)/指针所指类型占用的内存字节数