声明,本文仅用于本人复习参考,若因抄袭本文内容引发其他事故,均与本人无关
目录
1.顺序结构编程练习
顺序结构是C语言中的基本控制结构,指的是程序从上到下按顺序执行每一条语句。每条语句执行完成后,程序会自动跳转到下一条语句,直到程序结束。这种结构不包含条件判断或循环,适用于简单的、线性的操作。
7-1交换a和b的值
交换变量a,b的值,如输入a的值为1,b的值为5,则输出a的值为5,b的值为1。
输入格式:
输入两个整数,之间用一个空格间隔。
输出格式:
在一行中按照“a=x,b=y”的格式输出,其中x和y均是原样输出,不加宽度控制。
#include<stdio.h>
int main()
{
int a,b,c;
scanf("%d %d",&a,&b);
printf("a=%d,b=%d",b,a);
return 0;
}
7-2计算圆球体积
设圆球的半径为r,计算并输出圆球体积v。输出结果保留2位小数。提示:计算圆球的体积公式为:v=3/4*π*r^3 (π=3.14)
输入格式:
输入第一行给出一个正整数半径r(0< r ≤ 100)。
输出格式:
圆球的体积v保留两位小数。
#include<stdio.h>
#include<math.h>
int main()
{
int r;
double v,pi;
pi=3.14;
scanf("%d",&r);
v=pi*r*r*r*4/3;
printf("v = %.2lf",v);
return 0;
}
7-3求算式
编程求。从键盘输入a和x,输出结果保留2位小数。
输入格式:
从键盘输入a和x的值,中间用空格分隔。
输出格式:
输出结果保留2位小数。
#include<stdio.h>
#include<math.h>
int main()
{
double a,x,y,e;
e=2.71828;
scanf("%lf %lf",&a,&x);
y=sqrt(a*x)+log(a+x)/log(e)+pow(e,x);
printf("y = %.2lf",y);
return 0;
}
7-4心理阴影面积
这是一幅心理阴影面积图。我们都以为自己可以匀速前进(图中蓝色直线),而拖延症晚期的我们往往执行的是最后时刻的疯狂赶工(图中的红色折线)。由红、蓝线围出的面积,就是我们在做作业时的心理阴影面积。
现给出红色拐点的坐标 (x,y),要求你算出这个心理阴影面积。
输入格式:
输入在一行中给出 2 个不超过 100 的正整数 x 和 y,并且保证有 x>y。这里假设横、纵坐标的最大值(即截止日和最终完成度)都是 100。
输出格式:
在一行中输出心理阴影面积。
友情提醒:三角形的面积 = 底边长 x 高 / 2;矩形面积 = 底边长 x 高。嫑想得太复杂,这是一道 5 分考减法的题……
#include<stdio.h>
int main()
{
int x,y,a;
scanf("%d %d",&x,&y);
a=x-y;
int s;
s=100*a/2;
printf("%d",s);
return 0;
}
7-5 定期存款
客户到银行存 1 年期的定期存款。请编写程序, 输入存款金额和 1 年期定期存款利率(百分数), 计算并输出本金、到期利息和本息合计金额。
输入格式
存款金额
利率
注:存款金额小于100万元,利率为百分数,低于10%。
输出格式
本金
利息
合计
注:本金、利息和合计精确到分(四舍五入),按小数点对齐。
#include<stdio.h>
int main()
{
double x,y,z,sum;
scanf("%lf %lf",&x,&y);
z=x*y*0.01;
sum=z+x;
printf("本金:%11.2lf元\n利息:%11.2lf元\n合计:%11.2lf元",x,z,sum);
return 0;
}
2.选择结构编程练习
选择结构允许程序根据条件的不同执行不同的代码块。C语言中,主要有if
语句、if-else
语句、if-else if-else
链以及switch
语句。这些结构让你可以根据不同的条件或情况来控制程序的执行路径,从而实现更复杂的逻辑。
7-1 分段函数
根据如下分段函数,输入的x的值,输出对应的y值。
输入格式:
输入x的值。
输出格式:
输出对应的y值,小数点后保留3位小数。
#include<stdio.h>
#include<math.h>
int main()
{
double x,y;
scanf("%lf",&x);
if(x>6)
{
y=(x*x+4*x-6)*5/27;
printf("%.3lf",y);
}
else if(x>0 && x<=6)
{
y=log(16)/log(3)+x;
printf("%.3lf",y);
}
else
{
double a,b;
a=x*x*x+4;
b=fabs(a);
y=b*23/7;
printf("%.3lf",y);
}
return 0;
}
7-2判断字符或数字
键盘输入一个字符,要求判断是否为数字字符,如果是’a’~’z’或’A’~’Z’,则输出“character”,如果是‘0’~‘9’,则输出“digit”,如果都不是,则输出“ERROR”。
输入格式:
键盘输入一个字符。
输出格式:
如果是字母,则输出“character”,如果是数字,则输出“digit”,如果都不是,则输出“ERROR”。
#include<stdio.h>
int main()
{
char tar;
scanf("%c", &tar);
if((tar>='a' && tar<='z')||(tar>='A' && tar<='Z'))
{
printf("character");
}
else if(tar>='0'&& tar<='9')
{
printf("digit");
}
else
{
printf("ERROR");
}
return 0;
}
7-3输出三角形面积和周长
本题要求编写程序,根据输入的三角形的三条边a、b、c,计算并输出面积和周长。注意:在一个三角形中, 任意两边之和大于第三边。三角形面积计算公式:,其中s=(a+b+c)/2。
输入格式:
输入为3个正整数,分别代表三角形的3条边a、b、c。
输出格式:
如果输入的边能构成一个三角形,则在一行内,按照
area = 面积; perimeter = 周长
的格式输出,保留两位小数。否则,输出
These sides do not correspond to a valid triangle
#include<stdio.h>
#include<math.h>
int main()
{
double a,b,c;
double area,s,perimeter;
scanf("%lf %lf %lf",&a,&b,&c);
if(a+b>c && a+c>b && b+c>a)
{
int d;
s=(a+b+c)/2;
area=sqrt(s*(s-a)*(s-b)*(s-c));
perimeter=a+b+c;
printf("area = %.2lf; perimeter = %.2lf",area,perimeter);
}
else
{
printf("These sides do not correspond to a valid triangle");
}
return 0;
}
7-4考研录取情况
同学们以后准备考研的一定有不少.以河北某高校为例, 一共要考4门,分别是:数学(满分150)、英语(满分100)、政治(满分100)、专业课(满分150). 不过,你知道考研分数线的特点吗——不仅总分要过分数线,单科也必须过线! 假设某年该校研究生录取的分数线是这样的:数学和专业课单科分数线是85(含), 英语和政治单科分数线是55(含),总分分数线是305(含).并且规定——在单科和总分均过线的前提下, 总分370分(含)以上的是公费生,否则是自费生.现在告诉你一些考生的分数,你能判断他们的录取情况吗?。
输入格式:
输入数据表示考生的考研成绩. 一行4个整数,分别表示考生的数学、英语、政治和专业课成绩,中间用空格分隔。
输出格式:
输出考生的录取情况,A表示公费生,B表示自费生,C表示未录取。
#include <stdio.h>
int main()
{
int math,eng,pol,pro,sum;
scanf("%d %d %d %d",&math,&eng,&pol,&pro);
sum = math+eng+pol+pro;
if(math>=85&&eng>=55&&pol>=55&&pro>=85&&sum>=305)
{
if(sum>=370)
{
printf("A");
}
else
{
printf("B");
}
}
else
{
printf("C");
}
return 0;
}
7-5两个数的简单计算器
本题要求编写一个简单计算器程序,可根据输入的运算符,对2个整数进行加、减、乘、除或求余运算。题目保证输入和输出均不超过整型范围。
输入格式:
输入在一行中依次输入操作数1、运算符、操作数2,其间以1个空格分隔。操作数的数据类型为整型,且保证除法和求余的分母非零。
输出格式:
当运算符为+
、-
、*
、/
、%
时,在一行输出相应的运算结果。若输入是非法符号(即除了加、减、乘、除和求余五种运算符以外的其他符号)则输出ERROR
。
#include<stdio.h>
int main()
{
int x,y,b;
int z;
char c;
scanf("%d %c %d",&x,&c,&y); b=1;
switch ( c )
{
case '+': z=x+y;
break;
case '-': z=x-y;
break;
case '*': z=x*y;
break;
case '/': z=( y==0 )?(0):((float)x/y);
break;
case '%': z=x%y;
break;
default: b=0;
break;
}
if ( b )
{
printf("%d",z);
}
else
{
printf("ERROR");
}
}
7-6输入苹果等级和数量,计算并输出应付款
苹果店有4 个等级的苹果,一级5.50 元/kg、二级4.30 元/kg、三级3.00 元/kg、四级2.50 元/kg。利用switch 语句编写一个程序,输入苹果的等级、数量,输出应付款数。当输入的苹果的等级不合要求时,输出“Data Error!”,结束程序。
输入格式:
例如:在一行中给出等级和数量,中间用空格分隔。
输出格式:
例如:您应付金额为xx元。
#include<stdio.h>
int main()
{
int x,y;
scanf("%d %d",&x,&y);
switch(x)
{
case 1:printf("%.2lf",5.50*y);break;
case 2:printf("%.2lf",4.30*y);break;
case 3:printf("%.2lf",3.00*y);break;
case 4:printf("%.2lf",2.50*y);break;
default:printf("Data Error!");
}
return 0;
}
3.循环结构编程练习
循环结构是编程中用于重复执行一段代码的控制结构。C语言中主要有三种循环结构:for
循环、while
循环和do-while
循环。
for循环
for (初始化; 条件; 更新) {
// 循环体
}
- 特点: 通常用于已知次数的循环。
- 流程:
- 执行初始化语句。
- 判断条件表达式,如果为真,执行循环体;否则,跳出循环。
- 执行更新语句。
- 回到步骤2。
while
循环
while (条件) {
// 循环体
}
- 特点: 循环次数不确定,通常用于条件不明确的情况下。
- 流程:
- 判断条件表达式,如果为真,执行循环体;否则,跳出循环。
- 执行完循环体后,再回到步骤1。
do-while
循环
do {
// 循环体
} while (条件);
- 特点: 确保至少执行一次循环体,因为条件判断发生在循环体执行之后。
- 流程:
- 执行循环体。
- 判断条件表达式,如果为真,继续执行循环体;否则,跳出循环。
其他要点:
- 循环控制语句:
break
(跳出循环),continue
(跳过本次循环,继续下一次循环)。 - 无限循环: 通过
while (1)
或for (;;)
可以创建无限循环。 - 嵌套循环: 循环体中可以包含其他循环,用于处理多维数据等复杂情况。
7-2求幂级数展开的部分和
已知函数可以展开为幂级数
。现给定一个实数x,要求利用此幂级数部分和求
的近似值,求和一直继续到最后一项的绝对值小于0.00001。
输入格式:
输入在一行中给出一个实数x∈[0,5]。
输出格式:
在一行中输出满足条件的幂级数部分和,保留小数点后四位。
#include<stdio.h>
#include<math.h>
double fac(int a)
{
double result=1;
if(a==0||a==1)
result=1;
else while(a>1)
{
result*=a;
a=a-1;
}
return result;
}
int main()
{
double x;
double sum=1,factor;
int y=1;
scanf("%lf",&x);
do
{
factor=pow(x,y)/fac(y);
sum+=factor;
y++;
}
while(factor>=0.00001);
sum+=pow(x,y)/fac(y);
printf("%.4lf",sum);
return 0;
}
7-3输出闰年
输出21世纪中截止某个年份以来的所有闰年年份。注意:闰年的判别条件是该年年份能被4整除但不能被100整除、或者能被400整除。
输入格式:
输入在一行中给出21世纪的某个截止年份。
输出格式:
逐行输出满足条件的所有闰年年份,即每个年份占一行。输入若非21世纪的年份则输出"Invalid year!"。若不存在任何闰年,则输出“None”。
#include<stdio.h>
int main()
{
int year, i, count=0;
scanf("%d", &year);
if(year<=2000||year>2100)
printf("Invalid year!\n");
else
{
for(i=2001; i<=year; i++)
{
if(i%4==0&&i%100!=0||i%400==0)
{
printf("%d\n", i);
count++;
}
}
if(count==0)
printf("None\n");
}
return 0;
}
7-4 输出N以内的所有完数
所谓完数,是指它的因子之和刚好是其本身的正整数。如6的因子是1,2,3,而1+2+3=6,所以6是完数,且是最小的完数。
现在,用户输入N,请输出N以内的所有完数。
输入格式:
一个正整数N(6<=N<=10000)。
输出格式:
输出N以内的所有完数,一个完数占一行。
#include<stdio.h>
int main()
{
int a,b,c,sum;
scanf("%d",&a);
for(b=1;b<=a;b++)
{
sum=0;
for(c=1;c<b;c++)
if(b%c==0)
sum+=c;
if(sum==b)
printf("%d\n",b);
}
return 0;
}
7-5最大公约数和最小公倍数
本题要求两个给定正整数的最大公约数和最小公倍数。
输入格式:
输入在一行中给出两个正整数M和N(≤1000)。
输出格式:
在一行中顺序输出M和N的最大公约数和最小公倍数,两数字间以1空格分隔。
#include<stdio.h>
int main()
{
int x,y,m,n,t;
scanf("%d %d",&m,&n);
x=m;
y=n;
while(y!=0)
{
t=x%y;x=y;y=t;
}
printf("%d %d",x,m*n/x);
return 0;
}
7-6一批数中能被3或7整除的数之和
输入一批正整数,用-1作终止标记。求其中能被3或7整除的数之和。
输入格式:
在一行中输入若干个用空格间隔的整数(不要超过15个数),最后输入-1结束输入,数据之间只能用1个空格间隔。
输出格式:
直接输出整型结果,没有其它任何附加字符。
#include <stdio.h>
#include <string.h>
#define N 100
int main(void)
{
int buf[N]={0},i=0,j,sum=0;
while(buf)
{
scanf("%d",&buf[i]);
if(buf[i]==-1)
break;
i++;
}
for(j=0;j<i;j++)
{
if(buf[j]%3==0||buf[j]%7==0)
{
sum = sum +buf[j];
}
}
printf("%d",sum);
return 0;
}
4.函数编程练习
-
函数定义:包括返回类型、函数名、参数列表和函数体,用于描述函数的功能和行为。
-
函数声明:在使用函数之前,可以通过声明函数的返回类型和参数类型来告知编译器函数的存在和接口。
-
函数调用:通过函数名和实际参数来执行函数,返回值可以用来接收函数的计算结果。
-
函数参数:函数参数通过值传递方式传递,即传递的是参数的副本,而非原始变量。
-
返回值:函数可以返回一个值,返回类型需与函数体中的返回值类型一致。没有返回值的函数使用
void
作为返回类型。 -
递归函数:函数可以调用自身,递归函数必须包含基准条件以防止无限递归。
-
局部变量与全局变量:局部变量在函数内部有效,全局变量在整个程序中有效。
-
作用域:局部变量作用于其所在的函数内部,而函数名在整个源文件中有效。
-
函数重载:C语言不支持函数重载,每个函数名必须是唯一的。不同的函数名用于处理不同的功能。
-
返回类型:函数的返回类型可以是基本数据类型或自定义数据类型,也可以是
void
表示无返回值。
6-1求m到n之和
本题要求实现一个计算m~n(m<n)之间所有整数的和的简单函数。
函数接口定义:
int sum( int m, int n );
其中m
和n
是用户传入的参数,保证有m<n。函数返回的是m~n之间所有整数的和。
#include<stdio.h>
int sum(int m,int n)
{
int sum=0,i;
for(i=m;i<=n;i++)
sum+=i;
return sum;
}
6-2递归实现指数函数
本题要求实现一个计算(n≥1)的函数。
函数接口定义:
double calc_pow( double x, int n );
函数calc_pow
应返回x
的n
次幂的值。建议用递归实现。题目保证结果在双精度范围内。
double calc_pow(double x,int n)
{
double d=1.0;
for(int i=0;i<n;i++)
{
d*=x;
}
return d;
}
6-3使用函数输出一个整数的逆序数
本题要求实现一个求整数的逆序数的简单函数。
函数接口定义:
int reverse( int number );
其中函数reverse
须返回用户传入的整型number
的逆序数。
#include <stdio.h>
int reverse( int number)
{
int n,sum;
while(number!=0)
{
n=number%10;
sum=sum*10+n;
number/=10;
}
return sum;
}
6-4统计个位数字
本题要求实现一个函数,可统计任一整数中某个位数出现的次数。例如-21252中,2出现了3次,则该函数应该返回3。
函数接口定义:
int Count_Digit ( const int N, const int D );
其中N
和D
都是用户传入的参数。N
的值不超过int
的范围;D
是[0, 9]区间内的个位数。函数须返回N
中D
出现的次数。
#include <stdio.h>
int Count_Digit ( const int N, const int D )
{
int result=0,iNumber;
iNumber=(N>0)?N:(-N);
do
{
if(iNumber%10==D)
{
result++;
}
iNumber=iNumber/10;
}
while(iNumber>0);
return result;
}
6-5统计各位数字之和是5的数
本题要求实现两个函数:一个函数判断给定正整数的各位数字之和是否等于5;另一个函数统计给定区间内有多少个满足上述要求的整数,并计算这些整数的和。
函数接口定义:
int is( int number ); void count_sum( int a, int b );
函数is
判断number
的各位数字之和是否等于5,是则返回1,否则返回0。
函数count_sum
利用函数is
统计给定区间[a
, b
]内有多少个满足上述要求(即令is
返回1)的整数,并计算这些整数的和。最后按照格式
count = 满足条件的整数个数, sum = 这些整数的和
进行输出。题目保证0<a
≤b
≤10000。
int is(int number)
{
int numberSum = 0;
while (number != 0)
{
int lastNumber = number % 10;
numberSum += lastNumber;
number /= 10;
}
if (numberSum == 5)
{
return 1;
}
return 0;
}
void count_sum(int a, int b)
{
int count = 0;
int countSum = 0;
for (a; a <= b; a++)
{
if (is(a) == 1)
{
count++;
countSum += a;
}
}
printf("count = %d, sum = %d\n", count, countSum);
}
5.数组编程练习1
数组是C语言中用于存储一组相同类型数据的结构。以下是数组的基本概念和要点:
1. 数组定义
- 定义:数组在定义时指定元素的类型和数量。所有元素都存储在连续的内存位置中。
- 语法:
类型 数组名[大小];
- 示例:
int arr[10];
定义一个包含10个整数的数组。
2. 数组初始化
- 静态初始化:定义数组时可以同时初始化数组的元素。
- 语法:
类型 数组名[大小] = {值1, 值2, ...};
- 示例:
int arr[3] = {1, 2, 3};
初始化一个包含三个整数的数组。
3. 数组索引
- 索引:数组的索引从0开始,到
大小-1
为止。数组的每个元素可以通过索引访问。 - 示例:
arr[0]
访问数组的第一个元素,arr[1]
访问第二个元素。
4. 数组下标越界
- 警告:访问数组时,索引超出有效范围(即小于0或大于
大小-1
)会导致未定义行为或程序崩溃。
5. 多维数组
- 定义:C语言支持多维数组,如二维数组和三维数组。
- 语法:
类型 数组名[行][列];
- 示例:
int matrix[3][4];
定义一个3行4列的二维数组。
6. 数组作为函数参数
- 传递方式:数组名作为参数传递给函数时,实际上传递的是数组的首地址(指针)。
- 函数定义:
void func(int arr[]);
或void func(int *arr);
7. 数组大小
- 确定:静态数组的大小在定义时必须是常量。动态数组大小可以在运行时决定,通常使用指针和内存分配函数如
malloc
。
8. 数组与指针
- 关系:数组名可以被视为指向数组第一个元素的指针。访问数组元素时,
arr[i]
实际上等同于*(arr + i)
。
9. 数组元素类型
- 一致性:数组中的所有元素必须是相同的数据类型,不能混合不同类型。
10. 内存布局
- 连续性:数组的所有元素在内存中是连续存储的,这使得数组访问速度较快。
6-1在数组中查找指定元素
本题要求实现一个在数组中查找指定元素的简单函数。
函数接口定义:
int search( int list[], int n, int x );
其中list[]
是用户传入的数组;n
(≥0)是list[]
中元素的个数;x
是待查找的元素。如果找到
则函数search
返回相应元素的最小下标(下标从0开始),否则返回−1。
int search( int list[], int n, int x ){
int i;
for(i=0;i<n;i++){
if(list[i]==x){
return i;
}
}
return -1;
}
6-2使用函数的选择法排序
本题要求实现一个用选择法对整数数组进行简单排序的函数。
函数接口定义:
void sort( int a[], int n );
其中a
是待排序的数组,n
是数组a
中元素的个数。该函数用选择法将数组a
中的元素按升序排列,结果仍然在数组a
中。
void sort( int a[], int n ){
int min_index;
for(int i=0;i<n-1;i++){
min_index=i;
for(int j=i+1;j<n;j++){
if(a[min_index]>a[j]) min_index=j;
}
if(min_index!=i){
int temp=a[i];
a[i]=a[min_index];
a[min_index]=temp;
}
}
}
6-3使用函数找出数组中的最大值
本题要求实现一个找出整型数组中最大值的函数。
函数接口定义:
int FindArrayMax( int a[], int n );
其中a
是用户传入的数组,n
是数组a
中元素的个数。函数返回数组a
中的最大值。
int FindArrayMax( int a[], int n )
{
int i, max;
max = a[0];
for(i=0; i<n; i++ )
{
if(a[i]>max)
{
max = a[i];
}
}
return max;
}
7-1对a[10]数组中的素数排序
输入10个正整数到a数组中,对a[10]数组中的素数升序排序。
输入格式:
在一行中输入10个用空格间隔的正整数,数据之间只能各用1个空格间隔。
输出格式:
在一行中输出升序的素数序列,每个数输出占4列列宽。
#include<stdio.h>
#include<math.h>
int main()
{
int a[10];
int b[10] = {0};
int i,j = 0,k;
int *p;
int count = 0;
for(i=0;i<10;i++)
{
scanf("%d",&a[i]);
}
while(j < 100)
{
for(i = 0;i<9;i++)
{
if(i < 9)
{
if(a[i] > a[i+1])
{
b[i] = a[i+1];
a[i+1] = a[i];
a[i] = b[i];
}
}
}
j++;
}
for(i=0;i < 10;i++)
{
if(a[i] == 2 || a[i] == 3 || a[i] == 5 || a[i] == 7 ||a[i] == 11)
{
count++;
}
if(a[i] % 2 != 0 && a[i] % 3 != 0 && a[i] % 5 != 0 && a[i] % 7 != 0 && a[i] % 11 != 0)
{
count++;
}
if(a[i] == 1)
{
count--;
}
}
int c[10] = {0};
for(i=0;i < 10;i++)
{
if(a[i] == 2 || a[i] == 3 || a[i] == 5 || a[i] == 7 ||a[i] == 11)
{
c[i] = a[i];
}
if(a[i] % 2 != 0 && a[i] % 3 != 0 && a[i] % 5 != 0 && a[i] % 7 != 0 && a[i] % 11 != 0)
{
c[i] = a[i];
}
if(a[i] == 1)
{
c[i] = 0;
}
}
int d[count];
if(count == 0)
{
printf("Not found!");
}
j = 0;
for(i = 0;i<10;i++)
{
if(c[i] != 0)
{
d[j] = c[i];
j++;
}
}
for(k=0;k < count;k++)
{
if(k < count-1)
printf(" %d",d[k]);
else
{
printf(" %d",d[k]);
}
}
}
7-2方阵对角线元素求和及计数
对输入的一个N*N
的方阵,求其两条对角线上的元素之和及非零元素的数量。
输入格式:
第一行输入一个不超过20的正整数N
,
在接下来的N
行中,依次输入方阵的每一行的N
个元素,方阵元素为绝对值不超过1000的整数,中间以空格间隔。
输出格式:
在一行中以sum = <s>, count = <c>.
的格式输出方阵两对角线上的元素之和以及非零元素的数量,其中<s>
和<c>
分别表示元素之和
、非零元素数量
,输出时以实际数量替换。
提示:(1)两条对角线的交叉元素不重复计算;(2)严格按规定格式输出,不得随意增删空格、换行等字符。
#include <stdio.h>
#include <stdlib.h>
int main() {
int num,a[20][20],cout=0,sum=0,i,j;
scanf("%d",&num);
for(i=0;i<num;i++)
for(j=0;j<num;j++){
scanf("%d",&a[i][j]);
if(i==j||i+j==num-1)
{
if(a[i][j]!=0)
cout+=1;
sum+=a[i][j];}}
printf("sum = %d, count = %d.\n",sum,cout);
return 0;
}
6.数组编程练习2
6-1分类统计字符个数
本题要求实现一个函数,统计给定字符串中英文字母、空格或回车、数字字符和其他字符的个数。
函数接口定义:
void StringCount( char s[] );
其中 char s[]
是用户传入的字符串。函数StringCount
须在一行内按照
letter = 英文字母个数, blank = 空格或回车个数, digit = 数字字符个数, other = 其他字符个数
void StringCount( char s[] )
{
int letter = 0, blank = 0, digit = 0, other = 0, i;
int n = strlen(s);
for ( i=0; i<n; i++ ) {
if ( (s[i]>='a'&&s[i]<='z') || (s[i]>='A'&&s[i]<='Z') )
letter++;
else if ( s[i]==' ' || s[i]=='\n' )
blank++;
else if ( s[i]>='0'&&s[i]<='9' )
digit++;
else
other++;
}
printf("letter = %d, blank = %d, digit = %d, other = %d", letter, blank, digit, other);
}
7-1 将字符串中数字字符替换成$字符
将字符串中每一个数字字符都替换成一个$字符。
输入格式:
在一行中输入长度小于20的含有数字字符的字符串。在字符串中不要出现换行符,空格,制表符。
输出格式:
直接输出变化后的字符串。
#include<stdio.h>
#include<string.h>
int main()
{
char s[1000];
int i,len;
gets(s);
len=strlen(s);
for(i=0;i<len;i++){
if(s[i]<='9'&&s[i]>='0'){
s[i]='$';
}
}
for(i=0;i<len;i++){
printf("%c",s[i]);
}
return 0;
}
7-2复制n个字符
将一个字符串中的前n个字符复制到一个字符数组中去,n值小于字符串实际长度,不许使用strcpy函数。
输入格式:
在第一行中输入一个长度不超过20的字符串,并以回车结束,在第二行中输入一个整数n。
输出格式:
在一行中输出满足条件的字符串。
#include<stdio.h>
int main()
{
char a[10],b[10];
int n,i;
gets(a);
scanf("%d",&n);
for(i=0;i<=n-1;i++)
b[i]=a[i];
for(i=0;i<=n-1;i++)
printf("%c",b[i]);
return 0;
}
7-3判断回文字符串
输入一个字符串,判断该字符串是否为回文。回文就是字符串中心对称,从左向右读和从右向左读的内容是一样的。
输入格式:
输入在一行中给出一个不超过80
个字符长度的、以回车结束的非空字符串。
输出格式:
输出在第1行中输出字符串。如果它是回文字符串,在第2行中输出Yes
,否则输出No
。
#include<stdio.h>
int main()
{
int i,k,s;
char line[80];
k=0;
while ((line[k]=getchar())!='\n')//字符串的输入
k++;
line[k]='\0';//k加完后的值
i=0;
s=k;
k=k-1;
while(i<k)
{
if(line[i]!=line[k])
break;
i++;
k--;
}//跳出循环,出现两种情况。
if(i>=k)
{
for(i=0;i<s;i++)
printf("%c",line[i]);//输出字符串
printf("\n");
printf("Yes");
}
else
{
for(i=0;i<s;i++)
printf("%c",line[i]);
printf("\n");
printf("No");
}
return 0;
}
7-4英文单词排序
本题要求编写程序,输入若干英文单词,对这些单词按长度从小到大排序后输出。如果长度相同,按照输入的顺序不变。
输入格式:
输入为若干英文单词,每行一个,以#
作为输入结束标志。其中英文单词总数不超过20个,英文单词为长度小于10的仅由小写英文字母组成的字符串。
输出格式:
输出为排序后的结果,每个单词后面都额外输出一个空格。
#include <stdio.h>
#include <string.h>
main()
{
char str[20][10],t[20],str1[10];
int i,j,n=0;
while(1)
{
scanf("%s",str1);
if(str1[0]=='#')
{
break;
}
else
{
strcpy(str[n],str1);
n++;
}
}
for(i=0;i<n-1;i++)
for(j=0;j<n-i-1;j++)
{
if(strlen(str[j])>strlen(str[j+1]))
{
strcpy(t,str[j]);
strcpy(str[j],str[j+1]);
strcpy(str[j+1],t);
}
}
for(i=0;i<n;i++)
{
printf("%s ",str[i]);
}
}
7.指针编程练习
指针是C语言中的一个强大且复杂的特性,用于直接操作内存地址。以下是指针的基本概念和要点:
1. 指针定义
- 定义:指针是一个变量,它存储另一个变量的内存地址。
- 语法:
类型 *指针名;
- 示例:
int *ptr;
定义一个指向整数的指针。
2. 指针初始化
- 初始化:指针在使用之前通常需要初始化。可以将指针指向一个有效的内存地址。
- 示例:
int a = 10; int *ptr = &a;
将指针ptr
初始化为指向变量a
的地址。
3. 取地址运算符 (&)
- 功能:用于获取变量的内存地址。
- 示例:
&a
表示变量a
的地址。
4. 解引用运算符 (*)
- 功能:用于访问指针所指向地址的值。
- 示例:
*ptr
访问ptr
指向的变量的值。
5. 指针运算
- 运算:指针可以进行算术运算,如加减操作,通常用于遍历数组。
- 示例:
ptr++
使指针移动到下一个元素的位置。
6. 空指针 (NULL)
- 定义:空指针是一个不指向任何有效内存位置的指针,常用来表示指针未被初始化或不指向任何有效对象。
- 示例:
int *ptr = NULL;
7. 指针与数组
- 关系:数组名被视为指向数组首元素的指针。
arr[i]
等价于*(arr + i)
。 - 示例:
int arr[5];
和int *ptr = arr;
可以通过指针操作数组。
8. 指针与函数
- 传递:指针可以作为函数参数传递,用于修改函数外部变量的值或传递大数据。
- 示例:
void modify(int *p);
9. 动态内存管理
- 函数:
malloc
、calloc
、realloc
和free
用于动态分配和释放内存。 - 示例:
int *arr = (int *)malloc(10 * sizeof(int));
10. 指针的类型
- 类型匹配:指针类型决定了指针所指向的数据类型。
int *
指向整数,char *
指向字符等。
11. 指针与结构体
- 访问:通过指针访问结构体成员使用箭头运算符(
->
),例如ptr->member
。
12. 多级指针
- 定义:指向指针的指针,即多级指针,用于复杂的数据结构。
- 示例:
int **pptr;
是一个指向指针的指针。
6-1字符串正反序连接
将s所指字符串的正序和反序进行连接,形成一个新串放在t所指的数组中。
函数接口定义:
void fun (char *s, char *t);
其中s
和t
都是用户传入的参数。函数将s
所指字符串的正序和反序进行连接,形成一个新串放在t
所指的数组中。
#include <string.h>
void fun (char *s, char *t)
{
int i, l, m;
char a[100];
l = strlen(s);
for(i = 0;i < l;i++)
{
t[i] = s[i];
}
for(i = 0;i < l;i++)
{
t[i+l] = s[l-i-1];
}
}
6-2复制部分字符串
将一个字符串中从第m个字符开始的全部字符复制成为另一个字符串。
函数接口定义:
void strcopy(char *str1,char *str2,int m);
其中 str1
、str2
、m
都是用户传入的参数。函数在指针str1
所指的字符串中从第m
个字符开始的全部字符复制到指针str2
所指向数组中。
void strcopy(char *str1,char *str2,int m)
{
int i,j;
for(i = m - 1;str1[i] != '\0';i ++)
{
str2[j] = str1[i];
j ++;
}
}
6-3删除字符串中数字字符
删除一个字符串中的所有数字字符。
函数接口定义:
void delnum(char *s);
其中 s
是用户传入的参数。 函数的功能是删除指针 s
所指的字符串中的所有数字字符。
void delnum(char *s)
{
int i=0;
int j=0;
while(s[i]!='\0'){
if(s[i]>'9'||s[i]<'0')
s[j++]=s[i];
i++;
}
s[j]='\0';
}
6-4查找子串
本题要求实现一个字符串查找的简单函数。
函数接口定义:
char *search( char *s, char *t );
函数search
在字符串s
中查找子串t
,返回子串t在s
中的首地址。若未找到,则返回NULL。
char *search(char *s, char *t) {
int i = 0;
while (s[i] != '\0') {
if (s[i] == t[0]) {
int j = 1;
while (s[i + j] == t[j] && t[j] != '\0') {
j++;
}
if (t[j] == '\0') {
return s + i;
}
}
i++;
}
return NULL;
}
8.结构体编程练习
结构体是C语言中用于定义用户自定义数据类型的一种方式,允许将不同类型的数据组合在一起。以下是结构体的基本概念和要点:
1. 结构体定义
- 定义:使用
struct
关键字定义一个结构体类型。结构体可以包含不同类型的成员。 - 语法:
struct 结构体名 { 成员列表 };
- 示例:
struct Person { char name[50]; int age; };
2. 结构体变量
- 声明:定义结构体类型后,可以声明结构体变量。
- 语法:
struct 结构体名 变量名;
- 示例:
struct Person person1;
3. 结构体初始化
- 初始化:可以在声明时初始化结构体变量。
- 语法:
struct 结构体名 变量名 = { 值1, 值2, ... };
- 示例:
struct Person person1 = {"Alice", 30};
4. 访问结构体成员
- 操作:通过点运算符(
.
)访问结构体的成员。 - 示例:
person1.age = 30;
访问并修改person1
的age
成员。
5. 结构体指针
- 定义:结构体变量可以通过指针进行操作。使用箭头运算符(
->
)访问指针指向的结构体成员。 - 语法:
struct 结构体名 *指针名;
- 示例:
struct Person *ptr = &person1;
和ptr->age = 30;
6. 结构体嵌套
- 定义:结构体可以包含其他结构体作为成员,实现数据的层次化。
- 示例:
struct Address { char city[50]; }; struct Person { struct Address addr; };
7. 结构体数组
- 定义:可以创建结构体类型的数组,用于存储多个结构体实例。
- 示例:
struct Person people[10];
存储10个Person
类型的结构体。
8. 结构体作为函数参数
- 传递:结构体可以作为参数传递给函数。可以选择按值传递(复制整个结构体)或按指针传递(传递结构体的地址)。
- 示例:
void printPerson(struct Person p);
或void printPerson(struct Person *p);
9. 结构体与内存
- 对齐:结构体的内存布局可能会因为数据对齐要求而存在填充字节(padding)。
10. 自定义结构体类型
- 定义:可以使用
typedef
创建结构体的别名,使代码更简洁。 - 示例:
typedef struct { char name[50]; int age; } Person;
然后可以用Person
替代struct Person
。
7-2计算坐标系中两个点之间的距离
定义一个结构体类型表示平面上的一个点的坐标(x,y),并从键盘输入两个点z1,z2的坐标,坐标值为整型数据,输出这两点之间的距离。
输入格式:
从键盘输入两个点z1和z2的坐标,之间用空格分隔
输出格式:
输出数据保留两位小数。
#include<stdio.h>
#include<math.h>
struct pos{
int x;
int y;
};
int main()
{
struct pos pos1;
struct pos pos2;
scanf("%d %d %d %d",&pos1.x,&pos1.y,&pos2.x,&pos2.y);
double a;
int b;
b=pow(pos1.x-pos2.x,2)+pow(pos1.y-pos2.y,2);
a=sqrt(b);
printf("distance = %.2lf",a);
}
7-3时间换算
本题要求编写程序,以hh:mm:ss
的格式输出某给定时间再过n
秒后的时间值(超过23:59:59就从0点开始计时)。
输入格式:
输入在第一行中以hh:mm:ss
的格式给出起始时间,第二行给出整秒数n
(<60)。
输出格式:
输出在一行中给出hh:mm:ss
格式的结果时间。
#include<stdio.h>
int main()
{
int hh, mm, ss;
scanf("%d:%d:%d",&hh,&mm,&ss);
int n;
scanf("%d",&n);
ss = ss + n;
mm += (ss - ss%60) > 0, ss %= 60;
hh += (mm - mm%60) > 0, mm %= 60;
hh %= 24;
printf("%02d:%02d:%02d",hh,mm,ss);
return 0;
}
7-4通讯录排序
输入n个朋友的信息,包括姓名、生日、电话号码,本题要求编写程序,按照年龄从大到小的顺序依次输出通讯录。题目保证所有人的生日均不相同。
输入格式:
输入第一行给出正整数n(<10)。随后n行,每行按照“姓名 生日 电话号码”的格式给出一位朋友的信息,其中“姓名”是长度不超过10的英文字母组成的字符串,“生日”是yyyymmdd
格式的日期,“电话号码”是不超过17位的数字及+
、-
组成的字符串。
输出格式:
按照年龄从大到小输出朋友的信息,格式同输出。
#include<stdio.h>
#include<string.h>
struct dian{
char a[1000],b[1000];
double n;
};
int main()
{
int i,j,t;
double n;
char g[1000];
struct dian c[1000];
scanf("%lf",&n);
for(i=0;i<n;i++)
{
getchar();
scanf("%s%lf%s",c[i].a,&c[i].n,c[i].b);
}
for(i=1;i<n;i++)
{
for(j=0;j<n-i;j++)
{
if(c[j].n>c[j+1].n)
{
t=c[j].n;
c[j].n=c[j+1].n;
c[j+1].n=t;
strcpy(g,c[j+1].a);
strcpy(c[j+1].a,c[j].a);
strcpy(c[j].a,g);
strcpy(g,c[j+1].b);
strcpy(c[j+1].b,c[j].b);
strcpy(c[j].b,g);
}
}
}
for(i=0;i<n;i++)
printf("%s %.0f %s\n",c[i].a,c[i].n,c[i].b);
return 0;
}