编程练习
2.
一个整数如果只能被它本身和1整除,它就被称为质数(prime)。请编写一个程序,打印出1~100之间的所有质数。
分析:
质数(素数):指在大于1的自然数中,除了1和它本身外不再有其他因数的自然数。
1.输入的整数n能否被2~n-1之间的整数整除? 不能,则n是质数;反之,不是。
2.输入的整数n能否被2~√n之间的整数整除? 不能,则n是质数;反之,不是。
程序如下:
#include<stdio.h>
#include<stdlib.h>
int prime(int n)
{
int flag = 1; //flag = 1表示n为质数
int i;
if(n == 1)
{
flag = 0;
} //若n为1,则n不是质数
else
{
for(i = 2; i<=n/2 ; i++) //循环次数
{ //这里的条件部分·i<=n/2也可以用i<=n-1代替,用n/2是为了减少循环次数
if(n % i == 0) //判断是否为质数
flag = 0;
}
} //若n大于1,且能被2~n/2之间的数整除,则n不是质数
return flag;
} //若不满足以上条件,则n为质数,返回flag=1
int main()
{
int n;
for(n = 2; n <= 100; n++)
{
if(prime(n))
printf("%d ", n);
} //若函数prime返回的flag=1,则打印出n
system("pause");
return 0;
}
运行结果:
3.
等边三角形的三条边长度都相等,但等腰三角形只有两条边的长度是相等的。如果三角形的三条边长度都不等,那就称为不等边三角形。请编写一个程序,提示用户输入三个数,分别表示三角形三条边的长度,然后由程序判断它是什么类型的三角形。
提示:除了边的长度是否相等之外,程序是否还应考虑一些其他的东西?
分析: 该程序除了考虑三角形三条边的长度是否相等外,还应该考虑三角形成立的条件。输入的三条边都应当大于零且任意两边之和应该大于第三条边。
程序如下:
#include<stdio.h>
#include<stdlib.h>
int main()
{
float a, b, c;
printf("Please input triangle's three side length:\n");
scanf("%f %f %f", &a, &b, &c);
if(a <= 0 || b <= 0 || c <= 0)
{
printf("triangle's side length is not positive");
return 1;
} //判断输入的三条边是否大于0
if(a + b <= c || a + c <= b || b + c <= a)
{
printf("the sum of any two triangle's side length is less than the other one");
return 1;
} //判断输入的三条边中任意的两条边是否大于第三条边
if(a == b && b == c && c == a)
printf("equilateral\n"); //等边三角形
else if(a==b || b==c || c==a)
printf("An isosceles triangle\n"); //等腰三角形
else
printf("unequal triangle\n"); //不等边三角形
system("pause");
return 0;
}
运行结果:
4.
编写函数copy_n,它的原型如下所示:
void copy_n(char dst[], char src[], int n);
这个函数用于把一个字符串从数组src复制到数组dst,但有如下要求:必须刚好复制n个字符到dst数组中(不能多也不能少)。如果src字符串的长度小于n,那么你必须在复制后的字符串尾部补充足够的NUL字符,使它的长度正好为n。如果src的长度长于或等于n,那么你在dst中存储了n个字符后便可停止。此时,数组dst将不是以NUL字符结尾。注意调用copy_n时,它应该在dst[0]至dst[n-1]的空间中存储一些东西,但也只局限于那些位置,这与src的长度无关。
如果你计划使用库函数strncpy来实现你的程序,祝贺你提前学到了这个知识。但在这里我的目的是让你自己规划程序的逻辑,所以你最好不要使用那些处理字符串的库函数.
程序如下:
void copy_n(char dst[], char src[], int n)
{
int i, j, k;
int len = strlen(src);
if(len < n)
{//若src的长度小于n,则在复制了src长度后,在大于src且小于n长度的dst尾部补充NUL
for(i = 0; i < n; i++) //i代表src的长度 (小于n)
dst[i] = src[i]; //将src中字符串先复制到dst中
for(j = i + 1 ; j < n; j++) //j代表大于src且小于n的长度
dst[j] = '\0';
}
else //若src的长度大于n,则直接在dst中复制长度为n的src字符串
{
for(k = 0; k < n; k++) //K代表src的长度(大于n)
{
dst[k] = src[k];
} //将n长度范围内的src字符复制到dst中
dst[k] = '\0'; //当复制的长度等于n时,dst数组复制结束
}
}
//自己写了一个简单主函数,用来调用copy_n函数
#include<stdio.h>
#include<string.h>
void copy_n(char dst[], char src[], int n)
{
int i, j, k;
int len = strlen(src);
if(len < n)
{
for(i = 0; i < n; i++) //i代表src的长度 (小于n)
dst[i] = src[i]; //将src中字符串先复制到dst中
for(j = i + 1 ; j < n; j++) //j代表大于src且小于n的长度
dst[j] = '\0';
}
else //若src的长度大于n,则直接在dst中复制长度为n的src字符串
{
for(k = 0; k < n; k++) //K代表src的长度(大于n)
{
dst[k] = src[k];
} //将n长度范围内的src字符复制到dst中
dst[k] = '\0'; //当复制的长度等于n时,dst数组复制结束
}
}
int main(){
char x[20];
char y[20];
int z;
scanf("%s%d",&y,&z);
copy_n(x,y,z);
printf("%s",x);
return 0;
}
运行结果:
5.
编写一个程序,从标准输入中一行一行地读取文本,并完成如下任务:如果文件中有两行或更多行相邻的文本内容相同,那么就打印出其中一行,其余的行都不打印。你可以假设文件中的文本行不会超过128个字符(127个字符加上用于终结文本的换行符)。
考虑下面的输入文件。
This is the first line.
Another line.
And another;
And another;
And another;
And another;
Still more;
Almost down now --
Almost down now --
Anoter line.
Still more.
Finished!
//假定所有的行在尾部没有任何空白
//(它们在视觉上不可见,但它们却可能使邻近两行在内容上不同)
//根据这个输入文件,程序应该产生下列输出:
And another.
Almost down now --
所有内容相同的相邻文本行有一行被打印。注意“Another line”和“Still more”并未被打印,因为在文件中虽然各占两行,但相同文本行的位置并不相邻。
提示: 使用gets函数读取输入行,使用strcpy函数来复制它们。使用strcmp函数接受两个字符串参数并进行比较。如果两者相等,函数返回0,若不等,函数返回非零值。
分析:这里的strcpy与上一道题所提到的strncpy有一定的区别。
strcpy: 函数原型为extern char *strcpy(char *dest,char *src); 拷贝字符串后的\0,所以主要拷贝字符串。
strncpy: 函数原型为char * strncpy(char *dest, char *src, size_tn);不拷贝串后的 \0,所以主要拷贝字符。
strcmp: 基本形式为strcmp(str1,str2),若str1=str2,则返回零;若str1<str2,则返回负数;若str1>str2,则返回正数。
程序如下:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX_LINE 20 //最大处理行数
#define MAX_COLS 128//最大处理列数
//处理输入行数据,判断相邻行是否相同
void range(char input[MAX_LINE][MAX_COLS],char output[MAX_LINE],int i)
{
int flag = 0; //数组的下标
//遍历每一行并进行比较
while(flag<=i)
{
if(strcmp(input[flag],input[flag+1])==0) //当相邻两行相同时执行下列操作
{
strcpy(output,input[flag]); //将相同的行复制到output数组中
if(strcmp(output,input[flag+2])!=0) //当相邻的第三行不与前值相等时才打印输出
printf("%s\n",output);
}
flag++;
}
}
int main()
{
char input[MAX_LINE][MAX_COLS]={0}; //存放输入文件行
char output[MAX_LINE]={0}; //存放输出文件行
int i = 0; //数组下标
//把输入行依次存入input数组中用ctrl+z结束文件输入
for(;gets(input[i])!=NULL;i++) { }
range(input,output,i); //调用range函数
return EXIT_SUCCESS;
}
运行结果:
在分析问题的时候发现对于gets()与getchar()的区别不甚了解,在这里插播一下这个知识点。
函数原型:
char * gets(char * ptr); //gets读一行。
int getchar(void); //getchar()读一个字符。
gets() 用于从标准输入流stdio读入一个整行(以’\n’或EOF)结束,写入ptr指向的字符数组,并返回这个指针;出错或遇到文件结束时则返回NULL。行末的’\n’从流中取出,但不写入数组。gets()不检查被写入的数组大小。
getchar() 用于从标准输入流stdio读入一个字符,并返回这个字符。如果读到文件结尾,则返回EOF。注意到EOF不能用char类型表示,所以getchar()函数返回的是一个int型的数。使用时也应该注意到这一点。
一道编程题,一看一下午
这么低效率也是相当佩服自己了(囧ing。。。)
在冲浪中发现了很多前辈们的知识总结,可谓受益匪浅
在此深深鞠躬,向前辈们表达最真挚的感谢!
本来是想在这一篇就把第四章结束的
后来又觉得每篇博客的篇幅最好适中
Emmm那就明天考完科四再继续啦~
若这篇博客中有错误,望博友指出,在下不胜感激!