这些内容是我个人在学习C语言时遇到或使用到的个人觉得比较重要的内容,有些对于做题是比较重要的基础知识,大部分使用到了老师的PPT。
1、C程序是由函数组成的。(重要)
2、所有的C程序有且只有一个main()函数。(重要)
C程序总是从main()函数的第一条语句开始运行,当main()函数结束时,程序也就结束了。
3、 程序中包含了数据表达与数据处理(流程控制)两部分。
4、 算法的特征
(1)确定性。
(2)有穷性。
(3)可行性。
(4)有零个或多个输入。
(5)有一个或多个输出。
5、标识符命名规范(重要)
由字母、数字和下划线组成,其中第一个字符必须是字母或下划线。区别分大小写
2、直接常量
十进制表示:由数字0~9,正、负号组成;
八进制表示:以0(数字0)为前缀,其后由数字0~7组成;八进制数一般是无符号数。
十六进制表示:以0x或0X为前缀,其后由数字0~9和字母A~F(字母大小写均可)组成,十六进制数一般是无符号数。
4、在字符串中如遇到’\0’则认为该字符串结束
5、整型变量
Visual C++ 2010环境下,各种整型的关键字及占用内存字节数和取值范围如下表:
6、实型变量
Visual C++ 2010环境下,各种整型的关键字及占用内存字节数和取值范围如下表:
7、算术运算符和算术表达式
注意:
(1)两个整型数据做除法运算时,结果一定是整数。
(2)求余运算的结果是两个整型数据相除的余数。求余运算只能用于整型数据的运算。
(3)双目运算符两边的数据类型应相同,若不同时,编译系统会先转换为同一数据类型,然后再进行运算。
(4)如果a和b都是整型,则其商也为整型,小数部分被舍去,如3/4的结果为0,4/3的结果为1
8、自动转换
注意:
强制类型转换是一种不安全的转换,如果是从高级类型转换成低级类型,则会损失数据的精度。
1、整型数据的输入和输出
scanf()函数中的格式修饰符
printf()函数中的格式修饰符(重要)
2、实型数据的输入和输出
3、函数对字符型数据进行输入输出
使用getchar()函数和putchar()
(1) getchar()函数
ch=getchar();
(2) putchar()函数
putchar(输出参数);
4、常用数学库函数
使用时包含数学库函数 #include
① 指数函数exp(x):计算ex。
---如exp(2.3)的值为9.974182。
② 绝对值函数fabs(x):计算|x|。
对double型的变量取绝对值
---如fabs(-2.8)的值为2.8。
对int型的变量取绝对值
---如abs(-2)的值为2。
③ 以e为底的对数函数log(x):计算lnx。
---如log(123.45)的值为4.815836。
④ 幂函数pow(x,y):计算xy。
---如pow(1.3,2)的值为1.69。
⑤ 平方根函数sqrt(x):计算 。
---如sqrt(4.0)的值为2.0。
1、逻辑运算符
短路:C语言规定,只对决定整个表达式值所需的最少数目的子表达式进行运算。(重要)
例如:
a && b 如果a为 0 或者 false 则表达式为 0 或者 false 不再判断 b 的值
int a=0,b=1;
(a && b++);
printf("%d %d",a,b); 结果为: 0 1
a || b 如果a为 1 或者 true 则表达式为 1 或者 true 不再判断 b 的值
int a=1,b=1;
(a || b++);
printf("%d %d",a,b); 结果为: 1 1
2、if-else语句
一般形式:
单分支if语句
if(表达式)
语句1;
双分支if语句
if(表达式)
语句1;
else
语句2;
语句的嵌套
if (表达式1 )
if(表达式2 )
语句1;
else
语句2;
else
if(表达式3)
语句3;
else
语句4;
switch语句的一般形式如下:
switch(表达式)
{
case 常量表达式1:语句1;break;
case 常量表达式2:语句2;break;
…
case 常量表达式n:语句n;break;
default:语句n+1;break;
}
关于switch语句的几点说明。
(1)switch后的表达式可以是任何表达式,其值必须为整型,或字符型,或枚举型。
(2)每个case后面的常量表达式的值必须互不相同,否则就会出现互相矛盾的现象。
(3)各个case和default的出现次序不影响执行结果。
(4)可以让多个case共用一组执行语句。
(5)switch语句允许嵌套使用。
1、循环结构
for语句的一般形式为:
for(表达式1;表达式2;表达式3)
循环体语句;
for语句的执行过程如下: ① 首先计算表达式1。
② 判断表达式2,若其值为真(非0),则执行循环体语句,然后执行第③步;若值为假(0),结束循环,转到第
⑤步执行。
③ 计算表达式3。
④ 返回第②步继续执行。
⑤ 循环结束,继续执行for语句的下一条语句。
while语句的一般形式如下:
while(表达式)
循环体;
do
循环体
while(表达式);
2、改变循环结构的跳转语句
(1)break语句的作用是跳出循环。
(2)continue语句的作用是跳过循环体中continue后面的语句,继续下一次循环。continue语句只能用在循环语句中,常与if条件语句一起使用。
注意:只能用于switch语句和循环语句中。 使用for语句、while语句及do-while语句相互嵌套。
1、一维数组的定义
一维数组定义的一般形式为:
类型名 数组名[常量表达式];
例如:
int a[6];
注意:常量表达式不能为变量。如:
int b[n]; 是错误的。
一维数组初始化的一般形式为:
类型名 数组名[数组长度] = {初值表};
初值表中依次存放数组元素的初值。例如:
int a[6] = {6,1,4,5,7,2};
二维数组的一般形式为:
类型名 数组名[常量表达式1][常量表达式2];
int a[4][3];
初值表中依次存放数组元素的初值。例如:
int a[3][4] = {{ 1 , 2 , 3 , 4 }, { 5 , 6 , 7 , 8 }, {9 , 10 , 11 , 12 }};
字符数组也分一维字符数组与二维字符数组。
(1)一维字符数组的一般形式为:
char 数组名[常量表达式]
例如:char str[5];
(2)二维字符数组的一般形式为:
char 数组名[常量表达式1] [常量表达式2]
例如:char book[5][20];
字符数组初始化的一般形式为:
char 数组名[常量表达式] = {初值表};
例如:char str[5]= {'C', 'h', 'i', 'n', 'a'};
注意:
字符’\0’代表整数0,也就是ASCII码为0的字符。但’\0’不是字符’0’,字符’0’的ASCII码值为48。
2、字符串(重要)
字符串的输入
字符串常量是用双引号括起来的字符序列,它有一个结束标志’\0’。
1)利用函数scanf(),配合%s格式描述符。
调用格式为:
scanf("%s", 字符数组名) ;
输入一个字符串后,会自动在字符串后面加上’\0’。
2)使用函数gets()输入完整的字符串。
调用格式为:
gets(字符数组名);
输入一行字符时以Enter键作为结束符,且自动将回车符’\n’转换为’\0’,作为字符串的结束标志。
字符串的输出
1)利用标准输出函数printf(),配合%s格式描述符。
调用格式为:
printf("%s",字符数组名);
2)使用函数puts()输出完整的字符串。
调用格式为:
puts (字符数组名);
几个输入输出字符串的函数的比较:
3、字符串处理函数
(1)字符串复制函数strcpy()
一般调用格式为:
strcpy(字符串l,字符串2)
功能:将字符串2复制到字符串1。
注意:
1)参数字符串2可以是字符数组名,也可以是字符串常量。但参数字符串1必须是字符数组名。
2)字符串l必须有足够的空间,以便能容纳字符串2。
3)复制时直到遇到字符串2中的'\0'为止(包含'\0')。
4)若要将字符串2的前n个字符复制到字符串1中,可以使用strncpy( )函数,它的调用格式为:
strncpy(字符串1,字符串2,n)
(2)字符串连接函数strcat()
一般调用格式为:
strcat (字符串l,字符串2)
功能:连接两个字符串。
注意:
1)参数字符串2可以是字符数组名,也可以是字符串常量。但参数字符串1必须是字符数组名。
2)字符数组l必须有足够的空间,以便能容纳字符串2。
3)连接时用字符串2的首字符覆盖字符串1的结束标志'\0',系统在新字符串的末尾添加一个字符串的结束标志'\0'。
(3)字符串比较函数strcmp()
一般调用格式为:
strcmp (字符串l,字符串2)
功能:比较两个字符串的大小。
函数的返回值为一个整数。即:
当字符串1<字符串2时,返回值<0
当字符串1=字符串2时,返回值=0
当字符串1>字符串2时,返回值>0。
字符串比较的规则是:
从两个字符串的首字符开始,依次比较对应字符的ASCII码,直到出现不同的字符或'\0'为止。如果所有的字符都相同,返回0;否则,以第一个不相同字符的比较结果为准,返回这两个字符的差。
(4)求字符串长度函数strlen()
一般调用格式为:
strlen(字符串)
功能:计算字符串的长度,不包括结束标志'\0'。
(5)大写字母转小写字母函数strlwr()
一般调用格式为:
strlwr(字符串)
功能:将大写字母转换为小写字母。
(6)小写字母转大写字母函数strupr()
一般调用格式为:
strupr(字符串)
功能:将小写字母转换为大写字母。
1、函数的定义
(1)无参函数的定义
无参函数的定义形式如下:
类型名 函数名( ) /* 函数首部 */
{
函数体
}
或
类型名 函数名( void ) /* 函数首部 */
{
函数体
}
(2)有参函数的定义
有参函数的定义形式如下:
类型名 函数名(形式参数表列) /* 函数首部 */
{
函数体
}
说明:
1)有参函数比无参函数多了一项内容,即形式参数表列。在其中给出的参数称为形式参数(简称形参),格式为: 类型1 形参1,类型2 形参2,…,类型n 形参n 每个形参前面的类型必须分别写明。
2)函数体由一对大括号内的若干条语句组成,这些语句实现了函数的功能,并用return语句返回运算的结果。return语句逻辑上是函数的最后一条语句。它的一般形式是:
return 表达式;
表达式的类型(函数返回值)应与函数名的类型一致。一条return语句只能返回一个值。
3)编译系统不检查函数名与形参变量名是否相同,例如下面的函数定义是正确的。
int f(int f) { }
4)函数头部省略类型名时,默认函数的返回值的类型为int。
(3)空函数的定义
空函数的定义形式如下:
类型名 函数名( )
{ }
例如:
int fun( )
{ }
说明:
函数体是空的,调用此函数时,什么工作也不做。
在调用程序中写上fun( ),表明这里要调用一个fun函数,而这个函数还没有完成,等待以后完善。
2、函数调用的形式和过程
(1)函数调用的一般形式
函数名(实际参数列表);
实际参数列表中的参数称为实际参数,简称实参,可以是常数、变量和表达式。
(2)函数调用的方式
1)函数语句
函数名(实参列表);
2)函数表达式
函数作为表达式中的一部分出现在表达式中,例如:
a=abs(x);
函数嵌套调用图示:
函数调用的过程
① 被调函数的所有形参分配内存,再计算实参的值,并一一对应地赋予相应的形参。
② 为函数说明部分中定义的变量分配存储空间,再依次执行函数的可执行语句。当执行到“return(表达式);”语句时,计算返回值。
③ 释放在本函数中定义的变量所占用的存储空间(对于static类型的变量,其空间不会释放),返回主调函数继续执行。
3、参数传递
1)调用函数向被调用函数传递数据主要是通过函数的参数进行的,而被调用函数向调用函数传递数据一般是通过return语句实现的。
2)形参是函数定义时函数名后括号中的变量;实参是指调用函数时函数名后括号中的常量、变量或表达式。在调用函数时,将实参的值传递给形参,使形参在数值上和实参相同。
3)C语言提供了两种参数传递数据方式: 按值传递和按地址传递。
(1)按值传递
函数调用时,调用函数把实参的值传递给被调用函数的形参,形参值的变化不会影响实参的值。这是一种单向的数据传送方式。
当实参是常量、变量、表达式或数组元素,形参是变量名时,函数传递数据采用的是按值传递。
注意:
① 实参的个数应与形参一致,否则将会出现编译错误。 ② 定义函数时,系统并不给形参分配存储单元,只有函数被调用时系统才给形参分配存储单元。在调用结束后,形参所占用的存储单元被释放。 ③ 实参与形参即使同名,也会分配不同的分配存储单元。 ④ C语言规定,函数间的参数传递是“值传递”,即单向传递,实参可以把值传给形参,但形参的值不能传给实参,也就是说对形参的修改不会影响对应的实参。这是由于在内存中,实参与形参是不同的存储单元,函数执行结束后,形参的存储单元被释放。
(2)按地址传递
当函数的形参为数组或指针类型时,函数调用的参数传递称为按地址传递。 由于传递的是地址,使形参与实参共享同一存储单元,这样通过形参可以直接引用或处理该地址中的数据,达到改变实参值的目的。
4、 函数的返回值
1)函数的值只能通过return语句返回给调用函数。 return语句的一般形式为:
return 表达式;
return (表达式);
2)如果不需要从被调用函数返回函数值,可以省略return语句。省略时,返回的值不确定。
3)return语句中表达式值的类型应与函数定义中函数的类型保持一致。
4)对不需要返回函数值的函数,可以将其函数类型定义为“void”(即“空类型”)。
5、函数声明
函数声明的格式为:
类型名 函数名(类型1,类型2,…);
类型名 函数名(类型1 形参1,类型2 形参2,…);
当满足下面两个情况之一时,在主调函数中可以不对被调函数进行声明。
① 被调函数定义在主调函数之前时,对被调用函数的声明可以省去。
② 被调函数的返回值类型是整型或字符型时,对被调用函数的声明可以省去。
7、数组作函数的参数
(1)数组元素作函数实参
数组可以作为函数的参数使用,完成函数间的数据传送。数组用作函数参数有两种形式,一种是把数组元素作为实参使用;另一种是把数组名作为函数的形参和实参使用。 数组元素就是下标变量,它与普通变量并无区别。因此将数组元素作为函数实参使用与普通变量是完全相同的。在发生函数调用时,把作为实参的数组元素的值传送给形参,实现单向的值传送。
数组名作为函数参数调用函数的格式为:
函数名(数组名)
注意数组名后面不能有[ ]。
1)一维数组作函数参数
用一维数组作函数参数时,形参数组无需指定大小,但数组名后面的方括号不能省略。
用数组名作函数参数与用数组元素作实参有几点不同:
1)用数组元素作实参时,对数组元素的处理是按简单变量对待的。用数组名作函数参数时,则要求形参和相对应的实参都必须是相同类型的数组。 形参和实参二者类型不一致时,则会出错。
2)用数组名作函数参数时,并不是把实参数组的每一个元素的值都赋予形参数组的各个元素。 因为实际上形参数组并不存在,编译系统不为形参数组分配内存。 事实上,数组名就是数组的首地址。因此在数组名作函数参数时所进行的传送只是地址值的传送,也就是说把实参数组的首地址赋予形参数组名。形参数组名取得该首地址之后,也就指向了实参的数组。实际上是形参数组和实参数组为同一数组,共享相同的内存空间。 对数组名作为函数参数再强调以下几点: ① 形参数组和实参数组的名称不要求相同但类型必须一致,否则将会出错。 ② 形参数组和实参数组的长度可以不相同,因为在调用时,只传送形参数组的首地址而不检查其长度。当形参数组的长度与实参数组不一致时,虽然不会出现语法错误(编译能通过),但不提倡这样使用。 ③ 在函数形参表中,允许不给出形参数组的长度,或增加一个变量形参来表示数组元素的个数。
例如,例7.16的函数头部为:
void judge(int b[ ],int n)
④ 二维数组也可以作为函数的参数。在函数定义时形参数组第一维的长度可以省略,但第二维的长度不能省略。因此,以下写法都是合法的。
int max(int a[3][10])
或
int max(int a[ ][10])
8、局部变量和全局变量
变量的作用域,也就是说变量在不同的地方定义其作用域是不一样的。变量的作用域就是变量的有效范围。
C语言只允许在3个地方定义变量。
①函数内部的声明部分。 ②所有函数的外部。 ③复合语句中的声明部分。
变量定义的位置不同,作用域也不同。从变量的作用域来分,可以将其分为局部变量和全局变量。
局部变量
在一个函数内部定义的变量是局部变量,其作用域仅限于该函数内,它只在本函数范围内有效。C语言规定在复合语句内也可以定义变量,其作用域仅限于该复合语句内。
对局部变量注意如下几点:
① 不同的函数或复合语句中可使用同名的变量,但它们不是同一变量,它们在内存中占不同的单元。
② 主函数main()中定义的变量只在主函数中有效。主函数也不能使用其他函数中定义的变量。
③ 形参也是局部变量。在函数调用时为其分配内存,退出函数时将释放所占内存。
④ 在一个函数内部可在复合语句中定义变量,但变量只在本复合语句中有效。
⑤ 编译系统并不检查函数名与局部变量是否同名。
int fun(int n){int fun} /* 函数名与局部变量同名 */
全局变量
C语言规定在函数之外也可以定义变量,这样的变量称全局变量(也称外部变量)。在同一源程序文件中的函数可共用全局变量。 全局变量的有效范围为从定义全局变量的位置开始到该源文件结束。若在全局变量定义处之前的函数想引用该全局变量,则需要在该函数中用关键字extern作外部变量声明。
对全局变量注意如下几点:
① 全局变量的定义:同一作用域范围内只能定义一次,定义的位置在所有函数之外,系统根据全局变量的定义分配存储单元。对全局变量的初始化在定义时进行。
② 外部变量的声明:用于说明该变量是一个已在外部定义过的变量,现要在本函数中使用这个变量。可在不同函数中声明多次。
③ 如果全局变量与局部变量同名,则在局部变量的作用范围内,全局变量不起作用(程序对变量的引用遵守最小作用域原则)。
④ 由于全局变量可以被多个函数直接引用,因此全局变量为函数间进行数据传递的渠道之一。
9、变量生命周期与存储类型
变量从定义开始分配存储单元,到运行结束存储单元被回收,整个过程称为变量生命周期。
影响变量生命周期的是变量的存储类型,也就是说变量的存储类型不同其生命周期也是不同的。
静态存储与动态存储:
静态存储与动态存储
从变量的生命周期来分,可以将变量的存储类别分为静态存储方式和动态存储方式。
① 静态存储方式是指在程序运行期间分配固定的存储空间的方式。
② 动态存储方式是指在程序运行期间根据需要进行动态地分配存储空间的方式。
动态存储区用于存放函数的形参、自动变量;
静态存储区则用于存放全局变量和静态变量。
变量存放在何处决定了变量的生存期。用变量的存储类型说明来确定变量的存放位置。
变量的存储类型
带有存储类型的变量定义的一般形式为:
存储类型 数据类型 变量名;
在C语言中,变量的存储类型有以下4种。
① auto (自动类型)。
② register (寄存器类型)。
③ static (静态类型)。
④ extern (外部类型)。
1.auto变量
自动变量的定义形式是:
auto 类型名 变量表;
2.register变量
register变量也是自动变量,它与auto型变量的区别在于:register变量的值存放在寄存器中而不是在内存中。寄存器是CPU芯片内部的存储器,访问速度极快。常把一些对运行速度有较高要求、需要频繁引用的变量定义为register型。
3.static变量
static变量的定义形式是:
static 类型名 变量表;
例如:static int a,b;
static变量的存储单元被分配在数据区的静态存储区中。如果函数中的局部变量的值在函数调用结束后仍然保留,以便下一次调用该函数时使用,可以将局部变量定义为static类型。局部变量和全局变量都可以说明为static类型。
静态局部变量的生存期与全局变量相同,作用域与局部变量相同。
对静态局部变量和自动变量注意以下几点:
① 静态局部变量在编译时赋初值,即只赋一次初值;而对自动变量赋初值是在函数调用时进行,每调用一次函数重新赋一次初值。
② 自动变量如果没有赋初值,其初值是不确定的;若在定义静态局部变量时不赋初值,编译时系统自动赋初值0。并且赋初值只在函数第一次调用时起作用,以后调用时其值为前一次调用保留的值。
③ 静态变量和全局变量一样,属于变量的特殊用法,若没有静态保存的要求,不建议使用静态变量。
4.extern变量
extern变量即外部变量,是在程序中声明已在函数的外部定义过的全局变量。声明形式如下:
extern 类型名 变量表;
extern只能声明已经存在的变量,而不能定义变量。外部变量的作用域为从变量的定义处开始到本程序文件的结束,在此作用域内,外部变量可以为程序中各个函数所使用。
10、内部函数与外部函数
内部函数
static 类型名 函数名(形参表);
因为是使用static声明的,所以内部函数又称为静态函数。
这样定义的好处是:函数的作用域只局限于所在文件,在由多人分别编写不同的程序模块时,不用担心自己所用的函数名与别人使用的是否相同,即使函数名相同,也不会产生干扰。
外部函数
extern 类型名 函数名(形参表);
例如:
extern int fun(int a , int b);
外部函数在整个源程序中都有效。事实上C语言规定,如果在定义函数时省略extern,则默认为外部函数。
外部函数定义后,要在需要调用此函数的程序文件中用extern声明所调用函数的原型,表示该函数已在其他文件中被定义。
1、指针变量的定义和初始化
指针变量定义的形式为:
类型名 *指针变量名[=地址];
其中:
类型名 :是指针变量所指向对象的类型;
* : 是用于区分指针变量和其它类型变量的字符;
[=地址]:用于在定义时初始化指针变量,可省略。
指针变量与一般变量的定义方式基本相同,例如:
int *p; /* 定义指针变量p,p的类型是指针 */
1、结构的概念与定义
结构的概念及定义
概念
声明一个结构类型的一般形式为:
struct 结构名
{ 类型名 成员名1;
类型名 成员名2;
……
类型名 成员名n;
};
1)关键字struct与结构名一起构成结构类型名。
2)大括号中的内容是结构所包括的成员,也叫结构分量。成员的数据类型都可以是基本类型,也可以是结构类型。
3)结构类型定义只是说明了结构类型的构成情况,系统并不分配内存空间。
4)定义结构类型时,不允许将成员的数据类型定义成自身的结构类型,但是结构类型中可以含有指向自身类型的指针变量。
5) C语言把结构声明看做是一条语句,括号后面的分号是不可少的。
注意:
现在偷的懒以后都要补回来的!
希望大家认真学好C语言,不希望后悔!