C语言二级题解:查找字母以及其他字符个数、数字字符串转双精度值、二维数组上下三角区域数据对调

简介: 本文详解C语言二级考试三类典型题:统计字母及非字母字符个数、数字字符串转双精度浮点数、二维数组上下三角区域数据对调。含题目解析、错误定位与完整代码,适合备考学生、中职生及编程爱好者提升实战能力。

前言

本文来讲解:
查找字母以及其他字符个数、数字字符串转双精度值、二维数组上下三角区域数据对调

C语言二级,最好是能弄懂每一道程序题,这样会对自己的编程能力有很大的提升
适用人群:

  1. 要参加C语言二级
  2. 中职学生
  3. 想提升C语言编程思维
  4. C语言爱好者

一、程序填空题 --- 查找字母以及其他字符个数

难度:⭐

题目

以下程序的功能是:
统计字符串 (长度不超过 1000 个字符) 中每个字母的个数(不区分大小写),若字符不是字母,则统一归为其他字符。

请在程序的下划线处填入正确的内容并把下划线删除,使程序得出正确的结果。

代码如下:
在1️⃣2️⃣3️⃣处填空

#include<stdio.h>
#include<string.h>
void countstr(char *st,int cutor[]);
void main()
{
    char s[1000];
/**********************found***********************/
    int counters[27]= ___1️⃣___,i;
    printf("Input a string\n");
    gets(s);
    countstr(s,counters);
/**********************found***********************/
    for(i=0; i<=___2️⃣___;i++)
        printf("%c : %d\n",i+65,counters[i]);
    printf("others : %d\n",counters[i]);
}
void countstr(char *st,int cutor[])
{
    int i,j;
    char t;
    i=strlen(st);
    for(j=0;j<i;j++)
    {
        t=st[j];
        if(t>='a'&&t<='z')
           t=t-'a'+'A';
        if(t>='A'&&t<='Z')
/**********************found***********************/
           cutor[t- ___3️⃣___]++;
        else
            cutor[26]++;
    }
}

分析

根据题意以及代码可知
利用27个元素的cutor数组存储26个元素以及1个其他符号
当遇到字母a或A(不区分大小写),则在0号元素位置加一
也就是:'A' - 'A'   ---->  '任意字母' - 'A' 就是对应的数组下标了

解答代码如下:

#include<stdio.h>
#include<string.h>
void countstr(char *st,int cutor[]);
void main()
{
    char s[1000];
/**********************found***********************/
    //因为数组里存放的是26个字母以及其他字符的个数
    //所以要先初始化为 0
    int counters[27]= 1️⃣{0},i;
    printf("Input a string\n");
    gets(s);
    countstr(s,counters);
/**********************found***********************/
    //因为由for循环下面的输出语句可以知道
    //最下面个的是输出其他字符
    //那么当前的这个循环就是输出字母
    //字母有26个,从0开始就是到25
    for(i=0; i<=2️⃣25;i++)
        printf("%c : %d\n",i+65,counters[i]);
    printf("others : %d\n",counters[i]);
}
void countstr(char *st,int cutor[])
{
    int i,j;
    char t;
    i=strlen(st);
    for(j=0;j<i;j++)
    {
        t=st[j];
        if(t>='a'&&t<='z')
           t=t-'a'+'A';
        if(t>='A'&&t<='Z')
/**********************found***********************/
           //因为这里要保存某个字母的出现次数
           //所以就要将对应的字母转换为相应的元素
           //也就是字母 - 字符A就可以求得当前元素位置了
           cutor[t- 3️⃣'A']++;
        else
            cutor[26]++;
    }
}

二、程序修改 --- 数字字符串转双精度值

难度:⭐⭐⭐

题目

函数 int strtoval (char pst [], double* p) 的功能是,将 pst 中带符号的数字字符串转换成双精度数值,直到遇到非数字字符为止。函数返回值为 1 表示转换成功,为 0 表示转换失败,函数成功转换后的数值存储在指针 p 所指的存储单元中。
如:
+123.65a 转换数值后输出 + 123.650000,函数返回值为 1。
-32-3 转换数值后输出 - 32.000000,函数返回值为 1。
56.76a 转换数值后输出 + 56.760000,函数返回值为 1。
283.125 转换数值后输出 + 283.125000,函数返回值为 1。
对 + a8.6 转换失败,函数返回值为 0,输出出错信息。
请改正函数 fun 中指定部位的错误,使它能得出正确的结果。
注意:不要改动 main 函数,不得增行或删行,也不得更改程序的结构。

代码如下:
在代码中找出3个错误并修改

#include<stdio.h>
int strtoval(char pst[],double* p)
{
    int sucs;
    int plus;
    int i=0;
    double frac=0.1;
    *p=0.0;
    while(pst[i]==' ') i++;
/**********************found***********************/
    if(pst[i]=='+'&& pst[i]>='0'&&pst[i]<='9')
    {
        plus=1;
        sucs=1;
    }
    else if(pst[i]=='-')
    {
        plus=0;
        sucs=1;
    }
    else 
    {
        sucs=0;
        return sucs;
    }
/**********************found***********************/
    if(pst[i]=='+'&& pst[i]=='-')
        i++;
    if(pst[i]==' ')
        i++;
    if(!(pst[i]>='0'&&pst[i]<='9'))
    {
        sucs=0;
        return sucs;
    }
    while(pst[i]!='\0')
    {
        if(pst[i]>='0'&&pst[i]<='9')
        {
            *p=*p*10+pst[i]-'0';
            i++;
        }
        else if(pst[i]== '.')
            break;
        else 
        {
            if(plus==0)
                *p=-1.0**p;
            return sucs;
        }
    }
/**********************found***********************/
    if(pst[i]!= '.')
    {
        i++;
        while(pst[i]!='\0')
        {
            if(pst[i]>='0'&&pst[i]<='9')
            {
                *p=*p+(pst[i]-'0')*frac;
                frac/=10;
                i++;
            }
            else
            {
                if(plus==0)
                    *p=-1.0**p;
                return sucs;
            }
        }
        return sucs;
         }
         return sucs;
}
void main()
{
    char str[][100]={
        "    +123.65a",
        "    -32-3",
        "    56.76a",
        "    + 283.125",
        "    +a8.6"   
    };
    double a;
    int i;
    for(i=0;i<5;i++)
        if(strtoval(str[i],&a)==1)
            printf("vol=%f\n",a);
        else 
            printf("error,the string is %s\n",str[i]);
}

分析

简要分析题意:
函数 strtoval 的功能是将字符串 pst 转换为双精度浮点数
并将结果存储在指针 p 所指向的内存中
函数返回一个整数,表示转换是否成功,1 表示成功,0 表示失败

根据题意可以知道(可以先分析变量的作用):
sucs 用于检测转换是否成功
plus 用于标记数值是正数还是负数
frac 用于处理小数部分,初始值为 0.1

解答代码如下:

#include<stdio.h>
int strtoval(char pst[], double* p) {
    // sucs 用于记录转换是否成功,1 表示成功,0 表示失败
    int sucs;
    // plus 用于记录数值是正数还是负数,1 表示正数,0 表示负数
    int plus;
    // i 作为数组的索引,用于遍历字符串
    int i = 0;
    // frac 用于处理小数部分,初始值为 0.1,后续每处理一位小数就缩小 10 倍
    double frac = 0.1;
    // 将指针 p 所指向的内存初始化为 0.0,为后续存储转换后的双精度浮点数做准备
    *p = 0.0;
    // 跳过字符串开头的空格字符
    // 因为输入的字符串可能在数字或符号前有多个空格,所以使用循环跳过这些空格
    while (pst[i] == ' ') i++;
    /**********************found***********************/
    // 如果当前字符是 '+' 或者是数字字符
    // 这意味着字符串开头可能是正号或者直接是数字
    //所以要用逻辑或
    if (pst[i] == '+'|| (pst[i] >= '0' && pst[i] <= '9')) {
        // 记录为正数
        plus = 1;
        // 记录转换可能成功,因为当前字符符合预期,后续还需继续检查
        sucs = 1;
    } 
    // 如果当前字符是 '-'
    // 表示字符串代表的是一个负数
    else if (pst[i] == '-') {
        // 记录为负数
        plus = 0;
        // 记录转换可能成功,后续同样要继续检查剩余字符
        sucs = 1;
    } 
    // 若既不是 '+'、'-' 也不是数字字符
    // 说明字符串的起始部分不符合数字转换的要求
    else {
        // 记录转换失败
        sucs = 0;
        // 返回失败结果,终止函数执行
        return sucs;
    }
    /**********************found***********************/
    // 如果当前字符是 '+' 或者 '-'
    // 这是符号位,在后续处理数字时需要跳过
    if (pst[i] == '+' || pst[i] == '-')
        // 跳过符号字符
        i++;
    // 如果跳过符号后当前字符是空格
    // 同样需要跳过,保证后续处理的是有效的数字字符
    if (pst[i] == ' ')
        // 继续跳过空格
        i++;
    // 如果当前字符不是数字字符
    // 即跳过符号和可能的空格后,没有紧接着有效的数字,说明转换无法继续
    if (!(pst[i] >= '0' && pst[i] <= '9')) {
        // 记录转换失败
        sucs = 0;
        // 返回失败结果,终止函数执行
        return sucs;
    }
    // 以下开始处理整数部分,直到字符串结束
    while (pst[i] != '\0') {
        // 如果当前字符是数字字符
        if (pst[i] >= '0' && pst[i] <= '9') {
            // 将当前数字字符转换为数字并累加到 *p 中
            // 通过 pst[i] - '0' 把字符形式的数字转换为对应的数值,然后更新 *p
            *p = *p * 10 + (pst[i] - '0');
            // 移动到下一个字符,继续处理后续内容
            i++;
        } 
        // 如果遇到小数点
        // 意味着整数部分处理结束,要开始处理小数部分
        else if (pst[i] == '.')
            // 跳出循环,开始处理小数部分
            break;
        // 如果遇到非数字和非小数点的字符
        // 说明字符串中出现了不符合数字格式的内容
        else {
            if (plus == 0)
                *p = -1.0 * *p;
            return sucs;
        }
    }
/**********************found***********************/
    //如果是小数点的话,就进行小数位的运算
    if(pst[i]== '.')
    {
        i++;
        while(pst[i]!='\0')
        {
            if(pst[i]>='0'&&pst[i]<='9')
            {   //小数位的转换
                //先让小数位的数字乘frac(初始为0.1)
                //之后再将frac*10也就是小数的又后一位
                //就可以让其变成小数了
                *p=*p+(pst[i]-'0')*frac;
                frac/=10;
                i++;
            }
            else
            {
                if(plus==0)
                    *p=-1.0**p;
                return sucs;
            }
        }
        return sucs;
         }
         return sucs;
    
}
void main() {
    char str[][100] = {
        "    +123.65a",
        "    -32-3",
        "    56.76a",
        "    + 283.125",
        "    +a8.6"
    };
    double a;
    int i;
    for (i = 0; i < 5; i++) {
        if (strtoval(str[i], &a) == 1)
            printf("vol=%f\n", a);
        else
            printf("error,the string is %s\n", str[i]);
    }
}

程序修改题里面,如果没有思路,可以根据运算符来猜测怎样修改
因为计算机二级考试会有
/**********************found***********************/
这一行进行注释,那么这一行的下面一般就是程序错的位置了

小数位字符串转数字

这里提到了小数位数的字符串转小数,还是很实用的,这里再讨论一下这里

int frac = 0.1;
int i;
for(i = 0; pst[i] != '\0'; i++)
{
    //小数位的转换
    //先让小数位的数字乘frac(初始为0.1)
    //之后再将frac*10也就是小数的又后一位
    //就可以让其变成小数了
    *p=*p+(pst[i]-'0')*frac;
    frac/=10;
    i++;
}

三、程序设计 --- 二维数组上下三角区域数据对调

难度:⭐⭐⭐

题目

编写一个函数 void change(int p[][N], int n),其功能是将一个 int 型二维数组的上下三角区域的数据对调,数组大小限制在 100X100。

例如,N = 7 时,有二维数组:

上下三角区域的数据对调后 a 数组内容为:

int a[N][N] = {
{11,12,13,14,15,16,17},
{21,22,23,24,25,26,27},
{31,32,33,34,35,36,37},
{41,42,43,44,45,46,47},
{51,52,53,54,55,56,57},
{61,62,63,64,65,66,67},
{71,72,73,74,75,76,77} 
};
{11,21,31,41,51,61,71,
12,22,32,42,52,62,72,
13,23,33,43,53,63,73,
14,24,34,44,54,64,74,
15,25,35,45,55,65,75,
16,26,36,46,56,66,76,
17,27,37,47,57,67,77}

代码如下:
在change函数中编写

#include<stdio.h>
#define N 7
void change(int p[][N],int n)
{
    
}
void main()
{   int i,j;
    int a[N][N]={
    {11,12,13,14,15,16,17},
    {21,22,23,24,25,26,27},
    {31,32,33,34,35,36,37},
    {41,42,43,44,45,46,47},
    {51,52,53,54,55,56,57},
    {61,62,63,64,65,66,67},
    {71,72,73,74,75,76,77}
    };
    for(i=0;i<N;i++)
    {
        for(j=0;j<N;j++)
            printf("%4d",a[i][j]);
        printf("\n");
    }
    change(a,N);    
        printf("对调后的二维数组:\n");
    for(i=0;i<N;i++)
    {
        for(j=0;j<N;j++)
            printf("%4d",a[i][j]);
        printf("\n");
    }
}

分析

本题看似偏难,但是往正确的方向去想了,找到规律了,就容易了
上下三角区域:也就是右斜中心线不动,对应的行和列进行对调,如图

所以可以先定义i和j两个变量来充当二维数组的行和列
i为行下标,j为列下标
解答代码如下:

#include<stdio.h>
#define N 7
void change(int p[][N],int n)
{
    int i, j;
    //控制行
    for( i = 0; i < n; i++ )
        //控制列
        //i + 1是因为在i的左边是已经换好了的
        //那么i的右边则是没有交换过的
        //而与i相等没必要做交换所以j = i + 1;
        for( j = i+1; j < n; j++ )
        {   
            //行列行列进行交换
            int flag = p[i][j];
            p[i][j] = p[j][i];
            p[j][i] = flag;
        }
}
void main()
{   int i,j;
    int a[N][N]={
    {11,12,13,14,15,16,17},
    {21,22,23,24,25,26,27},
    {31,32,33,34,35,36,37},
    {41,42,43,44,45,46,47},
    {51,52,53,54,55,56,57},
    {61,62,63,64,65,66,67},
    {71,72,73,74,75,76,77}
    };
    for(i=0;i<N;i++)
    {
        for(j=0;j<N;j++)
            printf("%4d",a[i][j]);
        printf("\n");
    }
    change(a,N);    
        printf("对调后的二维数组:\n");
    for(i=0;i<N;i++)
    {
        for(j=0;j<N;j++)
            printf("%4d",a[i][j]);
        printf("\n");
    }
}

这里就是要注意列j的变化

希望本文对您有所帮助(* ̄︶ ̄)
本文专栏:C语言二级
苟日新,又日新,日日新

目录
相关文章
|
2月前
|
存储 弹性计算 监控
二手ERP对接闲鱼API:聚石塔强制入塔后的架构重构实录(正文骨架)
本文为二手ERP对接闲鱼API的权威重构指南,直击2026年聚石塔强制入塔新规。全文基于alibaba.idle.isv.*官方接口实测,涵盖入塔决策、全闭环接口清单(商品/订单/用户)、双Token模型、消息驱动架构、闲管家与第三方采集双通道设计、成色/验货字段映射、5大高频坑及合规红线,并附Python可运行源码。专为CTO/技术总监选型而写,240字。
|
2月前
|
缓存 人工智能 数据挖掘
阿里云qwen3.8-max模型详解:模型能力、价格、上下文限制及使用注意事项参考
本文全面解析阿里云的Qwen3.8-Max旗舰大模型,这款采用2.4万亿参数MoE架构的通义千问系列最强模型,定位为智能体时代全能旗舰,在全球5个核心区域同步部署。它具备百万级超长上下文窗口,支持文本、图像、2小时内长视频的原生多模态输入,可独立完成跨天级软件工程交付、法律金融等专业领域生产级任务,同时实现数千轮交互下的长程任务自主规划与闭环迭代。文章同步梳理了不同区域的功能支持差异、梯度定价策略与API调用要点,明确了其适配复杂智能体应用的核心优势,新用户登录百炼平台即可领取百万Tokens免费试用额度。
阿里云qwen3.8-max模型详解:模型能力、价格、上下文限制及使用注意事项参考
|
3月前
|
人工智能
Qwen3.8抢先体验!正式版即将发布并开源!
千问Qwen3.8即将开源,参数达2.4T,进化速度以“天”计,实力媲美Fable 5。预览版Qwen3.8-Max已上线阿里Token Plan等平台,限时优惠:日间Credits低至1折,夜间更优,个人/团队版月付仅35元起!
5161 158
|
2月前
|
Java 程序员 应用服务中间件
Maven之初识与安装
本文详解Maven安装与配置全流程:从基础概念、下载安装、环境变量配置到版本验证,助新手一次理清逻辑、顺利完成部署;涵盖一键构建、依赖管理核心功能,并提供交流支持。
200 0
Maven之初识与安装
|
2月前
|
存储 弹性计算 人工智能
阿里云服务器租赁费用全解析:收费标准、计费模式与活动报价参考
对于个人开发者、学生群体以及中小规模企业来说,云服务器租赁已经成为数字化业务落地的主流选择。不用采购笨重昂贵的实体硬件设备,开箱即用,支持弹性扩缩容,极大降低了企业与个人的上云门槛。但很多初次接触云服务器的使用者,常常被复杂的计费规则、多样的实例规格、五花八门的活动报价弄得无从下手,经常出现前期预估成本和实际收到的账单差距巨大的问题。本文完整梳理阿里云服务器租赁收费体系,区分轻量应用服务器与ECS云服务器两大产品线的计费逻辑,拆解包年包月、按量付费、抢占式实例三类主流付费模式,梳理新用户、老用户、企业用户对应的活动报价,同时附上可直接使用的命令行实操代码,帮助使用者精准评估租赁成本,避开各类计
420 1
|
2月前
|
人工智能 编解码 数据可视化
AI 漫剧本地部署实战|AI 音色克隆集成,漫剧配音素材与工程落地
本文详解AI漫剧本地化量产方案,聚焦语音配音短板,提供1000+克隆必备音色素材合集(含青年/少年/中老年/情绪向等分类),配套预训练音色调用与AI声音克隆双模式Python工程代码,支持ComfyUI集成、显存优化及版权合规指南,实现端到端离线漫剧全自动生产。
|
2月前
|
机器学习/深度学习 算法 C语言
二级C语言题解:矩阵主、反对角线元素之和,二分法求方程根,处理字符串中 * 号
本文详解三道C语言编程题:①矩阵主/反对角线元素求和(填空);②二分法求方程根(修改错误);③删除字符串中间的“*”号(程序设计)。含题目分析、易错点解析与完整代码,助力算法与指针实践能力提升。
96 1
二级C语言题解:矩阵主、反对角线元素之和,二分法求方程根,处理字符串中 * 号
|
2月前
|
C语言 数据安全/隐私保护
二级C语言题解:二维数组每行最大值与首元素交换、删除结构体的重复项、取出单词首字母
本教程专为C语言二级考生、中职学生及编程初学者设计,涵盖三大核心题型:二维数组每行最大值与首元素交换、结构体重复项删除(保留首个)、字符串单词首字母提取。含详细分析、易错点解析与标准代码,助你夯实基础、提升解题思维。
108 2
二级C语言题解:二维数组每行最大值与首元素交换、删除结构体的重复项、取出单词首字母
阿里云轻量应用服务器68元/年,新用户特价,不要退款,重新买价格459元,涨价了!
阿里云轻量应用服务器新用户专享价68元/年(2核2G、200M带宽、40GB ESSD),秒杀低至38元。⚠️地域选定后不可修改,退款将失去新用户资格,再购恢复原价459元/年!务必下单前确认地域,避免浪费优惠。阿里云轻量应用服务器官网:https://t.aliyun.com/U/dwftch
|
2月前
|
人工智能 安全 中间件
AI 帮你改了 20 个文件,最后 3 个忘了改——长任务为什么总是"差一口气"?
AI长任务常因“失忆”、误删、静默跳过、截断编造等问题翻车。UseIO通过Plan驱动拆解、检查点回滚、三级安全门控、结构化错误处理与交付前四点复查,构建工程级可靠性防护链,显著提升多文件重构等复杂任务的完成率与稳定性。(239字)

热门文章

最新文章