[TOC]
*2016/12/15*
-
C语言规定,标识符只能由字母(A
Z, az)、数字(0~9)和下划线(_)组成,并且第一个字符必须是字母或下划线。以下标识符是合法的:
a, x, x3, BOOK_1, sum5
以下标识符是非法的:
3s 不能以数字开头
sT 出现非法字符
-3x 不能以减号(-)开头
bowy-1 出现非法字符减号(-)
-
在标识符中,大小写是有区别的,例如BOOK和book 是两个不同的标识符。
-
%d称为格式控制符,它指明了以何种形式输出数据。格式控制符均以%开头,后跟其他字符。%d 表示以十进制形式输出一个整数。除了 %d,printf 支持更多的格式控制,例如:
-
%c:输出一个字符。c 是 character 的简写。
-
%s:输出一个字符串。s 是 string 的简写。
-
%f:输出一个小数。f 是 float 的简写。
-
-
C语言支持单行注释和多行注释:
-
单行注释以//开头,直到本行末尾(不能换行);
-
多行注释以/开头,以/结尾,注释内容可以有一行或多行。
-
-
在C语言中,表达式a=a#b可以简写为a#=b,#表示
+、-、*、/、%
中的任何一种运算符。 -
++ 在前面叫做前自增(例如 ++a)。前自增先进行自增操作,再进行其他操作。
-
++ 在后面叫做后自增(例如 a++)。后自增先进行其他操作,再进行自增操作。
-
对于语句赋值语句a=b=c;,先执行b=c,再执行a=b,而不是反过来,这说明赋值操作符=具有右结合性。
-
C语言的运算符众多,具有不同的优先级和结合性,我们将它们全部列了出来,方便大家对比和记忆:
优先级 运算符 名称或含义 使用形式 结合方向 说明 1 [] 数组下标 数组名[常量表达式] 左到右 () 圆括号 (表达式)/函数名(形参表) . 成员选择(对象) 对象.成员名 -> 成员选择(指针) 对象指针->成员名 2 - 负号运算符 -表达式 右到左 单目运算符 (类型) 强制类型转换 (数据类型)表达式 ++ 自增运算符 ++变量名/变量名++ 单目运算符 -- 自减运算符 --变量名/变量名-- 单目运算符 * 取值运算符 *指针变量 单目运算符 & 取地址运算符 &变量名 单目运算符 ! 逻辑非运算符 !表达式 单目运算符 ~ 按位取反运算符 ~表达式 单目运算符 sizeof 长度运算符 sizeof(表达式) 3 / 除 表达式/表达式 左到右 双目运算符 * 乘 表达式*表达式 双目运算符 % 余数(取模) 整型表达式/整型表达式 双目运算符 4 + 加 表达式+表达式 左到右 双目运算符 - 减 表达式-表达式 双目运算符 5 << 左移 变量<<表达式 左到右 双目运算符 >> 右移 变量>>表达式 双目运算符 6 > 大于 表达式>表达式 左到右 双目运算符 >= 大于等于 表达式>=表达式 双目运算符 < 小于 表达式<表达式 双目运算符 <= 小于等于 表达式<=表达式 双目运算符 7 == 等于 表达式==表达式 左到右 双目运算符 != 不等于 表达式!= 表达式 双目运算符 8 & 按位与 表达式&表达式 左到右 双目运算符 9 ^ 按位异或 表达式^表达式 左到右 双目运算符 10 | 按位或 表达式|表达式 左到右 双目运算符 11 && 逻辑与 表达式&&表达式 左到右 双目运算符 12 || 逻辑或 表达式||表达式 左到右 双目运算符 13 ?: 条件运算符 表达式1? 表达式2: 表达式3 右到左 三目运算符 14 = 赋值运算符 变量=表达式 右到左 /= 除后赋值 变量/=表达式 *= 乘后赋值 变量*=表达式 %= 取模后赋值 变量%=表达式 += 加后赋值 变量+=表达式 -= 减后赋值 变量-=表达式 <<= 左移后赋值 变量<<=表达式 >>= 右移后赋值 变量>>=表达式 &= 按位与后赋值 变量&=表达式 ^= 按位异或后赋值 变量^=表达式 |= 按位或后赋值 变量|=表达式 15 , 逗号运算符 表达式,表达式,… 左到右 从左向右顺序运算 -
puts() 函数在输出结束时会自动换行,而 printf() 和 putchar() 不会,需要手动添加换行符\n
-
printf 格式控制字符的完整形式如下:
[flags][width][.precision]type
-
i f(判断条件){
语句块1
}else{
语句块2
}

-
C语言规定,else 总是与它前面最近的 if 配对,
-
关系运算符的运算结果只有 0 或 1。当条件成立时结果为 1,条件不成立结果为 0。我们将运算结果 1 称为“真”,表示条件成立,将 0 称为“假”,表示条件不成立。
运算符 | 说明 | 结合性 | 举例 |
---|---|---|---|
&& | 与运算,双目,对应数学中的“且” | 左结合 | 1&&0、(9>3)&&(b>a) |
|| | 或运算,双目,对应数学中的“或” | 左结合 | 1||0、(9>3)||(b>a) |
! | 非运算,单目,对应数学中的“非” | 右结合 | !a、!(2<5) |
-
break 是C语言中的一个关键字,专门用于跳出 switch 语句。所谓“跳出”,是指一旦遇到 break,就不再执行 switch 中的任何语句,包括当前分支中的语句和其他分支中的语句;也就是说,整个 switch 执行结束了,接着会执行整个 switch 后面的代码。
-
在C语言中,共有三大常用的程序结构:
- 顺序结构:代码从前往后执行,没有任何“拐弯抹角”;
- 选择结构:也叫分支结构,重点要掌握 if else、switch 以及条件运算符;
- 循环结构:重复执行同一段代码。
-
for 循环的一般形式为: for(表达式1; 表达式2; 表达式3){ 语句块 }
它的运行过程为:
-
先执行“表达式1”。
-
再执行“表达式2”,如果它的值为真(非0),则执行循环体,否则结束循环。
-
执行完循环体后再执行“表达式3”。
-
重复执行步骤 2) 和 3),直到“表达式2”的值为假,就结束循环。上面的步骤中,2) 和 3) 是一次循环,会重复执行,for 语句的主要作用就是不断执行步骤 2) 和 3)。
“表达式1”仅在第一次循环时执行,以后都不会再执行,可以认为这是一个初始化语句。“表达式2”一般是一个关系表达式,决定了是否还要继续下次循环,称为“循环条件”。“表达式3”很多情况下是一个带有自增或自减操作的表达式,以使循环条件逐渐变得“不成立”。
-
-
break,用它来跳出 switch 语句。当 break 关键字用于 while、for 循环时,会终止循环而执行整个循环语句后面的代码。break 关键字通常和 if 语句一起使用,即满足条件时便跳出循环。
-
continue 语句的作用是跳过循环体中剩余的语句而强制进入下一次循环。continue语句只用在 while、for 循环中,常与 if 条件语句一起使用,判断条件是否成立。
-
a[3][4]
表示a数组第3行第4列的元素。 -
二维数组的初始化可以按行分段赋值,也可按行连续赋值。
例如对数组
a[5][3]
,按行分段赋值可写为:int a[5][3]={ {80,75,92}, {61,65,71}, {59,63,70}, {85,87,90}, {76,77,85} };
按行连续赋值可写为:
int a[5][3]={80, 75, 92, 61, 65, 71, 59, 63, 70, 85, 87, 90, 76, 77, 85};
这两种赋初值的结果是完全相同的。1)可以只对部分元素赋初值,未赋初值的元素自动取0值。例如:
int a[3][3]={{1},{2},{3}};
-
在C语言中,输出字符串的函数有两个:
- puts():直接输出字符串,并且只能输出字符串。
- printf():通过格式控制符 %s 输出字符串。除了字符串,printf() 还能输出其他类型的数据。
- 在C语言中,输入字符串的函数有两个:
-
- scanf():通过格式控制符 %s 输入字符串。除了字符串,scanf() 还能输入其他类型的数据。
- gets():直接输入字符串,并且只能输入字符串。
-
如果希望读取的字符串中不包含空格,那么使用 scanf() 函数;如果希望获取整行字符串,那么使用 gets() 函数,它能避免空格的截断。
-
返回值类型可以是C语言中的任意数据类型,例如 int、float、char 等。
-
函数名是标识符的一种,命名规则和标识符相同。函数名后面的括号( )不能少。
-
函数体是函数需要执行的代码。即使只有一个语句,也要由{ }包围。
-
在函数体中使用return语句返回数据。
-
函数定义时给出的参数称为形式参数,简称形参;函数调用时给出的参数(传递的数据)称为实际参数,简称实参。函数调用时,将实参的值传递给形参,相当于一次赋值操作。注意:实参和形参的类型、数目必须一致。
-
形参和实参有以下几个特点:
-
形参变量只有在函数被调用时才会分配内存,调用结束后,立刻释放内存,所以形参变量只有在函数内部有效,不能在函数外部使用。
-
实参可以是常量、变量、表达式、函数等,无论实参是何种类型的数据,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参,所以应该提前用赋值、输入等办法使实参获得确定值。
-
实参和形参在数量上、类型上、顺序上必须严格一致,否则会发生“类型不匹配”的错误。
函数调用中发生的数据传送是单向的,只能把实参的值传送给形参,而不能把形参的值反向地传送给实参。 因此在函数调用过程中,形参的值发生改变,而实参中的值不会变化。
-
-
函数声明给出了函数名、返回值类型、参数列表(参数类型)等与该函数有关的信息,称为函数原型(Function Prototype)。
-
定义在函数内部的变量称为局部变量(Local Variable),它的作用域仅限于函数内部, 离开该函数后就是无效的,再使用就会报错。在所有函数外部定义的变量称为全局变量(Global Variable),它的作用域默认是整个程序,也就是所有的源文件,包括 .c 和 .h 文件。
-
C程序的全部工作都是由各式各样的函数完成的,所以也把C语言称为函数式语言。
标准C语言(ANSI C)共定义了15 个头文件,称为“C标准库”,所有的编译器都必须支持,如何正确并熟练的使用这些标准库,可以反映出一个程序员的水平。
-
-
合格程序员:<stdio.h>、<ctype.h>、<stdlib.h>、<string.h>
- 熟练程序员:<assert.h>、<limits.h>、<stddef.h>、<time.h>
- 优秀程序员:<float.h>、<math.h>、<error.h>、<locale.h>、<setjmp.h>、<signal.h>、<stdarg.h>
-
-
main() 函数是主函数,它可以调用其它函数,而不允许被其它函数调用。因此,C程序的执行总是从 main() 函数开始,完成对其它函数的调用后再返回到 main() 函数,最后由 main() 函数结束整个程序。
-
部分预处理指令:
指令 | 说明 |
---|---|
# | 空指令,无任何效果 |
#include | 包含一个源代码文件 |
#define | 定义宏 |
#undef | 取消已定义的宏 |
#if | 如果给定条件为真,则编译下面代码 |
#ifdef | 如果宏已经定义,则编译下面代码 |
#ifndef | 如果宏没有定义,则编译下面代码 |
#elif | 如果前面的#if给定条件不为真,当前条件为真,则编译下面代码 |
#endif | 结束一个#if……#else条件编译块 |
-
编译(Compile)会将源文件(.c文件)转换为目标文件。对于VC/VS,目标文件后缀为 .obj;对于GCC,目标文件后缀为 .o。
-
用尖括号 #include <>:
- 一般用于包含标准的库头文件,编译器会去系统配置的库环境变量和者用户配置的路径去搜索,而不会在项目的当前目录去查找
-
用双引号 #include "":
- 一般用于包含用户自己编写的头文件,编译器会先在项目的当前目录查找,找不到后才会去系统配置的库环境变量和用户配置的路径去搜索
-
宏定义的一般形式为:
#define 宏名 字符串
-
对宏定义的几点说明 1) 宏定义是用宏名来表示一个字符串,在宏展开时又以该字符串取代宏名,这只是一种简单的替换。字符串中可以含任何字符,可以是常数,也可以是表达式,预处理程序对它不作任何检查,如有错误,只能在编译已被宏展开后的源程序时发现。
-
宏定义不是说明或语句,在行末不必加分号,如加上分号则连分号也一起替换。
-
宏定义必须写在函数之外,其作用域为宏定义命令起到源程序结束。如要终止其作用域可使用#undef命令。
-
-
带参数的宏,在调用中,不仅要宏展开,而且要用实参去代换形参。
-
对于带参宏定义不仅要在参数两侧加括号,还应该在整个字符串外加括号。
-
CPU 访问内存时需要的是地址,而不是变量名和函数名!变量名和函数名只是地址的一种助记符,当源文件被编译和链接成可执行程序后,它们都会被替换成地址。编译和链接过程的一项重要任务就是找到这些名称所对应的地址。
-
对星号*****的总结
- 表示乘法,例如int a = 3, b = 5, c; c = a * b;,这是最容易理解的。
- 表示定义一个指针变量,以和普通变量区分开,例如int a = 100; int *p = &a;。
- 表示获取指针指向的数据,是一种间接操作,例如int a, b, *p = &a; *p = 100; b = *p;。