目录
5.3 Fibonacci数列的前两个数为1, 1,以后每一个数都是其前两个数之和。求Fibonacci数列中的前20个数。用数组存放并按一行10个数的格式输出。
5.7 有17个人围成一圈(编号为1~17),从第1号开始进行1、2、3报数,凡报3者就退出,下一个人又从1开始报数……直到最后只剩下一个人时为止。请问此人原来的位置是多少号?
5.11 有一行文字,要求删去其中某个字符。此行文字和要删除的字符均由键盘输入。
5.12 编写一个函数atoi,其作用是将一个整数字符串转换成一个整数。
5.15 数字螺旋方阵的形式如图所示。请将螺旋方阵存放在n×n的二维数组中,并将其打印输出。要求n由程序读入,数字螺旋方阵由程序自动生成。
5.16 有3行文字,找出其中共有多少空格和多少单词(规定单词之间以一个或多个空格作为间隔)。
5.17 有n个学生,每人考m门课。(1)找出成绩最高的学生的学号和课程号。(2)找出有不及格课程的学生的学号及其各门课的全部成绩。(3)求全部学生全部课程总平均分。
5.19 有n个国家名,要求按字母先后顺序排列,并按顺序输出。
一、习题
5.3 Fibonacci数列的前两个数为1, 1,以后每一个数都是其前两个数之和。求Fibonacci数列中的前20个数。用数组存放并按一行10个数的格式输出。
#include<stdio.h>
int main(){
int arr[20] = {0};
int i = 0;
arr[0] = 1;
arr[1] = 1;
for(i = 2; i < 20; i++){
arr[i] = arr[i - 1] + arr[i - 2];
}
for(i = 0; i < 20; i++){
if(i != 0 && i % 10 == 0){
printf("\n");
}
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
5.7 有17个人围成一圈(编号为1~17),从第1号开始进行1、2、3报数,凡报3者就退出,下一个人又从1开始报数……直到最后只剩下一个人时为止。请问此人原来的位置是多少号?
#include <stdio.h>
int main(){
int num[50], n, *p, j, loop, i, m, k;
printf("请输入这一圈人的数量:\n");
scanf("%d", &n);
p = num;//开始给这些人编号
for (j = 0; j < n; j++){
*(p + j) = j + 1;
}
i = 0;//i用于计数,即让指针后移
m = 0;//m记录退出圈子的人数
k = 0;//k报数1,2,3
while(m < n - 1){//当退出的人数不大于总人数时,即留下的人数至少是一个人
//这句不能写成m<n,因为假设有8人,当退出了6人时,此时还是进行人数退出,即m++,
//这时是7<8,剩下的一个人自己喊1,2,3那么他也就退出了,将不会有输出
if (*(p + i) != 0){//如果这个人的头上编号不是0就开始报数加1,这里采用的方法是报数为3的人头上编号重置为0
k++;
}
if (k == 3){
k = 0; //报数清零,即下一个人从1开始报数
*(p + i) = 0;//将报数为3的人编号重置为0
m++; //退出人数加1
}
i++; //指针后移
if (i == n){//如果到了队尾,就要使指针重新指向对头//并且它只能放在i++后面,因为只有i++了才有可能i==n
i = 0;
}
}
printf("现在剩下的人是:");
for (loop = 0; loop < n; loop++){
if (num[loop] != 0){
printf("%2d号\n",num[loop]);
}
}
return 0;
}
5.8 编写程序在屏幕上画一条正弦曲线。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
int radian; //10倍弧度
double y; //y为y轴,值为-1到+1,步长为0.1;
int x; //用62列值代表x轴;62来源于2Pi*10约等于2*3.1*10;
//用反正弦值求x更加方便于按行输出
for(y=1; y>=-1; y-=0.1)
{
radian=asin(y)*10;
for(x=0;x<=62;x++)
{
if((x==radian)||(x==(31-radian)||(x==radian+61)))
//反余弦函数值域[0,pi]
printf("*");
else if(radian==0)
printf("-");
else
printf(" ");
}
printf("\n");
}
return 0;
}
5.9 用筛选法求100以内的素数。
#include<stdio.h>
//非筛选法
//int main(){
// int i, j, flag = 1;
// for(i = 2; i < 100; i++){
// flag = 1;
// for(j = 2; j < i; j++){
// if(i % j == 0){
// flag = 0;
// break;
// }
// }
// if(flag)
// printf("%d ", i);
// }
// return 0;
//}
//筛选法
int main(){
int i, j, a[100];
for(i = 0; i < 100; i++){
a[i] = i + 1;
}
a[0] = 0;//1不是素数,挖去
for(i = 0; i < 100; i++){
for(j = i + 1; j < 100; j++){
if(a[i] != 0 && a[j] != 0){//跳过已挖去的数
if(a[j] % a[i] == 0)
a[j] = 0;
}
}
}
printf("1-100的素数是:\n");
for(i = 0; i < 100; i++){
if(a[i] != 0){
printf("%d ", a[i]);
}
}
printf("\n");
return 0;
}
5.10 设计选择排序的C语言程序。
#include<stdio.h>
int main(){
int arr[10] = {32,5,6,10,8,13,25,17,9,12};
int i = 0, j = 0, min, temp;
printf("排序前:");
for(i = 0; i < 10; i++){
printf("%d ", arr[i]);
}
printf("\n");
//选择排序
for(i = 0; i < 9; i++){
min = i;
for(j = i + 1; j < 10; j++){
if(arr[j] < arr[min]){
min = j;
}
}
if(i != min){
temp = arr[i];
arr[i] = arr[min];
arr[min] = temp;
}
}
printf("排序后:");
for(i = 0; i < 10; i++){
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
5.11 有一行文字,要求删去其中某个字符。此行文字和要删除的字符均由键盘输入。
#include<stdio.h>
int main(){
char ch, a[100];
int i, j;
printf("输入字符串:");
gets(a);
printf("输入要删除的字符:");
scanf("%c", &ch);
for(i = 0, j = 0; a[i] != '\0'; i++){
if(a[i] != ch){
a[j++] = a[i];
}
}
a[j] = '\0';
puts(a);
return 0;
}
5.12 编写一个函数atoi,其作用是将一个整数字符串转换成一个整数。
#include<stdio.h>
char *my_itoa(int value, char str[], int radix)
{
const char fonts[] = "0123456789abcdefghijklmnopqrstuvwxyz";
char tmp_buff[33] = {0};
int i = 0, j = 0;
// 超出转换进制范围,退出
if ((radix < 2) || (radix > 36))
{
printf("radix err...\n");
return NULL;
}
// 不是10进制的负数,退出函数
if ((value < 0) && (radix != 10))
{
printf("value err...\n");
return NULL;
}
// 10进制支持负数转换
if ((value < 0) && (radix == 10))
{
value = -value;
*str++ = '-';
}
// 转换
while(value)
{
tmp_buff[i++] = fonts[value % radix];
value /= radix;
}
// 逆序
for(j=i-1; j>=0; j--)
{
*str++ = tmp_buff[j];
}
*str = '\0';
return str;
}
int main(void)
{
char str1[33] = {0};
char str2[33] = {0};
my_itoa(07654321, str1, 8);
my_itoa(0x123abcde, str2, 16);
printf("str1 = %s\n", str1);
printf("str2 = %s\n", str2);
return 0;
}
5.15 数字螺旋方阵的形式如图所示。请将螺旋方阵存放在n×n的二维数组中,并将其打印输出。要求n由程序读入,数字螺旋方阵由程序自动生成。
#include <stdio.h>
#define N 5
int matrix[N][N] = {0};
void left(int i, int j, int num);
void bot(int i, int j, int num);
void right(int i, int j, int num);
void top(int i, int j, int num);
int main(){
int i,j;
left(0,0,1);
for(i = 0; i < N; i++){
for(j = 0; j < N; j++){
printf("%5d ",matrix[i][j]);
}
printf("\n");
}
return 0;
}
void left(int i, int j, int num){
int y = i, x = j, number = num;
if(number>N*N)
return;
while(y<N && matrix[y][x]==0){
matrix[y++][x] = number++;
}
bot(y - 1, x + 1, number);
}
void bot(int i, int j, int num){
int y = i, x = j, number = num;
if(number>N*N)
return;
while(x<N && matrix[y][x]==0){
matrix[y][x++] = number++;
}
right(y - 1, x - 1, number);
}
void right(int i, int j, int num){
int y = i, x = j, number = num;
if(number>N*N)
return;
while(y>=0 && matrix[y][x]==0){
matrix[y--][x] = number++;
}
top(y + 1, x - 1, number);
}
void top(int i, int j, int num){
int y = i, x = j, number = num;
if(number>N*N)
return;
while(x>=0 && matrix[y][x]==0){
matrix[y][x--] = number++;
}
left(y + 1, x + 1, number);
}
5.16 有3行文字,找出其中共有多少空格和多少单词(规定单词之间以一个或多个空格作为间隔)。
#include <stdio.h>
#include<string.h>
int word = 0, blank = 0;
void StringBracket(char *str){
int i,len;
len = strlen(str);
flag = 0;//记录上一个是否为空格,是 则单词数+1,否则仍是当前单词
for(i = 0; i < len; i++){
if(str[i] != ' '){
if(flag == 0){//上一个字符为空格
word++;
flag = 1;
}
}
else{
blank++;
flag = 0;
}
}
}
int main(){
int i,j;
char a[100];
for(i = 0; i < 3; i++){
gets(a);
StringBracket(a);
}
printf("空格:%d\n单词:%d\n", blank, word);
return 0;
}
5.17 有n个学生,每人考m门课。
(1)找出成绩最高的学生的学号和课程号。
(2)找出有不及格课程的学生的学号及其各门课的全部成绩。
(3)求全部学生全部课程总平均分。
#include <stdio.h>
int main()
{
int score[50][10];
int loster[50];//存储不及格学生的各科成绩
int bloster,n,m,i,j,k=0,sum=0,maxi,maxj;
//bloster 记录是否及格
//maxi 记录学生号,maxj 记录课程号
float avg = 0;
printf("请输入学生数和课程数:");
scanf("%d %d",&n,&m);
maxi=maxj=0;
for(i=0;i<n;i++)
{
bloster = 0;
for(j=0;j<m;j++)
{
scanf("%d",&score[i][j]);
if(i!=0 && j!=0)
{
if(score[maxi][maxj] < score[i][j])
{
maxi = i;
maxj = j;
}
}
if(score[i][j] < 60)
bloster = 1;
sum += score[i][j];
}
}
if(bloster)
loster[k++] = i;
printf("最高成绩的学生号和课程号分别是:%d,%d\n",maxi+1,maxj+1);
for(i=0;i<k;i++)
{
printf("学生号%d的学生有不及格成绩,其各科成绩如下:\n",loster[i]+1);
for(j=0;j<m;j++)
printf("%d ",score[loster[i]][j]);
printf("\n");
}
printf("所有课程平均分为:%.1f\n",sum*1.0/(n*m));
return 0;
}
5.19 有n个国家名,要求按字母先后顺序排列,并按顺序输出。
#include <stdio.h>
#include <string.h>
void sort(char cs[5][20])
{
int i,j,p;
char st[20]; // 临时存储字符串
for(i = 0;i < 5;i++)
{
p = i;
strcpy(st,cs[i]); //strcpy:将字符串2复制到字符数组1中
// 找出最大一个的位置
for(j = i + 1;j < 5;j++)
{
if(strcmp(cs[j],st) < 0) // strcmp:比较字符串
{
p = j; // p记录最小值的位置
strcpy(st,cs[j]);
}
}
if( p != i)
{
strcpy(st,cs[i]);
strcpy(cs[i],cs[p]);
strcpy(cs[p],st);
}
puts(cs[i]);
}
}
int main()
{
char cs[5][20];
int i;
printf("输入五个国家的名字:\n");
for(i = 0;i < 5;i++)
{
gets(cs[i]); //当作一维数组
}
printf("\n");
sort(cs);
return 0;
}
二、注意
2.1 折半查找
#include<stdio.h>
#include<stdlib.h>
int main(){
int arr[19] = {2,5,6,7,8,13,15,17,19,21,23,25,26,27,28,35,41,52,63};
int left = 0, mid, right = 18, x;
printf("输入要查找的数:");
scanf("%d", &x);
while(left <= right){
mid = (left + right) / 2;
if(x == arr[mid]){
printf("该元素的的下标为%d\n", mid);
exit(0);
}
else if(x > arr[mid])
left = mid + 1;
else
right = mid - 1;
}
printf("没有找到该元素!\n");
return 0;
}
2.2 冒泡排序
#include<stdio.h>
int main(){
int arr[10] = {32,5,6,10,8,13,25,17,9,12};
int i = 0, j = 0, temp;
printf("排序前:");
for(i = 0; i < 10; i++){
printf("%d ", arr[i]);
}
printf("\n");
for(i = 0; i < 9; i++){
for(j = 0; j < 9 - i; j++){
if(arr[j] > arr[j + 1]){
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
printf("排序后:");
for(i = 0; i < 10; i++){
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
2.3
(1)
char *p;
scanf("%s", p); p未事先分配内存,野指针
(2)
void func2(char (&p)[10])
{
printf("%d ", sizeof(p));
}//p是装10个char类型数据的数组的引用,其结果类似于char p[10];10
printf("%d ", sizeof(char &));//1
(3)
sizeof(int)不是函数,值在编译时确定
(4)
&a[0]+1表示元素a[0]的地址加1
&a[0]++包含有对&a[0]的赋值运算,本身是非法的
(5)
int x =5;
const int * const p = &x; //* p =1;×
const int &q=x; //q++; × &q赋值初始化常量也会报错 这题本身就不成立
int const *next=&x; //next++;√
const int *j=&x; //(*j)++;×
(6)
int a=5, b=3, t;
int &ra = a;
int &rb = b;
t = ra;
ra = rb;
rb = t;//a和b的值被交换, 输出 a = 3, b = 5
对于&a而言,如果前面有类型符(如 int &a),它必然是对引用的声明。
引用就是变量的别名,对引用的操作就是对变量本身的操作,因此这个程序就是把变量a和b的值互换。