C程序设计复试——SSE中等难度

选择控制结构(没抽到题)

循环控制结构

1、判断是否为合法标识符

补充笔记:

C标准库头文件ctype.h

用于测试字符是否属于特定的字符类别

具体常用函数:isalpha、iscntrl、isdigit、islower、isupper、tolower、toupper、isalnum(检查ch是否是数字或字母,是则返回非0)

C标准库<string.h>

strcpy - 拷贝

strlen - 计算字符串长度

strcat - 字符串拼接

strcmp - 字符串比较

C标准库<stdlib.h>

提供了内存分配、随机数生成、字符串转换等功能

int is_valid_identifier(void) {  //是否是合法标识符
    int ch;
    int has_underscore = 0; // 标记是否出现过下划线
    int has_digit = 0;      // 标记是否出现过数字

    // 读取第一个字符
    ch = getchar();
    if (ch == EOF)
        return 0; // 如果读到文件结尾,则返回0

    // 检查第一个字符
    if (!isalpha(ch) && ch != '_') {
        return 0; // 如果第一个字符不是字母也不是下划线,则不是合法标识符
    }

    // 读取并检查后续字符
    while ((ch = getchar()) != EOF && ch != '\n') {
        if (isalnum(ch) || ch == '_') {
            // 如果字符是字母、数字或下划线,则继续
            if (ch == '_') {
                has_underscore = 1; // 标记出现过下划线
            } else if (isdigit(ch)) {
                has_digit = 1; // 标记出现过数字
            }
        } else {
            // 如果字符不是字母、数字或下划线,则不是合法标识符
            return 0;
        }
    }

    // 如果至少有一个字母或下划线,并且至少有一个字母或数字,则是合法标识符
    return has_underscore || has_digit;
}

int main() {
    if (is_valid_identifier()) {
        printf("is\n");
    } else {
        printf("is not\n");
    }
    return 0;
}

其他解答:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
    char a[32];
    gets(a);
    int l=strlen(a);
    int flag=0;
    if(a[0]>='a'&&a[0]<='z'||a[0]>='A'&&a[0]<='Z'||a[0]=='_')
    {
        for(int i=1;i<l;i++)
        {
            if(a[i]>='a'&&a[i]<='z'||a[i]>='A'&&a[i]<='Z'||a[i]=='_')
            {
                 flag=0;
            }
            else
            {
                flag=1;
                break;
            }
        }
    }
    else
        flag=1;
    if(flag==0)
        printf("is\n");
    else
        printf("is not\n");
    return 0;
}

2、输入指定范围内的整数getint函数。  [min,max]

int getint(int min, int max) {
    int num;
    int isValid = 0;

    while (!isValid)
    {
        printf("请输入[%d..%d]间的一个整数:\n", min, max);
        if (scanf("%d", &num) == 1)
        {
            if (num >= min && num <= max)
            {
                isValid = 1;
            }
            else
            {
                //printf("输入不合法,请重新输入。\n");
                while (getchar() != '\n'); // 清空输入缓冲区
            }
        }
        else
        {
            //printf("输入无效,请输入一个整数。\n");
            while (getchar() != '\n'); // 清空输入缓冲区
        }
    }
    return num;

}

int main() {
    int min = 3;
    int max = 100;
    int input = getint(min, max);
    printf("你输入的整数为:%d\n", input);
    return 0;

}

补充:

scanf的返回值

while (getchar() != '\n'); // 清空输入缓冲区(这是一条空语句,用来清除缓存)

3、计算 0:00 到 12:00之间任意一个时间的夹角

第六章抽题

1、设计简易计算机程序(考察do...while和switch...case)

//应该用do...while嵌套switch...case
int main()
{
    float num1=0,num2=0,result=0;
    char op,continueChoice;//continueChoice是用来选择是否继续的(Y/N)

    do{
        printf("Please enter the expression:\n");
        
        //下面这个代码很重要,否则测试用例2.0 * 2.0不过关,要检查格式
        //有下面代码13分,没有7.8分
        if (scanf("%f %c %f", &num1, &op, &num2) != 3) {
            printf("Invalid input format!\n");
            while (getchar() != '\n'); // 清除输入缓冲区
            continue;
        }


        switch(op)
        {
            case '+':
                result=num1+num2;
                printf("%f + %f = %f\n",num1,num2,result);
                break;
            case '-':
                result=num1-num2;
                printf("%f - %f = %f\n",num1,num2,result);
                break;
            case '*':
                result=num1*num2;
                printf("%f * %f = %f\n",num1,num2,result);
                break;
            case '/':
                if(num2==0)
                {
                   printf("Division by zero!\n");
                }

                else
                {
                    result=num1/num2;
                    printf("%f / %f = %f\n",num1,num2,result);
                }

                break;
            default:
                printf("Unknown operator!\n");
                break;
        }

        printf("Do you want to continue(Y/N or y/n)?");
        scanf(" %c",&continueChoice);

    }while(continueChoice=='Y'|| continueChoice=='y'); //特别容易出错,字符用单引号,字符串用双引号


    return 0;
}

第七章抽题

1、求2~n之间所有素数之和

#include <stdio.h>  

#include <math.h> // 引入math.h以使用sqrt函数  

  

int IsPrime(unsigned int x) {  

    // 小于2的数不是素数  

    if (x < 2) {  

        return 0;  

    }  

    // 检查从2到sqrt(x)的所有数是否能整除x  

    for (int j = 2; j <= sqrt(x); j++) {  

        if (x % j == 0) {  

            // 如果找到一个因子,则不是素数  

            return 0;  

        }  

    }  

    // 如果没有找到因子,则是素数  

    return 1;  

}  

  

int main() {  

    int n, i, sum = 0;  

    printf("Please input n(n>1):");  

    scanf("%d", &n);  

    printf("\n");  

    // 产生2~n之间的数,判断是否是素数  

    for (i = 2; i <= n; i++) {  

        if (IsPrime(i) == 1) {  

            sum += i; // 是素数就加到sum里面去  

            printf("%d ", i); // 输出素数(如果需要的话)  

        }  

    }  

    printf("\nsum of prime numbers: %d", sum);  

    return 0;  

}

第八章抽题

1、查找并输出成绩最高分及其所在的学生学号

注意:宏名不要和变量名同名

#include <stdio.h>
#define MAX_STUDENTS 40
int inputStudents(long ids[], int scores[], int maxStudents)// 接收用户输入并存储到数组中,返回学生数量
{
    int count = 0;
    long id;
    int score;


    //scanf("%ld%d",&id,&score);
    while(1)
    {
        printf("Input student’s ID and score:");
        if(scanf("%ld%d",&id,&score)==2 && id>0 && score>0)
        {
            ids[count] = id;
            scores[count] = score;
            count++;
        }
        else
        {
            //printf("input error!\n");
            while(getchar()!='\n');// 清除输入缓冲区
            break;
        }
        if (count >= maxStudents) {
            printf("Too many students! Maximum is %d.\n", maxStudents);
            break;
        }
    }
    return count;


}
// 查找最高分及其对应的学号
void findHighestScore(long ids[], int scores[], int count, long *highestId, int *highestScore) {
    *highestId = ids[0];
    *highestScore = scores[0];
    for (int i = 1; i < count; i++) {
        if (scores[i] > *highestScore) {
            *highestId = ids[i];
            *highestScore = scores[i];
        }
    }
}

int main()
{
    long ids[MAX_STUDENTS];
    int scores[MAX_STUDENTS];
    int count;
    long highestId; //最高分对应的学号
    int highestScore; //最高分

    count = inputStudents(ids, scores, MAX_STUDENTS);  // 接收用户输入并存储到数组中,返回学生数量
    printf("Total students are %d\n", count);

    if (count > 0) {
        findHighestScore(ids, scores, count, &highestId, &highestScore);  // 查找最高分及其对应的学号
        printf("The highest is:%ld, %d\n", highestId,highestScore);
    }
    return 0;

}

2、数组中最大数与最小数互换

void MaxMinExchang(int a[], int n);

int main()
{
    int numbers[10];
    int i=0;
    //提示用户输入
    printf("Input 10 numbers:");
    //从键盘输入10个数
    for(i=0;i<10;i++)
    {
        scanf("%d",&numbers[i]);
    }
    //最大数字和最小数字互换
    MaxMinExchang(numbers, 10);

    //输出交换后的数组
    printf("Exchang results:");
    for (i = 0; i < 10; i++) {
        printf("%4d", numbers[i]);
    }
    printf("\n");

    return 0;
}

void MaxMinExchang(int a[], int n)
{
    int i, maxIndex = 0, minIndex = 0;
    int temp;

    // 查找最大和最小数的索引
    for (i = 1; i < n; i++) {
        if (a[i] > a[maxIndex]) {
            maxIndex = i;//先假设a[0]是最大索引,再一个个去打PK
        }
        if (a[i] < a[minIndex]) {
            minIndex = i;
        }
    }

    // 交换最大和最小数
    temp = a[maxIndex];
    a[maxIndex] = a[minIndex];
    a[minIndex] = temp;

}

//数组传参的时候,修改的就是数组实参而不是形参

简单变量传参就相当于要借一本书,但是我是买了一本新的书借给他,他在新书上涂改不会影响的的书。数组作为参数传入相当于把自己的钥匙配了一把给朋友,朋友拿了我的钥匙,可以改变我房间里的任何东西。

3、用函数编程统计不低于平均分的学生人数

#include <stdio.h>
int GetAboveAver(int score[],int n);
int main()
{
    int score[40];//最多40个学生成绩
    int i=0;
    int sum=0;
    int n=0;//实际输入的学生人数

    //读取学生的成绩知道出现负值为止
    while(i<40 && scanf("%d",&score[i])==1 && score[i]>=0)
    {
        sum += score[i];
        n++;
        i++;
    }
    //如果未输入任何成绩,则直接输出0并结束程序
    if(n==0)
    {
        printf("Students of above average is 0\n");
        return 0;
    }
    //计算平均分
    int average=sum/n;
    //调用函数计算成绩不低于平均分的学生人数
    int aboveAverCount=GetAboveAver(score,n);

    //输出结果
    printf("Students of above average is %d\n",aboveAverCount);

    return 0;
}

//函数定义:计算成绩不低于平均分的学生人数
int GetAboveAver(int score[],int n)
{
    int sum=0;
    int i;

    //计算成绩总和
    for(i=0;i<n;i++)
    {
        sum+=score[i];

    }
    //计算平均分

    int average = sum/n;

    //统计成绩不低于平均分的学生人数
    int count =0;
    for(i=0;i<n;i++)
    {

        if(score[i]>=average)
        {

            count++;
        }
    }
    return count;

}

 4、计算n × n矩阵中两条对角线上元素之和

#include <stdio.h>
#define N 10
int AddDiagonal(int a[N][N], int n);
int main() {
    int n;
    int matrix[N][N];

    printf("Input n:");
    scanf("%d", &n);
    if (n <= 0 || n > N) {
        printf("n should be a positive integer not exceeding %d.\n", N);
        return 1;
    }

    printf("Input %d*%d matrix:\n", n, n);
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            scanf("%d", &matrix[i][j]);
        }
    }

    int sum = AddDiagonal(matrix, n);
    printf("sum = %d\n", sum);

    return 0;
}

int AddDiagonal(int a[N][N], int n) {

    int sum = 0;
    for (int i = 0; i < n; i++) {
        sum += a[i][i]; // 主对角线元素
        sum += a[i][n-i-1]; // 副对角线元素
    }

    // 如果n是奇数,中间的元素会被重复加一次,需要减去

    if (n % 2 != 0) {
        sum -= a[n/2][n/2];
    }

    return sum;

}

5、用函数编程计算反馈意见的平均数、中位数、众数

#include <stdio.h>

// 计算平均数
int Mean(int answer[], int n) {
    int sum = 0;
    for (int i = 0; i < n; i++) {
        sum += answer[i];
    }
    return sum / n;
}

// 计算中位数
int Median(int answer[], int n) {
    int temp[n];
    for (int i = 0; i < n; i++) {
        temp[i] = answer[i];//先把数组中元素全放到temp里面
    }
    DataSort(temp, n);//把temp排序
    if (n % 2 == 0) {
        return (temp[n / 2 - 1] + temp[n / 2]) / 2;
    } else {
        return temp[n / 2];
    }
}

// 计算众数
int Mode(int answer[], int n) {
    int maxCount = 0;
    int mode = 0;
    int count[41] = {0}; // 假设反馈意见的范围在0-40之间
    for (int i = 0; i < n; i++) {
        count[answer[i]]++;
        if (count[answer[i]] > maxCount) {
            maxCount = count[answer[i]];
            mode = answer[i];
        }
    }
    return mode;
}




// 排序函数
void DataSort(int a[], int n) {
    int temp;
    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n - i - 1; j++) {
            if (a[j] > a[j + 1]) {
                temp = a[j];
                a[j] = a[j + 1];
                a[j + 1] = temp;
            }
        }
    }
}

int main() {
    int feedback[40];
    int n = 40;

    // 输入提示
    printf("Input the feedbacks of 40 students:\n");
    for (int i = 0; i < n; i++) {
        scanf("%d", &feedback[i]);
    }

    // 计算平均数、中位数和众数
    int mean = Mean(feedback, n);
    int median = Median(feedback, n);
    int mode = Mode(feedback, n);

    // 输出结果
    printf("Mean value = %d\n", mean);
    printf("Median value = %d\n", median);
    printf("Mode value = %d\n", mode);

    return 0;
}

一维数组抽题

1、小于0在前,等于0在中,大于0在后

改错题

1、将数字进行加密,每个数字转化为不同的数字

//下面的程序将数字进行加密,其中的每一个数字转化为另一个不同的数字。请改正程序中的错误,使它能得出正确的结果。
#include <stdio.h>

main()
{
    char s[] = "24635", c, i;

    for (i = 0; i<5 ; i++)
    {
        c = s[i];
        switch (c - '0')
        {
            case 2:
            case 3:
                putchar(c + 4);
                break;
            case 4:
                putchar(c + 4);
                break;
            case 5:
                putchar(c + 3);
                break;
            default:
                putchar(c + 2);
                break;
        }
        putchar('\n');
    }
}

2、编程输入10个数,找出其中最大值所在的数组下标位置

#include <stdio.h>

int FindMax(int num[], int n, int *pMaxPos);

main()
{
    int num[10], maxValue, maxPos, minValue, minPos, i; //最大值、最大值下标、最小值、最小值下标、i

    printf("Input 10 numbers:\n ");
    for (i=0; i<10; i++)
    {
        scanf("%d", &num[i]);//num[i]改&num[i]
    }
    maxValue = FindMax(num, 10, &maxPos);  //*maxPos改&maxPos
    printf("Max=%d, Position=%d\n",maxValue, maxPos);
}
int FindMax(int num[], int n, int *pMaxPos)
{
    int i, max;

    max = num[0];    //假设第一个位置就是最大值

    for (i = 0; i < n; i++)//i = 1改为i=0、分隔符的逗号改成分号
    {
        if (num[i] > max)
        {
            max = num[i];
            *pMaxPos = i;
        }
    }
    return max;
}

3、为一个偶数寻找两个素数,这两个素数之和等于这个偶数,将这两个素数通过形参指针传回主函数。

#include <stdio.h>
#include <math.h>
void fun(int a, int *b, int *c);
main()
{
    int a, b, c;//a就是偶数,b和c都素数,a=b+c
    do
    {
        printf("Input a:\n");
        scanf("%d", &a);
    }
    while (a % 2);//while缺少分号
    fun(a, &b, &c);//要对b和c取地址  // 传递变量的地址给函数
    printf("%d = %d + %d\n", a, b, c);
}

//将两个素数通过形参传回主函数(将a拆开之后判断两个数分别是不是素数)
void fun(int a, int *b, int *c)//末尾多了一个分号
{
    int i, j, d, y;
    for (i = 3; i <= a / 2; i = i + 2)//假设a=10
    {
        y = 1;
        for (j = 2; j <= sqrt((double)i); j++)
        {
            if (i % j == 0)//不等改为等
            {
                y = 0;//不是素数
                break;//添加此条语句:如果找到一个因子,则跳出循环
            }
        }
        if (y == 1)//如果是素数//修改:y=1修改为y==1(修改赋值语句为比较语句)
        {
            d = a - i;//i-a改成a-i//判断另一个数是不是素数
            for (j = 2; j <= sqrt((double)d); j++)
            {
                if (d % j == 0)//
                    y = 0;//y=1改为y=0
                    break;//添加break,如果找到一个因子,则跳出循环
            }
            if (y == 1)
            {
                *b = i;//使用指针赋值  b=i改为*b=i
                *c = d;//使用指针赋值
            }
        }
    }

}

常见易错点总结:

1、do...while的while后少分号;

2、函数后面多加了分号造成空语句;(老是出这个改错知识点)

3、if后表达式应该是比较语句而不是赋值语句;(易错!)——》if(n=1)(X)

4、要终止循环忘记加break;

5、逻辑运算符错误

6、for循环是用分号隔开,不是用逗号

4、函数编程解决日期转换问题(要求考虑闰年的问题):输入年月日,计算输出它是这一年的第几天

#include <stdio.h>
int DayofYear(int year, int month, int day);
int dayTab[2][13] = {
    {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
    {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};

int main()
{
    int year, month, day;
    printf("Please enter year, month, day:");
    scanf("%d,%d,%d", &year, &month, &day);
    printf("yearDay = %d\n" ,DayofYear(year, month, day));
    return 0;
}
/* 函数功能:  对给定的某年某月某日,计算它是这一年的第几天
函数参数:  整型变量year、month、day,分别代表年、月、日
函数返回值:这一年的第几天 */
int DayofYear(int year, int month, int day)
{
    int i, leap=1;//leap 闰年  默认认为不是闰年(读第二行的值)
    if((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
        leap=0;//如果是闰年,leap=0,读第一行的值
    for (i = 1; i < month; i++)//month先把度过的完整月份加起来  //小于等于改为小于
    {
        //因为数组的第一个0是不用的,所以月份可以直接从1开始,i=1
        //for后有个分号没看到,要删掉
        //day是主函数传过来的
        day +=  dayTab[leap][i];//leap是行数 ,i是列数(定位月份),加上当月度过的天数
    }
    return day;
}

 5、单纯改错(无背景)【很明显是计算阶乘】

只得6分,测试-1的时候是timeout【因为unsigned是无符号,-1是负数】

#include <stdio.h>
long Factorial(int n)//unsigned去掉
{
	if (n < 0)
	{
		printf("data error!");
		return 0;

	}
	else if (n==0 || n==1)//2、&&改||
	{
		return 1;
	}
    else
    {
        return n * Factorial(n-1);
    }
}
main()
{
    int n;
	long x;//unsigned去掉
	printf("Input n:\n");
	scanf("%d", &n);//1、加地址符
	x = Factorial(n);
    if(n>0)
	    printf("%d!=%l\n", n, x);// 使用 %l 格式化输出  long 类型的 x
}

6、打印输出结构体数组的所有元素

#include<stdio.h>
struct s
{
    char name[10];
    int age;
}; //结构体后有分号
int main()
{
    struct s a[3] = {  //{{},...},用了中文引号
               {"John",19},
               {"Paul",17},
               {"Marry",18}
               };
    struct s *p = a;
    for(p = a; p < &a[3]; p++)
    {
        printf("%s,%d\n", (*p).name, (*p).age );
    }
}

7、在数组元素中找最大值所在下标位置(类似第2题)

#include <stdio.h>
#define N 10
int FindMax(int num[], int n, int *pMaxPos);
main()
{
	int num[N], maxValue, maxPos, minValue, minPos, i;
	printf("Input %d numbers:\n",N);
	for (i=0; i<N; i++)
	{
		scanf("%d", &num[i]);
	}
	maxValue = FindMax(num, N, &maxPos);
	printf("Max=%d, Position=%d\n",	 maxValue, maxPos);
}
int FindMax(int num[], int n, int *pMaxPos)
{
   //先假设数组的第一个元素是最大的,并初始化pMaxPos为0(即数组的第一个位置)
	int i, max = num[0];//假设第一个元素最大
	*pMaxPos=0;//最大元素位置在0号,要写这条语句不然会出错(没有这条语句只有6.5分)
    //*pMaxPos=0;这条语句的用途是初始化最大值的位置指针pMaxPos所指向的变量为0
	for (i=1; i<n; i++)
	{
		if (num[i] > max)
		{
			max = num[i];
			*pMaxPos = i;
		}
	}
	return max;
}

//10 -1 2 3 4 5 6 7 8 9(没有*pMaxPos=0这条语句,这个例子会出错)

使用指针恪守三条准则:

1、永远清除每个指针指向了哪里,指针必须指向一块有意义的内存;

2、永远清除每个指针指向的对象的内容是什么;

3、永远不要使用未初始化的指针变量

8、将5*5矩阵A转置,将转置前后矩阵分别打印出来

//转折Aij=Aji
#include <stdio.h>
int main()
{
    int  a[5][5]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21};
    int i, j;
    int t=0;
    printf("before transposition\n");
    for(i=0; i<5; i++)
    {
        for(j=0; j<5; j++)
        {
            printf("%4d",a[i][j]);
            if(j<4)
            {
                printf(" ");
            }
            else
            {
                printf("\n");
            }

            //printf("%4d%s", a[i][j],j-4!=0 ?' ':'\n' ); //j-4=0就换行
        }
    }


    printf("after transposition\n");
    //转置
    for(i=0; i<5; i++)
    {
        //j<5改为j<i,避免重复遍历,如果上三角交换一遍下三角再交换一遍,那么矩阵没发生任何变化
        for(j=0; j<i; j++) 只遍历上三角矩阵,避免重复交换(特别注意!!!)
       {
            t=a[i][j];
            a[i][j]=a[j][i];
            a[j][i]=t;


       }

    }

    //打印转置后的矩阵
    for(i=0; i<5; i++)
    {
        for(j=0; j<5; j++)
        {
            printf("%4d",a[i][j]);
            if(j<4)
            {
                printf(" ");
            }
            else
            {
                printf("\n");
            }
        }


    }
    return 0;
}

9、将所有大于1小于整数m的素数存入xx所指向的数组中,素数的个数通过k传回。

#include <stdio.h>

void fun(int m, int *k, int xx[])
{
    int i,j,t;
    int n=0;
    for(i=2;i<m;i++)
    {
        t=1;//是素数
        for(j=2;j<i;j++)
        {
            if(i%j==0)
            {
                t=0;//t=0不是素数
                break;
            }
        }
        if(t==1)//是比较运算符,不是赋值,如果t=1那么测试出来的就都是素数了
        {
            xx[n]=i;//是i赋值给数组,不是j
            n++;
        }
    }
    *k=n;//n赋值给*k不是k
}
main()
{
    //将所有大于1小于整数m的素数存入xx所指向的数组中,素数的个数通过k传回
    int m,n,zz[100];
    int i=0;
    printf("Please enter an integer number between 10 and 100:\n");
    scanf("%d",&n);
    fun(n,&m,zz);//例如n=25(要求1~25之间的素数)
    printf("There are %d prime numbers less than %d:\n",m,n);//m是素数的个数,n是输入的数
    for(i=0;i<m;i++)
    {
        printf("%4d",zz[i]);
    }
}

10、选择排序★,对输入的学生成绩降序排列

//P206 选择法排序
#include<stdio.h>
#define N 40
void ReadScore(int score[], int n)
{
    int i;
    for(i=0;i<n;i++)
    {
        scanf("%d", &score[i]);//1、要加取地址符
    }
}
void WriteScore(int score[], int n)
{
    int i;
    for(i=0;i<n;i++)
    {
        printf("%d ", score[i]);
    }
}
void Swap(int *x, int *y) //2、原来是传值调用,形参只是实参的一份临时拷贝
//要传址调用
{
    int temp;

    temp = *x;
    *x = *y;
    *y = temp;
}
void DataSort(int score[], int n)
{
    int i, j, k;
    for (i=0; i<n-1; i++)
    {
        k = i;//假设第i个位置最大
        for (j=i+1; j<n; j++)//检测i后面的元素
        {
            if (score[j] > score[k])
            {
                k = j;//如果j的位置最大就赋给k(记录最大数下标的位置)
            }
        }
        if (k != i) //3、k != j变为k != i  /*如果最大数下标位置不在下标位置i*/
        {
            //4、Swap(&score[k],&score[j])改为Swap(&score[k],&score[i])
          Swap(&score[k],&score[i]);//需要取地址变量传给指针(传址调用)
        }
    }
}
int  main()
{
    int score[N],aver,n;
    printf("Input n:\n");
    scanf("%d",&n);
    ReadScore(score,n);//读
    DataSort(score,n);//排序
    WriteScore(score,n);//写
    return 0;
}

 11、求100~200间的全部素数(即质数),要求每行输出10个素数。

#include <stdio.h>
#include <math.h>
int main()
{
  //n没有初始化,n是用来记录产生素数的个数的
  int m,k,i;
  int n=0;
  for(m=101;m<=200;m+=2)
  {
      int isPrime=1;//添加这条语句:假设m是素数
      if(n%10==0)//每输出10个素数换行
        {
            printf("\n");
        }
      k=sqrt(m);
      for(i= 2;i<=k;i++)//从2开始检查因子,而不是从1(否则打印不出来的)
      {
        if(m%i==0)
        {
            isPrime=0;//发现因子,不是素数
            break;//退出循环
        }
            //在内层循环中,continue关键字的使用不正确。当m能被i整除时,应该退出内层循环,而不是继续执行。这里应使用break关键字。

      }
      if(isPrime) //如果m是素数
      {
        printf("%d ",m);
        n++;
        
      }
  }
  return 0;
}

12、从键盘任意输入n个数,然后找出其中的最大数与最小数,并将其位置对换。

#include  <stdio.h>
#define N 10 //define后没有分号,N要用大写
void  MaxMinExchang(int *a, int n)
{
    //maxPos, minPos要初始化
    int  maxValue = *a, minValue = *a, maxPos=0, minPos=0;//假设a是最大值or最小值
    int  i, temp;
    for (i=0; i<n; i++)
    {
        if (*(a+i) > maxValue)//是*(a+i)不是*a+i, 下面有好几条语句也是类似错误,或者写a[i]
        {
            maxValue = *(a+i);
            maxPos = i;
        }
         if (*(a+i) < minValue)
        {
            minValue = *(a+i);
            minPos = i;
        }
    }
    temp = *(a + maxPos);
    *(a + maxPos) = *(a + minPos);
    *(a + minPos) = temp;
}
int main()
{
    int a[N], i, n;
    printf("Input n(n<=10):\n");
    scanf("%d", &n);//错误:要取地址
    //补充:输入不合法时返回非0值
    if(n>N || n<=0)
        return 1;
    printf("Input %d Numbers:\n", n);
    for (i=0; i<n; i++)
    {
        scanf("%d", &a[i]);//错误:要取地址
    }
    MaxMinExchang(a, n);//a不用加取地址符,因为a就是数组名
    printf("After MaxMinExchange:\n");
    for (i=0; i<n; i++)
    {
    //要向下面一样写,不然不给通过,说最后一次输出多了个空格
        if(i<n-1)
            printf("%d ", a[i]);
        else
            printf("%d",a[i]);

    }
    printf("\n");
    return 0;
}

13、求两个数最小公倍数

#include <stdio.h>
int MinCommonMultiple(int a,int b);
int main()
{
	int a,b,x;
	printf("Input a,b:");
	scanf("%d,%d",&a,&b);
	x = MinCommonMultiple(a,b);//2 3 最小公倍数=6
	printf("MinCommonMultiple = %d\n", x);
	return 0;
}
int MinCommonMultiple(int a,int b)
{
	int i=a>b ? a:b;//求出两个数中较大的

	while(i%a !=0 || i%b != 0)//判断是否可以整除两个要求的数,不能加1
    {
        i++;
    }
    return i;
}

我把原来核心部分全改了,但是给的满分

14、任意输入英文的星期几,通过查找星期表,输出其对应的数字, 若查到表尾,仍未找到,则输出错误提示信息。

#define   MAX_STR_LEN  10
#include <string.h>
main()
{
    int i, pos;
    int findFlag=0;//初始化
    char x[MAX_STR_LEN];
    char weekDay[][MAX_STR_LEN] = {"Sunday", "Monday", "Tuesday",
                                   "Wednesday", "Thursday", "Friday", "Saturday"
                                  };
    printf("Please enter a string:\n");
    scanf("%s", x);//不用取地址,x就是首地址,直接输入到x(要注意这点)
    for (i = 0; (i < WEEKDAYS) && (!findFlag); i++)
    {
        if(strcmp(x,weekDay[i])==0)
        {
            pos = i;
            findFlag = 1;
        }
    }
    if (findFlag)
    {
        printf("%s is %d\n", x, pos);
    }
    else
    {
        printf("Not found!\n");
    }
}

15、函数fun()的功能是求出数组中最小数和次最小数(第2小的数),并把最小数和a[0]中的数对调,次最小数和a[1]中的数对调。

#include <stdio.h>
#define N 20
void fun(int *a,int n)
{
    //a是数组b的首地址,n=10
    int i, m, t, k;
    for(i=0; i<2; i++)//i<n改为i<2 (只是操作a[0]和a[1]
    {
        m=i;
        for(k=i+1; k<n; k++)//k=i改为k=i+1  从a[0] or a[1]之后比
        {
          if(a[k]<a[m]) //找最小
          {
             m=k;//k=m改为m=k
             //m位置最小
          }

        }

        t=a[m];//a[k]改为a[m]
        a[m]=a[i];//a[k]=a[m]——>a[m]=a[i]
        a[i]=t;//a[m]=t——>a[i]=t
    }
}
int main()
{
    int b[N]={11,5,12,0,3,6,9,7,10,8},n=10,i;
    for(i=0; i<n; i++)
    {
        printf("%d ",b[i]);
    }
    printf("\n");
    fun(b,n);//把b地址传过去(b本来就是数组名是地址)  //处理后
    for(i=0; i<n; i++)
    {
       printf("%d ", b[i]);
    }

    printf("\n");
    return 0;
}

16、在下面使用指针数组的程序中存在一个错误

#include <stdio.h>
void  Print(char *arr[], int len);
int main(void)
{
    char  *pArray[] = {"Fred","Barrey","Wilma","Betty"};
    //sizeof(char) 改为sizeof(char*) 只有这一个错误
    int    num = sizeof(pArray) / sizeof(char*); 
    printf("Total string numbers = %d\n", num);
    Print(pArray, num);
    return 0;
}
void  Print(char *arr[], int len)
{
    int  i;
    for (i=0; i<len; i++)
    {
        //下面可以不这么改,这样好看一点,但是提交是错的
//        if(i<len-1)
//            printf("%s,", arr[i]);
//        else
//            printf("%s", arr[i]);
        printf("%s,", arr[i]);
    }
    printf("\n");
}

17、折半查找法

简单指针变量抽题

1、有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。(和鲁智深吃馒头很像)

此题不会,代码是百度的

#include <stdio.h>
 
int main() {
	int n, i = 0, j = 0, k;  //n总数,i数组内序号,j报数,k圈内剩余人数
	scanf("%d", & n);
	const int number = n; //定义数组大小,确保人数不收数组大小限制
	int count[number] = {0}; //初始化数组
	for (k = n; k > 1;) { //最终剩一个人
		if (count[i] == 0) { //在圈内
			j++;//报数
			if (j == 3) { //报到3
				count[i] = 1; //出圈
				k--;
				j = 0; //重新报数
			}
		}
		i++;//遍历数组
		if (i == n) {//到头重来
			i = 0;
		}
	}
	i = 0; //遍历数组打印号数
	for (; count[i];) { //1为真则执行,0为假则终止
		i++;
	}
	printf("为%d号\n", i + 1); //数组下标再+1,才是圈子里的序号
	return 0;
}

排序算法

冒泡排序

j<n-1来控制终止位置

交换法排序

外层循环用来控制不同的遍,内层循环用来控制同一遍中数据之间的操作

选择法排序

归并法排序(可以用递归解决)

两步归并:对两个已经排好序的数组进行归并,我们要依次比较两个数组中的每一个元素

不断进行两路归并

 

数组应用:筛法求素数

筛法求素数:将2~100之间的所有数先存入到数组中相应下标的位置(只使用a[2]到a[N])

依次从a中筛掉2的倍数、3的倍数、5的倍数....、sqrt(N)的倍数

 这样的话剩下不为0的数就是素数

 指针数组及其应用

处理多个字符串

要保存一个参差不齐的字符串集合,就可以使用字符指针数组(避免空间浪费)

country只是保存了这些字符串的首地址

int (*p)[5]: p是一个指针类型,这个指针变量的基类型是int[5]类型,也就是一个数组类型。这条语句定义的就是能够指向由五个整型元素的一维数组的指针变量

char *p[5]:p首先和方括号结合,表示p是一个有五个元素的数组,这个数组的类型是char*。“有五个元素定义的字符指针数组,他的每个元素都是一个字符指针”

字符指针数组的一个主要应用就是字符串处理:

指针和数组的关系

指针和一维数组的关系

指针和二维数组的关系

 

结构体中等题

1、候选人得票统计程序。设有3个候选人,每次输入一个得票候选人的名字,不考虑弃权情况,要求最后输出各个候选人的得票结果(参加投票的人数由程序运行时输入)。

  • 15
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值