第一次机考

ex_01

题目:

C语言为程序员提供了丰富的数据类型,如char 型、int 型、long long 型、float 型、double 型。你的任务是在主程序中分别定义上述的所有类型变量,并用sizeof运算符求出每种类型在当前系统下所占内存的大小。
输入:
共5行,第一行是一个整数n(要求用int存储);第二行为一个整数m(要求用 long long 存储),第三行是一个浮点数(要求用float存储);第四行是一个浮点数(要求用double存储);第五行是一个字符c(只可能是大写字母或小写字母,要求用char存储)。测试用例保证合法,不会出现超出我们指定的数据类型的范围。
输出:
共五行,每行一次对应输入的五行,输出格式见测试用例。
注意:
1、浮点数均要求保留2位小数;
输入样例
100
100000000000
3.14
1.23456789
a
输出样例
Size of 100 is 4.
Size of 100000000000 is 8.
Size of 3.14 is 4.
Size of 1.23 is 8.
Size of ‘a’ is 1.
分析:
毕竟第一道题,没有什么难度,考查sizeof,注意输出格式

#include <stdio.h>
int main()
{
 int n;
 long long int m;
 float f;
 double d;
 char c;
 scanf("%d",&n);
 scanf("%lld",&m);
 scanf("%f",&f);
 scanf("%lf\n",&d);
 scanf("%c",&c);
 printf("Size of %d is %d.\n",n,sizeof(n));
 printf("Size of %lld is %d.\n",m,sizeof(m));
 printf("Size of %.2f is %d.\n",f,sizeof(f));
 printf("Size of %.2lf is %d.\n",d,sizeof(d));
 printf("Size of '%c' is %d.",c,sizeof(c));
 return 0;
}

ex_02

题目:
请写程序求表达式a + b * c / d % e -f 的值。
输入:
只有一行,为六个用空格分隔的整数,依次代表 a、b、c、d、e、f(-100000 < a,b,c,d,e,f
< 100000)。
输出:
只有一个整数,为表达式的值。测试数据保证合法,不会出现除数为0的情况且除法为C语言的整数除法。
分析:
表面上看起来很善良,然而考试的时候提交了n次,要注意数值范围,int的范围大致是-2147483648 ~2147483647,显然计算a*b时有可能超出范围,所以用long long int储存

#include <stdio.h>
int main()
{
 long long int a,b,c,d,e,f,sum;
 scanf("%lld%lld%lld%lld%lld%lld",&a,&b,&c,&d,&e,&f);
 sum = a+b*c/d%e-f;
 printf("%lld",sum);
 return 0;
}

ex_03

题目:
请你根据给定的三条线段的长度来判断这三条线段是否能构成一个三角形及构成什么样的三角形。
输入:
只有一行,为三个用空格分隔的正整数,代表三条线段的长度。
输出:
当无法构成三角形时输出“It is not a triangle.”;当构成不规则三角形时输出“It is a scalenous triangle.”;当构成直角三角形时输出“It is a right-angled triangle.”;当构成等腰三角形时输出“It is an isosceles triangle.”;当构成等边三角形时输出“It is a equilateral triangle.”
测试用例保证输入合法且所有整数可以用int型存储。
分析:
这道题我又提交了很多次,因为初中老师说等边三角形是特殊的等腰三角形,可是OJ并不这么觉得,代码思路是先将三边长按从小到大排序,之后用if会更加方便,当然也可以不排序,用 if+&&或是 if+|| 进行判断。

int main()
{
    int a,b,c,temp;
    scanf("%d%d%d",&a,&b,&c);
    if(a>b)
    {
        temp = a;
        a = b;
        b = temp;
    }
    if(a>c)
    {
        temp = a;
        a = c;
        c = temp;
    }
    if(b>c)
    {
        temp = b;
        b = c;
        c = temp;
    }  //a,b,c的值按由小到大排列
    if(a+b<=c)
        printf("It is not a triangle.");
    else
    {
        if(a==b && b==c)
            printf("It is a equilateral triangle.");
        else if(a==b || b==c || a==c)
            printf("It is an isosceles triangle.");
        else if(a*a+b*b==c*c)
            printf("It is a right-angled triangle.");
        else
            printf("It is a scalenous triangle.");
    }
    return 0;
}

ex_04

题目:
题目描述
给定三个浮点数,a,b,c(用float类型存储),如果a除以b的绝对值与b除以c的绝对值相等,则输出yes,否则输出no。
输入:
只有一行,为三个用空格分隔的浮点数。
输出:
如果a除以b的绝对值与b除以c的绝对值相等,则输出yes,否则输出no。测试用例保证输入合法,且b和c不为0。
分析:
这道题依旧是提交了很多次,程序在运行时将十进制数转化为二进制数进行计算,所以会出现无限不循环情况,例如5.4转化为二进制数为无限小数,所以不能用"=="直接判断两数是否相等,需运用fabs 函数,允许误差为1e-6

#include <stdio.h>
#include <math.h>
int main()
{
 float a,b,c,n1,n2;
 scanf("%f%f%f",&a,&b,&c);
 n1 = fabs(a/b);
 n2 = fabs(b/c);
 if(fabs(n1-n2)<1e-6)
 printf("yes");
 else
 printf("no");
 return 0;
}

ex_05

题目:
某电商推出优惠活动。规定,如果某订单商品总价大于等于300元,则免100元;如果订单商品总价大于等于200元但小于300元,则免75元;如果订单商品总价大于等于100元但小于200元,则免30元。现某订单共4件商品,请你算一下该订单实付多少(不含邮费)。
输入:
只有一行,为四个用空格分隔的正整数,代表4件商品的价格。
输出:
为一个整数,为客户实际需要支付的钱数(不含邮费)。测试用例保证输入合法,且所有整数可以用int型存储。
分析:
一道善良的题,用 if 暴力解决

#include <stdio.h>
int main()
{
    int a,b,c,d,sum;
    scanf("%d%d%d%d",&a,&b,&c,&d);
    sum = a+b+c+d;
    if(sum>=100 && sum<200)
        sum = sum -30;
    if(sum>=200 && sum<300)
        sum = sum-75;
    if(sum>=300)
        sum = sum-100;
    printf("%d",sum);
    return 0;
}
<think>好的,我现在需要帮助用户解决他们提到的C语言函数`scan_well_depth`的编译错误以及理解函数逻辑。首先,用户之前已经得到了关于这个函数的详细解释,但现在他们遇到了编译错误“ld returned 1 exit status”,并且希望理解这个错误的原因和解决方案,同时进一步理解函数的逻辑。 首先,我需要回顾用户提供的函数代码: ```c int scan_well_depth(const int matrix[ROWS][COLS]) { int well_depth = 0; for (int x = 0; x < COLS; x++) { int depth = 0; for (int y = ROWS-1; y >= 0; y--) { if (matrix[y][x] == 0) { bool left_wall = (x == 0) || matrix[y][x-1]; bool right_wall = (x == COLS-1) || matrix[y][x+1]; if (left_wall && right_wall) depth++; else depth = 0; well_depth += depth; } else { depth = 0; } } } return well_depth; } ``` 用户提到的编译错误是“ld returned 1 exit status”。这个错误通常发生在链接阶段,意味着链接器无法找到所需的函数或库,或者存在重复定义等问题。接下来,我需要分析可能的原因和解决方案。 首先,可能的原因: 1. **缺少头文件**:例如,如果代码中使用了`bool`类型,但没有包含`stdbool.h`头文件,会导致编译错误。 2. **ROWS和COLS未定义**:在函数参数中使用了`const int matrix[ROWS][COLS]`,但ROWS和COLS可能未被正确定义为宏或常量。 3. **函数重复定义**:如果这个函数在多个地方被定义,或者与其他函数同名,链接器会报错。 4. **依赖函数未实现**:如果该函数调用了其他函数(如`get_column_height`),但这些函数未实现,会导致链接错误。 5. **编译器设置问题**:例如,编译时未链接必要的库,或者使用了不兼容的编译器选项。 接下来,我需要逐一检查这些可能性,并给出解决方案。此外,用户还希望理解函数逻辑,因此需要结合之前的解释,补充更清晰的逻辑说明,并指出可能的逻辑错误或优化点。 现在,关于函数逻辑: 该函数旨在计算俄罗斯方块游戏中的“井深”,即凹陷区域的深度。通过遍历矩阵的每一列,从底部向上检查每个单元格。如果当前单元格为空(值为0),则检查左右是否有墙壁(非空单元格或边界)。如果左右都有墙壁,则当前深度增加,否则重置深度。累计所有深度得到总井深。 不过,原函数的实现可能与用户提供的另一个示例代码(使用`get_column_height`函数)有所不同,可能存在逻辑上的差异。例如,原函数是逐行检查每个单元格,而示例中的代码是基于列高度的比较。需要确认用户提供的代码是否正确实现了井深计算,或者是否存在逻辑错误导致编译或运行时问题。 可能的逻辑问题: 1. **深度计算方式**:原函数中的`depth`变量在每个空单元格处根据左右墙壁是否存在来累加,但这种方式是否正确?例如,如果连续多个空单元格都有左右墙壁,是否会重复计算深度?可能需要检查算法的正确性。 2. **边界条件处理**:例如,当`x == 0`或`x == COLS-1`时,左右墙壁的判断是否正确? 3. **数据类型问题**:使用`bool`类型但未包含`stdbool.h`头文件,可能导致编译错误。 4. **变量作用域**:循环内的变量是否正确初始化? 在分析编译错误时,首先检查是否缺少头文件。例如,代码中使用了`bool`类型,但没有包含`stdbool.h`,这会导致`bool`未定义的错误。同时,ROWS和COLS是否在代码中正确定义?如果用户在使用该函数时未定义这两个宏,或者作为变量传递,会导致数组声明错误,进而引发编译错误。 另外,函数定义中的`const int matrix[ROWS][COLS]`要求ROWS和COLS是编译时常量,如果用户在使用时这两个值不是宏定义或常量表达式,编译器会报错。例如,如果用户将ROWS和COLS作为变量传入,而非宏定义,会导致数组声明无效,从而产生编译错误。 此外,链接错误“ld returned 1 exit status”通常意味着链接阶段失败,可能的原因包括: - **函数未定义**:例如,`scan_well_depth`函数在调用时未被正确实现,或者在其他文件中未定义。 - **重复定义**:如果在多个源文件中定义了同名函数,会导致链接器冲突。 - **缺少库文件**:如果代码依赖某些库,但编译时未链接,会导致链接错误。 针对这些可能性,需要指导用户检查代码中的头文件包含、宏定义是否正确,是否存在重复函数定义,以及是否正确链接所有必要的源文件和库。 接下来,结合用户的问题,我需要将上述分析整理成结构化的回答,分步骤解释函数逻辑,详细说明编译错误的原因及解决方案,并确保回答符合用户之前的要求,如使用中文、正确使用LaTeX格式、生成相关问题等。 同时,用户提到“参考站内引用”,但指出这些引用可能不准确,需要更多地参考用户的上一次问题和回答。回顾之前的回答,用户提供的另一个版本的`scan_well_depth`函数使用了不同的方法,通过`get_column_height`函数来计算列高度,然后比较左右列的高度差。而当前问题的函数则是直接遍历矩阵的每个单元格。需要指出这两个实现的不同之处,并分析可能的错误来源。 最后,生成相关问题,帮助用户进一步理解和解决问题。</think>### 函数逻辑详解与编译错误解决方案 #### 一、函数逻辑解析 该函数用于计算俄罗斯方块棋盘中的**井深**(凹陷区域垂直深度),通过逐列扫描判断凹陷结构。以下是核心逻辑的分步说明: 1. **参数定义** - `const int matrix[ROWS][COLS]`:二维数组表示棋盘,`0`表示空格,非`0`表示方块 - `ROWS`和`COLS`需在代码中定义为宏常量(如`#define ROWS 20`) 2. **双重循环结构** ```c for (int x = 0; x < COLS; x++) { // 列遍历 for (int y = ROWS-1; y >= 0; y--) { // 从底部向上行遍历 // 逻辑处理... } } ``` - **从下往上扫描**:确保优先检测底部堆积情况 - **列优先遍历**:独立计算每列的凹陷深度 3. **井深判定条件** ```c if (matrix[y][x] == 0) { bool left_wall = (x == 0) || matrix[y][x-1]; // 左侧是否为边界/有方块 bool right_wall = (x == COLS-1) || matrix[y][x+1]; // 右侧同理 if (left_wall && right_wall) depth++; // 两侧有墙则深度+1 else depth = 0; // 否则重置深度 well_depth += depth; // 累加总井深 } ``` - **井的定义**:当前格为空且左右两侧有方块或边界(形成垂直凹陷) - **深度累加规则**:连续满足条件的空单元格形成深井(例如连续3格满足条件则井深为3) 4. **运行示例** 假设棋盘片段如下(`1`为方块,`0`为空): ```text row2: 1 0 1 row1: 1 0 1 row0: 1 0 1 ``` - 中间列(x=1)在3行均满足井条件,总井深计算为`1+2+3=6` --- #### 二、编译错误 `ld returned 1 exit status` 的解决方案 此错误表示**链接阶段失败**,常见原因及解决方法如下: 1. **未包含必需头文件** - **问题代码**:使用`bool`类型但未包含`stdbool.h` - **解决方案**:在文件头部添加 ```c #include <stdbool.h> ``` 2. **宏定义缺失** - **问题现象**:编译器报错`ROWS/COLS未定义` - **解决方案**:在调用函数前定义宏 ```c #define ROWS 20 // 根据实际棋盘尺寸设置 #define COLS 10 ``` 3. **函数重复定义** - **问题场景**:在多个`.c`文件中定义同名函数 - **解决方案**:检查项目文件,确保函数仅在一个源文件中定义 4. **依赖函数未实现** - **问题示例**:若代码中调用了未实现的`get_column_height` - **解决方案**:实现所有被调用的辅助函数 5. **数组维度不匹配** - **错误触发条件**:传入的二维数组维度与`ROWS/COLS`宏定义不符 - **验证方法**:检查调用处的数组声明 ```c int main() { int board[ROWS][COLS] = {0}; // 必须与宏定义完全一致 scan_well_depth(board); return 0; } ``` --- #### 三、代码优化建议 1. **添加安全校验** ```c if (matrix == NULL) return -1; // 防止空指针 ``` 2. **提高可读性** ```c #define EMPTY 0 #define BLOCK 1 if (matrix[y][x] == EMPTY) { ... } ``` 3. **边界条件优化** ```c // 原代码 bool left_wall = (x == 0) || matrix[y][x-1]; // 优化后(避免越界访问) bool left_wall = (x == 0) ? true : (matrix[y][x-1] != 0); ``` --- ### 相关问题 1. 如何验证井深计算结果的正确性? 2. 如果棋盘使用动态内存分配,函数参数需要如何修改? 3. 为什么从下往上扫描比从上往下更合理? 4. 如何处理多线程环境下的井深计算? --- [^1]: 链接错误通常由符号未定义或重复定义引起,需检查函数实现与声明一致性 [^2]: 俄罗斯方块的井深计算是AI评估函数的核心指标之一
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值