1. 基础知识
2. 函数与编译预处理
3. 数组
4. 函数
5. 基本数据类型
1. 基础知识
1.1 关于#include<stdio.h>和void main() 的说明
关于程序的一些说明:
#include<stdio.h>是在程序编译之前要进行处理的的内容,因此也称为预处理命令。
先介绍下include,include是一个计算机专业术语,指C/C++中包含头文件命令,用于将指定头文件嵌入源文件中。而stdio.h则是C语言编译系统提供的一个文件名,stdio是“standard input & output”的缩写,即有关标准输入输出的信息。C语言本身不提供输入输出语句。一般开头有#符号的都是预处理命令。
只有在程序的开头写上:#include<stdio.h>,才能调用库函数。
大家或许也会看到这种用法:#include "stdio.h",这两种用法有什么差异呢?
#include<stdio.h>一般用包含系统文件,它是查找先从系统目录查找开始查找。
#include "stdio.h"一般用包含项目文件,它是查找先从项目目录查找开始查找。
关于void main() 的说明
void main()表示函数无返回值,就是说在程序的结尾处不需要加上return 0。而return是在函数体中,用来返回特定值的。
一个C程序中必须至少有一个函数,而且其中必须有一个并且仅有一个以main为名,这个函数称为主函数,主函数是整个程序的入口。
1.2 C语言的32个关键字
关键字通常也称为保留字,是由C语言规定的具有特定意义的标识符。
2. 函数与编译预处理
2.1 初识C语言(包含:程序和编译、注释、固定代码、格式化输出函数、字符串常量、转义字符、格式化字符串和转换说明、变量和声名、赋值、初始化、格式化输入函数scanf、输出函数puts等)
求长方形面积
/*
求长方形面积
*/
# include <stdio.h>
int main(void)
{
int width;
int height;
puts("求长方形的面积。") ;
printf("长:");
scanf("%d",&width) ;
printf("宽:");
scanf("%d",&height) ;
printf("面积是%d。\a\n",width*height) ;
return 0;
}
2.2 运算和数据类型(包括:运算符和操作数、使用printf函数打印%、多个转换说明、单目运算符、赋值运算符、表达式和赋值表达式、数据类型和对象、整型常量和浮点型常量、double类型的运算、数据类型和运算、类型转换、转换说明等)
获取整数的最后一位数字
// 获取整数的最后一位数字
# include <stdio.h>
int main(void)
{
int no;
printf("请输入一个整数:");
scanf("%d",&no);
printf("最后一位是%d。\n",no % 10) ;
return 0;
}
运算和数据类型总结
# include <stdio.h>
int main(void)
{
int a;
int b;
double r;
printf("整数a和b的值:");
scanf("%d%d",&a,&b) ; // 输入%d时scanf默认空格作为数值分隔符
printf("a + b= %d\n",a+b);
printf("a - b= %d\n",a-b);
printf("a * b= %d\n",a*b);
printf("a / b= %d\n",a/b);
printf("a %% b= %d\n",a%b);
printf("(a+b)/2 = %d\n",(a+b)/2);
printf("平均值=%f\n\n",(double)(a+b)/2);
printf("半径:");
scanf("%lf",&r);
printf("半径为%.3f的圆的面积是%.3f。\n",r,3.14*r*r);
return 0;
}
2.3 分支结构程序(包括:if语句、相等运算符、关系运算符、嵌套的if语句、计算三个数的最大值、条件运算符、复合语句、逻辑运算符、短路求值、switch语句和break语句、switch语句和i语句、选择语句)
if语句
// 奇数和偶数的判断
# include <stdio.h>
int main(void)
{
int no;
printf("请输入一个整数:");
scanf("%d",&no);
if (no%2)
puts("该整数是奇数。");
else
puts("该整数是偶数。");
return 0;
}
嵌套的if语句
// 奇数和偶数的判断
# include <stdio.h>
int main(void)
{
int no;
printf("请输入一个整数:");
scanf("%d",&no);
if (no>0)
if (no%2==0)
puts("该整数是偶数。");
else
puts("该整数是奇数。");
else
puts("您输入的不是正数。\a\n");
return 0;
}
复合语句(程序块)
//计算两个数中的较大值和较小值
#include <stdio.h>
int main(void)
{
int n1,n2,max,min;
puts("请输入两个整数。");
printf("整数1:") ; scanf("%d",&n1) ;
printf("整数2:") ; scanf("%d",&n2) ;
if (n1>n2) {
max = n1;
min = n2;
} else {
max = n2;
min = n1;
}
printf("较大的数是%d。\n",max);
printf("较小的数是%d。\n",min);
return 0;
}
计算三个数的最大值
# include <stdio.h>
int main(void)
{
int n1,n2,n3,max;
puts("请输入三个整数:");
printf("整数1:"); scanf("%d",&n1) ;
printf("整数2:"); scanf("%d",&n2) ;
printf("整数3:"); scanf("%d",&n3) ;
max = n1;
if (n2>max) max=n2;
if (n3>max) max=n3;
printf("最大值是%d。\n",max) ;
return 0;
}
条件运算符
//差值计算
# include <stdio.h>
int main(void)
{
int n1,n2;
puts("请输入两个整数:");
printf("整数1:"); scanf("%d",&n1) ;
printf("整数2:"); scanf("%d",&n2) ;
printf("他们的差是%d。\n",(n1>n2)?n1-n2:n2-n1) ;
return 0;
}
switch语句
# include <stdio.h>
int main(void)
{
int sw;
puts("整数:"); scanf("%d",&sw) ;
switch (sw) {
case 1 : puts("A"); puts("B"); break;
case 2 : puts("C"); //没有break语句时,程序会落到下一条语句上
case 5 : puts("D"); break;
case 6 :
case 7 : puts("E"); break;
default : puts("F"); break; //控制表达式的判断结果与任何一个case都不一致的时候执行
}
return 0;
}
2.4 程序的循环控制(do语句,复合语句(程序块)中的声明,读取一定范围内的值,求多个数的和及平均值,复合赋值运算符,后置递增匀运算符,while语句,字符常量和putchar函数,前置递增运算符,for语句,约数的枚举,多重循环,程序的组成元素和格式,连接相邻的字符串常量)
逆向显示整数值(do和while语句)
//逆向显示整数值
#include <stdio.h>
int main(void)
{
int no;
do {
printf("请输入一个正整数:");
scanf("%d",&no) ;
if (no <= 0)
puts("\a请不要输入非正整数。");
} while(no<=0);
printf("该整数逆向显示的结果是");
while (no>0) {
printf("%d",no%10);
// no= no/10;
no /= 10;
}
puts("。");
return 0;
}
约数的枚举,for语句
//约数的枚举,for语句
#include <stdio.h>
int main(void)
{
int i,n;
printf("整数的值:");
scanf("%d",&n) ;
for (i=1;i<=n;i++)
if(n%i==0)
printf("%d ",i);
putchar('\n');
return 0;
}
二重循环,九九乘法表
//二重循环,九九乘法表
#include <stdio.h>
int main(void)
{
int i,j;
for (i=1;i<=9;i++){
for (j=1;j<=9;j++)
printf("%3d",i*j);
putchar('\n');
}
return 0;
}
多重循环
//多重循环
#include <stdio.h>
int main(void)
{
int retry;
do {
int i,no;
do {
printf("请输入一个正整数:");
scanf("%d",&no) ;
if (no<=0)
puts("\a请不要输入非正整数。");
} while (no<=0);
for (i=1;i<=no;i++)
putchar('*');
putchar('\n');
printf("是否继续执行?【Yes...0/No...9】:");
scanf("%d",&retry) ;
} while (retry==0);
return 0;
}
3. 数组
(数组的声明,访问数组,数组的遍历,数组的初始化,数组的复制,对数组的元素进行倒序排列,对象式宏,数组元素的最大值和最小值,赋值表达式的判断,数组元素的个数,多维数组)
数组的声明、访问和遍历
//数组的遍历
#include <stdio.h>
int main(void)
{
int i;
double x[7];
// double x[7]={0.5,1.5,2.5,3.5,4.5,5.5,6.5}
for (i=0;i<7;i++)
x[i] = 0.5+i;
for (i=0;i<7;i++)
printf("x[%d]=%.1f\n",i,x[i]);
return 0;
}
对数组的元素进行倒序排列
//对数组的元素进行倒序排列
#include <stdio.h>
int main(void)
{
int i;
int x[7];
for (i=0;i<7;i++){
printf("x[%d]:",i);
scanf("%d",&x[i]);
}
for (i=0;i<3;i++){
int temp = x[i];
x[i] = x[6-i];
x[6-i] = temp;
}
puts("倒序排列。");
for (i=0;i<7;i++)
printf("x[%d]=%d\n",i,x[i]);
return 0;
}
对象式宏,数组元素的最大值和最小值
//对象式宏,数组元素的最大值和最小值
#include <stdio.h>
#define NUMBER 5
int main(void)
{
int i;
int tensu[NUMBER];
int max,min;
printf("请输入%d名学生的分数。\n",NUMBER);
for (i=0;i<NUMBER;i++){
printf("%2号:",i+1);
scanf("%d",&tensu[i]);
}
min = max = tensu[0] ;
for (i=1;i<NUMBER;i++){
if(tensu[i]>max) max = tensu[i];
if(tensu[i]<min) min = tensu[i];
}
printf("最高分:%d\n",max);
printf("最低分:%d\n",min);
return 0;
}
4. 函数
(main函数和库函数,函数定义(函数头,返回类型,函数名,形参声明,函数体),函数调用,三个数中的最大值,将函数的返回值作为参数传递给函数,调用其他函数,值传递,没有返回值的函数,不含形参的函数,作用域,文件作用域,头文件和文件包含指令,数组的传递,函数的传递和const类型的修饰符,线性查找(顺序查找),哨兵查找法,多维数组的传递,作用域和存储器)
函数定义和调用
//函数定义和调用
#include <stdio.h>
int max2(int a,int b)
{
if (a>b)
return a;
else
return b;
}
int main(void)
{
int n1,n2;
puts("请输入两个整数。");
printf("整数1:") ; scanf("%d",&n1) ;
printf("整数2:") ; scanf("%d",&n2) ;
printf("较大整数的值是 %d。\n",max2(n1,n2));
return 0;
}
将函数的返回值作为参数传递给函数
//将函数的返回值作为参数传递给函数
#include <stdio.h>
int sqr(int x)
{
return x*x;
}
int diff(int a,int b)
{
return (a>b?a-b:b-a);
}
int main(void)
{
int x,y;
puts("请输入两个整数。");
printf("整数x:") ; scanf("%d",&x) ;
printf("整数y:") ; scanf("%d",&y) ;
printf("x和y的平方差是 %d。\n",diff(sqr(x),sqr(y)));
return 0;
}
调用其他函数 ,求四个整数中的最大值
//调用其他函数 ,求四个整数中的最大值
#include <stdio.h>
int max2(int a,int b)
{
return (a>b)?a:b;
}
int max4(int a,int b,int c,int d)
{
return max2(max2(a,b), max2(c,d));
}
int main(void)
{
int n1,n2,n3,n4;
puts("请输入四个整数。");
printf("整数n1:") ; scanf("%d",&n1) ;
printf("整数n2:") ; scanf("%d",&n2) ;
printf("整数n3:") ; scanf("%d",&n3) ;
printf("整数n4:") ; scanf("%d",&n4) ;
printf("最大值是 %d。\n",max4(n1,n2,n3,n4));
return 0;
}
值传递
//值传递
#include <stdio.h>
double power(double x, int n)
{
int i;
double tmp = 1.0;
for (i = 1; i <= n; i++)
tmp *= x;
return tmp;
}
int main(void)
{
double a;
int b;
printf("求a的b次幂。\n");
printf("实数a:") ; scanf("%lf",&a) ;
printf("实数b:") ; scanf("%d",&b) ;
printf("%.2f的%d次幂是%.2f。\n",a,b,power(a,b));
return 0;
}
没有返回值的函数
//没有返回值的函数
#include <stdio.h>
void put_stars(int n)
{
while (n-- > 0)
putchar('*');
}
int main(void)
{
int i, len;
printf("生成一个直角在左下方的等腰直角三角形。\n");
printf("短边:") ; scanf("%d",&len) ;
for (i=1 ; i <= len; i++){
put_stars(i);
putchar('\n');
}
return 0;
}
不含形参的函数
//不含形参的函数
#include <stdio.h>
int scan_pint(void)
{
int tmp;
do {
printf("请输入一个正整数:");
scanf("%d",&tmp);
if (tmp<=0)
puts("\a请不要输入非正整数。");
} while ( tmp<=0 ) ;
return tmp;
}
int rev_int(int num)
{
int tmp = 0;
if (num > 0 ){
do {
tmp = tmp * 10 + num % 10;
num /= 10;
} while (num>0);
}
return tmp;
}
int main(void)
{
int nx = scan_pint();
printf("该整数倒转后的值是 %d。\n",rev_int(nx));
return 0;
}
数组的传递
// 数组的传递
#include <stdio.h>
#define NUMBER 5
int max_of(int v[], int n) // 返回含有n个元素的数组中的最大值
{
int i;
int max= v[0];
for (i=1;i<n;i++)
if (v[i] > max)
max = v[i];
return max;
}
int main(void)
{
int i;
int eng[NUMBER]; //数组1 英语分数
int mat[NUMBER]; //数组2 数学分数
int max_e, max_m; //两个数组的最大值
printf("请输入%d名学生的分数。\n",NUMBER) ;
for (i=0; i<NUMBER; i++){
printf("[%d]英语:",i+1); scanf("%d",&eng[i]);
printf(" 数学"); scanf("%d",&mat[i]);
}
max_e = max_of(eng,NUMBER) ; //调用函数 max_of() 及数组的传递
max_m = max_of(mat,NUMBER);
printf("英语最高分=%d\n",max_e);
printf("数学最高分=%d\n",max_m);
return 0;
}
函数的传递和const类型的修饰符
// 函数的传递和const类型的修饰符
/* C语言提供了禁止在函数内修改接收到的数组内容的方法。
只要在声明形参的时候加上被称为const的类型修饰符就可以了。
*/
#include <stdio.h>
// 将数组中的元素都赋值为 0
void set_zero(int v[],int n)
{
int i;
for (i=0; i<n; i++)
v[i] = 0;
}
/*打印数组*/
void print_array(const int v[],int n)
{
int i;
printf("{");
for (i=0; i<n; i++)
printf("%d ",v[i]);
printf("}");
}
int main (void)
{
int ary1[] = {1,2,3,4,5};
int ary2[] = {3,2,1};
printf("ary1= "); print_array(ary1,5); putchar('\n');
printf("ary2= "); print_array(ary2,3); putchar('\n');
set_zero(ary1,5);
set_zero(ary2,3);
printf("把0赋给了两个数组的所有元素。\n");
printf("ary1= "); print_array(ary1,5); putchar('\n');
printf("ary1= "); print_array(ary1,5); putchar('\n');
return 0;
}
线性查找(顺序查找)
// 线性查找(顺序查找)
#include <stdio.h>
#define NUMBER 5
#define FAILED -1
/*查找n个元素数组中与key一致的元素*/
int search(const int v[], int key, int n)
{
int i = 0;
while (1){
if (i == n)
return FAILED;
if (v[i] == key)
return i;
i++;
}
}
int main(void)
{
int i, ky, idx;
int vx[NUMBER];
for (i=0; i < NUMBER; i++){
printf("vx[%d]:",i);
scanf("%d",&vx[i]);
}
printf("要查找的值:");
scanf("%d",&ky) ;
idx = search(vx, ky, NUMBER);
if(idx == FAILED)
puts("\a查找失败。");
else
printf("%d是数组的第%d号元素。\n",ky,idx+1);
return 0;
}
多维数组的传递
//多维数组的传递
#include <stdio.h>
/*创建n行3列的二维数组,数组中的每个元素都是v*/
void fill(int m[][3], int n, int v)
{
int i, j;
for (i=0; i<n; i++)
for (j=0; j<3; j++)
m[i][j] = v;
}
/*显示二维数组的元素*/
void mat_print(const int m[][3], int n)
{
int i,j;
for (i=0; i< n; i++) {
for (j=0;j<3;j++)
printf("%4d",m[i][j]);
putchar('\n');
}
}
int main(void)
{
int no;
int x[2][3] = {0};
int y[4][3] = {0};
printf("赋给所有构成元素的值:");
scanf("%d",&no) ;
fill(x,2,no);
fill(y,4,no);
printf("--x--\n"); mat_print(x,2);
printf("--y--\n"); mat_print(y,2);
return 0;
}
自动存储期和静态存储期
/*静态存储期,在函数中使用static定义出来的对象,或者在函数外声明定义出来的对象
都被赋予了静态存储期*/
// 自动存储期和静态存储期
#include <stdio.h>
int fx = 0;
void func(void)
{
static int sx = 0; /*静态存储期+块作用域*/
int ax = 0; /*自动存储期+块作用域*/
printf("%3d%3d%3d\n",ax++, sx++, fx++);
}
int main(void)
{
int i;
puts(" ax sx fx");
puts("-----------");
for (i=0; i<10; i++)
func();
puts("------------");
return 0;
}
5. 基本数据类型和数
(算数类型和基本数据类型,基数,基数转换,整数和字符型,<limits.h>头文件,字符型,位和CHAR_BIT,sizeof运算符,size_t 型和 typedef 声明,整型的灵活应用,整数的内部表示,无符号整数的内部表示,有符号整数的内部表示,按位操作的逻辑运算,位移运算符,整型常量,整型常量的数据类型,整数的显示,数据溢出和异常,浮点型,浮点型常量,<math.h>头文件,循环的控制,运算符的优先级和结合性,数据类型转换)
<limits.h>头文件
//不含形参的函数
#include <stdio.h>
#include <limits.h>
int main(void)
{
puts("该环境下各字符型、整型数值的范围");
printf("char :%d~%d\n",CHAR_MIN,CHAR_MAX);
printf("signed char :%d~%d\n",SCHAR_MIN,SCHAR_MAX);
printf("unsigned char :%d~%d\n",0,UCHAR_MAX);
printf("short :%d~%d\n",SHRT_MIN,SHRT_MAX);
printf("int :%d~%d\n",INT_MIN,INT_MAX);
printf("long :%ld~%ld\n",LONG_MIN,LONG_MAX);
printf("unsigned short :%u~%u\n",0,USHRT_MAX); // 无符号10进制整数
printf("unsigned :%u~%u\n",0,UINT_MAX); // 无符号10进制整数
printf("unsigned long :%u~%u\n",0,ULONG_MAX); // 无符号10进制整数
return 0;
}
判断编译器默认的char是有符号类型还是无符号类型
// 判断编译器默认的char是有符号类型还是无符号类型
#include <stdio.h>
#include <limits.h>
int main(void)
{
value();
printf("这个编译器中的char型是");
if (CHAR_MIN)
puts("有符号的。") ;
else
puts("无符号的。") ;
return 0;
}
显示字符型和整型的长度
/*显示字符型和整型的长度*/
#include <stdio.h>
int main(void)
{
printf("sizeof(char) =%u\n",(unsigned)sizeof(char));
printf("sizeof(short) =%u\n",(unsigned)sizeof(short));
printf("sizeof(int) =%u\n",(unsigned)sizeof(int));
printf("sizeof(long) =%u\n",(unsigned)sizeof(long));
return 0;
}
显示数据类型和变量的长度
/*显示数据类型和变量的长度*/
#include <stdio.h>
int main(void)
{
int na,nb;
double dx, dy;
printf("sizeof(int) = %u\n", (unsigned)sizeof(int));
printf("sizeof(double) = %u\n", (unsigned)sizeof(double));
printf("sizeof(na) = %u\n", (unsigned)sizeof(na));
printf("sizeof(dx) = %u\n", (unsigned)sizeof(dx));
printf("sizeof(na+nb) = %u\n", (unsigned)sizeof(na+nb));
printf("sizeof(na+dy) = %u\n", (unsigned)sizeof(na+dy));
printf("sizeof(dx+dy) = %u\n", (unsigned)sizeof(dx+dy));
return 0;
}
求数组元素个数
/*求数组的元素个数*/
#include <stdio.h>
int main(void)
{
int vi[10] ;
double vd[25];
printf("数组vi的元素个数= %u\n", (unsigned)(sizeof(vi)/sizeof(vi[0]))) ;
printf("数组vd的元素个数= %u\n", (unsigned)(sizeof(vd)/sizeof(vd[0]))) ;
return 0;
}
基于 <math.h>头文件 求出两点间的距离
// <math.h>头文件
/*求出两点间的距离*/
#include <stdio.h>
#include <math.h>
double dist(double x1, double y1, double x2, double y2)
{
return sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
}
int main(void)
{
double x1,y1;
double x2,y2;
printf("求两点间的距离。\n");
printf("点1...X坐标"); scanf("%lf",&x1) ;
printf(" Y坐标"); scanf("%lf",&y1) ;
printf("点2...X坐标"); scanf("%lf",&x2) ;
printf(" Y坐标"); scanf("%lf",&y2) ;
return 0;
}
参考资料
明解C语言入门篇,柴田望洋