C语言程序设计笔记-知识点及例题_第1页
C语言程序设计笔记-知识点及例题_第2页
C语言程序设计笔记-知识点及例题_第3页
C语言程序设计笔记-知识点及例题_第4页
C语言程序设计笔记-知识点及例题_第5页
已阅读5页,还剩58页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第一章程序设计基本概念

1.1程序和程序设计

程序:连续执行的一条条指令的集合称为“程序”。

1.1.2程序设计

1.确定数据结2.确定算法3.编码4.在计算机上调试程序5.整理并写出文档资料

1.2算法

定义:是指为了解决某个特定的问题而采取的确定且有限的步骤。

1有穷性2确定性3可行性4有零个或多个输入5有一个或多个输出

1.3结构化程序设计和模块化结构

结构化程序由三种基本结构组成

1顺序结构2选择结构3循环结构

12)计算机能直接执行的程序是(B)o

A)源程序B)目标程序C)汇编程序D)可执行程序

13)以下叙述中正确的是(D)

A)程序设计的任务就是编写程序代码并上机调试

B)程序设计的任务就是确定所用数据结构

C)程序设计的任务就是确定所用算法

D)以上三种说法都不完整

第二章:C程序设计的初步知识

(11)以下叙述中正确的是(C)o

A)C程序的基本组成单位是语句B)C程序中的每一行只能写一条语句

二级C语言程序设计试卷)

C)简单C语句必须以分号结束D)C语句必须在一行内写完

(11)以下叙述中正确的是(C)

A)C程序中的注释只能出现在程序的开始位置和语句的后面

B)C程序书写格式严格,要求一行内只能写一个语句

C)C程序书写格式自曰,一个语句可以写在多行上

D)用C语言编写的程序只能放在一个程序文件中

第二课:C语言的基础知识

2.2标识符,常量和变量

2.2.1标识符:

定义:由字母,数字和下划线组成,并且第一个字符必须为字母或下划线的。这样的

组成就是标识符。

注意:在C中大写字母与小字字母被认为是两个不同的字符。

分类:

关键字:在C中己经定义好了的,不能用作它用的。如ifdoubleint等等。

预定义标识符:如printfscanf

用户标识符:用户根据自己的需求来定义的。

(12)以下选项中,能用作用户标识符的是(C;

A)voidB)8_8C)_0_D)unsigned

(11)以下选项中合法的标识符是(C)

A)1-1B)1—1C)-11D)1—

(12)以下选项中不合法的标识符是(C)

A)printB)F0RC)&aD)_00

2.2.2常量:

定义:是指在程序的执行的过程中,其值不会被改变的量。

分类:

、整型常量:没有小数的常量

如:391234等等都是。

实型常量:有小数点的常量

如:3.93.03.

字符常量:由单个字符组成的量

如:‘a''b''3’

字符串常量:至少由一个字符组成的量

如:“a”“abc”“beijing”

符号常量:符号常量的值到底是多少,这是由在来定义符号有量时来决定

(13)以下选项中,能用作数据常量的是ID)

A)oll5B)0118C)1.5el.5D)115L

(13)以下选项中不能作为C语言合法常量的是(A)。

A)'cd'B)0.le+6C)〃\a〃D)'\0U'

(13)以下选项中不属于字符常量的是(B)

A)'C'B)C)'\xCC0*D)'\072,

2.3整型常量与实型常量

整型常量的几个表示方法

十进制数:

八进制数:以0开头的数字,由0-7组成。

下列合法的八进制数是

A,0B,028C,-077D,01.0

十六进制数:以0X开头,由0-9和A-F组成.

A,oxffB,OxabcC,0x11D,0x19

实型常量123.4

小数形式:123.4

指数形式:1.234e2

L字母e和E之前必须要有数字

2.字母e和E之后的数字必须是整数

3.字母e,和数字之间不能有空格。

A,2.607E-10.8103E2-77.77456E-20.le+61.23E1.2

2.2.4变量:

1.定义:在程序的运行过程中其值可以被改变的量,就叫变量。

2.原则:变量必须先定义后使用。变量定义的过程就是给变量开辟存储单元的过程。

3.分类:

整型变量:用关键芈血来表示.

shortint短整型

longint长整型在内存中占4个字节如123L

unsigned无符号如有-200U这就是错的。

变量的定义:inta这是定义了一个整型变量a.

实型变量:用关键字double或float来表示。

float单精度在内存中占4个字节

double双精度在内存中占8个字节。

2.2.5算术表达式

一、基本的算术运算符

+・*/%这些是双目运算符(就是指操作对象有两个)

注意:

除%外,其它的运算符的运算对象可以是整型也可以是实型。%的操作对象只

能是整型。

如10%3=110.7%310%4.5x%3=0

+-也可以做为单目运算。-5.4+4.9

说明:

1.如果双目运算符两边运算数的类型一致,则所得结果的类型与运算数的类型一

致。如1.0/2.0=0.51/2=0

2.如果双目运算符两边运算数的类型不一致,则系统会自动进行类型转换,使两边

的类型一致后,再进行运算。

1.0/2=0.5

3,所有的单精度数据,在运算过程中都以双精度进行运算。

二、优先级

()+-*/%+-

由高------------低

如(5+1)/2=???

2.5.3强制类型转换表达式

格式:(类型名)(表达式)

例:(int)3.23d-3

(double)1()%3=?

(14)表达式:4-(9)%2的值是(B)

A)0B)3C)4D)5

(14)设变量已正确定义并赋值,以下正确的表达式是(C)

A)x=y*5=x+zB)int(15.8%5)C)x=y+z+5,++yD)x=25%5.0

2.6赋值表达式

格式:变量名二表达式

注:1.不可以颠倒(左边必须是变量名,右边必须是C语言中合法的表达式)

2.功能就是先求出右边表达式的值,然后把此值赋值给赋值号左边的变量。确切

的说是把数据存入以该变量为标识的存储单元中去。a=4,a=7

3.结合性的优元级仅高于逗号表达式。顺序是自右向左的。如a=2+7/3

4."="是一个赋值号,不是一个等号。

5.x伸。变量的值也是可以传递和赋值的。它的意思就是将变量Y中的值赋值到

X中去。同痒N=N+1也成立

6.赋值运算符的左侧只能是变量,不能是常量或表达式a+b=c这就是违法的

70赋值号的右边也可以是一个赋值表达式。如a=b=7+l;

补充;表达式与语句的区别,

表达式后面加一个分号就是语句。

2.6.2复合赋值表达式

例:

a+=3....a=a+3同理可得a*=3/=-=

a+=a-=a+aa的初值是9

a+=a-=18

a+=(a=a-18)

a+=(a=-9)

a+=a

-18

(15)若有定义语句:inlx=10;,则表达式x-=x+x的值为(B)

A)-20B)-1()C)0D)10

(14)设有定义:inlx=2;,以下表达式中,值不为6的是(D)

A)x*=x+lx=x*(x+l)B)x++,2*x

C)x*=(1+x)D)2*x,x+=2

(17)若变量均已正确定义并赋值,以下合法的C语言赋值语句是(A)

A)x=y==5;B)x=n%2.5;C)x+n=lD)x=5=4+1;

2.7++和一一的讲解

++咱身加1

-:自身减1

i=3i++I=i+1i=4

单目

3++

++II++

当++在前,先自身加1,然后再干别人让干的事情。

当++在后,先别人让干的事情然后再干自身加1。

inti=3;

inta;

a=i++;a=3

a=++I;a=4

第三课:输入和输出语句

3.2输出语句的讲解

一、printf函数的一般调用形式

格式:printf(格式控制,输出项L输出项2,.……);

在printf函数的最后面写上;号就是输出语句。

1,给输出项白提供输出格式说明

格式说明符:

作用:就是使数据按格式说明符的要求进行输出。

组成:由%号和紧跟在其后的格式描述符组成。

int.....%d

float或double-%f或e%

char-....%c

2.提供原样输出的文字或字符

在“”中除了格式说明符之外的内容要全部原样输出。

各个输出项之间要用逗号隔开。

输出项可以是任意合法的常量,变量或表达式。

printf中常用的格式说明

在格式说明符中,每一个格式说明符都必须以%号开头由相应的类型标识字母结束。

但在他们之间可以有其它的一个内容:

%c:输出一个字符

%d:输出一个十进制的数据

%o:以八进制格式输出。

%X:以十六进制输出

%u:无符号十进制输出

%f:以带小数点的数字输出

%e:以指数形式输出

%s:输出一个字符串C

%%:输出一个%号

%4d:输出的数据长度是4个长度,当原来的长度大于4个时会自动突破。小于4个时会

填充空格。

%x.yf:x代表数制的宽度(包括小数点)。Y代表小数点后面的小数位数,

注意事项:

L输出比较自由一些,输出有的各个数之到底是什么,取决于格式说明符之间的内容。

2.格式说明符要与输出项一一对应。

3.输出语句中还可以有\n\r\t\a

4.尽量不要在输出语句中改变输出变量的值。

5.输出的数据中如果存在变量,一定要定义过的。

输入语句

格式:scanf(格式控制,输入项1,输入项2,…);

例如:想通过键盘输入3个数分别给变量a,b,c。并且他们分别为整型,浮点型,双精度

型。

输入语句为scanf("%d%f%lf',&k,&a,&y);

说明:

1.格式说明符与输出语句一样。

2.在格式串中,必须含有与输入项一一对应的格式转换说明符。

3.在VC6.0的环境下,要收输入的DOUBLE型数据的格式说明符一定要用%此否

则数据不能正确的输入

4.由于输入是一个字符流,所以当输入的数据少于输入项时,程序会等待用户输入,

直到满足要求。当输入的数据多于输入项时,多余的数据会自动作废。

复合语句:多个语句被{}括起来,当成一条语句来执行。

空语句:最后的表示只有一个;

程序举例:

lo编写一个程序,从键盘上输入两个数字,让后让他们互换一下。

#inckide<stdio.h>

main()

(

inta,b;

printf("请输入两个数字:");

scanf(n%2d%3d';&a,&b);

printfCqian:%d%d”,a,b);

intc;

c=a,a=b,b=c;

printf("后:%d%d',a,b);

1

2。编写程序,对一个double型数据进行四舍五入运算。要求保留两位有效小树。

123.4567

1234567*100=12345.67

12345.67+0.5=12346.17

(int)(12346.17)=12346

12346/100=123.46

第四课:C语言的程序结构

4-1节、关系运算与逻辑运算

一、简介

关系表达式与逻辑表达式的运算结果都会得到一个逻辑值。就是“真”、"假”

在C语言中0表示“假”,非0(无论是负数还是正数都是真,更多时候用1来代替)

表示“真

二、儿个简单的关系运算符

<<=>>===!=

注意:

1,由两个字符组成的运算符,中间不能有空格

2,它们都是双目运算符,具有自左至右的结合性。

3,上面的6个运算符中,前4个的优先级要比后2个的优先级要高。

先计算,后判断,最后进行赋值运算。

三、几个简单的逻辑运算符

&&与一假则假

II或一真则真

!非非假则真,非真则假

4-2、4-3节、if语句

一、定义:

只有两种结果。要么执行这条语句,要么执夕亍那条语句。

if(条件表达式)

上述条件成立执行的句子

else

上述条件不成立执行的句子

如:

if(成绩>60)

显示及格

else

显示不及格

二、分类

1.不含有else的语句

2.含有else语句

if(条件)

语句1;

else

(

语句2;

语句3;

}

注:

1.没有分号

2.控制的是与if或者else紧临的“一条”语句c

4-4节、结合一个例题来给大家分析if的嵌套

输入一个学生的成绩,评定他的等级。每十分一个等级

if()

elseif()

elseif()

else

if(a>=90)printf("a");

clseif(a>=80)printf(,,bH);

elseif(a>=70)printf("c");

elseif(a>=60)printf("dH);

elseprintf("e");

4-6节、条件表达式

是C语言中唯一的一个三目运算。

格式:表达式1?表达式2:表达式3

当1成立(非零时)时,表达式的值就是2的值,否则就是3的值。

如:

1.1<2?4:5

2.printf(',%du,x<0?(-l)*++x:x++);(假定X的值为-3)

3.++X>3?(x<3?a:b):b

4-7节、switch语句(一)

switch(表达式)

case常量表达式1:语句1

case常量表达式2:语句2

case常量表达式3:语句3

case常量表达式4:语句4

case常量表达式5:语句5

OOO

case常量表达式N:语句N

4-8节、switch语句(二)

switch(AZlO)

(

case10:printf("A");

case9:printf("A");

case8;printf("b");

case7;printf("c");

case6;printf(',dH);

default:printf("e");

第五课:循环结构

5-1>5-2节、while语句

一、格式:

while(表达式)

循环体

注:1:

2:

3:一条

while(a<3)l

{a+=s;2

s=a;3}

1.......100

inti=l,sum=();

while(i<101)

surn=sum+i++;

printf("%d",sum);

丛1开始加到哪个数时他们的和将超过1000?

inii=l,sum=0;

while(sum<1000)

{sum+=i;999+42=1041

i++;}4243

printf("%d",—i);

5-3节、do-while语句

dowhile()

格式:

do

循环体

while(表达式)

1235813

do

(

a3=al+a2;

al=a2;

a2=a3;

}while(a3<=1000);

1:1

2:;

5-4节、for语句(I)

for语句和for语句构成的循环结构

一、格式:

for(表达式1;表达式2;表达式3)

循环体

相当于while语句的

表达式1;

while(表达式2)

{

循环体;

表达式3;

)

k=0

for(;k<=10;)

{printf(u*");

k++;

)

intk=0;

whi!e(k<10)

(

printfC,*");

k+十;

注:

1:表达式可以省略,但分号不可以。

2:表达式可以是任意有效的C语言表达式

课后习题部分,笔记不再提供,请大家看教程。

第六课、字符型数据

6-1节、字符型常量

格式:'a,W…

要求:

1,单引号中的大写字母和小写字母代表不同的字符常量。

2.单引号中的空格也是一个字符常量,但不能是两个连续的单引号

3.字符常量只能用单引号括起来,不能用双引号。

转义字符

\n代表回车

''代表一个单引号’

\\代表一个'

\”代表一个双引号

注意:

1.转义字符常量,如'\141,只代表一个字符

2.反斜线后的8进制数可以不用0开头。如1中所讲的141就是一个8进制数。

0141

3.反斜线后的16进制数只可以用x开头,不可以用X开头。

字符串常量

格式:由双引号括起来的一串字符。

同时也要知道“A"和'A,是不一样的。

"A",A'

ACSII码

A65a97

匕',A'=32

6.2节、字符变量

格式:chara=,s,

6.3字符的输入和输出

Printf和scanf函数输出和输入字符

对于字符型数据的格式说明符是%c

Charc=,a,;

Printf(4k%c,,,c);

Chara,b,c,d;

Scanf("%c%c%c”,&a,&b,&c);

6-3节、程序举例

写出26个大写字母和他们的ASCII代码要求每行输出两组数据。

#include<stdio.h>

Main()

(

Charch;intI;

For(i=0;i<26:i++)

(

Ch=i+65;

If(i%2==0)

PrintR\");

PrintfC4c=%c,ASCII=%d,,,ch,ch);

)

)

在上面的程序中有对于字符的输入与输出,在C语言中也有另外的输入输出字符的

语句。

输入:变量名=getchar()

输出:pulchar(变量名)

第七章函数

7-1节、库函数

1.调用C语言标准库函数时要求的include命令行

Include命令行必须以#开头,系统提供的头文件以.h作为文件的后缀,文件名用一

对双引号或一对尖括号(需要注意include命令行不是C语句,因此不能在最后加分号)

2.标准库函数的调用

函数名(参数表)

如:putchar(ch)

(1)出现在表达式中的...ch=getchar()

(2)做为单独的语句完成某种操作。--printf(“********”);

7.2函数的定义和返回值

由于C语言中的定义的函数不能完成用户所有的要求,所以用户可以为自己定义函数

实现相应的功能。

7.2.1函数定义的语法

1:格式:

函数返回值的类型名函数名(类型名形式参数1,类型名形式参数2……)

(

说明部分

语句部分

I

2:函数名和形式参数都是用户命名的标识符。在同一个程序中,函数名必须唯一,

形式参数名只要在同一函数中唯一即可,可以与其他函数中的变量同名。

3:C语言规定,不能在函数的内部定义函数。

4:若在函数的首部省略了函数返回值的类型名,则说明该函数的返回值是int类

5:除了返回值类型为int类型的函数外,函数必须先定义后调用。

6:当没有函数返回值,则必须把函数定义成void类型。

例:编写求两个双精度数之和的函数。

doubleadd(doublea,doubleb)

(

doubles;

s=a+b;

returns;

)

7-2节、函数的返回值

函数的值通过return语句返回,

return表达式;

此表达式的值必须与函数首部所说明的类型一致,若类型不一致,则以函数值的

类型为准。需要注意的是,无论函数体中有多少个return语句,只能执行一次。

函数体内可以没有return语句,这时也必须定义函数为viod类型。

7-3节、函数的调用

7.3.1函数的两种调用方式

格式为:

函数名(实在参数表)

当实参的个数多于二个时,各实参用逗号隔开。实参的个数必须与调用函数中形

参的个数相周,类型一一对应匹配。

如没有形参,则形式为函数名()注意后面的小括号不能丢。

如题:

#include<stdio.h>

doubleadd(doublc,doublc);

main()

(

doublem,n,z;

scanf("%lf

z=add(m,n);

printf(<4%lf,,z);\

)

doubleadd(doublea,doubleb)

(

doubles;

s=a+b;

returns;

}

7.3.2函数调用时的语法要求

1.调用函数时,函数名必须与所调用的函数名字完全一致。

2.实参的个数必须与形参的个数一致。

3.C语言中规定,函数必须先定义后使用。

4c语言中,函数可以直接或间接的自己调用自己。称为递归调用

fac(n)=fac(n-l)*n

7-4节、函数的说明

在C语言中凡是未在调用前定义的函数,C编译程序都默认函数的返回值为int型。

对于返回值是其它类型的,若把函数的定义放在调用之后,应该在调用之前对函数进行

说明。

说明的格式:

类型名函数名(参数类型1,参数类型2.。”。)

也可以用以下格式

类型名函数名(参数类型1参数名1,参数类型2参数名2,……)

函数说明的位置:

一般为了让程序早点识别出程序中的定义好了的函数,一般将其放在程序的开始

部分

7-5节、调用函数和被调用函数之间的数据传递

一:三种格式进行传递

1.实在参数和形式参数之间进行数据传递

2.通过return语句把函数值返回调用函数

3.能过全局变量,但这不是一种好的方式,通常不提倡使用.

通过一个程序来看一下数据到底是怎样传递的。

#include<stdio.h>

viodtry(int,int,int);

main()

{

intx=2,y=3,z=0;

printfC(l)x=%dy=%dz=%d\n,,,x,y,z);

try(x,y,z);

printfCX4)x=%dy=%dz=%d\n,,,x,y,z);

)

voidtry(intx,inty,intz)

(

printf("(2)x=%dy=%dz=%d\n,,,x,y,z);

z=x+y;

x=x*x;

y=y*y;

printf(44(3)x=%dy=%dz=%d\n”,x,y,z");

)

屏幕上的结果是:

(1)x=2y=3z=0

(2)x=2y=3z=()

⑶x=4y=9z=5

(4)x=2y=3z=0

再来一个程序

#include<stdio.h>

viodswap(int,int);

main()

intx=10,y=20;

printfC(1)x=%dy=%d\n”,x,y);

swap(x,y);

printffc(4)x=%dy=%d\n,,,x,y);

)

voidswap(inta,intb)

(

intt;

printf("(2)a=%db=%d\n,,,a,b);

t=a;a=b;b=t;

printf("(3)a=%db=%d\n,\a,h);

1

程序运行结果

(1)x=10y=20

(2)a=10b=20

⑶a=20b=10

(4)x=10y=20

7.6程序应用举例

编写一个函数isprime(inta),用来判断自变量a是否为素数。若是素数,函数返回整数1,

否则返回0.

#include<stdio.h>

intisprimc(int)

main()

(

intx;

printff'cntcraintegernumbcr:,,);

scanfT%d”,&x);

if(isprimc(x))

printff4%disprime\n",x);

else

printf("%disnotprime\n>\x);

)

intisprime(inta)

(

inti;

for(i=2;i<=a/2;i++)

if(a%i==0)

return0;

return1;

}

编写函数myupper(ch),把ch中的小写字母转换成大写字母作为函数值返回,其他字

符不变。主函数中不断输入字符,用字符@结束输入,同时不断输出结果。

#inckide<stdio.h>

#include<ctype.h>

charmyupper(charch)

(

if(ch>=,a,&&ch<=,z,)

ch=ch-32;

returnch;

main()

(

chare;

whilc((c=gctchar())!=,@,)

(

c=myuppcr(c);

putchar(c);

)

)

编写函数统计输入字符的个数,用@字符结束输入,在主函数中调用此函数,输出统

计结果。

#include<stdio.h>

longcountch();

main()

(

longn;

n=countch();

printR“n=%ld\n”,n);

I

longcountch()

(

longcn;

fbr(cn=O;getchar()!=,@,;cn-H-)

returncn;

)

7/0--7/3节、课后习题

[7.1]以下说法中正确的是C

A)C语言程序总是从笫--个定义的函数开始执行

B)在C语言程序中,要调用的函数必须在main函数中定义

C)C语言程序总是从main函数开始执行

D)C语言程序中的main函数必须放在程序的开始部分

[7.2]以下函数的类型是C

A)与参数x的类型相同

B)void类型

C)int类型

D)无法确定

fff(floatx)

{printf("%d\n",x*x);)

[7.3]以下函数调用语句中,含有的实参个数是B

A)1B)2C)4D)5

func((exp1,exp2),(exp3,exp4,exp5));

17.41以下程序的输出结果是C

A)llB)200)21D)31

func(inta,intb)

{intc

c=a+b;

returnc;

)

main()

intx=6,y=7,7=8,r;

r=func((x-,y++,x+y),z-);

printf("%d\n",r);

)

[7.5]以下程序的输出结果是A

A)-lB)0C)1D)2

main()

{inti=2,p;

P=f(i,i+D;

printf("%d",p);

)

intf(inta,intb)

{intc;

c=a;

if(a>b)c=l;

elseif(a==b)c=0;

elsec=-l;

return(c);

[7.61以下程序的输出结果是D

A)()B)1C)6D)无定值

fun(inta,intb,intc)

{c=a*b;|

main()

{intc;

fnn(2,3,c);

printf("%d\n",c);

)

[7.7]以下程序的输出结果是A

A)5.B)3.C)4.D)8.25

doublef(intn)

{inti;doubles;

s=1.0;

for(i=l;i<=n;i++)s+=1.0/i;

returns;

)

main()

{inti,m=3;floata=0.0;

for(i=0;i<m;i++)a+=f(i);

printf("%f\n';a)L;

)

二、填空题

[7.8]以下程序的输出结果是___12.

unsignedfun6(unsignednum)

unsignedk=1;

do

k*二num%10;num/=10;}

while(num);

returnk;

)

main()

{unsignedn=26;

printf("%d\n",fun6(n);

)

[7.9]以下程序的输出结果是—9.0.

doublesub(doublex,doubley,doublez)

{y-=i.O;

z=z+x;

returnz;

)

main()

{doublea=2.5,b=9.0;

printf("%f\n",sub(b-a,a,a));

)

[7,10]以下程序的输出结果是—4.

funl(inta,intb)

{intc;

a+=a;b+=b;

c=fun2(a,b);

return

fun2(inta,intb)

{intc;

c=(a*b)%3;

returnc;

)

main()

{intx=ll,y=19;

printf("%d\n",fun1(x,y));

)

[7.11]下面pi函数的功能是,根据以下公式返回满足精度要求的的值.请填空

pi/2=1+173+1/3*2/5+1/3*2/5*3/7+1/3*2/5*3/7*4/9+...

doublepi(doubleeps)

{doubles=O.O,t=l.O;

intn;

for(—n=1—:t>eps;n++)

{s+=t;

t=n*t/(2*n+l);

)

return(2.0*_S);

)

[7,12]以下函数用以求x的y次方.请填空.

doublefun(doublex,inty)

{inti;doublez=l;

for(i=l;i<=y_;i+十)

returnz;

[7,13]以下程序的功能是计算5=51<!.请填空.

longf(intn)K=1

inti;longs;

s=_l;

fbr(i=l;i<=n;i++)s=_s*i

returns;

main()

longs;intk,n;

scanf("%d1&n);

s=_0—;

for(k=0;k<=n;k++)s=s+f(k)—;

printf(H%ld'jiH,s);

三、程序调试和编程题

[7,14]以下fun函数月以判断n是否是素数,fun函数中有逻辑错,请调试改正.

fun(intn)

{intk,yes;

for(k=2;k<=n/2;k++)

if(n%k==O)

returnyes=0;

yes=l;

returnyes;

第八章:指针变量

8.1变量的地址和指针:

在最开始的时候,一直给大家强调变量要先定义,后使用。为什么会这个样子?这

是因为,每当我们使用一个变量系统就必须要给他开辟一个存储单元。系统要对它的值

进行记录。每时每刻的记录。怎样进行记录呢?系统会自动的开辟一个地方将该变量监

督起来,观察和记录它的变化。这个地方多大放什么东西?这都要求我们提前和系统说

好。所以就有了变量要先定义在使用说法。其实变量定义的过程就是给他开辟存储空间

的过程。那么存储空间又是什么东西呢??

计算机种有一个硬件叫内存条,当我们提起这个硬件的时候往往都会说多大的。

1G2Q4G……这都是在说他的空间大小。计算机中的内存是以字节为单位的一片连续的

存储空间,每一个字节都有一个编号,这个编号就称为内存地址。如同旅馆的房间一样,

单人间,双人间等等,每个房间都有自己的编号。

内存中的空间是连续的,地址号也是连续的,并且都是用二进制数来表示的。

变量在定义的时候先要说明定义的类型。如:intk;doubleb;charch;等等如此的定

义。这样是在和电脑系统打招呼,我们是2人要一个两人间。目的就是告诉老板你的房

间要是两个人的空间。不能定的是2人间,结果来了3个人住;同时也不能定的2人间,

结果就你自己来了(末自己来说多花钱了)。

综上所述:变量的定义就是给变量开辟存储空间的过程。

intafloatb

a|ab|b|bb

跚是变微义的眼系螂随机微的地界空间。在结合我们在一开始讲的不同类

型的变量的大小,其实就是在说变量所占的内存单元的多少。

1()12就是整型变量a的首地址,1014就是浮点型变量b的首地址。

当要用到一个变量时,系统就会迅速的找到这个变量。所以在C程序中还有这样的一

个变量的存在,就是指针。

指针就是用来存放一个变量在内存中的地址,当要调用这个变量的时候能迅速的找

到。用来存放一个变量地址的变量就叫指针变量。

同时大家也要走出一个误区就是:指针变量之所以叫变量,就是因为它旦面所存放的

变量的地址也不断的变化的。指针是可以移到的。

8.2指针变量的定义和由针变量的基类型

一:格式:

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

int*pi.*pj:

与之前不一样的地方就是在变量的前面加了一个九*是一个说明符,用来说明该

变量是指针变量。*号省略的话就和普通的变量一样了。

又如:

int*pi;char*ch;inta;charc;

指针的作用都是一样的,都是用来存放地址的,为什么还要分类型的。原因就是指

针变量pi只能存放整型变量的地址,指针变量ch只能存放字符变量的地址。

如何让一个指针存放一个变量的地址呢?

pi=&a;ch=&c;

&叫取址符。*叫指针运算符。

能过以上的讲解在家一定对指针有了更进一步和了解。我们共同的回顾一下;

变量的定义就是给其开辟存储单元的过程。

任何一个变量都有自己的存储地址。

指针就是用来存放变量地址的。

指针也是一个变量。

指针也要一个地址。

那,

有没有能存放指针变量地址的一个对象呢?用该怎么称呼?

它是专门用来存放指针的地址的。

它就是指向指针的指针。

int**p,*s;

p=&s;

**p就是一个指向指针的指针。它里面只能存放同种数据类型的指针的地址。

8.3给指针变量赋地址值

一个指针变量可以通过不同的方式获得一个确定的地址值,从而指向一个具体的对象。

(在以后的课程中,每当一个指针中存放了一个变量的地址的时候,我们就说这个指针

指向了这个变量)。

intk=l,*q,*p;

q=&k;

q--------->i

这/口J以d:q指南了变4k;

q=&k+lq=&(k+1)这是错误的,指针q就是用来存放地址的,前两个例子不是。

同时:

&必须放在运葬对象的左边,而且运算对象的类型必须与指针变量的基类型相同。

2,通过指针变量获得地址值

可以通过赋值运算,把一个指针变量中的地址值赋给另一个指针变量,从而使这

两个指针指向同一地址。

intk,*p,*q;

q=&k;p=q;

也就是说指针变量p和q都指向了变量k.

注:当进行赋值运算时,赋值号两边指针变量的基类型必须相同。

3.给指针变量赋“空”值;

“空

null的代码值为0,当执行了以上和赋值语句后,称P为空指针。null的代码值为0.

p=''0'p=0;

注意:P并不是指向地址为。的存储单元,而是一个有确定的值“空”。

8.4对指针变量的操作

C语言提供了一个称作“间接访问运算符”的单目运算符:当指针变量中存放

[一个确切的地址值是,就可以用“间接运算预算符”通过指针来引用该地址的存储单

兀O

int*p,i=10,j;

p=&i;

则这样的赋值语句

j=*p;

上面的这个赋值语句我们可以这样理解:j变量的值是由指针指向的空间中的值赋予

的。这里的*P代表指针P中存放的变量i的地址中的值。*不是乘而是用来说明指针的说

明符。

J二[〜*'W〜***〜〜**wj=,|

如果有这样的表达式代表:

j=*p+l代表指针P指向的空间中中的值加1后的值给了变量j;

再如

int*p,k=();

p=&k;

*p=100;

*p+=l;

注意:当*p出现在赋值号左边时,代表的是指针所指的存储单元,当出*p出现在赋值

号右边时,代表的是指针所指的存储单元的内容。

如果有:

*p+=l

++*p

(*P)++

这三个表达式有什么不一样吗?

++和*两个运算符的优先级相同。但按自右至左的方向结合。因此++*p相当于++(*p)。

而在(*p)++中,一本括号不可以少,(*p)++代表先取里面的值然后再加1。而如果去

掉怎成了*P++,根据顺序,先++然后再取值。这样就成了先p++再取值。而P++就是指针

先向后移动。

例8,1

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

#include<stdio.h>

main()

(

inta,b,min,*pa,*pb,*pmin;

pa=&a;pb=&b;pmin=&min;

scanfC%d%d'',pa,pb);

printf(<4a=%d,b=%d\n,,,a,b);

*pmin=*pa;

if(*pa>*pb)

*pmin=*pb;

printf(4€min=%d\n,\inin);

I

8.4移动指针

所谓移动指针就是对指针变量加上减去一个整数,或通过赋值运算,使指针变量指向

相邻的存储单元。

(因此只有当指针指向一串连续的存储单元时,指针的移动才有意义)

a[0]a[l]a[2]a[3]a[4]

1122334455

p=&a[()f,

q=p+2

q++

q++

q--

p++

对指针进行加减运算时,数字“1”不再代表十进制数1,而是指一个单位存储单元长度。

这个单元到底多长,要看存储数据的类型了。

如果是int则代表1个存储单元长度就是位移4个字节。如果是char类型则代表1个

存储单元长度就是位移1个字节。如果变量的类型是double,8个字节为一个单位,而指

向它的指针是int,4人字节为一个单位。那么这个时候指针每移动一个单位就代表移动

4个字节的长度,这个时候读取数据的时候就会已错。

8.5函数之间地址值的传递

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

若函数的形参为指针类型,调用该函数时,对应的实参必须是基类型相同的地址值或

者是已指向某个存储单元的指针变量。

例题:编写函数myadd(int*a,int*b),函数中把指针a和b所指的存储单元中的两

个值相加,然后将和值作为函数值返回。在主函数中输入两个数给变量,把变量地址做

为实参,传给对应的形参。

#inckide<stdio.h>

intmyadd(int*a,int*b)

(

intsum;

sum=*a+*b;

returnsum:

}

main()

(

intx,y,z;

int

p=&x,q=&y;

printf(4tenterx,y:‘‘);

scanR"%d%d”,&x,&y);

z=myadd(*p,*q);

printf(ti%d+%d=%d,\x,y,z);

)

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

之前我们已经知道形参值的改变并不能改变本应实参的值,把数据从被调用函数返回

到调用函数的唯一途径是通过return语句返回函数值。

例题:调用swap函数,交换主函数中变量x和y中的数据

#include<stdio.h>

voidswap(int*,int*)

main()

(

intx=30,y=20;

printf(u(1)x=%dy=%d\n”,x,y);

swap(&x,&y);

printfT(4)x=%dy=%d\n”,x,y);

)

voidswap(int*a,int*b)

(

intt;

printfT⑵a=%db=%d\nM,*a,*b);

t=*a;*a=*b;*b=t;

printfCu(3)a=%db=%d\n,,,*a,*b);

)

例题:编写函数。rder(int*ajnt*b),使用函数中的第一个实参总是存放两个数中较

小的数,第二个参数存放两个数中较大的数

#include<sldio.h>

voidswap(int*xl,int*x2)

(

intt;

t=*xl;*x1=*x2;*x2=t;

1

voidorder(int*a,int*b)

{if(*a>*b)swap(a.b);

)

main()

(

intx,y;

printf("输入x,y:”);

scanf("%d%d”,&x,&y);

printf(t<x=%dy=%d\n”,x,y);

order(&x,&y);

printff'x=%dy=%d\n,,,x,y);

)

8.5函数返回地址值

函数值的类型不仅可以是简单的数据类型,而且可以是指针类型

例:以下函数把主函数中变量i和j中存放较大数的那个地址作为函数值传回。

第九章数组

之前我们只学过单个变量的定义,而有的时候就需要一片连续的存储单元。单个单个

的定义第一,分配的内存空间不一定连续,这样指针就不能移动了。第二,单个单个的

定义会费时费力。所以这个时候就需要一个东西来满足用用户这样一个需求。数组就在

这样的条件下产生了。

数组:多个相同类型的变量被存储在一片连续的存储单元中。

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

★一维数组的定义:

当数组中每个元素只带有一个下标时,称这样的数组为一维数组。

格式:类型名数组名【整型常量表达式】

如inta[10]

说明:

1.定义了一个名为a的一维数组

2.方括号中的10规定了a数组含有10个元素,它们是(a[0].a[lj.a[2].

a[3].a[4].a[5].a[6].a[7].a[8].a[9])

3.类型名int规定了a数组中每个元素都是整型,在每个元素中只能存放整形数。

4.每个元素只有一个下标,C语言规定每个数组第一个元素的下标总为。(称为数组

下界),那么最后一个9(称为数组的下标为上界)

5.在内存中给数组中每个成员开辟了一个存储单元。总计大小:10*4=40字节。这

样每当调用数组中的一个成员时就用它们的下标。如aW

注:当同时定义多个数组时彼此之间用,号隔开

如doublew[22],v[100],u[5];

以上定义了三个数组。

需要注意的是,【】中的内容只能是整型常量或整型常量表达式。如inta[ll+22]也可以。

★一维数组元素的引用

格式:数组[下标表达式]

其实x[0],x[j],x[i+k]都是对数组中元素的合法引用形式。但是需要注意的是下标

表达式的值必须大于或等于0,并且小于数组上界的数。

能过上面知识讲解,大家应该建立以下概念:

1:一个数组元素实质上就是一个变量名,代表内存中一个存储单元。一个数组占有

一串连续的存储单元。

2:在C语言中一个数组不能整体引用。不能说用一个数组名就代表整个数组了。这

是错误的。因为在C语言中规定数组名是一个地址常量,它代表整个数组的首地址。

int木p;inta[10]p-a(p-&a[0])a--&a[0]a-10

3:数组元素中下标表达式的值必须是整数。在编写程序时保证数组下标不越界是十分

重要的。

a[2.5]a[10]=123

★一维数组的初始化

一维数组的始化,其实就是给数组元素赋值。

格式:inta[8]=-:0,1,2,4,5,6,7}

所赋的值放在等号后的一对花括号中,数值类型必须必须与所说明的类型一致,所赋

值之间用逗号隔开。系统会按赋值顺序来自动分配。

当花括号中的值少于数组元素个数时,将自幼给数组后面元素赋值0.如

inta[10]={l}这个时候除了a[0]=l外,其它的都是0;

对于字符数组也是一样;

chara[10]={<1,)

不够的也会赋值'\0'

通过赋初值定义数组的大小

C语言中规定,可以通过赋初值来定义数组的大小,这时数组说明符的一对方括号中

可以不指定数组的大小。

如inta[]={l,1,1,1,1,1,1,1,1,1)

这样相当于数组中有了10个元素

例题:编写一个程序,通过键盘给数组a中的10个成员赋初值。

^include<stdio.h>

main()

(

inta[10];

inti,*p;

P二a;

for(i=0;i<10;i++)

{scanf("%d",p);

printf(“a[i]=%d",*p);}

)

编写一个程序定义一个含有30个成员的数组。并给其赋值,要求从1这样的奇数开始。

当赋值完毕后,按每行10个输出。

include<stdio.h>

ftdefinem30

main()

(

inta[m];

inti,k=l;

for(i=0;i<m;i++)

{a[i]=k;

k+=2;}

for(i=0;i<m;i++)

{printf(“a[%d]=%d",i,a[i]);

if((i+l)%10--0)

printf("\n");}

)

9.2一维数组和指针

★一维数组和数组元素的地址

前言:定义的数组名可以认为是一个存放地址值的指针变量名,其中的地址值是数

组第一个元素的地址,也就是数组所占一串连续存储单元的起始地址。重要的是:这个

指针变量中的地址值不可改变,也就是说,不可以给数组重新赋值。因此,也可以认为

数组名是一个地址常量。

如:floata[lC],*p,x;

语句a=&x或a++这样的语句都是非法的。因为不能给a重新赋地址值。一旦定义a永

远指向a数组的首地址。

虽然不可以改变数组名a中的内容,但可以用对数组名加一个整数的办法,来依次

表达该数组中不同元素的地址。

如:inta[10],*p;p=a+4~~~p=&a[4]

再如:for(k=0;k<10;k++)

p=a+k;

在循环中并没有改变数组名a中的内容,但通过表达式:a+k逐一给出了a数组中每个

元素的地址,使P依次指向a数组中和每一个元素。

如果要能过类似上面的语句给数组中的元素赋值,语句为:

for(k=0;k<10;k++)

scanf(“%d”,a+k);

如有p=a或p=&a[0]这两个表达式所要表达的意思是一样的。都是指指针P指向了数

组a的首地址。所以当要依次访问数组中的每一个元素时可以用以下的两个形式;

P++;

或a+k(k的值是不断变化的如上面的for语句一样)

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

a是数组元素的首地址,a(即a+0)的值即等于则用a+1的值等于

在以前我们学过“间接访问运算符”一一“钎来引用地址所在的存储单元。因此对

于数组a[0],可以用表达式*&a[0]来引用也可以用*(a+0),还可以用a[0]来表示。

但需要注意的是对于*(p+k)这样的表达式不能这样写*p+k,这样写的话就错了。代

表指针取值后再加K的值了。

总结:表示数组元素s[i]的表达式应当有

s[i]*(s+i)*(p+i)*p[i]

(但当p=s+2时,p=&a[2].*p[0]就是a[2]的值了)

9.3函数之间对一维数组和数组元素的引用

数组元素作实参

每个数组元素实际上代表内存中的一个存储单元,故和普通变量一样,对应的形参

必须是类型相同的变量。数组元素的值可以传送给该变量,在函数中只能太该变量进行

操作,而不能直接引用数组元素,更不能在函数中改变对应数组元素中的值。

数组名作实参

数组名也可以作为实参传送,但数组名是一个地址值,因此,对应的形参就应当是一

个指针变量,此指针变量的基类型必须与数组的类型一致。这样就可以通过指针变量来

引用调用函数中对应的数组元素,从而达到对调用函数中对应的数组元素进行操作而改

变其中的值。

例:编写程序,通过一个函数给主函数中定义的数组输入若干大于或等于0的整数,

用负数作为输入结束标志,调用另一个函数输出该数组中的数据。

ttinclude<stdio.h>

#defineM100

voidarrout(int

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论