C语言的基础知识点
下段时间打算回过头去研究下数据结构与算法,很多年没使用了,需要在复习一下,参考教程是 Mark Allen Weiss 的 Data Structures and Algorithm Analysis in C, 但是多年没有碰C语言了,有必要再把一些语言相关的特性回顾一下。这里先说说数据结构与算法的研究对象,数据结构主要研究组织大量数据的方法, 而算法分析则是对算法运行时间的评估。因为是方便自己复习,知识点比较零碎。
part1:基础概要
- C语言程序,无论大小,都是由函数和变量组成的。 函数指定所要执行的计算操作,变量用于存储计算过程中所使用的值。C语言中,函数定义中,圆括号列表内的值称为形式参数,函数调用时,与形参对应的值称为实际参数。所有的变量都必须先声明,后使用。声明用于说明变量的属性,由类型名和变量表组成。如 int x, y, z。 函数原型与函数定义中的参数名不要求相同,例如在main函数中调用power函数,需要将函数原型声明在main之前,power(int m, int n), 此处m,n 可以省略。
- C语言中,所以参数都是按照“值传递”的。被调函数只能修改其局部副本的值,而不影响主调函数。被调函数可以将参数声明为指针类型,调用函数通过提供特定值的变量地址,能让被调函数修改主调函数中变量的值。参数为数组名时,传递给函数的参数是数组的起始元素的地址。
- 局部变量,也称自动变量,每次进入函数时,必须显示为其赋值,否则为无效值。
- 定义是创建变量并分配存储单元,而声明是说明变量的性质,不分配存储单元。
- 外部变量可以再全局范围内访问,函数间可以使用外部变量交换数据,而不必使用参数表。外部变量定义在函数外,且只能定义一次,定义后编译程序会为其分配存储单元。函数中要使用外部变量,必须先用extern语句声明(外部变量定义在使用它的函数前除外),通常把变量和函数的extern声明放在头文件中(.h)。
- #define 用于把符号常量定义为一个字符串, 程序中出现的所有被define定义的名字,都将用相应的文本进行替换。
- 转义字符通常用来表示不可见的字符,C语言中常用的转义字符有:\n 换行 \b 回退 \t 制表 \\ 反斜杠本身。 printf是一个通用的格式化输出函数, 该函数的第一个参数是待打印的字符串,每个 % 表示后面的其他参数一一替换的位置,并可指定打印格式。如 printf("%3d\t%6.2f", d, f), 其中3和6用于指明打印宽度,方便对齐, .2用于指明浮点数后面的小数位数, %c 表示字符,%s表示字符串。getchar函数从文本流中读入下一个字符。下面的代码打印输入内容,windows中Ctrl + Z 后回车,产生EOF,EOF是一个与任何字符都不同的特殊值。如 c = getchar() 之类的赋值表达式,复制后会具有其左边变量保存的值。函数默认返回类型为int,这里的int可以省略,函数不一定都有返回值,不带表达式的return语句将控制权交给调用者,但不返回有用的值。
#include <stdio.h> #include <stdlib.h> int main() { int c; while((c = getchar()) != EOF) putchar(c); system("pause"); }
part2:类型,运算符与表达式
- 对象可以用const修饰,表示其值不能修改。类型限定符signed or unsigned 可用于限定 char类型或任何整形(通常:short 16位,int 16 or 32位, long 32位),unsigned char 取值范围 0-255, signed char 取值范围 -128-127。long类型常量以l或L结尾,如123456L, 没有后缀f或F的浮点数被当做double。
- 整数可以用十进制,八进制或十六进制表示。0开头表示八进制,0x or 0X开头表示十六进制,整数31可以写成,037 或 0x1F。0XFUL表示无符号长整形,等于15。
- 字符常量‘\0’表示值为0的字符,也就是空字符null。字符串常量就是字符数组,内部使用‘\0’作为串的结尾。应搞清字符常量与仅包含一个字符的字符串的区别:'x', "x"是不用的,前者是一个整数,其值只字母x在机器字符集中对应的数值,后者是包含一个字符和一个结束符'\0'的字符数组。
- 常量表达式在编译时求值,而不再运行是求值。
- #define MAXLINE 1000
- char line[MAXLINE+1];
- 枚举常量是一个常量整型值的列表。enum boolean { NO, YES }; 没有显示说明的情况下,第一个枚举值为0,第二个为1。若指定了某一枚举名的值,其后的枚举值依次递增。
- enum escapes { BELL = '\a', BACKSPACE = '\b', TAB = '\t',
- NEWLINE = '\n', VTAB = '\v', RETURN = '\r' };
- enum months { JAN = 1, FEB, MAR, APR, MAY, JUN,
- JUL, AUG, SEP, OCT, NOV, DEC };
- 所有变量必须先声明,后使用,声明指定变量的类型,后面可以跟一个或多个该类型变量。可以在声明的同时,对该变量初始化,后面紧跟一个等号和表达式,外部变量和静态变量自动初始化为0,未经显示初始化的自动变量为无效值。任何类型的变量用const修饰表示该变量的值不能修改,数组用const修饰,则指定数组的所有元素不能修改。
- 算术运算符:+,-,*,/,%(取模),整数除法,会截断结果中的小数部分,x % y的结果是x除以y的余数。
- 关系运算符:<,<=,>,>= 具有相同优先级,优先级次于他们的是相等性运算符:==, != , 逻辑运算符 &&, ||优先级低于相等性运算符,并且在知道结果真假后立即停止计算,&& 优先级高于||。关系运算符的优先级比算术运算符的优先级低,i < a -1 等价于 i < (a - 1)。
- goto语句常用语跳出多层循环,标号的作用域是整个函数,后面跟一个冒号,可位于goto语句所在函数的任何语句之前,尽量不要使用goto语句。
- 局部变量(自动变量)或函数参数的作用域是声明该变量的函数,外部变量或函数的作用域从声明它的地方开始,到其所在文件的末尾。如果需要在外部变量定义之前使用该变量,或者变量定义和使用不在同一文件中,则需要在声明时强制使用extern关键字。外部变量的定义和声明应严格区分开来,声明说明变量的属性,定义引起存储器的分配。一个程序的所有源文件,一个外部变量只定义一次,其他地方通过extern声明使用。
- 用static修饰外部变量或函数,则他们的作用域被限定为被编译源文件的剩余部分,除了该函数或外部变量所在文件外,其他文件中无法访问。static也可修饰局部变量,与自动变量不同的是,它不随函数的退出而消失,static类型的局部变量是在只能在某函数中使用但一直占据存储空间的变量。
- register变量,register声明告诉编译器,该变量的使用频率较高,考虑将该变量放在cpu寄存器中,但编译器可忽略次选项。register 声明只适用于局部变量(自动变量和参数参数)。
- 对于外部变量和静态变量,若不进行显示初始化,则自动初始化为0,初始化表达式必须是常量表达式,只初始化一次。自动变量和寄存器变量,每次进入函数重新初始化,不显示初始化则为无效值。
- 对于数组,没有初始化的元素将被自动初始化为0, 不能跳过前面的元素直接初始化后面的元素。字符数组可以用字符串常量来初始化,最后一位字符为'\0'。
- C语言预处理指令,#include <文件名> include的行将被替换成文件名所指定的文件的内容, 先在系统目录中找头文件,没找到就去当前目录中找,or #include "" 先在当前目录中找头文件,没找到则去系统目录中找, #define 名字 替换文本,宏替换,后续所有出现名字记号的地方都将被替换成替换文本。
- 如果const位于*的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;如果const位于*的右侧,const就是修饰指针本身,即指针本身是常量。指向常量数据的非常量指针,在传递大型数据对象如结构给函数时(数组是自动以传引用方式传递的,而结构是以传值方式传递的),可以获得既有传引用调用的性能,又有传值调用的安全性。
指向非常量数据的常量指针,这种情况就是指针总是指向同一个内存单元,其中的数据项可以通过该指针类修改,但指针本身不能被修改。典型例子就是数组,数组名是一个指向数组首元素地址的的常量指针,可以通过对它做指针算术运算来操作数组的元素,但,不能对数组名有任何修改。说了这么多,其实看看英文翻译,就能很清楚的理解区别,指针常量:pointer to const ,如函数参数。 常量指针:const pointer,如数组名。
浙公网安备 33010602011771号