概述
目录
第1章 什么是C语言
第2章 算法
第3章 最简单的C程序设计
3.1 数据类型
3.1.1 常量
3.1.2 变量
3.1.3 数据类型
3.2 运算符和表达式
3.3 数据的输入输出
3.3.1数据的输入
3.3.2数据的输出
第4章 选择结构程序设计
4.1 if条件选择
4.2 switch多分枝选择
第5章 循环结构程序设计
5.1 for循环结构
5.2 while循环结构
第6章 数组
6.1 一维数组
6.2 二维数组
6.3 字符数组
第7章 函数的使用
7.1 为什么使用函数
7.2 函数的定义
7.3 函数的调用方式
7.4 数组作为函数参数
7.5 内部函数和外部函数
7.5.1 局部变量
7.5.2 全局变量
内部函数
外部函数
第8章 指针
8.1 什么是指针
8.2 指针变量
8.3 指针的使用方式
8.3.1指针变量的使用
8.3.2 指针变量作为函数参数
8.3.3 通过指针引用数组
8.3.4 通过指针引用字符串
8.3.5 指向函数的指针(函数指针变量)
8.3.6返回指针值的函数
8.3.7 指针数组
8.3.8 动态内存分配与指向它的指针变量
第9章 自定义数据类型
9.1 结构体类型
9.2 共用体类型
9.3 枚举类型
第10章 对文件的输入输出(主要讨论数据文件)
10.1 什么是文件
10.2 文件分类
10.3 文件的使用
第1章 什么是C语言
C语言的先祖是BCPL语言。它是由美国贝尔实验室的D.M.Ritchie在1972-1973年间设计出来的计算机编程语言。C语言还是目前使用最为广泛的计算机编程语言之一,由于它学习起来简单、使用方便、功能强大和容易上手等特点,普遍被广大程序设计者使用。
第2章 算法
算法需要有以下特性:(1)有穷性:有限的操作步骤;(2)确定性:每个步骤都是确定的,不能含糊;(3)有零个或多个输入:从外界获取必要输入信息;(4)有一个或多个输出:一个没输出的算法没有意义;(5)有效性:每个步骤都能有效执行;
第3章 最简单的C程序设计
3.1 数据类型
3.1.1 常量
常量包括以下几种:整形常量、实型常量、字符常量、字符串常量和符号常量。整形常量如100等;实型常量有两种形式,一种是十进制小数形式如10.21,另一种是指数形式如12.34e3(代表12.34×10*3);字符常量包括普通字符如‘a’,和转义字符‘n’。字符串常量是使用双撇号把若干个字符括起来,如“boy123”。符号常量是指使用#define指令,指定一个符号代表一个常量,如#define P1 3.12,这时P1代表3.12。
3.1.2 变量
变量代表一个有名字的、具有特定属性的一个存储单元,存储单元里的值是可以改变的,所以变量的值可以改变。在使用变量时必须先定义,后使用。在有些情况下我们不希望变量的值被改变,这时可以将变量定义为常变量。使用const可以将变量定为常变量,如const int P1=12,之后P1的值将不会被改变。
3.1.3 数据类型
在定义变量和函数时,需要指定相应的数据类型,数据类型包括:整型类型、浮点类型、枚举类型(enum)、空类型(void)和派生类型。
整型类型:注意整型中,区分有无符号的整型,无符号需要加上unsigned,如unsigned int a;
类型 | 字节 |
基本整形(int) | 2或4 |
短整型(short) | 2 |
长整型(long int) | 4 |
双长整型(long long int) | 8 |
字符型(char) | 1 |
布尔型(bool)值true 和 false | 1 |
浮点类型:
类型 | 字节 |
单精度浮点型(float) (有效6位) | 4 |
双精度浮点型(double) (有效8位) | 8 |
长双精度浮点型(long double) 有效(16位) | 16 |
复数浮点型 (不常用) |
派生类型:
指针类型(*) | 数组类型([ ]) | 结构体类型(struct) | 共用体类型(union) | 函数类型 |
数据以补码的形式存储再存储空间中。
补码求法:正·数的补码就是其二进制码如5的补码是0000 0000 0000 0101,负数的补码是其正数的二进制码取反,再加1,如-5,它的正数是5,5的二进制码是0000 0000 0000 0101,取反为1111 1111 1111 1010,再加1,得-5的补码是1111 1111 1111 1011。
3.2 运算符和表达式
经常混肴的运算符有:/(除法运算符)、%(求余运算符)、++和--(自增和自减运算符),例如++i(--i),它们在使用i之前,先使i的值加(减)1;i++(i--),它们在使用i之后,使i的值加(减)1。
强制类型转换符:使用强制类型转换符可以使一个表达式转换成所需的类型,一般形式如:(类型名)(表达式),例如(double)a,(float)(5%3)将5%3的值转换为float类型。
需要注意的运算符:= 赋值运算符、== 等于运算符、?:条件运算符、(sizeof)求字节数运算符、,->成员运算符、<<左移运算符、复合的赋值运算符,例如j×=y+8,等价于j=j×(y+8)等。
左移运算符(<<)
将一个运算对象的各二进制位全部左移若干位(左边的二进制位丢弃,右边补0)。
例:a = a << 2 将a的二进制位左移2位,右补0,
左移1位后a = a * 2;
若左移时舍弃的高位不包含1,则每左移一位,相当于该数乘以2。
右移运算符(>>)
将一个数的各二进制位全部右移若干位,正数左补0,负数左补1,右边丢弃。
操作数每右移一位,相当于该数除以2。
例如:a = a >> 2 将a的二进制位右移2位,
左补0 or 补1 得看被移数是正还是负。
注意: 当一个占多字节的整型数据,给一个占少字节的整型变量或字符变量赋值时,只能将它的低字节原封不动的送到被赋值变量,例如:a占4个字节,b占2个字节,当b=a时,只能把a的2位低字节赋给b。
3.3 数据的输入输出
3.3.1数据的输入
通过标准的输入函数完成,系统函数库中标准的输入函数有:scanf(格式输入)、gets(输入字符串)、getchar(输入字符)。
scanf函数的一般形式:scanf(格式控制,地址列表),如scanf(“a=%f,b=%f”,&a,&b);
gets函数的一般形式:gets(地址),如int a[10],gets(a),从键盘输入字符串,送到数组a中。
getchar函数的一般形式:a=getchar(),从键盘输入一个字符,送到字符变量a。
3.3.2数据的输出
标准输出函数有:printf(格式输出)、puts(输出字符串)、putchar(输出字符)
printf函数的一般格式:printf(格式控制,输出列表),如printf(“a=%d,ch[]=%s”,a,ch);a是变量名,ch是数组ch[]的数组名。
puts函数的一般格式:puts(地址),如int a[10],puts(a),这地址是指要输出数组的地址。
putchar函数的一般格式:putchar(字符),如char c=‘a’,putchar(c),输出字符变量c的值。
printf 的格式字符(scanf的格式基本一样)
d,i | o | x,X | u | c | s | f | e,E | g,G |
十进制输出整数 | 八进制 | 十六进制 | 无符号十进制输出整数 | 字符输出 | 字符串输出 | 小数形式输出单、双精度数 | 指数形式输出实数 | 选用%f或%e中输出宽度较短的一种格式 |
printf 和scanf 的格式附加字符
printf | printf | printf | scanf | scanf |
l | m(代表一个正整数) | n(代表一个正整数) | l | h |
用于长整型整数,可加于d,0,x,u前面 | 数据最小宽度 | 对实数时,表示输出n个小数,字符串时,表示截取字符个数 | 用于输入长整型数据,如%ld,%lx,%lo | 用于输入短整型数据,如%hd,%ho,%hx |
第4章 选择结构程序设计
4.1 if条件选择
if语句的一般形式是:if(表达式)语句1,如if(a+b>10) printf("yes");表达的意思是,如果a+b的值大于10,则执行printf函数输出yes。通过判断if表达式的真假,来判断是否执行语句1。
if语句一般与else语句一起使用,以实现更多功能,例如
if(表达式) 语句1;
else 语句;
例如 if(a>b) a=b;
else b=a;
这里表示如果a>b,则a=b,否则b=a;
if和else还可以嵌套使用,例如
if(number>50) a=1;
else if(number>40) a=2;
else if(number>30) a=3;
else if(number>20) a=4;
else a=5;
注意 : 关系运算符的优先级低于算术运算符
关系运算符的优先级高于赋值运算符
! | && | || |
逻辑非 | 逻辑与 | 逻辑或 |
!(逻辑非),如果a为真,则!a为假,如果a为假,则!a为真。
优先级:!(非)>&&(与)>||(或)
优先级:!(非)>算术运算符>关系运算符>&&(与)>||(或)>赋值运算符
4.2 switch多分枝选择
switch语句是多分枝选择语句,switch的一般形式如下:
switch(表达式)
{
case 常量1 :语句1
case 常量2 :语句2
case 常量n :语句n
default :语句n+1
}
注意:switch后面括号内的“表达式”,其值的类型应为整数类型(字符型)
在执行switch语句时,根据switch表达式的值找到相应的入口标号,然后从相应的case中执行语句,在执行完入口标号的case语句后,程序会继续往下执行下面的case标号的语句,直到switch程序结束,所以一般情况下需要在case子句后面,应用break语句,使程序跳出switch结构。如果没有与switch表达式相匹配的case常量,流程会转去执行default标号后面的语句。
switch语句使用例子:
#include<stdio.h>
int mian()
{
char ch;
int a=0;
ch=getchar();
switch(ch)
{
case 'a' : printf("a");break;
case 'b' : printf("b");break;
case 'c' : printf("c");break;
default : printf("d");
}
return 0;
}
第5章 循环结构程序设计
5.1 for循环结构
for循环的一般形式: for(表达式1;表达式2;表达式3) 语句,例如
for(i=1;i<10;i++)
sum=sum+i;
其中表达式1可以省略,如for(;i<10;i++),但分号不能省。但是当表达式2省略时,表示无限循环。
for循环实现冒泡算法:
void xunhuan(int r[],int n)
{
int i,j,temp=0;
for(i=1;i<n;i++)
for(j=1;j<=n-i;j++)
if(r[j]>r[j+1])
{
temp=r[j];
r[j]=r[j+1];
r[j+1]=temp;
}
}
5.2 while循环结构
while实现循环有两种方式,一种是使用do.....while结构,另一种是使用while结构。
do.....while语句的一般形式为:
do
{语句}
while(表达式);
例如:
#include<stdio.h>
int main()
{
int i=1,sum=0;
do
{
sum=sum+i;
i++;
}while(i<=100);
printf("sum=%dn",sum);
return 0;
}
while语句的一般形式为:
while(表达式)语句;
例如,使用while和for语句实现的冒泡算法
#include<stdio.h>
int main()
{
int i=0,j=0,flag=1,temp=0;
int a[5]={10,2,57,7,98};
while((i<4)&&flag)
{
flag=0
for(j=0;j<4-i;j++)
if(a[j]>a[j+1])
{
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
flag=1;
}
i++;
}
for{i=0;i<4;i++}
printf("%d ",a[i]);
return 0;
}
注意:break语句和continue语句的区别是,在执行for或while循环语句时,通过break语句可以提前终止循环,跳出循环体。而continue语句只是提前结束本次循环,而不是终止整个循环,然后继续执行下一次循环。
第6章 数组
6.1 一维数组
数组是一组有序数据的集合,数组中的每个元素都是同一种类型。通过数组可以存储一组数据或多组数据。定义一维数组的一般形式为:类型符 数组名 [常量表达式];例如int a[10],定义了一个名为a的数组,它包含10个元素,它第一个元素是a[0]。当数组常量表达式为空时,数组的长度由初始化列表中元素的个数决定,例如int a[ ]={1,2},这时a数组的长度为2。
数组的常量表达式可以是常量和符号常量(#define P1 3.12,其中P1代表符号常量),但不能是变量。如果数组是在被调用的函数里面(不包括主函数)定义的数组,其长度可以是变量或非常量表达式。例如:
void fun(int n)
{
int a[2*n];//合法,n的值从实参传来
.
.
.
}
这种情况称为“可变长数组”,允许每次调用fun函数时,n有不同的值,但在执行fun函数时,n的值是不变的。如果指定fun函数中的a数组为静态(static)存储方式,则不能用“可变长数组”,例如:static int a[2*n];这是不合法的,即可变长数组不能定义为静态存储方式。
一维数组的数组名代表数组的起始地址。一维数组的初始化可以用“初始化列表”或给数组元素逐个赋值,其中“初始化列表”的方式,如:int a[10]={0,1,2,3,4};,把初始化列表的数值,逐个赋给a数组的前5个元素,系统会自动给后面5个元素赋初值为0。给数组元素赋值,如a[0]=1;
数组中的元素引用,可以通过数组名加下标的方式,一般形式为:数组名[下标],下标可以是整型常量、整型的符号常量、整型表达式或者是整型变量,如int i=1; b=a[i]。
数组实现的冒泡算法
#include<stdio.h>
int main()
{
int a[10];
int i,j,t;
printf("input 10 numbers :n");
for(i=0;i<10;i++)
scanf("%d",&a[i]);
printf("n");
for(i=0;i<9:i++)
for(j=0;j<9-i;j++)
if(a[j]>a[j+1])
{t=a[j];a[j]=a[j+1];a[j+1]=t;}
printf("the sorted numbers :n");
for(j=0;j<10;j++)
{
printf("%d",a[j]);
}
printf("n");
return 0;
}
6.2 二维数组
二维数组定义的一般形式:类型符 数组名[常量表达式1][常量表达式2];
例如:float a[3][4],定义一个3×4(3行4列)的数组a,常量表达式1表示数组的行数,常量表达式2表示数组的列数。
二维数组可以看成一个特殊的一维数组,它的元素又是一个一维数组,例如,把a看为一维数组,它有3个元素:a[0],a[1],a[2],每个元素又是一个包含4个元素的一维数组,如a[0]包含:a[0][0],a[0][1],a[0][2],a[0][3]。a[0]、a[1]、a[2]可以看作三个一维数组名。二维数组元素的存放是按行存放的,先放第一行,再放第二行。在内存中二维数组的各元素是连续存放的,不是二维的,是线性的。
二维数组初始化和引用数组元素
二维数组的初始化形式:
1、给二维数组部分元素赋初值:如
int a[3][4]={{1,2},[5],{9}}; 表示给第一行的1、2列分别赋值1和2,给第二、三行的第1列,分别赋值5和9,其余元素值自动为0;
2、把所有数据写在一个花括号中,按数组元素在内存中的排列顺序对各元素赋初值。
如int a[2][2]={1,2,3,4};
3、分行给二维数组赋初值。
例如:int a[2][2]={{1,2},{3,4}};
4、如果给数组全部元素赋初值(即提供全部初始化数据),定义二维数组时,第1维(行)的长度可以不指定,但第2维(列)的长度不能省略。
如:a[ ][2]={1,2,3,4}; 定义一个2×2的数组a
二维数组元素的引用:二维数组元素表示形式,数组名[下标1][下标2],下标应是整型表达式,如 a[0][1]=1;b=a[0][1]; 把数组a的第0行,第1列的元素赋值给b,b=1。
6.3 字符数组
字符数组的一般形式与一维数组和二维数组的一样的,只是数据类型不同,例如,char a[2]={'I','k'};char a[ ]={I','k'};,这两个数组的长度都是一样的。char a[2][2]={{'b','a'},{'c','d'}}; char a[][2]={{'b','a'},{'d'}};,当字符数组初值的个数小于数组长度时,只将这些字符赋给数组中前面的元素,其余的元素自动定为空字符(即‘ ’)。
在C系统中,使用字符数组存储字符串常量时会自动加一个'