期末复习C语言知识点归纳
一、概述部分
主要考察知识点:
C程序的结构特点;C程序的扩展名;程
序的开发过程;
函数的构成;
C语言使用的基本符号:ASCII字符集;
标识符的命名规则;
关键字、用户自定义标识符
1.C程序的基本模块是函数,一个C语言源程序可以由一个
或多个函数组成,有且只有1个main()函数,可以放在程序
中的任何位置.
2.函数的定义是平行的,不能嵌套定义,但可以进行嵌套
调用。
3.一个C程序不论有几个函数,都是从main()函数开始执
行.
4.C源程序文件的扩展名".c"。
++6.0下C语言程序的完整实现过程包括4个基本步骤:
编辑形成源文件(.c)
编译,形成目标文件(.obj)
链接,形成可执行文件(.exe)
运行.
6.函数的构成:变量定义、语句、注释
7.标识符
按照
C
语言所定义的规则来命名的符号,用作变量名、数组
名、函数名等,系统定义的关键字也遵循该规则。
规则:由字母、数字、下划线组成,第一个字符必须
是字母或下划线。
C
语言中的标识符分:关键字、用户定义标识符
例如
:area
、
a234
、
_1234
为合法标识符
6x
、
a-b
、
a+b
为非法标识符
注意
:
标识符区分大小写。
PRINTF
和
printf
是不同的标识符
用户自定义的标识符应避开
C
语言的关键字及库函数
名。
4.c语言的32个关键字:看附表,留印象
二、数据类型、常量、变量、表达式
注意:
常用数据类型的关键字;
常量的表达形式;
变量的定义及赋值;
各类表达式的计算规则;
不同数据类型数据混合运算时的类型转
换;
典型问题:数据的混合计算、整数的分
解、数据交换
1.数据类型
c语言中,整型、实型、字符型是最基本的数
据类型.
此外还有构造类型,如数组,结构体,共用体等。
2.常量
指在程序运行中,其值不能被改变。
分为整型常量、实型常量、字符常量、字符串常量。
整型常量
C
语言中主要有十进制、八进制、十六进制等:8进制以0
引导,16进制以0x或0X引导,十进制不能以0开头.
十进制例如12、-3、32767等。
八进制用数字0开头,由0-7这8个数字组成。
例如010、016为合法八进制数
127、018为非法八进制数
十六进制用数字0和字母x或X开头,用0-9表示前10
个数字,字母A-F(可小写)表示后6个数字。
例如0xAF、0x10、0x34为合法十六进制数
100、ABC、0xAFH为非法十六进制数
实型常量(float或double型)
表示方式有两种:小数形式和指数形式。
小数形式:
例如:0.123、.123、123.都是合法形式,为double型。
0.123F(float型)
指数形式:
例如:2.3026可用以下任何一种指数表示
0.23026E1
、
2.3026e0
、
23.026E-1
但下面的指数形式为非法
E3.5e3.6
字符型常量
一个字符常量占一个字节存储空间.用单引号限定。有普
通字符和转义字符。如:
普通字符:如
‘A’
、
’c’
、
’5‘
都是合法的字符常量。
转义字符:如
’n’换行’’反斜杠
’’’单引号’”’双引号
’ddd’三位八进制’xhh’二位十六进制
’
0x41
’
(表示以十六进制数41为ASCII码值的字符,即
’
A
’
的转义字符形式).
‘
0
’
(表示空字符,在字符串中用作字符串的结束标志)
注意:转义字符表面上由多个字符
组成,但在内存中只占1字节的空
间。
字符串常量
用英文双引号括起来.如:”hellon”
字符串中的字符个数称为字符串的长度.空字符串长度为
0.
字符串存储中每个字符占一个字节,字符串结尾自动加一
个结束标志符’0’,所以字符串存储的时候,占用的空
间长度要比串的实际长度多1.
strlen(“china”),求字符串的字
符个数,5(个)
sizeof(“china”),求字符串占用
的存储空间,6(字节)
注意下面两种情况:
(1)charch[100]={“Hello”};
该串的长度(字符个数)为5,但数组ch
的空间长度为100。
(2)charch[]={“Hello”};
该串的长度(字符个数)为5,但数组ch
的空间长度为6。
3.变量
指在程序运行过程中其值可以改变的量,表示存储数据的空
间,需要时要先定义。
变量的命名必须符合标识符的命名规则,且不能和
C
语言
中关键字同名。
(
例如
:main
是关键字
)
例如
:a
、
b
、
ab
、
a_1
为合法变量
define
、
printf
为非法变量
注意
:ab
是一个整体,含义不同于
a
乘以
b
。
变量定义,如:
intx,a1,a2;
charch1,ch2;
floatm;
doubles;
VC++6.0下,int型数据占4个字节,float型数据占4
个字节,double型数据占8个字节,.char型数据占
1个字节.
自加和自减运算符
例如:a++和++a等价于a=a+1
b--和--b等价于b=b-1
a++和++a的区别:
假设a的初值为5
表达式a++值为5,最后a值为6。
表达式++a值为6,最后a值为6。
条件运算
由"?"和":"构成,它是根据条件从两个表达式中选择一个
进行计算取值的操作,优先级高于赋值运算符,低于算术运
算和关系运算.
例如:inta=1,b=2,c=3,d=4,z;
z=(a>b)?c:d;结果:z值为4
三、输入输出函数
重点:输入输出的格式控制
1.数据输出printf
格式:printf(格式符,输出项1,输出项2,….)
格式符功能
%c输出一个字符
%d输出十进制整数
%f输出小数形式浮点数
%e输出指数形式浮点数
%s输出一个字符串
数据宽度说明:
1)在%和格式字符之间插入一个整数来指定输出宽度。
例如:%4d、%5c
2)对于float和double类型的实数,可以用n1.n2形式
n1指定输出数据的宽度(包括小数点),n2指定小数
点后小数的位数。
例如:%12.3f、%12.0f
题型:判断输出结果时格式的正确与否!
例1输出整型变量a和b的值,数据宽度均为4。
printf(“a=%4d,b=%4d”,a,b);
例
2
输出单精度变量
k
的值。
printf(“%10.2f”,k);
2.
数据输入
scanf
格式
:scanf(
格式符,输入项
1
,输入项
2
,
…)
格式符功能
%c
输入一个字符
%d
输入十进制整数
%f
输入单精度数
%lf
输入双精度数
%s
输入一个字符串
题型:判断输入数据时的格式正确与否!
例
1
从键盘上输入两个整数,保存在变量
a
和
b
中。
scanf(“%d%d”,&a,&b);
例
2
从键盘上输入一个双精度数,保存在变量
data
中。
scanf(“data=%lf”,&data);
键盘输入
23.5
,则输入格式应为:
data=23.5
3.
字符专用的
getchar
函数和
putchar
函数
分别用来输入字符和输出字符。
例
1
从键盘上输入一个字符保存在
ch
中。
charch;
ch=getchar();
例
2charc1=’A’,c2;
c2=c1+1;
putchar(c2);
输出结果是
’B’
。
例
3
输出一个回车换行符。
putchar(‘n’);
例
:
从键盘上输入一串字符,最后以
’!’
为结束标志。分别
统计大写字母,小写字母、数字出现的次数。
#include
main()
{
charch;
intn1=0,n2=0,n3=0;
printf(“
请输入一串字符以
!
结束
:n”);
ch=getchar();//
先输入一个字符
while(ch!='!')
{
if(ch>='A'&&ch<='Z')
n1++;
if(ch>='a'&&ch<='z')
n2++;
if(ch>='0'&&ch<='9')
n3++;
ch=getchar();//
继续输入下一个字符
}
printf("
大写字母出现次数是
%dn",n1);
printf("
小写字母出现次数是
%dn",n2);
printf(“
数字出现次数是
%dn",n3);
}
4.
字符串专用的输入输出函数
gets()
和
puts()
例如:
charstr[100];
gets(ch);//
输入一个字符串存入字符数组
str
puts(ch);//
输出字符数组
str
中存放的字符串
6
.复合语句
格式
:
{
语句
1
语句
2
….
语句
n
}
例
2若已经定义
inta,b;
且已赋值,要将
a
和
b
中的
数进行交换,下面选项中不正确的是
A){a=a+b,b=a-b,a=a-b}
B){t=a,a=b,b=t;}
C){a=t;t=b;b=a;}
D){t=b;b=a;a=t;}
结构化程序设计的三种基本结构:
顺序结构、选择结构(分支结构)、循
环结构
四、选择结构
注意:
条件表达式的构造;关系运算、逻辑运
算;
选择结构的基本语句:
if语句
if-el
if-el的嵌套结构(el与if的匹配
规则)
switch语句的语法要求,执行流程
1.关系运算符
>
、
<
、
>=
、
<=
、
==
、
!=
关系运算的结果只有两种
:
真或假
C语言中关系运算的结果为真用1表示,假
用0表示。
例
16>=6‘a’>’A’’1’<‘5’
结果均为真,值为
1
例
26!=6‘D’==’d’‘9’>’F’
结果均为假,值为
0
2.逻辑运算符
&&(
与
)||(
或
)!(
非
)
优先级
:!>&&>||
例
1
若变量
a
值为
10
,变量
b
值为
16
,计算表达式。
a>b||a>sqrt(b)&&b>=16
最后结果为真,表达式的值为
1
3.
条件表达式的构造:
注意:
数学上的表达式:0≤x≤10
在C程序中的表达:x>=0&&x<=10
判断char型变量ch中存放的是大写字母或小写字母:
判断整数n能否被整除m整除:
判断年份是否是闰年:
语句
单分支结构:
if(条件表达式)语句
若表达式为真,则执行语句;否则if语句结束。
注意:
条件表达式可以是常量、变量、关系
表达式、逻辑表达式
当常量、变量、关系表达式、逻辑表
达式的取值不是0的时候,条件为真;
若取值为0,则条件为假。
-el:二选一
if(条件表达式)
{语句组1}
el
{语句组2}
表达式的值非0表示真,执行语句组1;否则,执
行语句组2.
例1从键盘上输入两个整数,输出较大的数。
#include
main()
{
intx,y;
printf(“请输入两个整数:n”);
scanf(“%d%d”,&x,&y);
if(x>y)
printf(“%d”,x);
el
printf(“%d”,y);
}
语句的嵌套
多选一结构:
if(表达式1)
{语句组1}
elif(表达式2)
{语句组2}
elif(表达式3)
{语句组3}
el
{语句组n}
注意:
el与if的配对规则:
el总是与它前面的、最近的、没有
与其他el进行配对的if进行配对。
例
1
根据输入的学生成绩,大于或等于
90
分为
A
,
60
分以下等级为
E
,其余每
10
分一个等级。
#include
main()
{
intg;
printf(“
请输入一个整数
:n”);
scanf(“%d”,&g);
if(g>=90)printf(“An”);
elif(g>=80)printf(“Bn”);
elif(g>=70)printf(“Cn”);
elif(g>=60)printf(“Dn”);
elprintf(“En”);
}
语句
一般格式:
switch(表达式)/*switch表达式为整
型或字符型值!*/
{
ca常量1:语句组1/*ca后面必须是
常量或常量表达式!*/
ca常量2:语句组2
.........
default:语句组//也可省略该语句
}
可以使用break语句来中止后面语句的执行.
switch表达式通常为整型或字符型值,ca中的常量类
型与之对应,ca后面的表达式可以是常量或常量表达
式,不能为变量表达式.
若表达式的值与表达式1相等,则执行语句1;若与表达
式2相等,则执行语句2……若均不相等则执行语句n。
例1分析switch语句的执行
#include
main()
{
intg=3;
switch(g)
{
ca1:printf(“****n”);break;
ca2:printf(“
n”);break;
ca3:printf(“&&&&n”);
ca4:printf(“@@@@n”);break;
ca5:printf(“$$$$n”);break;
default:printf(“~~~~n”);
}
}
程序运行结果:&&&&@@@@
五、循环结构
注意:
三种循环语句:
while语句、do-while语句、for语句
语法格式,流程理解;运用;while循
环和do-while循环的区别
典型问题:
一组有规律的数的求和、求积数、
素数判断(特别重要)
循环
格式
:
while(
条件表达式
)
循环体
若条件表达式为真,则执行循环体。再判断表达式,若仍为
真,则重复执行循环体直到表达式为假时循环结束。
注意:
条件表达式可以是常量、变量、关系
表达式、逻辑表达式
当常量、变量、关系表达式、逻辑表
达式的取值不是0的时候,条件为真;
若取值为0,则条件为假。
例
1
编程计算
S=1+2+……100
。
#include
main()
{
intk=1
;
s=0;//
和数变量初始值为
0
,切记!
while(k<=100)
{s=s+k;
k=k+1;//
循环变量变化,必须的!
}
printf(“%d”,s);
}
-while循环
格式
:
do
循环体
while(
表达式
);
先执行循环体,然后判断表达式。若为真则重复执行
循环体直到表达式为假时循环结束。
例
1
用
do-while
循环计算
10!
#include
main()
{
intk=1;
doubles=1;//
积数变量初始值为
1
,切记!
do
{s=s*k;k++;}
while(k<=10);
printf(“%ld”,s);
}
注意:while循环和do-while循环
的区别
while循环是先判断表达式,因
此循环体有可能一次也不执行。
do-while循环是先执行一次循
环体,再判断表达式,所以不论
表达式为真为假,循环体至少要
执行一次。
循环
格式
:
for(
表达式
1;
表达式
2;
表达式
3)
循环体
先执行表达式
1
,然后判断表达式
2
,若为真则执行
循环体。然后执行表达式
3
,再判断表达式
2
,若仍
为真则重复执行循环体直到表达式
2
为假时结束。
例
1
用
for
循环计算
S=1+2+…100
。
#include
main()
{
intk,sum=0;
for(k=1;k<=100;k++)
sum=sum+k;
printf(“%d”,sum);
}
例
2
若一个三位数个位、十位、百位的立方和等于它本身
则称这个数为水仙花数。例如
153
是一个水仙花数。
编程输出所有的水仙花数。
#include
main()
{
inta,b,c,i;
for(i=100;i<=999;i++)
{
a=i/100;
b=i%100/10;
c=i%10;
if(a*a*a+b*b*b+c*c*c==i)
printf("%dn",i);
}
}
4.令循环中断的break语句
break语句可以用在switch语句中用于结束某分
支的执行,也可用在循环语句中,使循环提前结束。
用在循环体内表示强行退出循环。
例1计算S=1+2+3+…n,直到累加和大于5000为止。
#include
main()
{
inti,s=0;
for(i=1;;i++)
{
s=s+i;
if(s>5000)break;
}
printf(“%d”,s);
}
注意:当有多重循环时,break只能退出最内层循环。
素数判断的算法!
ue语句
用在循环体中用来跳过本次循环余下的语句,立即开
始下一轮循环的判断和执行,整个循环并未因
continue
结束。
例
1
写出下列程序运行结果。
inti,k=0,s=0;
for(i=1;i<=5;i++)
{
s=s+i;
if(s>5)
{printf(“i=%d,s=%d,k=%dn”,i,s,k);
continue;
}
k=k+s;
printf(“i=%d,s=%d,k=%dn”,i,s,k);
}
运行结果
:
i=1,s=1,k=1
i=2,s=3,k=4
i=3,s=6,k=4
i=4,s=10,k=4
i=5,s=15,k=4
六、数组
注意:
数组的定义和初始化、数组与循环的结
合、数组的应用(如:最大值最小值问
题、)、字符串与字符数组
数组是包含多项相同类型数据的一种数据结构,它使用同一
个名字命名,再用下标进行分量标识.数组元素的下标从0
开始,数组长度为n时,最末元素的下标是n-1.
1.
定义一维数组
一维数组定义格式
数据类型数组名[数组长度];
//数组长度指数组中可以存放的数据元素的个数,用整数
常量表示,也可用代表一个正整数的符号常量表示
例
1
定义一个包含
4
个整数的数组
a
inta[4];
例
2
定义一个包含
3
个双精度数的数组
b
doubleb[3];
注意
:C
语言中数组的下界从
0
开始计数。
例如
:a[4]
的
4
个元素分别为
a[0]
、
a[1]
、
a[2]
、
a[3]
数组有一维数组,二维数组,和多维数组.数组中的每一个分
量称为一个数组元素。
2.
数值型一维数组的初始化
用一对大括号将数组的初值括起来。
例如:inta[6]={10,20,30,40,50,60};
注意:C语言中,不允许初值个数多于数组定义的长度。
inta[]={10,20,30,40,50,60};
给初值的情况下,数组的长度可省略,系统以初值的个数作
为数组的长度。
对部分元素的初始化,例如:inta[6]={10,20,30}是对前
3个元素的赋值.
例1inta[3]={1,2,3};
此例中a[0]值为1、a[1]值为2、a[2]值为3
例2inta[5]={0};
此例中数组a的全部元素值均为0
例3inta[3]={1,2,3,4};
此例中由于初值个数多于数组元素个数,所以非法。
例
4inta[]={0,0,0,0};
此例中省略数组元素个数,初值为
4
个
0
等价于
inta[4]={0};
注意
:
数组名是一个常量值,不能对它赋值。
例如
:inta[3];
a=5;
此语句非法,应改为
a[0]=5;
3.一维数组应用
例1从键盘上输入10个整数,输出最大数和最小数。
#include
main()
{
inta[10],i,max,min;
printf("
请输入
10
个整数
:n");
for(i=0;i<=9;i++)
scanf("%d",&a[i]);
max=a[0];
min=a[0];
for(i=1;i<=9;i++)
{
if(a[i]>max)max=a[i];
if(a[i]
}
printf("
最大数是
%dn",max);
printf("
最小数是
%dn",min);
}
例2斐波数列的定义如下:
1、1、2、3、5、8、13、……
编程输出斐波数列的第40项值。
#include
main()
{
longa[40];
inti;
a[0]=1;
a[1]=1;
for(i=2;i<=39;i++)
a[i]=a[i-1]+a[i-2];
printf("%ld",a[39]);
}
4.
字符数组
字符串用字符数组存放。每元素存放一个字符.
如:
charch[]={'x10','x21','x1f','x5a'};
该数组中的初值字符为转义字符。
字符串
用双引号将一串字符括起来称字符串。如:
”Hello,world!”
C
语言中用一维数组来存放,并以
’0’
作为结束标志。
‘0’
就是
0
,占用空间但不计入串的实际长度。
例如
:
字符串
”student”
的长度为
7
,占用空间为
8
通常利用字符数组存放字符串。如:
charstr[20]={"hello"};
该字符串的实际长度为5个字符,占用的数组空间长度为20
'0'是字符串的结束标志.系统在存放一个字符串时,会在
串的最后一个字符后添加'0'。
任何一个一维数组在内存中都占用一段连续的空间.
用"%s"格式输入字符串时,遇到回车键结束,但获得的字
符中不包含回车键本身,而是在字符串末尾添加'0'.
使用一个一维scanf()函数使用"%s"格式输入多个字符
串时,输入的各字符串之间要以空格键分隔.
如:charch[20];
scanf(“%s”,ch);//从键盘输入一个字符串存入数组ch
用%s格式符为一个字符数组输入字符串时,只有第一个
空格之前的字符串被读入到字符数组中.
如:对上面的ch数组,输入“Helloworld!”则只有空
格前面的“Hello”被存入数组。
字符串常用函数
使用下列函数时要包含头文件
1)字符串拷贝函数
strcpy(s1,s2)
表示将s2复制到s1中。
2)字符串连接函数
strcat(s1,s2)
表示将s2连接到s1后面形成一个新字符串。
3)字符串长度函数
strlen(s)
计算出
s
的实际长度不包括
’0’
。
4)
字符串比较函数
strcmp(s1,s2)
若
s1>s2,
函数返回值大于
0
若
s1=s2,
函数返回值等于
0
若
s1
函数返回值小于
0
字符串应用
例
1
从键盘上输入一个字符串,输出它的长度。
#include
#include
main()
{
char*p,str[100];
p=str;
printf("
请输入一个字符串
:n");
gets(p);
printf("%d",strlen(p));
}
5.定义二维数组
定义格式
:
类型名数组名
[
一维上界
][
二维上界
]
例
1
定义一个
2
行
2
列的整型数组
a
inta[2][2];
此例中数组
a
共有
4
个元素,分别是
a[0][0]
、
a[0][1]
、
a[1][0]
、
a[1][1]
。
例
2
定义一个
4
行
4
列的整型矩阵
a
inta[4][4];
二维数组的初始化
用嵌套的大括号将数组初值括起来。
例
1inta[4][3]={{1,2,3},{4,5,6},{7,8,9},{10,11,12}};
例
2inta[4][3]={{1,2},{4,5},{7},{10}};
此例中系统自动给空缺的地方补
0
例
3inta[4][3]={{1,2},{4,5}};
系统自动给后面的行补初值
0
例
4inta[4][3]={1,2,4,5};
此例中数组
a
的第一行中元素和第二行的第一个
元素依次为
1,2,4,5
其余全部为
0
定义二维数组大小
例
1inta[][3]={{1,2,3},{4,5},{6},{8}};
有
4
个行花括号
,
因此说明是
4
行
3
列。
例
2inta[][3]={1,2,3,4,5};
表示一个
2
行
3
列数组。
定义并初始化二维数组时,数组的列
数(第二维)不能省略!
如:
inta[2][]={{1,2},{3,4,5}};是错误的。
二维数组应用
例:从键盘上输入5个学生3门课程的成绩,分别计算
每个学生的平均分和每门课程的平均分。
#include
#defineM5
#defineN3
main()
{
inta[M][N],i,j,sum;
printf("请输入15个分数(0-100):n");
for(i=0;i<=M-1;i++)
for(j=0;j<=N-1;j++)
scanf("%d",&a[i][j]);
printf("每个学生的平均分n");
for(i=0;i<=M-1;i++)
{
sum=0;
for(j=0;j<=N-1;j++)
sum=sum+a[i][j];
printf("%4d",sum/N);
}
printf("n");
printf("
每门课程的平均分
n");
for(i=0;i<=N-1;i++)
{
sum=0;
for(j=0;j<=M-1;j++)
sum=sum+a[j][i];
printf("%4d",sum/M);
}
}
七、函数
注意:
函数的种类:库函数、自定义函数;
函数的定义;
函数的参数:形参、实参、参数的个数;
函数的类型;
函数的声明;
函数调用过程中参数传递问题;
1.函数的定义
带返回值的函数
格式
:
类型名函数名
(
参数列表
)
{
语句
return
返回值
}
例
1
已知
F(X)=2*X+3
,计算
F(1)+F(2)+….F(10)
的值。
#include
intf(intx)
{
return2*x+3;
}
voidmain()
{
inti,sum=0;
for(i=1;i<=10;i++)
sum=sum+f(i);
printf("%d",sum);
}
例
2
编程输出
2
至
100
之间所有的素数之和。
#include
intisprime(intnum)
{
inti;
for(i=2;i<=num-1;i++)
if(num%i==0)
return0;
return1;
}
voidmain()
{
inti,sum=0;
for(i=2;i<=100;i++)
if(isprime(i)==1)
sum=sum+i;
printf("%d",sum);
}
例
3
从键盘上输入两个整数,分别输出它们的最大公约数
和最小公倍数。
#include
intgetmax(inta,intb)
{
intresult;
result=a
while(a%result!=0||b%result!=0)
result=result-1;
returnresult;
}
intgetmin(inta,intb)
{
intresult=1;
while(result%a!=0||result%b!=0)
result=result+1;
returnresult;
}
voidmain()
{
inta,b;
printf("
请输入两个整数
:n");
scanf("%d%d",&a,&b);
printf("
最大公约数是
%dn",getmax(a,b));
printf("
最小公倍数是
%dn",getmin(a,b));
}
不带返回值的函数
格式
:
void
函数名
(
参数列表
)
{
语句
}
函数的类型
表示函数返回值的类型,是函数定义
时,函数名前面的标识符,若缺省,则
系统默认为int型。
函数调用过程中的传值和传地址
传值是指子程序中变量的变化不会影响主程序变量。
传地址是指子程序中变量的变化会影响主程序变量。
例
1
交换两变量
a
和
b
的值。
(
传值方式
)
#include
voidchange(inta,intb)
{
intt;
{t=a;a=b;b=t;}
}
voidmain()
{
inta=3,b=5;
printf("a=%db=%dn",a,b);
change(a,b);
printf("a=%db=%dn",a,b);
}
运行结果
:
a=3b=5
a=3b=5
函数
change(inta,intb)
为传值方式,最后
a
和
b
的值
并未交换。故传值方式不能改变主程序变量的值。
例
2
交换两变量
a
和
b
的值。
(
传地址方式
)
#include
voidchange(int*a,int*b)
{
intt;
{t=*a;*a=*b;*b=t;}
}
voidmain()
{inta=3,b=5;
printf("a=%db=%dn",a,b);
change(&a,&b);
printf("a=%db=%dn",a,b);
}
运行结果
:
a=3b=5
a=5b=3
函数
change(int*a,int*b)
为传地址方式,最后
a
和
b
的值
成功交换。故传地址方式能改变主程序变量的值。
八、指针
指针变量初始化的方法inta;
int*p=&a;
赋值语句的方法inta;
int*p;
p=&a;
不允许把一个数赋予指针变量,故下面的赋值是错误
的:int*p;p=1000;被赋值的指针变量前不能再加“*”
说明符,如写为*p=&a也是错误的。
通过指针变量获得地址值
通过赋值语句将一个指针变量的值赋给另一个指针变量。
如:int*p,*q,a=0;
p=&a;
q=p;
则指针变量p和q保存的是同一个变量a的地址,即p
和q指向同一个整型变量。对p指向的变量的操作也就是对
q指向的变量的操作。
如:*p++;printf(“%d”,*q);的输出结果为1。
给指针变量赋“空”值
在stdio.h头文件中,系统定义了一个符号常量NULL,
其值为0,可通过给指针变量赋一个“空”值(即0值),使
其不指向任何内存单元,方法为:
p=NULL;或p=0;或p=’0’;
指针变量定义及赋值,举例:
例
1
定义两个指向整型变量的指针
p1
和
p2
。
int*p1,*p2;
例
2
定义两个整型变量
m
和
n
及两个指针
p
和
q
,并使
p
和
q
分别指向
m
和
n
。
intm,n,*p,*q;
p=&m;
表示
p
存放变量
m
的地址
q=&n;
表示
q
存放变量
n
的地址
例
3
定义一个包含
10
个整数的数组
a
和一个指针
p
,并
使
p
指向
a
。
inta[10],*p;
p=a;
表示
p
指向数组
a
的首地址,即
a[0]
的地址。
注意
:
例
3
中
p=a
不能写成
p=&a
,因为
a
本身就是地址。
例
3
指针间的赋值
假设已有下列定义
:
int*q,*p,k=0;
q=&k;
例如
:p=q;
表示两指针间赋值,读作
p
指向
q
。
此时
p
和
q
均指向变量
k
的地址。
例
4
空指针
在
C
语言中空值用
NULL
表示,其值为
0
例
5
定义指针时可以给指针赋值
NULL
例如
:int*p=NULL;
表示
p
没有指向任何地址
等价于
p=’0’;
或
p=0;
注意
:
此时指针
p
没有实际单元,所以暂时不能访问。
例
6
通过指针引用存储单元
假设已有下列定义
:
int*p,m,n=0;
p=&n;
例如
:m=*p;
表示将
p
指向存储单元内容给变量
m
等价于
m=n;
*p=*p+1;
等价于
n=n+1;
注意
:*p=*p+1;
还可以写成下面的形式
*p+=1;
或
++*p;
或
(*p)++;
例
7
指针的移动
当指针指向一片连续空间时,移动才有意义。
假设已有下列定义
:
inta[5],*p,*q,k;
p=a;
例如
:q=p+2;
表示将
q
指向元素
a[2]
的地址
p++;
表示将
p
向后移一个单元
q--;
表示将
q
向前移一个单元
k=p[2];
等价于
k=a[3];
例
8
指针的比较
若两指针指向一片连续空间,可比较大小。
假设已有下列定义
:
inta[10],*p,*q,k;
p=a;
q=p+2;
例如
:if(p
小于
q”);
由于条件成立,所以输出
p
小于
q
。
k=q-p;
表示
p
和
q
之间相差的元素个数
最后
k
值为
2
函数之间地址值的传递
1)形参为指针变量时实参和形参之间的数据传递
在函数调用过程中,主调函数通过实参传递给被调函数的
形参,这种调用称为传值调用。形参的改变不会影响实参。
如果实参传递给形参的不是普通变量,而是地址,则形参
和实参指向的实际上是同一个内存单元,形参指向的存储
单元的改变,也就是实参指向的存储单元的改变。这种将
地址作为参数传递的调用方式称为传引用调用。
例:
传值调用:
main()
{
inta=1,b=2;
fun(a,b);
printf(“%d,%d”,a,b);
}
voidfun(intp,intq)
{
intt;
t=p;p=q;q=t;
}
输出结果:1,2输出结果:2,1
传引用调用时应当注意实参的基类型必须与形参的基类
型一致。
通过这种方式,可以在被调函数中直接改变主调函数中变
量的值。
传引用调用:
main()
{
inta=1,b=2;
fun(&a,&b);
printf(“%d,%d”,a,b);
}
voidfun(int*p,int*q)
{
int*t;
t=p;p=q;q=t;
}
函数返回地址值
函数的返回值不光可以为基本类型,还可以为指针类型,
即可以定义返回指针的函数,称为指针型函数。
其一般定义形式如下:
基类型*函数名(形参表)
{
函数体
}
其形参一般为指针。
注意:在被调函数中定义的变量属于局部变量,其生存期
为函数执行过程中。当被调函数执行完返回主调函数中时,
被调函数中定义的变量将不再存在。所以,如果被调函数返
回的地址是被调函数中定义的变量的地址,则返回的地址值
无效。
指针的应用
例
1
从键盘上输入两个整数,输出较大数。
(
要求使用指针
)
#include
main()
{
inta,b,*p,*q;
p=&a;
q=&b;
printf("
请输入两个整数
:n");
scanf("%d%d",p,q);
if(*p>*q)
printf("%d",*p);
el
printf("%d",*q);
}
例
2
从键盘上输入
10
个整数,输出最大数和最小数。
#include
main()
{
inta[10],*p,k,max,min;
p=a;
printf("
请输入
10
个整数
:n");
for(k=0;k<=9;k++)
scanf("%d",&p[k]);
max=p[0];
min=p[0];
for(k=1;k<=9;k++)
{
if(p[k]>max)max=p[k];
if(p[k]
}
printf("
最大数是
%dn",max);
printf("
最小数是
%dn",min);
}
九、指针处理字符串
例1定义一个未知长度的字符串s。
char*s=”Hello”;
此例采用指针方式,
s
指向字符串
”Hello”
的起始地址
字符串的赋值
假设已有下列定义
:
char*sp,s[6];
例
1
给
sp
赋值
”hello”
,让指针变量
sp
指向字符串。
sp=”hello”;
例
2
给字符数组
s
赋值
”hello”
。
strcpy(s,”hello”);
表示将
”hello”
复制到
s
中
例
3
给字符数组
s
赋值
”student”
。
strcpy(s,”student”);
此例语法上没有错误,但数组
s
空间不够,最后
会产生错误结果。
注意:
1)例2不能写成s=”hello”;因为s是数组名即地址常量,
故不能直接赋值。
2)strcpy为字符串函数,需要包含头文件
字符数组的单独赋值
例
1charstr[10]={‘s’,‘t’,‘r’,‘i’,‘n’,‘g’,‘!’,‘0’};
此例中数组
str
共
10
个元素
,
最后
2
个元素也是
’0’
此字符串共占
10
个空间,实际长度为
7
。此例中
若省略
’0’
效果相同。
例
2charstr[]={‘s’,‘t’,‘r’,‘i’,‘n’,‘g’,‘!’,‘0’};
此例定义一个包含
7
个字符的字符串,最后一个
’0’
不能省略。此时
str
可以作为字符串使用。
例
3charstr[]={‘s’,‘t’,‘r’,‘i’,‘n’,‘g’,‘!’};
此例只是定义一个
7
个字符的数组,但由于没有
’0’
str
不能作为字符串使用,否则会产生错误。
例
9
字符数组的整体赋值
例
1charstr[10]={“string!”};
charstr[10]=”string!”;
以上两种写法都是合法的,效果相同。
例
2charstr[7]=”string!”;
这种方法虽然语法上没有错,但由于
’0’
没有放入
注意:
数组中,可能会产生错误结果。
将上述语句改为charstr[]=”string!”;
就完全正确了,系统自动计算数组大小。
这种写法简单又不会出错,推荐使用。
例
10
字符串的输入和输出
使用
scanf
和
printf
时,格式符均为
%s
。
例
1charstr[15];
scanf(“%s”,str);
表示将输入的一串字符依次存放在
str
中。
例
2charstr[15];
scanf(“%s”,&str[3]);
表示将输入的一串字符从第
4
个元素的地址开始
依次存放。
例
3charstr[15],*p;
p=str;
scanf(“%s”,p);
这和例
1
功能相同,只是使用指针方法。
例
4charstr[]=”student”;
printf(“%s”,str);
表示输出整个字符串
str
的内容。
字符串应用
例
1
从键盘上输入一个字符串,输出它的长度。
#include
#include
main()
{
char*p,str[100];
p=str;
printf("
请输入一个字符串
:n");
gets(p);
printf("%d",strlen(p));
}
例
2
从键盘上输入一个字符串,输出其反字符串。
方法一
(
单个输出法
)
#include
#include
main()
{
chars[100];
inti;
printf("
请输入一个字符串
:n");
scanf("%s",s);
for(i=strlen(s)-1;i>=0;i--)
printf("%c",s[i]);
}
方法二
(
整体输出法
)
#include
#include
main()
{
chars1[100],s2[100];
inti,j=0;
printf("
请输入一个字符串
:n");
scanf("%s",s1);
for(i=strlen(s1)-1;i>=0;i--)
s2[j++]=s1[i];
s2[j]='0';
printf("%s",s2);
}
本文发布于:2023-03-03 12:51:37,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/zhishi/a/1677819098121003.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:c语言知识点.doc
本文 PDF 下载地址:c语言知识点.pdf
留言与评论(共有 0 条评论) |