az计算机二级C语言

p1--C程序设计的初步知识(一)

C程序的运行过程
az计算机二级C语言_第1张图片
image.png
程序设计的步骤

(1)确定数据结构
(2)确定算法★

有穷性(步骤有限)
确定性(含义确切)
可行性(能够实现)
有零个或多个输入(数据输入)
有一个或多个输出(数据输出)

(3)编码
(4)在计算机上调试程序
(5)整理并写出文档资料

结构化程序

三大结构★:
顺序结构:程序从上到下顺序执行
选择结构(分支结构):程序可以沿不同路径执行
循环结构:指定程序重复执行


p2--C程序设计的初步知识(二)

基本结构:

#include      //  standard input output 标准输入输出函数(标准库函数)、尖括号也可以写成双引号"stdio.h"
main()      //有且只有一个
{

}

示例1:

#include 
main()
{
double a,b, area;  
a=1.2;
b=3.6;
area=a*b;
printf("a=%f, b=%f, area=%f\n",a,b, area)
}

标识(zhi)符★

1、什么是标识符?
符合一定规则的符号集合。
2、标识符命名规则
(1)由字母(a...z,A...Z)、数字(0...9),下划线(_)组成
(2)必须由字母、下划线开头如:A3,_balll
(3)不能是C语言关键字(关键字是标识符一种,自己命名不能再使用关键字命名)
(4)区分大小写如:A3,a3是两个完全不同的标识符
(5)长度一定,与系统有关(考试中不涉及)

3、标识符的分类
①关键字
②预定义标识符
系统中具有某些功能含义的名字
③用户标识符

正确标识符:sum i a2 a_2 _a2 _a_2 printf(关键字) PRINTF
错误的标识符:2a a? c.g a-2

常量

1.什么是常量?
在程序中其值不能被改变的量。


az计算机二级C语言_第2张图片
2.png

3、如何定义符号常量
关键字define
用法#define 标识符 常量值
示例:

#include 
#define PI 3.1415926   //常用大写来表示符号常量
main()
{
    double r, s;
    r=5.0;
    s=PI*r*r;
    printf("s=%f\n", s);
}

p3--C程序设计的初步知识(三)

变量

1.什么是变量
在程序运行中,值可以改变的量。
2.变量的命名规则
3.变量的特点
(1)变量在内存中要占用连续的若干个字节;(2)所占用的字节数由变量的数据类型确定;
(3)变量使用必须要先定义★。
记忆理解:一个有大小的盒子,大小取决于数据类型

整型数据

整型常量的表示形式
十进制整数:0、-111、15、21
八进制整数:00、-0111、015、021、017
十六进制整数:0×0、-0x111、0×21、0x1f
注意:只有十进制整数有负数(指的是存储的时候)、八进制最大到7、
十六进制最大F

整型数据存储形式

计算机的存储单位
二进制的位(bit)
8bit=1字节。1024字节=1KB,1024KB=1M,
1024M=1G


az计算机二级C语言_第3张图片
image.png

整型数据存储形式

负数的存储
(1)转成反码(原码计算会造成数据缺失):0变1,1变0
(2)在反码上加1
注意转换时最高位符号位不转换,如果是无符号的,最高位当做数字

整数-5存储格式5的二进制101
2个字节内存存储形式

  • 整型数据类型有一定范围,超出范围从新开始。


    az计算机二级C语言_第4张图片
    整型数据类型.png
整型变量定义形式:

整型数据类型 变量名1[=值],变量名2[=值]...;

short int x;/*定义了一个短整型变量x*/
intx=1,y=10;/*定义了两个整型变量x,y;其中x的值1,y的值10*/
longx=-30,y;/*定义了两个整型变量x,y;其中x的值-30,y暂时无值*/
unsigned x;/*定义了一个无符号整型变量x*/

定义时给变量赋值称为初始化。


实型数据

实型常量(浮点数、实数)的表示形式

一般形式的实数:12.345、-1.23456、7.0
指数形式的实数:-1.2345E3、0.12345e-4
注意:
★E或e之前必须有数字、之后必须是整数、之前之后必须有数,
数字和E(或e)之间没空格

  • 0是整型常量,0.0是双精度常量
实型数据类型

float(单精度 4个字节) -1038~1038
double(双精度 8个字节) -10308~10308
★注意:如不特别定义任意用到的一个实数在C中都是double类型的,超出范围处理成0值,实数存在误差。

实型变量定义形式

实型数据类型变量名1[=值],变量名2[=值]…;

float  x;/*定义了一个单精度型变量x*/
double  x=1.0,y=10.5;/*定义了两个双精度型变量x,y;其中x的值1.0,y的值10.5*/

p4第二章-C程序设计的初步知识(四)

算数表达式

基本运算符号

运算符 名称 优先级 结合性
+、- 取正、取负 2 自右向左
*、/、% 乘、除、取余数 3 自左向右
+、- 加、减 4 自左向右

注意:不同类型转换,例如:1/2.0=0.5 (★通过加.0来转换为实型)
相同类型结果类型不变例如:1/2=0
若是单精度后边加0变成双精度
★%左右运算必须都是整数

单目运算符右边存在数值
双目运算符左右都存在数值

  • 运算规则(优先级):先函数,再括号,后乘除,终加减。
    例:(1+sqrt(c)b)-28

强制转换类型:(数据类型)(表达式)
例:(double)(10%3)结果会是双精度1
5/2的结果为2,结果也为整型

int (4.9)=4 不进行四舍五入

赋值表达式
主要运算符号=
形式:变量名=表达式 例:a=10;
理解记忆:变量好比一个盒子,把等号右边的东西放到左边的盒子里。

注意:
1.等号优先级最低,先计算右边,在赋值给左边;
2.n=n+1;有意义,在原有变量n的基础上,增加1;
3.★左边不能是表达式a+b=c错误
4.★右边可以是赋值表达式a=b=7+1;但是a=7+1=b是错误的

复合赋值表达式

主要运算符号+=、-=、=、/=、%=
例:n+=1;(n=n+1)
n
=m+1(n=n*(m+1))

例:已有变量a ,其值为9,计算表达式a+=a-=a+a的值

  1. 先计算a+a=18
    2.计算 a-=18(此时a仍然是9)
    3.计算 a+=-9(此时a是-9)

赋值运算的类型转换
赋值两边类型不一致,将等号右侧的值转换成左侧数据类型,仅限数值,成为“赋值兼容"。

整数运算符转换原则:
1.运算符号两边一个短整型,一个长整型,都转化成长整型
2.运算符号两边一个无符号,一个有符号,都转化成无符号

整数赋值转换原则:
1.左短右长,截取右边,丢高保低
2.左无右有,复制右边,负数变整数
3.左有右无,复制右边,高位为1,变负数

★自增、自减、逗号运算符号

符号形式++、--
含义:使运算对象+1或者-1
例:
int i=1;i++;(相当于i=i+1)
int i=1;i--;(相当于i=i-1)
注意:
1.自增、自减符号可以放在变量前面形成前缀,也可以放在后面形成后缀;
2.如果是前缀,先做自我运算,后运行语句;
3.如果是后缀,先运行语句,后做自我运算;
4.不要在一个表达式中多次对同一个变量做++、--运算。
附:n++效果可以等同与将++号去掉,在这条语句中后面添加n=n+1
++n效果可以等同于将++号去掉,在这条语句中前面添加n=n+1

逗号表达式的形式:表达式1,表达式2,…,表达式n
逗号表达式运算法则从左到右,一个表达式一个表达式计算,全部运算完毕后,最后一个表达式的结果是整个表达式的值。
例:(i=3,i++,++i,i+5)表达式的值为10,i的值是5


P5第三章-顺序结构(一)

3.1赋值语句

赋值语句也称作表达式语句,主要在赋值表达式后加入分号; 就构成表达式语句。

int i=10;//赋初值语句
i=12;//赋值语句

3.2数据输出

C语言没有输入输出语句,应用标准函数库中的函数完成输出。
例:

#include/*命令行调用标准库函数*/
main()//主函数程序的入口
{
/*屏幕输出一句话*/
printf("Hello World!");
}

printf 函数的调用形式:
printf(格式控制,输出项1,输出项2,…);
实际调用中加上分号就构成输出语句。

例:printf("a=%d b=%d",a,b);
格式控制的作用:
1.按照指定的输出格式输出格式由%符号和紧跟其后的格式描述符(此例为d)组成。如整型%d,单精度%f,双精度%lf
2.原样输出文字和字符。
注意:输出%需要写%%。
例子:

#include     //包含输入输出库函数
main()                      //主函数程序入口
{
int i=2518;            //定义一个整型变量i,值是2518
double a=3.1415;       //定义一个双精度变量a,值是3.1415
printf("i=%d,a=%f,a*10=%e\n",i,a,a*10);  //输出i和a以及a*10的值。%e指定输出为指数形式
}

常用输出格式:以%号开头,一个格或字符结束,中间可以插入宽度说明,左对齐减号,前导数字0
%c 输出一个字符
%d 或%i输出整型数据,短整型(short)%hd,长整型(long)%ld
%o 输出八进制形式,不带前导0,%#o带前导0
%x或%X 输出十六进制形式,不带前导0x,%#x或者%#0x带前导0x
%u 以无符号(unsigned)输出整型数
%f 输出单精度,可用%lf输出双精度
%e或%E 以指数形式输出浮点数[-1]m.dddddde土xxx
%g或%G 系统决定使用%f还是%e输出保证输出宽度最小
%s 输出一个字符串,遇到'\0'终止,不受最大宽度约束
%p 输出变量内存地址
%% 输出一个%

长度修饰符
%与格式字符之间可以加入数字,L,h等一些符号和数字控制精确的显示格式
输出数据所占宽度的格式说明
(1)默认输出实际宽度,且右对齐
(2)%nd整数输出,小于n左边补空格,右对齐
%8d指定8位显示,右对齐,若为四位数,前面会有4位空格补齐。

#include 
main()
{
    int a=1234;
    printf("a=%8d",a);
 } 

image.png

(3)%n1.n2f 浮点数输出, n1代表宽度包括小数点n2小数位数,如果小数位数大于n2,截取并四舍五入,如果小于右边补0.如果整个数值长度小于n1,右对齐,左边补空格。如果大于n1,自动突破宽度限制。G或者g不加宽度,6位自动截取,加宽度左边不足补0,超过突破
(4)可以仅指定小数位数%.n2f
(5)n2可以为零,如%n1.0f代表不输出小数
(6)%0n1d或者%.n2d 代表左边不足补0
(7)%0n1.n2f 左边不足补0★
(8)%n1s 不足右边补空格,右对齐
(9)%.n2s 超过n2长度字符串,取前n2字符★。
(10)-% 代表默认左对齐
记忆方法:
整数宽,小数截,不足看%后,是0补0,没有补空,默认右边,加负左边


printf使用注意事项:
(1)输出自由控制
(2)如有格式控制即%,有几项后边输出几项,类型必须匹配,%多于输出项,会出乱码,%少于输出项,多余的不输出。
例:

printf("%d%d%f”,m,n,l,k); //k将不会输出

(3)转义字符 \n回车 \r换行但无回车 \t制表符 \a 响铃等控制符
(4)输出%输出两个%%
(5)printf函数有返回值
(6)尽量不要在printf中做变量运算,printf(“%d%d”,k,++k);
(7)如果出现*号,顺次写入
例:

printf("%*d”,m,n);     \\ m取代*号代表宽度,n是输出值

P6第三章-顺序结构(二)

3.3数据输入

scanf函数调用形式:
scanf(格式控制,输入项1,输入项2.…);
例如:
scanf("%d%f%lf”,&k,&a,&y);
注意:
1.务必使用&运算符,除非变量本身是地址变量。
2.输入double类型时候一定使用%lf。

输入格式字符及其功能:

%c 输入一个字符
%d 输入有符号的整数
%i 输入有先导的八进制和十六进制
%o 输入八进制,有无先导均可
%x 输入十六进制,有无先导均可
%u 无符号整型
%f 输入单精度小数,有无指数均可
%lf 输入双精度小数,有无指数均可
%s 输入字符串,以\0'作为结束

scanf函数的使用说明:

(1)务必格式字符数量和输入数量对应
(2)可以%加整数指定宽度,但不可以指定小数宽度,字符会按照指定宽度进行截取,非四舍五入
(3)输入流按照格式依次读取,多余的下次输入继续读入(单次程序运行)
(4)scanf函数有返回值
(5)数值型数据,遇到空格、回车符、制表符代表本次输入结束
(6)遇到%*格式符,跳过一个格式符对应的数据
例:
(1)scanf(%d%f%le”,&k,&a,&y);
输入1012.31234567.89  (回车)
正确读入也可以:
10 
12.3 
1234567.89 
(2)scanf("%3d%5f%5le",&k,&a,&y);
输入123456.789.123
k值123 a值456.7 y值89.12

例(遇到%*格式符,跳过一个格式符对应的数据):
(3)scanf("%g%*d%d%d",&x,&y,8&z);
输入12 34 56 78、
x值12 y值56 z值78

例(如果在scanf格式控制符处加入其它符号,输入时必须按照它的原样格式输入):
scanf("please input x,y,z:%d%d%d”,&x,&y,&z;
输入时候:
please input x,y,z:121314

3.4复合语句和空语句:

一对大括号之间多条语句组成的一个语句组称为复合语句
{语句1;语句2;语句3;}
只有一个分号";"的语句叫做空语句
例:

main()
{
;//这是一条空语句
}
两个变量交换数值(重点算法)

原理:
两个杯子里的水如何交换?
第一步:x的水倒进t,使x为空
第二步:y的水倒进x, x变为y
第三步:t的水倒进y,y变为x


az计算机二级C语言_第5张图片
image.png

例:

#include
main()
{
intx,y,t;//定义三个整型变量
printf("Enter x&y \n");//屏整上输出一句话Enter x&y 后换行
scanf(“%d%d”,&x,&y);//从键盘上接受x,y的值
printf("x=%d y=%d\n",x,y);//先输出x,y的原始值
t=x;x=y;y=t;  //关键算法
printf("x=%d y=%d\n",x,y);//输出结果
}
小数点后两位(102)四舍五入

原理:
(1)原数乘以100
(2)加上0.5
(3)取整
(4)除以100输出
例:

#include 
main()
{
double x;//定义双精度变量x
printf("Enter x\n");//屏幕上输出一句话Enterx后换行
scanf(“%lf”,&x);//从键盘上接受x的值
printf("(1)x=9%lf\n',x);//先输出x的原始值
x=x*100;  //关键算法(1)先乘以100
x=x+0.5; //加上0.5
x=(int)x;//取整,去小数部分
x=x/100;  //恢复四舍五入后的数值
printf("(2)x=%lf y=%d\n",x);//输出结果
}

P8第四章-选择结构(一)

4.1关系运算和逻辑运算

1.什么是逻辑值?
在C语言中没有逻辑类型,非0表示“真”,0值为“假”
2.什么是关系运算?
关系运算就是“比较运算"
一般指两个整数或者两个字符的比较
关系运算符号包括:
<(小于)<=(小于等于)
>(大于)>=(大于等于)
==(等于)!=(不等于)
运算结果只有0(假)或者1(真)

例:计算下列表达式的值
7>5的值是1
7<5的值是0
7>5>3的值是0 ★7>5返回1,1是小于3的,故为假
7<5<1的值是1 ★
a=7>5a的值是1 赋值级别最低
计算规则:先算>号,后赋值

注意:
关系运算尽量避免两个浮点数做相等比较。
两个浮点数是否相等的比较方法:
两个浮点数做减法,和一个精度值作比较
例:
double a=1.53,b=1.53;
b-a<10e-6

3.逻辑运算符
&&逻辑“与”运算符两边都为真时候,结果为真(并且)
|| 逻辑“或”运算符两边有一边为真,结果为真(或者)
!逻辑“非”(运算级别最高)非真即假,非假即真 例:判断一个数是不是在0-10之间
逻辑表达式:x>0&&x<10;
特别注意:短路现象
a=0;b=0;a++&&b++;a变成1,b还是0
a=1;b=0;a++ || b++;a变成2,b还是0

4.2 if语句和用if语句构成的选择结构

语句形式:
形式1 if(表达式)语句1
形式2 if(表达式)语句1 else 语句2

if语句的嵌套:语句1和语句2可以是多层if语句,原则else与它最近的if配对。
形式如:
if(表达式)         if(表达式)语句1
  形式1或形式2       else if(表达式)语句2
else             else if(表达式)语句3
  形武1或形式2       .......
              else 语句n


例:

#include
main()
{
intx,y;
printf("Enterx&y\n");
scanf("%d%d",&x&y);
if(x>=y)//判断x和y的大小
{printf("x=%d",×);}  //if没有大括号{},if只对下面的第一条语句负责。
else
{printf("y=%d",y);}
}

例:根据学生成绩划分级别90分以上A,60分以下E其余的10分一个等级

#include
main()
int g;
printf("Enter g:");
scanf("%d",&g);
printf("g=%d",g);
if(g>=90)printf("A\n");//判断级别
else if(g>=80)printf("B\n");
else if(g>=70)printf("C\n");
else if(g>=60)printf("D\n");
else printf("E\n");
★条件运算符?

条件表达式的形式:表达式1?表达式2:表达式3
含义:当表达式1非零时,运算表达式2的值,否则运行表达式3的值。
例:

y=X>10?100:200
printf("abs(x)=%d",x<0?(-1)*x:x);//求绝对值(abs()表示求绝对值,在这里原样输出)

switch语句形式:

switch(表达式)
{
case  常量表达式1:语句1[break;]  //break 看情况加,非必须
case   常量表达式2:语句2[break;]
case   常量表达式n:语句n[break;]
default: 语句n+1 [break;]  //前面都不符合后,执行的默认语句,非必须。
}

表达式可以是整型表达式,也可以是字符型表达式


az计算机二级C语言_第6张图片
image.png

例:

#include
main()
{
int g;
printf("Enter g:"); scanf("%d",&g);
printf("g=%d",g);
switch(g/10)/没有break的情况
{
case 1.0:
case 9:printf("A\n"); break;
case 8:printf("B\n");break;
case 7:printf("C\n");break;
case 6:printf("D\n");break;
defualt:printf("E\n");
}
4.5 goto语句(此知识点非大纲要求)

C语言可以在语句前加标号
goto语句形式:goto语句标号;
例:

stop:printf("stop");
goto stop;

P10第五章-循环结构(一)

【大纲分析】
1.for 循环结构。
2.while 和do-while循环结构。
3.continue 语句和break语句。
4.循环的嵌套。

5.1 while循环语句

while循环语句的一般形式:
while(表达式)循环体
例:输出10个*

k=0;
while(k<10)//循环判断条件可以用“当”理解,去掉大括号,只对下面第一句负责
{
printf(“*");k++;
}
5.2 do-while循环语句

do-while循环语句的一般形式:
do 循环体 while(表达式);
例:输出10个*

k=0;
do 
{
printf("*”); k++;
}while(k<10);
while与do-while的比较

1.形式比较:
while(表达式)循环体
do循环体while(表达式)
2.最少循环次数
例:
int i=0;        int i=o;
do//至少循环一次   while(i>0)//不满足条件不循环
{         {
printf(“显示”);    printf(“显示”);
}while(i>0);    }

程序举例
考试中对公式求解遇到的情况
1.基本累加,累乘
例:计算 公式1+2+3+4...+n,n取到100的值

#include 
main()
{
   int n=0,sum=0;//定义n个数,sum最后求和项值
   while(n<=100)
   {
       sum=sum+n;//可以简写成sum+=n;
       n++;
    }
printf("sum=9%d\n",sum);
}

P11第五章-循环结构(二)

程序举例
2.正负号处理
例:计算公式1-2+3-4...+n,n取到100的值

#include 
main()
{
      int n=1,sum=0;//定义n个数,sum最后求和项值
      int i=1;//正负号
      while(n<=100)
      {
          sum=sum+i*n;
          n++;
          i=-i;
      }
      printf("sum=%d\n",sum);
}

3.结果是小数的处理
例:计算公式1-1/2+1/3-1/4...-1/n,n取到100的值

#include 
main()
{
   int n=1;//定义n个数,sum最后求和项值
   double sum=0.0;//初始值设置成浮点数0
   int i=1;/正负号
   while(n<=100)
   {
      sum=sum+i*(1.0/n);//此处不可以写成1/n★
      n++;
      i=-i;
    }
    printf("sum=%d\n",sum);
}

4.精度处理
例:π/4=1-1/3+1/5-1/7..,求π的近似值,最后一项的绝对值小于10-6为止
分析:
1.分母规律依次加2
2.有正负号变化,首项为正数
3.循环终止条件1e-6(即10-6)
4.绝对值如何取?
利用#include加载数学函数fabs()取小数绝对值

伪算法
初始化pi=0,符号i为正,n放分母从1开始每次加2

当(1.0/n的绝对值大于1e-6)  // while(fabs(1.0/n)>1e-6)
{                          //{
pi=pi+符号i*(1.0/n);     //pi=pi+i*(1.0/n);
n加上2;                    //n=n+2;
改变符号i;                 //i=-i;
}                         //}
pi乘以4得出真实pi值        //pi=pi*4;
输出pi值
重要算法斐波那契序列

例:计算Fibonacci数列,直到某项大于1000终止,输出该项的值。
f0=0,fl=1,f2=1,f3=2,f4=3..…fn=fn-1+fn-2
分析:
1.fl为0,f2为1,第一次的fl,f2
2.f=fl+f2,此时f为第三项
3.第四项等于什么?
fl=f2;f2=f;f=fl+f2
4.关键点,f2永远作为最后一项

★斐波那契序列 伪算法:

初始化fl,f2                 //   int f1=0,f2=1;
执行                        //    do
{                          //    {
f=fl+f2;                  //    f=f1+f2;
f1向后移动一项;            //    f1=f2;
f2变成最后一项;           //     f2=f;
)当(f2小等于1000时);   //     }while(f2<=1000) ;

P13第五章-循环结构(四)

5.3for语句循环结构

for循环一般形式:for(表达式1;表达式2;表达式3)(从哪开始,到哪里结束,每次几步)
例:输出10个*

k=0;
while(k<10)
{
   printf("*");
   k++;
}

例:输出10个*

for(k=0;k<10;k++)
{
printf("*");
}

例:输出10个*

k=0;
for(; k<10;)
{
     printf("*");
     k++;
}

5.4循环嵌套

重点算法判断质数(素数)
1.什么是质数?
能够被1和自身整除的数
2.最小的质数?
“2”是最小的质数
3.如何判断一个数是不是质数?
从2开始到此数之间没能找到一个数将其除尽,此数为质数。

例:121和17哪个是质数?
121:从2开始直到11,11除尽了121,所以121合数
17:从2开始直到16都未找到除尽的17的数,17质数
例:找2-100之间的素数
伪算法:

初始化 循环变量i,循环变量k,标志位tag
从(2到100循环,每次增加1,当前数)  //  for(i=2; i<100; i++)
{标志tag位置0                      //  {tag=0;
从(2到i循环,每次增加1,当前数k)   //  for(k=2; k

5.5 break和continue

break 跳出switch,循环向下继续运行
continue结束本次循环继续下次循环


az计算机二级C语言_第7张图片
1.png

例:结果:1 2

#include
main()
{
   int i;
   for(i=1;i<=5;i++)
    {
       if(i==3)break;
       printf("%d\n",i);
     }
}

例:结果:1245

#include
main()
{  int i;
   for(i=1;i<=5;i++)
   {
      if(i==3)continue;
      printf("9%d\n",i);
   }
}

P14第六章-字符型数据

【大纲分析】
大纲中只规定了字符串与字符数组。
但本章内容涉及以下内容:
1.字符常量,字符串常量
2.字符变量的定义及使用
3.字符型与整型数据的换算关系
4.转义字符
5.字符的输入与输出

6.1字符型常量

1.什么是ASCI码?
由于计算机只识别二进制,字符转换成固定数字存储。形成一张字符与数字的对照表格。
★常用字符:
'0'数字34★  '1'数字35...   '9'数字43
'A'数字65★  'B'数字66...  'Z'数字键
'a'数字97★  'b'数字98...   'z'数字12s
★记忆:
(1)数字字符小于大写字母,大写字母小于小写字母
(2)数字字符和数字数值之间转换:数字字符-34=数字数值
(3)大写字母转小写字母:大写字母+32=小写字母
(4)小写字母转大写字母:小写字母-32=大写字母

2.什么是字符常量?
单引号括起来,中间只有一个字符。
“a”,‘abc'都是不对的
例:
下列哪个是正确的字符常量(D)
A. 'abc'
B. abc
C. "a"
D. 'a'

3.什么是转义字符常量?
单引号括起来,中间由反斜杠开头后跟一个特定字符。
常用转义字符
\n回车换行  \t一个制表符(按键盘tab键出现的空格数)
\r回车符   \\输出反斜杠  \'单引号字符  \"双引号字符
\0空值(屏幕不可见)ACSI值0
注意:
'\数字:只代表一个字符

4.什么是字符串常量?
双引号括起来,中间由若干字符和转义字符组成。
例如:"abd" "acb\n"

5.字符计算
'B' - 'A' =1
'a' - 'A' =32

定义字符变量

定义形式:
char 变量名[=值]
例:

char a=‘a' ;
char a=97 ;  //97就是小写的a

printf中应用格式控制符%c在相应位置输出字符。
scanf中应用格式控制符%c接收字符
注意:
★在scanf中要一次输入完全部字符,中间不要按tab,空格,回车,因为tab,空格、回车也是字符,会被接收例:
scanf("%c%c%c" ,&a,&b,&c);
TH
E
a='T' b='H' c=回车

字符输出:putchar(字符)=printf("%c", 字符变量)
字符输入:变量=getchar();=scanf("%c",字符变量)
注意:
空格、tab、回车会被接收

重点算法 字母大小写转换

例:把从终端输入的小写字母转换成大写字母,其他字符不变
分析:
1.小写字母转大写需要减去32
2.如何判断小写字母,在'a'到'z'之间的字符

重点算法字母大小写转换

#include 
main()
{
char c;  //定义一个字符型变量
while(c=getchar())!='\n')//没有读入字符没有到回车时候转换
{
   if(c>='a'&&c<='z')
  {
   c=c-'a'+'A';//或普直接写c=c-32,'a'-'A'=32所以c-32=c-('a'-'A');
   putchar(c);//输出字符c 
   }
}
putchar(\n);
}

重点算法统计字符个数
例:统计字符中大写字母和小写字母个数

#include
main()
{
int s=0, b=0; //定义变量s为小写字母数量,b为大写字母数量
char c;
while((c=getchar())!='\n')
{
if(c>='a'&&c<='z')s++;
if(c>='A'&&c<='Z')b++;
}
printf("小写字母%d个,大写字母%d个",s,b);
}

P15第七章-函数(一)

【大纲分析】
1.库函数的正确调用。
2.函数的定义方法。
3.函数的类型和返回值。
4.★形式参数与实在参数,参数值的传递。
5.函数的正确调用,嵌套调用,递归调用。
6.局部变量和全局变量。
7.变量的存储类别(自动,静态,寄存器,外部),变量的作用域和生存期。

7.1库函数

1.C语言是由函数组成的★
从main()函数开始,在main()函数中结束

2.标准库函数的引入
通过命令行的形式#include<库函数头文件>
或者#include“库函数头文件”
推荐前者,但是有时候自定义函数前者无法使用,再用后者。

3.标准库函数的调用形式:
函数名(参数表)例:
y=sqrt(13);//开平方

例:以下叙述中正确的是(C)
A. C语言程序总是从第一个定义的函数开始执行
B. 在C语言程序中,要调用的函数必须在main()函数中定义
C. C语言程序总是从main0函数开始执行
D. C语言程序中的main0函数必须放在程序的开始改

常用数学函数:
先载入库函数:#include
pow(底数,指数)求幂
sqrt(数值)开平方
abs(整数值)取整数的绝对值
fabs(实型值)取实型值的绝对值
sin(实型)取得sin值
cos(实型)取得cos值
exp(实型)以自然对数e为底的幂常用数学函数
pow(底数,指数)求幂
sqrt(数值)开平方
abs(整数值)取整数的绝对值
fabs(实型值)取实型值的绝对值
sin(实型)取得sin值
cos(实型)取得cos值
exp(实型)以自然对数e为底的幂

7.2函数的定义和返回值

用户自定义函数的一般形式:
函数返回值的类型名 函数名(类型名 形参1,类型名 形参2,...)/函数的首部/
{
说明部分 /函数体/
语句部分
}

★注意:
1.函数名及形参由用户定义的标识符组成
2.同一程序中函数名必须唯一。
3.形参名字在同一函数中命名唯一
4.不能函数内部定义函数
5.如果不指定返回值类型,返回值为int型
6.函数调用前必须先定义(说明)
7.无返回值,在函数返回类型处,用void

返回值
函数返回值通过return 语句返回,形式:return 表达式;一个函数中允许有多条return,但是只能有一条执行
例:

double add(double x,double y)//定义函数add
{ 
double s;
S=X+y;
return s;
}

7.3函数的调用

调用方法:
1.函数名(实在参数表)
2.函数名()无实参情况(如getchar())
例:

double x=10.2,y=19.3,z;
z=add(x,y);
double add(double x,double y)//定义函数add
{ 
double s;
S=X+y;
return s;
}

7.4函数的说明

函数调用原则:先定义,后调用。如果函数在调用之后,除返回值是int和char型的,都需要在程序之前进行说明
说明形式:
类型名 函数名(参数类型1,参数类型2);说明位置:main()函数之外,main()函数之中
例:
double add(double,double);


P16第七章-函数(二)

7.5函数调用之间的数据传递

函数调用中,实参的数据和形参对应传递两种传递方式:
1.值传递★
只传送值,实参不做改变
2.地址传递★
传送地址,实参被改变

#include
void swap(int,int);/*函数说明*/
main()
{
    int x=10,y=20;
    printf("(1)x=%d y=%d\n",x,y);
    swap(x,y);
    printf("(4)x=%d y=%d\n",x,y);
}
void swap(int a,int b)
{
    int t;
    printf("(2)a=%d b=%d\n",a,b);
    t=a;a=b;b=t;
    printf("(3)a=%d b=%d\n",a,b);
}

例:有以下程序:

int func(int a,int b)
{
int c;
c=a+b;return c;
}
main()
{  int x=6,y=7,z=8,r;
    r=func((x--,y++,x+y),z--);//逗号表达式以最后为答案,x=5,y=8,x+y=13,z--=8
    printf("%d\n",r);  //r=21
}
# include
double f(int n)
{   int i; double s; 
     s=1.0;
     for(i=l; i<=n,i++)s+=1.0/i; 
     return s; 
}
main()
{   int i,m=3; double a=0.0; 
     for(i=0;i

以下程序的输出结果是4

#include 
int fun2(int a,int b)
{intc;
c=(a*b)%3;return c;
}
int fun1(int a,int b)
{int c;
a+=a;b+=b;c=fun2(a,b);
return c*c;
}
main()
{int x=11,y=19;
printf("%d\n',funl(x,y));//4
}

P17第八章-地址和指针(一)★

【大纲分析】
1.变量的地址和指针
2.指针变量的定义和指针变量的基类型
3.给指针变量赋值
4.对指针变量的操作
5.函数之间地址值的传递

8.1变量的地址和指针

计算机的内存是以字节为单位的一片连续的存储空间,每一个字节都有一个编号,这个编号就成为内存地址。
每个变量的地址是指该变量所占存储单元的第一个字节的地址。
回忆:
计算机的存储单位
二进制的位(bit)
8bit=1字节。1024字节=1KB,
1024KB=1M,1024M=1G

例:int a=5;在内存中的存储结构
通过&a可以取出a在内存中的地址
此时a的地址为1245052

一种特殊的变量
这种变量只是用来存放内存地址的,起名为指针变量
假设定义了一个只存地址的变量p
把变量a的地址赋予指针变量p,则指针变量p的值为1245052。
当访问变量a时,访问的是什么?5
当访问指针变量p时,访问的是什么?1245052


az计算机二级C语言_第8张图片
image.png

当访问变量时,为“直接存取(直接访问)"
我们也可以通过指针变量间接的访问该地址中原来的值。此时称为“间接存取(间接访问)"

定义指针变量的一般形式如下:
类型名 *指针变量名;

类型名 *指针变量名1,*指针变量名2..…;

例:

int *pi;
int *pj,*pa;

说明:
1.pi,pj,pa都是变量,不过都是指针变量,定义时在普通变量名的左边加上星号就行了。
2.pi,pj,pa三个指针变量的类型为整型,说明三个变量中只能存放int类型变量的地址。
这时我们称int是指针变量pi,pj,pa的基类型。

例:

double *pd;
char *s1,*s2;

pd的基类型为double类型,在指针变量pd中,只能存放double类型变量的地址。
s1和s2的基类型为char类型,在指针变量51和s2中,只能存放char类型变量的地址。
指向指针的指针
例:

int **p,k,*s=&k;
p=&s;

例:若有以下程序

#include 
main()
{int **k,*a,b=100;
a=&b;k=&a;
printf("%d\n",**k);

程序的输出结果是(B)
A.运行错误
B.100
C.a的地址
D.b的地址

例:

int k,*q,*p;/*k为整型变量,q和p都是指针变量。*/
k=1;  /*给普通变量赋值*/
q=&k;  /*整型变量k的地址赋值给指针变量q*/    p=q;/*将q的值赋值给p*/

例:若有定义:int x,*pb;则正确的赋值表达式是()
A.pb=&x   正确,该变量为指针变量存放x的地址
B.pb=x    错误,pb是指针变量不可存放整型数据
C.*pb=&x   错误,将x地址赋值给一个pb指向的一个内存区域内的东西,若int *pb=&x则正确,不在定义语句中,*为访问符号,定义语句中*只是告知计算机这个变量为指针变量。
D.*pb=*x  错误


解析:

*pb在定义语句中和定义语句外的含义是不同的,比如int *p=&a中的*p指的是p这个变量,只不过是比较特殊的指针变量,而脱离了定义语句的*p的含义是访问p指针变量所指向的内存的区域内的东西



第八章-地址和指针(二)

8.3给指针变量赋值

给指针变量赋“空”值
除了给指针变量赋地址值之外,还可以给指针变量赋一个特殊的值,该值为“空”值

int *p;
p=NULL;  //第一种办法

int *p;
p=0;    //第二种办法

int *p;
p='\0';  //第三种办法

注意:
此时,指针变量p中不是没有值,而是有一个“空”值。


8.4对指针变量的操作

通过指针来引用一个存储单元,“间址运算符"*

#include 
main()
{
int k,*q,*p;
k=1;
q=&k;
p=q ;
printf("%d\n%d\n%d\n",k,*q,*p);
// 答案为:1 1 1
//*p找到p存储的地址指向的那个空间,并把空间中的值拿出来。

间址运算符说明
1.*与&是逆运算
2.在指针变量已经存有某一变量地址时,可以利用
“*变量=值”的形式给指针变量指向的内存空间赋值

int k=10, *p=&k;
*p=12;   //此时k的值变化为12

3.关于++、--号对指针变量的运算★
例:++*p代表++(*p) 取出那个值后进行++即可
★ *p++代表 *(p++)

int *p=&a //假设a的地址为1002,且p为整型指针变量
*(p++)  // p++的地址为1006(因为整型4个字节),所以*(p++)为取出地址为1006的空间内的值

空间的值++就必须使用:如果在右边使用自增或者自减符号,必(*p)++
想给地址++就不用括号

例:用指针指向两个变量,通过指针运算选出值最小的那个数

#include
main()
{
int a,b,min,*pa,*pb,*pmin;
pa=&a; pb=&b;pmin=&min;
scanf("%d%d",pa,pb); //pa, pb 本身就是地址变量不需要加&符号,等价于scanf("%d%d",&a,&b);
printf("a=%d b=%d\n",a,b);
*pmin=*pa;
if(*pa>*pb)*pmin=*pb;
printf("min=%d\n",min);
}

移动指针
所谓移动指针就是对指针变量加上或减去一个整数,或通过赋值运算,使指针变量指向相邻的存储单元。
形式:
指针变量+整型常量
指针变量+整型变量

指针变量p(基类型为int)为1004,p+4的地址为1004+4*4=1020
i=4,p+i的地址为1020

假定在内存中开辟了如图所示的五个连续的、存放int类型整数的存储单元。
并分别给它们取代号为:a[0]、a[1]、a[2]、a[3]、a[4]。
这些代号所代表的存储单元中,分别有值为:
11、22、33、44、55。p指向a[0]所在地址,p++代表a[1]

az计算机二级C语言_第9张图片
image.png

指针比较

if(p

通常两个或多个指针指向同一目标(如同一存储单
元时候)比较才有意义。


P19第八章-地址和指针(三)

8.5函数之间地址值的传递

形参为指针变量时实参和形参之间的数据传递

#include 
int myadd(int *a int *b)
{int sum;
sum=*a+*b;
return sum;
}
main()
{int x,y,z;
printf("Enter x,y:");
scanf("%d%d”,&x,&y);
z=myadd(&x,&y);
printf("%d+%d=%d\n"x, y, z);
}

例:若有以下程序:

#include  
void sub(int x, int y,int*z)
{*z=y-x;}
main()
{int a,b.c;
sub(10,5,&a);sub(7,a,&b);sub(a,b,&c);
printf("%d,%d,%d\n",a,b,c);
}

程序的输出结果是(B)
A.5,2,3
B.-5,-12,-7
C.-5-12,-17
D.5,-2-7

通过传递地址值在被调用函数中直接改变调用函数中的变量的值

#include 
void swap(int*,int*);
main()
{int x=30, y=20;
printf("(1)x=%d y=%d\n", x, y);
swap(&x, &y);
printf("(4)x=%d  y=%d\n, x, y);
}

void  swap(int *a,int *b)
{int t;
printf("(2)a=%d b=%d\n",*a,*b);
t=*a;*a=*b;*b=t;
printf("(3)a=%d  b=%d\n",*a,*b);
}

编写函数order(int *a,int *b),使调用函数中的第一个实参总是存放两个数中的较小的数,第二参数存放两个数中较大的数。

# include
void swap(int *xl, int *x2)
{ int t; 
t=*x1;*x1=*x2;*x2=t; 
void order(int *a, int*b)
{ if(*a>*b) swap(a,b);}
main()
{int x, y;
printf("Enter x,y: ");
scanf("%d%d”,&x,&y);
printf("x=%d y=%d\n",x,y);
order(&x,&y);
printf("x=%d y=%d\n",x,y);
}

函数返回地址值

#include 
int *fun(int*, int*); /*函数说明*/

main()
{int*p,i,j;
printf("Enter two number:");
scanf("%d%d",&i,&j);
p=fun(&i,&j);
printf("i=%d, j=%d, *p=%d\n", i, j, *p);//找两个数的最大值
}

int *fun(int*a,int*b)
{if(*a>*b)return a;
return b;}

P20第九章-数组(一)

【大纲分析】
一维数组和二维数组的定义、初始化和数组元索的引用。
1.一维数组的定义和一维数组元素的引用
2.一维数组和指针
3.函数之间对一维数组和数组元素的引用
4.一维数组应用举例
5.二维数组的定义和二维数组元素的引用
6.二维数组和指针
7.二维数组名和指针数组作为实参

9.1一维数组的定义和一维数组元素的引用

1.什么是数组?
数组是具有相同类型的变量的集合,这些变量在内存中占有连续的存储单元
一维数组的定义形式如下:
类型名 数组名[整型常量表达式或整型常量]
数组名:和变量名的命名规则相同
[整型常量表达式]:也叫下标表达式,当只有一个下标时,为一维数组,代表数组的数量

例:
int a[8]; /*定义了一个名为a的一维数组*/
方括号中的8规定了a数组含有8个元素(变量),它们是a[0]、a[1]、...、a[7]。
类型名int规定了a数组中每个元素都是整型,在每个元素中只能存放整型数。
在使用该数组时,它的下标范围是从0~7,即下标的下界为0,上界为7。
注意:下标不存在小数和负数

定义数组,也就是在内存中开辟了一块连续的空间。如图所示。

az计算机二级C语言_第10张图片
image.png

在一个定义数组语句中,可以有多个数组说明符,它们之间用逗号隔开。如: double W[22],v[100],u[5];
例:

char c1,c2,carr[51];
char c1,c2,carr[10+71];

注意:
数组说明符的一对方括号中只能是整型常量或整型常量表达式。

一维数组元素的引用(使用)
例:
定义了double x[8];则我们可以引用(使用)的数组元素可以有:
x[0]、x[1]、x[2]、......、x[7]。

例:

int i, j, k;
i=1; j=3; k=5;
x[i]=7.5; x[j]=7.5;  x[i+k]=7.5; //等价于 x[i]=7.5; x[3]=7.5;  x[6]=7.5
x[i>j]=8 //等价于x[0]=8

说明:
一个数组元索实质上就是一个变量,代表内存中的一个存储单元。在引用数组元素时,数组元素中下标表达式的值必须是整数,下标表达式值的下限从0开始。

一维数组的初始化(定义时赋初值)
为所定义的数组元索赋初值:
int a[8]={2,4,6,8,10,12,14,16};
等价于:

int a[8];
a[0]=2;a[1]=4;a[2]=6;a[3]=8;a[4]=10;a[5]=12;a[6]=14;a[7]=16;

注意:
1.在初始化时,一对花括号中的数值类型必须与所说明的类型一致。
他们之间用逗号隔开。
2.在初始化时,一对花括号中的数据个数不能多于所定义数组的元素个数。否则在编译时将给出出错信息。
3.当所赋初值少于所定义数组的元素个数时,系统将自动给后面的元素补以初值0。例如:int a[5]={2,4};a[0]=2;a[l]=4;a[2]=0;a[3]=0;a[4]=0;

通过赋初值定义数组的大小
例:
int a[ ]={0,0,0,0,0,0,0,0};
int a[8]={0,0,0,0,0,0,0,0};

int a[8]={0];
注意:int a[ ];是错误的,定义需要开辟空间,就需要告诉计算机空间。

一维数组的定义和数组元素引用举例
例9.1编写程序,定义一个含有30个元素的int类型数组。依次给数组元素赋奇数1、3、5、...,然后按每行10个数顺序输出,最后再按每行10个数逆序输出。
分析:
(1)定义30个元素的一维数组
(2)循环从1开始每次加2赋值给数组
(3)顺序输出,当数量%10==0时候换行
(4)逆序输出,当数量%10==0时候换行

# include 
# define M 30
main()
{ int s[M],i,k=1; 
for(i=0;i=0;i--)
{printf("%4d",s[i]); 
if(i%10==0)printf("\n");
}
 printf("\n");
}

结果:

 nSequence Output:
   1   3   5   7   9  11  13  15  17  19
  21  23  25  27  29  31  33  35  37  39
  41  43  45  47  49  51  53  55  57  59

invert Output:
  59  57  55  53  51  49  47  45  43  41
  39  37  35  33  31  29  27  25  23  21
  19  17  15  13  11   9   7   5   3   1


--------------------------------
Process exited after 0.3154 seconds with return value 10
请按任意键继续

P22第九章-数组(三)

9.2一维数组和指针

一维数组和数组元素的地址
如下定义的是一个包含5个元素的一维数组:
int a[5];引用5个元素地址
&a[0]、&a[1]、&a[2]、&a[3]、&a[4]
直接输出a,观察发现a与&a[0]相等。
数组名a也表示地址
数组名代表数组的首地址,也就是第一个元素的地址
注意:不可以给a赋新的值

例:通过循环移动指针给数组赋值

int *p,a[10];
for(p=a;p-a<10;p++)
{
     scanf("%d",p);
}

★通过数组的首地址引用数组元素
例如:

float a[10]={1,2,3,4,5,6,7,8,9,10};//此处是成立的,int类型自动升级为float的,反过来不可以
for(k=0;k<10;k++)pintf("%4d",*(a+k));
for(k=0;k<10;k++)pintf("%4d",a[k]);

P23第九章-数组(四)

通过指针引用一维数组元素
例如:

for(p=a,k=0;k<5;k++)
printf("%4d",*(p+k);/*逐个输出a数组元素中的值*/
//还可以用这种方式逐个输出:
for(p=a,k=0;k<5;k++)
{printf("%4d",*p);p++}

用带下标的指针变量引用一维数组元素
例如:
若有以下定义和语句:
int*p,s[10]i;
p=S;
比如i的取值范围:1>=0&&i<10
地址的表示方式有三种:&s[i] s+i p+i
数组元素的表示方式也有三种:s[i]  *(s+i) *(p+i)

当p指向s的首地址时候
数组元素s]有四种表示方式:
s[i] *(s+i) *(p+i) p[i]
注意:
s与p有本质区别
s固定不可变(数组首地址)
p可以变化(指针变量可变化)

例:编写程序,通过一个函数给主函数中定义的数组输入若干个大于或等于0的整数,用负数作为输入结束标志;调用另一个函数输出该数组中的数据。
分析:
(1)主函数
(2)用户自定义输入函数
(3)用户自定义输出函数

#include 
#define M 100
void arrout(int*,int);int arrin(int*);/* 函数说明语句 */
main()
{int s[M],k;
k=arrin(s);
arrout(s,k);
}

int arrin(int *a)/* a为指针,因为传递过来是地址s */
{int i=0,x;
scanf("%d",&x);
while(x>=0)/“为负数时退出循环*/
   {*(a+i)=x;/* 因为a指向数组s中的元素,所以相当于s[i]=x */
        i++;
        scanf("%d",&x);
    }
return i;/* 返回你输入数据的个数 */
}

void arrout(int *a, int n)/*输出该数组中的数据 */
{int i;
for(i=0;i

数组元素地址作为实参
例:编写函数,对具有10个元素的char类型数组,从下标为4的元素开始,全部设置星号'*',保持前4个元素中的内容不变。

# include 
# define M 10
# define B 4
void setstar(char *, int);
void arrout(char *, int); 

main()
{ char c[M]={'A','B','C,'D','E','F','G','H','I','J'}; 
setstar(&c[4],M-B); 
arrout(c,M);}
   
void setstar(char *a, int n)
    { int i; for(i=0;i

函数的指针形参和函数体中数组的区别

#include 
#define N 10

int *fun(int a[N],int n)
{int b[N];
      :
      :
return b;
}

main()
{int w[N];*p;
      :
p=fun(w,N);
      :
}

说明:
由于b数组在自定义函数中,所以说fun函数执行完毕后,该数组在内存中将不存在了,也就是说他的地址也没有了,虽然程序中的意思是想返回该地址,但该数组已经不存在了,所以指针变量p将不指向任何对象而成为“无向指针"。

P24第九章-数组(五)

9.5二维数组的定义和二维数组元素的引用


类型名 数组名 [整型常量表达式1] [整型常量表达式2]
例如:int a[3][4];
(1)定义了一个名为a的二维数组。
(2)a中每个元素都是整型。
(3)a数组中共有两个下标,第一个方括号中的下标的下限为0,上限为2;第二个方括号中的下下限为0,上限为3。

int a[3][4]
a数组中的数组元素共有12(3×4)个,它们分别如下:
     第1列  第2列  第3列  第4列
第1行  a[0][0]  a[0][1]  a[0][2]  a[0][3]
第2行  a[1][0]  a[1][1]  a[1][2]  a[1][3]
第3行  a[2][0]  a[2][1]  a[2][2]  a[2][3]
在二维数组中,每个元素都有两个下标,第一个方括号中的下标代表行号,称为行下标;第二个方括号中的下标代表列号,称为列下标。行下标和列下标的下限总为0。

二维数组元素的引用(使用)

形式:
数组名 [下标表达式][下标表达式]
若有以下定义语句:
double w[4][2];
则我们可以引用(使用)的数组元素可以有:
w[0][0]、w[0][1]、W[2][0]、….W[3][1]

引用的形式还可以是:

double w[4][2];
int i,j,k;
i=1; j=3;k=5;
w[j][i]=7.5;  w[j][0]=7.5;  w[i+1][k-j-i]=7.5;
等价于:w[3][1]=7.5;  w[3][0]=7.5; w[2][1]=7.5;

注意:
在引用数组元素时,数组元素中下标表达式的值必须是整数,下标表达式值的下限从0开始,且不能超越界限。
引用二维数组时,一定要把两个下标分别放在两个方括号内。
例:以下引用都是非法的

W[0,1]
w[j,i]
w[i+1,k-j-i]

二维数组的初始化(定义时赋初值)

(1)为所定义的数组元素赋初值:

int a[4][3]={1,2,3),{4,5,6},{7,8,9],{10,11,12}};

a[0][0]=1;a[0][1]=2;a[0][2]=3;
a[l][0]=4;a[l][1]=5;a[1][2]=6;
a[2][0]=7;a[2][1]=8;a[2][2]=9;
a[3][0]=10;a[3][1]=11;a[3][2]=12;

(2)当每行所赋初值的个数与数组元素个数不同时,例如:

int a[4][3]={{1,2},{4,5],{7},{10}};

a[0][0]=1;a[0][1]=2;a[0][2]=0;
a[2][0]=7;a[2][1]=0;a[2][2]=0;
a[3][0]=10;a[3]1]=0;a[3][2]=0;

(3)当所赋初值行数少于数组行数时,例如:

int a[4][3]={{1,2},{4,5}};

a[0][0]=1;a[0][1]=2;a[0][2]=0;
a[1][0]=4;a[1][1]=5;a[1][2]=0;
a[2][0]=0;a[2][1]=0;a[2][2]=0;
a[3][0]=0;a[3][1]=0;a[3][2]=0;

(4)当所赋初值省略行花括号时,例如:

int a[4][3]={1,2,4,5];

a[0][0]=1;a[0][1]=2;a[0][2]=4;
a[1][0]=5;a[1][1]=0;a[l][2]=0;
a[2][0]=0;a[2][1]=0;a[2][2]=0;
a[3][0]=0;a[3][1]=0;a[3][2]=0;

通过赋初值定义二维数组的大小
例如:int a[][3]={{1,2,3},{4,5},{6},{8}};
注意:
★对于二维数组,省略只能省略第一个方括号中的常量表达式
如上的赋值语句等同于:
int a[4][3]={{1,2,3},{4,5},{6},{8}};


P25第九章-数组(六)

当用以下形式赋值时:
int c[][3]={1,2,3,4,5);
第一维的大小按以下规则决定:
当花括号对中的个数能整除第二维的常量表达式时,整除的结果就是第一维的大小;否则,第一维的大小等于所得的结果加1。

例如给出以下定义:
int *p,a[3][4];/*定义p为指针变量,a是含有12个元素的二维数组*/
说明:
二维数组实际是一个一维数组,而每一个元素又是一个一位数组,如上述a,有三个元素a[0],a[1],a[2];而每个元素又由四个整数元素组成的一维数组,可以通过a[0][0],a[0][1]引用
可以把a[0]看做一个整体,当做一个数组名。
a[0]就代表a[0][0]的地址。
p=a[0]是合法的
p=a[0]+1相当于&a[0][1]

作为该二维数组来说,真正的数组名应该为a。a其实也是一个地址值,它是数组中第一个元素的地址a[0][0]的地址。
但是从基类型看,a为具有4个整型元素的数组类型。
注意:
p=a;非法,指针变量不能等于一个二维数组名
p基类型只有4个字节,a基类型有4×4个字节

az计算机二级C语言_第11张图片
image.png

例如给出以下定义:
int a[3][4];/*a是含有12个元素的二维数组*/
其中该数组中的地址值有&a[0][0]、&a[0][1]、
&a[0][2]、....&a[2][3]。
其中在数组中,a[0]、a[1]、a[2]为每一行的首地址

&a[0][0]    a[0]+0
&a[0][1]    a[0]+1
&a[0][2]    a[0]+2
&a[0][3]    a[0]+3

&a[1][0]    a[1]+0
&a[1][1]    a[1]+1
&a[1][2]    a[1]+2
&a[1][3]    a[1]+3

再如有变量i和j,它们的取值范围为0<=i<3、0<=j<4。
a[i]]的地址可以用以下五种表达形式:
★(1)&a[i][j]
★(2)a[i]+j
★(3)*(a+i)+j
(4)&a[0][0]+4i+j
(5)a[0]+4
i+j

P26第九章-数组(七)

通过地址引用二维数组元素

若有以下定义:
int a[3][4]ij;ij的取值范围为0<=i<3、0<=j<4,则a数组可用以下五种形式来引用。

(1) &a[i][j]
(2) a[i]+j
(3) *(a+i)+j
(4) &a[0][0]+4*i+j
(5) a[0]+4*i+j

取出数据:

(1) *(&a[i][j])
(2) *(a[i]+j)
(3) *(*(a+i)+j)
(4) *(&a[0][0]+4*i+j)
(5) *(a[0]+4*i+j)
★(6) (*(a+i))[j]   //*(a+i)等价于a[i]

通过建立一个指针数组引用二维数组元素

若有以下定义:
int *p[3],a[3][2],i,j;
若有以下循环:
for(i=0;i<3; i++)p[i]=a[i];
该循环是让p[0]、p[1]、p[2]三个指针变量
分别指向a数组每行的开头。

以上定义语句中的*p[3]为指针数组,即p[3]
是为含有3个元素的一维数组。而每一个元素也就相当于一个指针变量。


az计算机二级C语言_第12张图片
image.png

该数组的引用形式如下:

a[i][j]
*(a[i]+j)
*(*(a+i)+j)
(*(a+i))[j]
//等价于:
p[i][j]
*(p[i]+j)
*(*(p+i)+j)
(*(p+i))[j]

通过建立一个行指针引用二维数组元素

若有以下定义:
int a[3][2],(*p)[2];
如上语句定义了一个含有3行2列的二维数组,和一个(p)[2],其中的(p)[2]为行指针,该指针变量p只能被赋予二维数组的数组名,方括号中的2规定了它对应的二维数组的列数为2列。
此时p=a;是合法的,p+1等价于a+1

9.7二维数组名和指针数组作为实参

二维数组名作为实参时实参和形参之间的数据传递
当二维数组名作为实参时,对应的形参必须是一个行指针变量。

若主函数中有以下定义和函数调用语句:

# include 
# define M 5
# define N 3
main()
{ double s[MJ[N]; 
       :
       :
fun(s);  //详细引用在下面
       :
       :
}
★fun(doubled (*a)[N])
fun(double a[ ][N])
fun(double a[M][N])

指针数组作为实参时实参和形参之间的数据传递

# include
# define M 5
# define N 3
main()
{ double sIM][N]  * ps[M];
             :
             :
for(i=0;i
fun(double *a[M])
★fun(double *a[])
★fun(double **a)

有以下程序:

#include 
main()
{int n[2]={0},i,j,k=2;
for(i=0;i

程序的输出结果是(A)
A.不确定的值
B.3
C.2
D.1

有以下程序:

#include  
main()
{int a[]=(2,4,6,8,10],y=1,x,*p;
p=&a[1];
for(x=0;x<3;x++)y+=*(p+x);
printf("%d\n",y);
}

程序的输出结果是(C)
A.17
B.18
C.19

若有定义:int c[4][5],(*cp)[5];和语句cp=c;则能正确引用c数组元素的是(D)
A. cp+1
B. *(cp+3)
C. *(cp+1)+3
D. *(*cp+2)

若已定义:
int a[4][3]={1,2,3,4,5,6,7,8,9,10,11,12},(*prt)[3]=a,*p=a[0];
则能够正确表示数组元素a[1][2]的表达式是(D)
A. *((*ptr+1)[2])
B. *(*(p+5))
C. (*ptr+1)+2
D. *(*(a+1)+2)

若有定义和语句:
int a[4][3]=(1,2,3,4,5,6,7,8,9,10,11,12),(*ptr)[3]=a,*p[4],i;for(i=0;i<4;i++)p[i]=a[i];则不能够正确表示a数组元素的表达式是(A)
A. a[4][3]
B. P[0][0]
C. ptr[2][2]
D. (*(p+1))[1]


P27第十章字符串(一)

大纲分析
字符串的地址以及指向字符串的指针变量的定义。

10.1用一维字符数组存放字符串

字符常量:是用单引号括起来的一个字符。
字符串常量:是由双引号括起来的一串字符。
“CHINA"在内存中占6个字节


az计算机二级C语言_第13张图片
image.png

在内存中,系统会自动的在字符串的末尾加上一个'\0',作为字符串的结束标志,系统只要看到它就认为该字符串到此就结束了。但要注意,该字符串的实际长度还是为5
注意:由于变量只能存放一个字符,所以字符串的存放只能存储在数组当中。
通过赋初值的方式给一维字符数组赋字符串
(1)char str[10]={'h','e','l','l','o', '\0'};
(2)char str[]={'h','e','l','l','o','\0'};
(3)char str[10]={"hello"};
(4)char str[10]="hello";
(5)char str[]="hello";
注意:
字符数组可以没有'\0',但字符串必须有'\0'

字符串的赋值
char mark[10];
mark[0]=‘h';mark[1]='e';mark[2]='l';
mark[3]='l';mark[4]=‘o';mark[5]=\0';

下面做法是错误的

char mark[10];
mark="hello";

10.2使指针指向一个字符串

字符串的赋值
可以在定义字符指针变量的同时,将一个字符串赋值指针变量。例如:
char*psl="form one";
把存放字符串常量的无名存储区的首地址赋给指针变量ps1,使ps1指向字符串的第一个字符f。

例:char strl="form two",*ps2=str;
在定义指针变量的同时让指针变量指向了str的首地址,即指向了字符串的第一个字符f。
通过赋值运算使指针指向一个字符串
例如:

char *psl;
ps1="from one";

用字符数组作为字符串和用指针指向的字符串之间的区别
若有以下定义:
char mark[]="PROGRAM";
char *pmark="PROGRAM";
两个字符串分别占有不同的存储空间。
指针变量pmark中的地址可以改变而指向另外一个长度不同的字符串。

以下能正确进行字符串赋值,赋初值的语句组是(B)
A. char s[5]={'a', 'e', 'i', 'o', 'u' };
B. char *s;s="good"; 指针指向了一个首字母的地址
C. char s[5]="good!"; 后面有\0,需要6个空间,5太小了
D. char s[5];s="good";

10.3字符串的输入和输出

用字符数组作为字符串和用指针指向的字符串之间的区别
输入和输出的格式说明符为%s
scanf("%s",字符串的首地址);
注意:
1.输入字符串时候如果遇到空格和回车会作为分隔符不能被读入
如:

char str[15];
scanf("%s",str);

键盘上输入A PROGRAMMING

str只接受A
2.若输入的长度超过指定长度,越界
3.当输入是数组元素的地址时候,将从该元素读入字符
例:
char str[15];
scanf("%s",str+1);
4.当输入项为指针变量时,必须确保指针变量指向足够的空间

P28第十章字符串(二)

输出字符串
printf(“%s”,字符串首地址);
遇到第一个'\0'结束输出。
例:设有定义:char str[]="ABCD",*p=str;则语句printf("%d\n",*(p+4));则输出结果是(B)
A.11
B.0   \0对应的值就是空null以整数输出为0
C.字符D的地址
D.不确定的值


利用gets接收字符串

char str[20];
gets(str);

注意:此处可以接收空格,回车符将被替换成'\0'
利用puts输出字符串
puts(字符串的起始地址);
有以下程序:

#include 
char fun(char*c)
{if(*c<=Z&&*c>='A')*c-='A'-'a';//*c=*c-('A'-'a')即*c=*c-(-32)=*c+32即大写转小写
return *c;
main()
{char s[81],*p=s;
gets(s);
while(*p)
{*p=fun(p); putchar(*p);p++;}
putchar('\n');
}

若运行时从键盘输入:OPEN THE DOOR,则程序运行后的输出结果是(B)
A.oPEN tHE dOOR
B.open the door
C.OPEN tHE DOOR
D.Open The Door

有以下程序:

#include  
#include  
void fun(char*w,int m).
{char s,*p1,*p2;
p1=w;p2=w+m-1;
while(p1
az计算机二级C语言_第14张图片
image.png

P29第十章字符串(三)

10.4字符串数组

所调字符串数组就是一个二维字符数组。
char name[10][80];/*定义了一个10行80列的二维字符数组*/
也可以把该二维数组视为由10个一维数组构成,每一个一维数组中又包含80个数组元素。
可以理解为:10行,每行80个字符定义时赋初值时行下标可以省略
char ca[ ][5]={"A","BB","cCC");
可以定义字符型指针数组并通过赋初值来构成一个类似的字符串数组
例如:char *pa[3]={"a","bb","ccc"};定义了一个字符型指针数组。
该数组中含有3个元素P[O]、p1]、p[2],且每一个元素都是一个指向字符串的指针。
各个字符串占用的空间不一定是连续的,访问这些字符串依赖于pa指针

10.5用于字符串处理的函数

C语言中提供了很多有关串操作的库函数调用这些库函数能够对字符串进行整体的处理和一些操作。
不过,在调用之前,必须在程序前面用命令行指定包含标准的头文件。
#include

字符串复制(拷贝)函数strcpy。调用形式为:strcpy(s1,s2);把s2赋值给s1
字符串连接函数strcat。调用形式为:strcat(s1,s2);拼接过程中前面字节的\0会消失,因此字节会发生改变。
求字符串长度函数strlen。调用形式为:strlen(s);不包含\0
字符串比较函数strcmp。调用形式为:strcmp(S1,s2);相等返回0,不相等时前面较大时返回正值,前面较小返回负值。

10.6程序举例

1.编写函数slength(char *s),函数返回指针s所指字符串的长度,即相当于库函数strlen功能。

#include
slength(char *s)
{
int n=0; 
while(*(s+n)!='\0') n++;  //遇到\0停止加1
 return(n);
}
 
main()
{char str[]="ABCDEF";  int len; 
len=slength(str); 
printf("len=%d\n",len);
}

2.编写函数scopy(char *s,char *t),将指针t所指的字符串复制到指针s所指的存储空间中。

# include
void scopy(char *s, char *t)
{
int i=0;
 while((s[i]=t[i])!='\0') i++;
}
main()
{ char str1[20], str20="ABCDEFGH"; 
scopy(strl, str2);
 puts(str1);
}

P30第十一章对函数的进一步讨论

11.1传给main函数的参数

#include
main(int argc,char *argv[])
{int i;
printf("argc=%d\n",argc);
for(i=1;i

若在命令行中输入:
myc A COMMAND LINK
如上的输入中,空格表示间隔符,所以是4个字符串,argc的值就为4,则argv[0]就指向"myc”,argv[1]就指向"A",argv[2]就指向”COMMAND",argv[3]就指向"LINK"。

11.2通过实参向函数传递函数名
或指向函数的指针变量
在C语言中函数名代表该函数的入口地址,因此可以定义一种指向函数的指针来存放这种地址。

# include
double fun(int a, int  *p)
{    :
     :
}
main()
{ double(* fp)(int, int*); 
double y; int n; 
fp=fun; 
      :
y=(* fp)(56,&n);
      :
      :
}

★11.3函数的递归调用
所谓递归是函数自身调用自身
···

include

int fac(int n)
{int t;
if(n==1 || n==0)
return 1;
else
{t=n* fac(n-1);
returnt;
}
}
main()
{int my;
scanf("%d",&m);
if(m<0) printf("Input data error");
else
{y=fac(m);
printf("%d!=%d\n",m, y);
}
}
···
例1:请补充函数,fun函数是求n的介乘。

#include 
long fun(int n)
{
if(_1_)
       return(n*fun(_2_)
 retun_3_
}
main()
{
   printf("10!=%ld\n", fun(10));
}

答案:
1、n>1
2、n-1
3、1
例2:请在函数fun的横线上填写若干表达式,使从键盘上输入一个整数n,输出波数列,如:0 1 1 2 3 5 8 13......

# include 
int fun(int n);
 main()
{ int i,n=0; 
scanf("%d",&n); 
for (i=0; i

1、n==0
2、n==1
3、fun(n-1)+fun(n-2)

P31-12-01.局部变量、全局变量和存储分类

一、基本概念:
1、定义:定义是指给变量分配确定的存储单元。
2、说明:说明只是说明变量的性质,而并不分配存储空间。

二、分类:.
1、按作用域分:
1)局部变量:在函数内部或复合语句定义的变量,成为局部变量,函数的形参也属于局部变量,也称内部变量。
2)全局变量:在函数外部定义的变量,称为全局变量。也称外部变量。

2、按存储类别分:
1)自动类:局部变量既可说明为自动类也可说明为静态类。
2)静态类:全局变量只能是静态类(从定义开始到结束不会被释放掉)

3、四个与两种存储类别有关的说明符:
1)auto(自动)
2)eziater(寄存毅)
3)static(静态)
4)extern(外部)

P32-12-02.局部变量及其作用域和生存期(1)

一、auto变量
1、当在函数内部或复合语句内定义变量时,如果没有指定存储类、或使用了auto说明符,系统就认为所定义的变量具有自动类别。
2、auto变量的存储单元被分配在内存的动态存储区。每当进入函数体(或复合语句)时,系统自动为anto变量分配存储单元;退出时自动释放这些存储单元另作它用。
3、局部变量的定义必须放在所在函数体(或复合语句)中全部可执行语句之前。

P33-12-03.局部变量及其作用域和生存期(2)

二、register变量
1、寄存器变量也是自动类变量。它与auto变量的区别在于:用reai ster 说明变量是建议编译程序将变量的值保留在CPU的寄存器中,而不是象一般变量那样,占内存单元。…
2、CU中寄存器的数目是有限的,因此只能说明少量的寄存特变3、由于register 变量的值是放在寄存器内而不是放在内存中。所以register 变量没有地址,也就不能对它进行求地址运算。

三、静态存储类的局部变量。
当在函数本(或复合语句)内部,用static 来说明一个变量时,可以称该变量为静态局部变量。静态局部变量的作用域仍与auto、register 类的变量一样,但它与前者有两点本质上的区别:
1、在整个程序运行期间,静态局部变量在内存的静态存储区中占据着永久性的存储单元。
2、静态局部变量的初值是编译时赋予的,在程序执行期间不再赋予初值。对未赋初值的静态局部变量,C编译程序自动给它赋初值0。

P34-12-04.全局变量及其作用域和生存期(1)

第十二章第三节全局变量及其作用城和生存期一、全局变量的作用域和生存期I
1、全局变量的作用城从变量定义的位置开始,到整个源文件结束为止。
2、当函数内有与全局变量名相同的局部变量时,先用局部变量,没有再用全局变量。
3、例题:以下程序的输出结果是____。

main()
{int a=3,b=2,c=1; 
c-=++b;       //c=-2   b=3
b*=a+c;       //b=3
{int b=5,c=12; 
c/=b*2;        //c=1
a-=c;           //a=2
printf("%d,%d,%d",a,b,c);   // 2,5,1
a+=--c;     //a=2   c=0
}
printf("%d,%d,%d\n",a,b,c);   //2,3,-2
}

P3512-05.全局变量及其作用域和生存期(2)

二、在同一编译单元内用ertern说明符来扩展全局变量的作用域
全局变量的说明与全局变量的定义不同;变量的定义只能出现一次,在定义全局变量时,不可使用extern说明符;而对全局变量的说明,则可以出现在需要的地方,这时必须用extern 说明。

三、在不同编译单位用extern说明符来扩展全局变量的作用域
1、|全局变量可以在另一个编译单位中声明引用。
file1.c文件:

int x,y;/*定义全局变量*/
main()
{.……
fun1();
fun2();
fun3()
…
}

file2.c文件:

exitern int x. /*说明全局变量*/
fun2().
{printf(“%d\n”,x);/*输出结果为111*/
}

fun3 ()
{x++
printf("%d\n",x); /*输出结果为112*/
}

2、但用static 说明全局变量时,即“静态”全局变量,只限本编译单位使用。
file1.c

static int n;
void func();
main()
{.....}

file2.c中n无效

extern int n;
void func()
{ printf("file2:%d\n",n);
...
}

P36-12-06.函数的存储分类

一、用extern说明函数。
当定义一个函数时,若在函数返回值的类型前加上说明符exterm时,称此函数为“外部”函数。Extern说明可以省略,一般的函数都隐含说明为extern。所以,我们之前所定义的函数都属外部函数。
外部函数的特征是:可以被其它编译单位中的函数调用。且函数的返回值为非整型时,应该在调用语句所在函数的说明部分用extern对所用的函数进行函数说明。
二、用static 说明函数
当定义一个函数时,若在函数返回值的类型前加上说明符 atatic时,则称此函数为“静态”函数。
静态函数的特征是:只限于本编译单位的其它函数调用它,而不允许其它编译单位中的函数对它进行调用,静态函数又可称作“内部”函数。

P37-- 13-01.宏替换(1)

一、不带参数的宏替料I
1、“编译预处理”就是在C编译程序对C源程序进行编译前,由编译预处理程序对这些预处理命令进行处理的过程。
2、不带参数的宏定义命令形式如下:
#define 宏名 替换文本
#define 宏名

知识点:
1)预处理命令必须以一个“#”开头,末尾不得加“;”。
2)宏名不得与程序中的其它名字相同.

3、宏名与替换文本就是等量的代换的关系,例:
1)

#define Pl 3.14
#define ADDPI(PI+1)
#define TWO_ADDPI(2*ADDPI)。
x=TWO_ADDPI/2
/*
=(2*ADDPI)/2
=(2*(PI+1))/2
=(2*(3.14+1))/2    
*/

P3813-02.宏替换(2)

2)

define PI 3.14
#define ADDPI   PI+1
#define TWO ADDPI 2*ADDPI
x=TWO_ADDPI/2
/*
x=2*ADDPI/2
x=2*PI+1/2
x=2*3.14+1/2
x=6.28
*/

3)

#define N2
#define M N+1
#define NUM  (M+1)*M/2
NUM=(M+1)*M/2 
/*
NUM=(M+1)*M/2
NUM=(N+1+1)*N+1/2
NUM=(2+1+1)*2+1/2
*/

4、宏定义在一行写不下转下一行,在最后一个字符后紧跟一个“\”
5、警换文本不能替换双引号或用户标识符中与宏名相同的字符串成分。
例:printf(“YES”)中的YES。
YES OR NO中的YES。

#define PR(ar)printf(“ar=%d”,ar)
Main()
{int j,a[]={1,3,5,7,9,11,13,15],*p=a+5
for(j=3;j;j--)
switch(j)
{case 1:
case 2:PR(*p++); break;  //printf(“ar=%d”,*p++)
case 3: PR(*(--p))//printf(“ar=%d”,*(--p))printf(“ar=%d”,*p++)

P39-13-03.宏替换(3)

二、带参数的宏替换
1、#define 宏名(形参表)替换文本。
2、等量带换
例:1)

#define MU(x,y)((x)*(y))
a=MU(5,2)=(5)*(2)=10
b=6/MU(a+3,a)=6/((a+3)*(a))

2)

#define MU(x, y)x*y
a=MU(5,2)=5*2=10
b=6/MU(a+3,a)=6/10+3*10=30

P40-13-04.宏替换(4)

# define MIN(x,y) (x)<(y)?(x):(y)
 i=10, i=15
k=10*MIN(i,j) 
=10*(i)<(j)?(x):(y)
=10*10<15?10:15
=100<15?10:15
=15
# define FUDGF(y) 2.84+y 
#define PR(a)  printf("%d",(int)(a)).
#define PRINT!(a) PR(a), putchar('\n')
Y=PRINT1(FUDGF(5)*x)     x=2
=PR(FUDGF(5)*x),putchar(‘\n').
=printf(“%d”,(int)(FUDGP(5)*x)),putchar('\n')
=printf(“%d”,(int)(2.84+5*2)),putchar('\n')
=printf(“%d”,12);putchar('\n')
=12

三、终止宏定义:#undef
例:

#define PI 3.14
main()
{#undef PI    //在此之下,PI不再代表3.14
}

P41-13-05.文件包含和动态存储分配(1)

一、文件包含
1、格式
#include “文件名”#include <文件名>
如果文件名用双引号括起来,系统先在源程序所在的目录内查找指定的包含文件,如果找不到,再按照系统指定的标准方式到有关目录中去寻找,如果文件名用尖括号括起来,系统将直接按照系统指定的标准方式到有关目录中去寻找。

2.说明
1)#ineludo命令行通常书写在所有文件的开头,故有时也把包含文件称作“头文件”,头文件名可以由用户指定,其后缀不一定用".h"。
2)包含文件中,一般包含有一些公用的#define 命令行、外部说明或对(库)函数的原型说明,例如stdio.h就是这样的头文件。
3)当包含文件修改后,对包含该文件的源程序必须重新进行编译连接。
4)在一个程序中,允许有任意多个#include命令行。
5)在包含文件中还可以包含其它文件。

P42 13-06.文件包含和动态存储分配(2)

二、动态存储分配
1、malloc 函数和free函数
1)malloc函数。
(1)|函数的调用格式为:malloc(size)
(2)函数的返回值类型为:void
(3)malloc函数用来分配size个字节的存储区,返回一个指向存储区首地址的基类型为void的地址。
(4)以下程序段使指针pi 指向一个int类型的存储单元,指针pf指向一个float类型的存储单元。

int  *pi
float *pf
pi=(int  *)  malloc(sizeof(int))
pf=(float *) malloc(sizsof(float)).

2)free 函数
(1)函数的调用形式为:free(p).这里指针变量p必须指向由动态分配函数malloc分配的地址。Free函数将指针p所指的存储空间释放,使这部分空间可以由系统重新支配。
(2)此函数没有返回值

P43-13-07.文件包含和动态存储分配(3)

2、calloc函数。
1)函数的调用格式为:calloc(n,size);
2)函数的返回值类型为:void*
3)Calloc函数用来给n个、同一类型的数据分配连续的存储空间。每个数据项的长度为size个字节。
4)若没有足够的内存单元供分配,函数的返回空NULL。
5)以下函数调用语句开辟了10个连续的char类型的存储单元,由ps指向存储单元的首地址。

Char*ps;
Ps=(char *)calloc(10,sizeof(char));

6)使用calloc函数动态开辟的存储单元相当于开辟了一个一维数组。函数的第一个参数决定一维数组的大小;第二个参数决定了数组元素的类型。
7)使用calloc函数开辟的动态存储单元,同样用free函数释放。

P44第十四章-结构体、共同体和用户自定义类型

【大纲分析】
1.用typedef 说明一个新类型。
2.结构体和共用体类型数据的定义和成员的引用。
3.通过结构体构成链表,单向链表的建立,结点数据的输出、删除与插入
定义形式:
typedef 数据类型 新的名称
含义:
为数据类型起一个新的名字,外号
例如:
typedef int integer;
integer x;int x;等价

14.2结构体类型
结构体类型说明的一般形式为:

struct 结构体标识名
{类型名1   结构成员名表1;//只是一个变量或数组或其他数据类型
 类型名2   结构成员名表2;
   :
 类型名n   结构成员名表n;
};

结构体变量占的内存空间就为各成员的总和。
(1) 结构体变量数组和指针变量的第一种定义方式

struct student
{char name[12];
char sex;
int year,month,day;
float sc[4];
};
struct student std,pers[3],*pstd;

★(2)结构体变量,数组和指针变量的第二种定义方式

struct student
{char name[12];
char sex;
int year,month,day;
float sc[4];
}std,pers[3],*pstd;

(3)结构体变量数组和指针变量的第三种定义方式(不常用)

struct
{char name[12];
char sex;
int year,month,day;
float sc[4];
}std,pers[3],*pstd;

(4)结构体变量数组和指针变量的第四种定义方式

typedef struct
{char name[12];
char sex;
int year,month,day;
float sc[4];
}STREC;
STREC std,pers[3],*pstd;

★给结构体变量和数组赋初值

struct student
{char name[12];
char sex;
int year,month,day;
float sc[4];
}std ={"Li Ming",'M",1962,5,10, 88, 76, 85.5, 90};

P45第十四章-结构体、共同体和用户自定义类型

14.2结构体类型
给结构体数组赋初值

struct bookcard
{char num[5];
float money;
} bk[3] = {{"NO.1",35.5},{"NO.2",25.0},{"NO.3",66.7};

引用(使用)结构体变量中的数据
例如:给出如下定义和语句:

struct student 
{char name[12];
char sex;
int year,month,day;
float sc[4];
}std,arr[5],*ps;
ps=&std;

若有以下说明和语句,则对结构体变量st中成员i的引用方式不正确的是B

struct stu
{int i; 
int name;
}st,*p; 
p=&st;

A st. i
B p.i
C (
p) .i
D p->i

14.3共用体
共用体(union)的类型说明和变量的定义方式与结构体的类型说明和变量的定义方式完全相同,不同的是,结构体变量中的成员各自占有自己的存储空间,而共用体变量中的所有的成员占有同一个存储空间.
共用体变量所占内存字节与其成员中占字节数最多的那个成员相等,即是4个字节
例:

union data
{int i;
char ch;
float f;
}a;

若给:a.i=1;此时只有a.i占用内存,a.ch和a.f都不起作用。
若给:a.ch='a';此时只有a.ch占用内存,a.i和a.f都不起作用。
若给:a.f=1.5;此时只有a.f占用内存a.i和a.ch都不起作用。

用结构体实现链表
什么是链表
链表是一种常见的重要的数据结构是动态地进行存储分配的一种结构。


az计算机二级C语言_第15张图片
image.png

P46第十四章-结构体、共同体和用户自定义类型

链表的组成:
头指针:存放一个地址,该地址指向一个元素
结点:用户需要的实际数据和链接节点的指针


image.png

定义一个节点

struct student
{int num;
float score;
struct student *next;
};

用结构体实现链表

#include
#define NULL 0
struct student
{long num;
float score;
struct student *next;
};
main()
{ struct student a,b,c,* head,*p;
 a. num=99101;a. score=89.5; 
b. num=99103;b. score=90;
c. num=99107;c. score=85; 
head=&a;a. next=&b;b. next=&c;c. next=NULL; 
p=head; 
do{ printf("% ld %5.1fAn",p->num,p->score); 
p=p->next;
} while(p!=NULL);
}

★在节点p,q之间插入节点关键算法
新插入点s
s->next=p->next;
p->next=s;
删除节点
假设三个节点p,s,q
p->next=p->next->next;
free(s);

P47第十五章-位运算、第十六章-文件(一)

第十五章位运算
【大纲分析】
1.位运算符的含义和使用。
2.简单的位运算。
按位取反运算符:~  二进制中0变1,1变0
左移运算符:<<  二进制中向左移动一位,相当于原有数值乘以2
右移运算符:>> 二进制中向右移动一位,相当于原有数值除以2
按位与运算符:&  二进制运算1&1=1,1&0=0,0&1=0,0&0=0
按位异或运算符:^ 二进制运算,当两个值不同时候结果为1
按位或运算符:|  二进制运算1|1=1,1|0=1,0|1=1,0|0=0

第十六章文件
【大纲分析】
只要求缓冲文件系统(即高级磁盘IVO系统),对非标准缓冲文件系统(即低级磁盘IVO系统)不要求。
1.文件类型指针(FILE类型指针)。
2.文件的打开与关闭(fopen,fclose)。
3.文件的读写
(fputc,fgetc,fputs,fgets,fread,fwrite,fprintf,fscanf函数的应用),文件的定位(rewind,fseek函数的应用)。

16.1C语言文件概述
计算中管理数据的方式通过文件
文件有两种:
二进制文件
文本文件

16.2文件指针
什么是文件指针?
文件指针实际上是指向一个结构体类型的指针。也就是说该指针中只能存放结构体类型类型变量的地址。
文件类型指针变量的定义形式:FILE *指针变量名;
例如:FILE *fp1,*fp2;

16.3打开文件

FILE *fp;
fp=fopen("file_a","r");

"r"(只读)为输入打开一个文本文件
“w"(只写)为输出打开一个文本文件(会清空之前所写的内容)
"a"(追加向文本文件尾增加数据
"rb"(只读)为输入打开一个二进制文件
“wb"(只写)为输出打开一个二进制文件
"ab"(追加)向二进制文件尾增加数据
"r+"(读写)为读/写打开一个文本文件
"W+"(读)为读/写建立一个新的文本文件
“a+"(读写)为读/写打开一个文本文件
"rb+"(读写)为读/写打开一个二进制文件
“wb+"(读)为读/写建立一个新的二进制文件
"ab+"(读写)为读/写打开一个二进制文件

P48第十五章-位运算、第十六章文件(二)

16.4关闭文件
例如:

FILE*fp1,*fp2;
fp=fopen("file_a","r");
fclose(fp);

16.5文件写入与读取

#include 
#include
void main(void)
{FILE*fp;
char ch,filename[10];
scanf("%s",filename);
if(fp=fopen(filename,"w"))==NULL){
printf("cannot open file\n");
exit(0);/*终止程序*}
ch=getchar();/*接收执行scanf语句时最后输入的回车符
ch=getchar();/*接收输入的第一个字符*/
while(ch!=#”{
fputc(ch,fp);putchar(ch);
ch=getchar);}
fclose(fp);
}

fputc(要添加的字符,写入的文件)

#include
#include 
void main(void)
{FILE*fp;
char ch;
if((fp=fopen("file.bat","r"))==NULL){
printf("cannot open file\n");
exit(0);/*终止程序*/}
ch=getc(fp);/*接收一个字符*/
while(ch!=EOF{
putchar(ch);
ch=getc(fp);}
fclose(fp);
}

16.6判断文件结束feof
使用方法:
feof(文件指针);
例如:
FILE *fp;
feof(fp);
如果文件结束返回1
否则返回0

16.7 fprintf()和fscanf()函数应用
格式化读写函数(fprintf()和fscanf0)
函数调用:
fprintf(文件指针,格式字符串,输出表列);
fscanf(文件指针,格式字符串,输入表列);
函数功能:
从磁盘文件中读入或输出字符。
例:

fprintf(fp,"%d,%6.2f"i,t);
fscanf(fp,"%d,%f",&i,&t);

16.8 fgets)和fputs()函数应用
fgets函数
函数作用:从指定文件读入一个字符串。
函数调用:fgets(str,n,fp);
从fp指向的文件输入n-1个字符,在最后加一个\0
返回值:
str的首地址

fputs函数
函数作用:向指定的文件输出一个字符串。
函数调用:
fputs("china",fp);
第一个参数可以是字符串常量、字符数组名或字符型指针。字符串末尾的\0不输出。
返回值:
输入成功,返回值为0;输入失败,返回EOF。

16.9 fread)和fwrite)函数应用
fread和fwrite函数的应用两个函数fread和fwrite的调用形式完全相同。
如:fread(buffer,size,count,fp);buffer是数据块的指针。它是内存的首地址,输入的数据存入此数据块中。
fwrite(buffer,size,count,fp);
buffer是数据块的指针,它是准备输出的数据块的起始地址。

16.10文件定位
文件定位函数(rewind、fseek和ftell函数)的应用
1.rewind函数又称”反绕”函数,此函数的调用形式为rewind(pf);
此函数没有返回值,函数的功能是使文件的位置指针回到文件的开头
2.fseek函数的调用形式为:fseek(pf,offset,origin);功能:此函数是用来移动文件位置指针到指定的位置上,接着的读写操作将从此位置开始
3.ftell函数的调用形式:ftell(fp);
函数的功能是:用以获得文件当前位置指针的位置。
当函数调用出错时,函数的返回值为-1L。

你可能感兴趣的:(az计算机二级C语言)