C语言练习题(14) 有以下函数,该函数的功能是( )int fun(char *s) { char *t = s; while(*t++); return(t-s); }(非常详细的讲解)

2023-10-27

1:有以下函数,该函数的功能是( )

int fun(char *s)
{
char *t = s;
while(*t++);
return(t-s);
}

A: 比较两个字符的大小 B: 计算s所指字符串占用内存字节的个数
C: 计算s所指字符串的长度 D: 将s所指字符串复制到字符串t中


解析 B

*t++ 最后会在’\0’后一个位置停止 '\0’后一个位置为此时指针指向 尾部减去头部包括\0就是字节数

而c答案字符串长度不包括最后的\0

2:若有“ float a[3]={1.5,2.5,3.5},pa=a;(pa++)*=3; ”,则 *pa 的值是( )

A: 1.5 B: 2.5 C: 3.5 D: 4.5

解析 B

*pa=a;指针pa指向a[0]; pa++,返回值仍是pa操作之前的值;

(pa++)取pa指向的地址的值;(pa++)*=3;将该值变为原来的3倍,也就是数组a的第一个值为4.5; 则a[0]此时变为4.5. 由于pa++之后,所以pa指向a[1],所以值为2.5。

此题最重要的地方是pa++是先使用再++,如果没有注意到便会出错选成4.5.

3:以下程序运行后的输出结果是( )

#include <stdio.h>
int main()
{
int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, *p = a + 5, *q = NULL;
*q = *(p+5);
printf("%d %d\n", *p, *q);
return 0;
}

A: 运行后报错 B: 6 6 C: 6 11 D: 5 10

解析 A

*p为6,即数组向后移动五位

*q = *(p+5);这是一个错误语句。

我们将p指针向后移动5个位置,使其指向a数组的第11个元素(即11)。然后我们将p指针指向的值(即11)赋给q指针指向的位置。但是,由于q初始值为NULL,它并没有指向任何有效的内存位置,所以这个赋值操作是非法的。

在接下来的printf函数中,我们尝试输出p和q的值。但由于之前的非法赋值操作导致程序崩溃,因此无法继续执行printf函数,程序异常终止。

4:设有定义 char *p[]={“Shanghai”,“Beijing”,“Honkong”}; 则结果为 j 字符的表达式是( )

A: *p[1] +3 B: *(p[1] +3) C: *(p[3] +1) D: p[3][1]

解析

题中j所在位置即p[1][3],这时有多种办法表示p[1][3],(p[1] +3)或是(*(p+1)+3)
B:先通过p[1]获取指针数组中第2个元素的值,即"Beijing"的地址。然后在这个地址上偏移3个字节,即指向字符串中的第4个字符,即’j’字符。
A: p[1] +3表示对指针数组p中的第2个元素进行解引用操作,即获取字符串常量"Beijing"。然后将字符串的首字母’B’的ASCII码值与3相加。
C:
(p[3] +1) 表示对指针数组p中的第4个元素进行解引用操作,但是p数组中只有3个元素,所以超出了数组的有效索引范围。这是非法的表达式。
D:p[3][1] 表示对指针数组p中的第4个元素进行解引用操作,但是p数组中只有3个元素,所以超出了数组的有效索引范围。这是非法的表达式。

5:以下叙述中正确的是( )

A: 即使不进行强制类型转换,在进行指针赋值运算时,指针变量的基类型也可以不同
B: 如果企图通过一个空指针来访问一个存储单元,将会得到一个出错信息
C: 设变量p是一个指针变量,则语句p=0;是非法的,应该使用p=NULL;
D: 指针变量之间不能用关系运算符进行比较

解析 B

A:指针变量的赋值只能赋予地址, 决不能赋予任何其它数据,否则将引起错误;
C: p=NULL ;和 p=0 ;是等价的;
D:指向同一数组的两指针变量进行关系运算可表示它们所值数组元素之间的关系。

D:例如,可以使用等号运算符(==)来比较两个指针变量所指向的元素是否相等。如果相等,则表示它们指向同一个元素。
① 可以使用大于号(>)或小于号(<)来比较两个指针变量所指向的元素的大小关系。如果一个指针变量的值大于另一个指针变量的值,则表示第一个元素在数组中的位置靠后。相反,如果一个指针变量的值小于另一个指针变量的值,则表示第一个元素在数组中的位置靠前。
② 还可以使用大于等于号(>=)或小于等于号(<=)来比较两个指针变量所指向的元素的大小关系。如果一个指针变量的值大于或等于另一个指针变量的值,则表示第一个元素在数组中的位置靠后或相同。相反,如果一个指针变量的值小于或等于另一个指针变量的值,则表示第一个元素在数组中的位置靠前或相同。
③需要注意的是,对指针变量进行关系运算时,必须确保两个指针变量指向同一类型的数组元素,否则结果可能不准确。此外,还要注意避免指针越界访问数组元素,否则会导致未定义的行为。

6:珠玑妙算游戏(the game of master mind)的玩法如下。

计算机有4个槽,每个槽放一个球,颜色可能是红色(R)、黄色(Y)、绿色(G)或蓝色(B)。例如,计算机可能有RGGB 4种(槽1为红色,槽2、3为绿色,槽4为蓝色)。作为用户,你试图猜出颜色组合。打个比方,你可能会猜YRGB。要是猜对某个槽的颜色,则算一次“猜中”;要是只猜对颜色但槽位猜错了,则算一次“伪猜中”。注意,“猜中”不能算入“伪猜中”。
给定一种颜色组合solution和一个猜测guess,编写一个方法,返回猜中和伪猜中的次数answer,其中answer[0]为猜中的次数,answer[1]为伪猜中的次数。

示例:
输入: solution=“RGBY”,guess=“GGRR”
输出: [1,1]
解释: 猜中1次,伪猜中1次。

核心代码模式:

int* masterMind(char* solution, char* guess, int* returnSize)
{
    *returnSize = 2;
    int *res = (int *)calloc(2, sizeof(int));
    int count=0;
    for (int i=0;i<4;i++)
    {
        if (solution[i]==guess[i])
        {
            solution[i] = 0;
			guess[i] = 0;
            count++;
        }
    }
    res[0]=count;
   int fake_count=0;
        for (int i=0;i<4;i++)
        {
            for (int j=0;j<4;j++)
            {
                if (solution[i] == guess[j] && guess[j] != 0)
			    {
				guess[j] = 0;
				fake_count++;
				break;
			    }   
            }
        }
        res[1]=fake_count;
        return res;
}

完整代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
int* masterMind(char* solution, char* guess, int* returnSize)
{
    *returnSize = 2;
    int* res = (int*)calloc(2, sizeof(int));
    int count = 0;
    for (int i = 0; i < 4; i++)
    {
        if (solution[i] == guess[i])
        {
            solution[i] = 0;
            guess[i] = 0;
            count++;
        }
    }
    res[0] = count;
    int fake_count = 0;
    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            if (solution[i] == guess[j] && guess[j] != 0)
            {
                guess[j] = 0;
                fake_count++;
                break;
            }
        }
    }
    res[1] = fake_count;
    return res;
}

int main() 
{
    char solution[4] = {0};
    char guess[4] = {0};
    for (int i = 0; i < 4; i++)
    {
        scanf("%c", &solution[i]);
    }
    for (int i = 0; i < 4; i++)
    {
        scanf("%c", &guess[i]);
    }
    int returnSize;
    int* result = masterMind(solution, guess, &returnSize);
    printf("count: %d\n", result[0]);
    printf("fake_count: %d\n", result[1]);
    free(result);
    return 0;
}

解析
代码中的变量说明:

solution:表示正确的序列,由4个数字组成。
guess:表示玩家猜测的序列,也由4个数字组成。
returnSize:表示返回结果的数组的大小,这里设置为2。
res:表示返回的结果数组,其中res[0]表示正确位置数,res[1]表示错误位置数。

代码的执行过程如下:

①首先将返回结果数组的大小设置为2,并分配2个int类型的空间。 定义一个count变量,用来记录猜中数字和位置正确的数量,初始化为0。
② 遍历solution和guess数组的每个元素,如果当前位置的数字相等,则表示猜中了,将solution和guess数组中对应位置的数字都设为0,同时count自增1。

数字设置为0是为了防止下一次循环出现重复。

③ 将正确位置数保存到结果数组的第一个位置res[0]中。 定义一个fake_count变量,用来记录仅猜中数字但位置不正确的数量,初始化为0。

④使用两个嵌套的循环分别遍历solution和guess数组的每个元素,如果当前位置的数字在guess数组中可以找到且没有被匹配过(不为0),则表示猜中了数字但位置不正确,将guess数组中对应位置的数字设为0,同时fake_count自增1,并跳出内层循环。

同样的,数字设置为0是为了防止下一次循环出现重复。

⑤将错误位置数保存到结果数组的第二个位置res[1]中。 返回结果数组res。

7:给出一个整型数组 numbers 和一个目标值 target,请在数组中找出两个加起来等于目标值的数的下标,返回的下标按升序排列。

(注:返回的数组下标从1开始算起,保证target一定可以由数组里面2个数字相加得到)
数据范围:2≤len(numbers)≤10 ^5,−10≤numbers i ≤10 ^9 ,
0≤target≤10 ^9

示例1
输入:[3,2,4],6
返回值:[2,3]
说明:因为 2+4=6 ,而 2的下标为2 , 4的下标为3 ,又因为 下标2 < 下标3 ,所以返回[2,3]

示例2
输入:[20,70,110,150],90
返回值:[1,2]
说明:20+70=90

int* twoSum(int* numbers, int numbersLen, int target, int* returnSize ) 
{
  *returnSize = 2;
   int* res = (int*)calloc(2, sizeof(int));
   for (int i=0;i<numbersLen;i++)
   {
    for (int j=i+1;j<numbersLen;j++)
    {
        if (numbers[i]+numbers[j]==target)
        {   
                res[0]=i+1;
                res[1]=j+1;   
            break;
        }
    }
   }
   return res;
}

提示:运行是可以通过的,但是运行超时了,呜呜呜呜呜呜呜,再写一个吧。

不超时版核心代码:

int* twoSum(int* numbers, int numbersLen, int target, int* returnSize ) 
{
    int size=2;
    int* target_arr=(int*)malloc(sizeof(int)*size);
    for(int i=0;i<numbersLen;i++)
    {
        if(numbers[i]>target+10)
        {
            continue;
        }
         
        for(int j=i+1;j<numbersLen;j++)
        {  
            if(numbers[i]+numbers[j]==target)
            {
                target_arr[0]=i+1;
                target_arr[1]=j+1;
            }
             
        }
    }
    *returnSize=size;
    return target_arr;
}

不超时版完整代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>

int* twoSum(int* numbers, int numbersLen, int target, int* returnSize)
{
    int size = 2;
    int* target_arr = (int*)malloc(sizeof(int) * size);
    for (int i = 0; i < numbersLen; i++)
    {
        if (numbers[i] > target + 10)
        {
            continue;
        }

        for (int j = i + 1; j < numbersLen; j++)
        {
            if (numbers[i] + numbers[j] == target)
            {
                target_arr[0] = i + 1;
                target_arr[1] = j + 1;
            }

        }
    }
    *returnSize = size;
    return target_arr;
}

int main() 
{
    int numbers[] = {0};
    int numbersLen = 0;
    scanf("%d",&numbersLen);
    for (int k = 0; k < numbersLen; k++)
    {
        scanf("%d", &numbers[k]);
    }
    int target = 0;
    scanf("%d", &target);
    int returnSize = 0;
    int* result = twoSum(numbers, numbersLen, target, &returnSize);
    printf("%d, %d\n", result[0], result[1]);
    free(result);
    return 0;
}

解析

①首先,外层的for循环用于遍历数组中的每一个元素。循环变量i的初始值为0,每次迭代增加1,直到达到数组的长度。

②在内层的for循环中,用变量j从i+1开始遍历数组中剩下的元素。这是因为我们要找的是两个不同的数,因此不需要重复计算已经计算过的组合。

③在每一次内层循环中,首先判断numbers[i]和numbers[j]的和是否等于目标值target。如果是,则将i和j的索引分别加1赋值给数组a的第一个和第二个元素。这样就找到了满足条件的两个数的索引。

④如果内层循环中的条件不满足,则执行continue语句,跳过本次循环继续执行下一次。这是因为根据给定的条件,如果numbers[i]大于target+10,那么numbers[j]肯定也会大于target+10,因此不需要继续进行计算,直接进入下一次外层循环。

为什么numbers[i]的值超过了目标值target加上10,就不存在满足条件的组合?
这是因为组合的每个元素都是正整数,所以每次选择一个元素加到组合中,组合的值就会增加。当组合的值超过了目标值加上10,说明即使后续选择的元素都是最小的元素1,也无法使组合的值减小到小于等于目标值,因此就不存在满足条件的组合。因为mumbers的取值是可以为-10的!!
举例 [20,-10,5,5] target=10这种情况10+10=20,是可以满足的,但是如果是[21,-10,5] target=10,10+10=20,这种情况就不可以了。已经比它大了。

总结起来,这个条件判断的目的是对数组中的元素进行过滤,排除掉那些已经超过目标值加上10的元素,以提高代码执行的效率。

⑤最后,代码执行完毕后,数组a中存储着满足条件的两个数的索引值。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C语言练习题(14) 有以下函数,该函数的功能是( )int fun(char *s) { char *t = s; while(*t++); return(t-s); }(非常详细的讲解) 的相关文章

随机推荐

  • 事务的相关内容

    1 事务 事务 Transaction 是一系列对系统中数据进行访问与更新的操作所组成的一个程序执行逻辑单元 1 事务的语法 2 事务的特性 3 事务的并发问题 4 事务的隔离级别 1 1 事务的语法 1 开启事务 start transa
  • VMware Workstation 与 Device/Credential Guard 不兼容 解决方案

    win10专业版官方解决方案 https kb vmware com s article 2146361 win10家庭版解决方案 win10家庭版本身是不支持Hyper V服务的 但是如果是 win10预览体验家庭版 会在 服务 中发现有
  • Arduino - 看门狗定时器(WDT:Watch Dog Timer)

    看门狗定时器 WDT Watch Dog Timer 实际上是一个计数器 一般给看门狗一个大数 程序开始运行后看门狗开始倒计数 如果程序运行正常 过一段时间CPU应该发出指令让看门狗复位 令其重新开始倒计数 如果看门狗计数减到0 就认为程序
  • 针对于CentOS8安装docker与compose的教程

    针对安装持续报错问题 为了避免掉坑 请跟着教程一步步来 安装完centOS 8系统之后 我们先配置一个国内的yum源 先确保网络的连通 这是我的版本号 1 首先进入 etc yum repos d 目录下 新建一个bak目录 用于保存系统中
  • ArgumentException:Input Axis vertical is not setup.

  • Windows下通过远程桌面连接向远程电脑传输文件

    一 打开远程桌面连接 在搜索框中输入 远程桌面连接 进入下面的界面 二 配置连接 点击显示选项 选择本地资源 查看详细信息 选择要使用的磁盘 我要使用D盘中的文件 所以勾选了D盘 确定后点击连接 三 传输文件 连接到远程服务器 打开文件管理
  • 在STM32上运行ROS节点——rosserial&stm32开发及调试方法

    近期接手了一些ROS机器人项目 这里将开发中遇到的问题和解决方法记录下来 stm32强大的外设资源为机器人底层设备控制带来了极大的便利 本文简述借助rosserial项目在stm32中运行ROS节点的方法 基本原理 ref http wik
  • 什么是数据湖 Data Lake

    什么是数据湖 Data Lake 背景 随着近几年机器学习的兴起对数据的需求更加灵活 如果从数据仓库中提数会有一些问题 比如 数据都是结构化的 做算法的经常要理解数仓模型 甚至要深入到做了什么业务处理 很多处理都不是他们想要的 数据是经过处
  • 转置矩阵(matrix transpose)和逆矩阵(matrix inverse)的相关公式

    转载自 https blog csdn net yinhun2012 article details 84236202 这一篇是为了后面着色效果的数学基础做积累 之前我们使用矩阵的大部分情况都是直接的仿射空间变换 就是仿射空间A变换到仿射空
  • Android:ARouter原理源码解析

    文章目录 前言 一 ARouter使用 二 ARouter初始化 init 函数 整体 LogisticsCenter初始化 拦截器初始化 三 跳转解析 跳转 总结 前言 一 ARouter使用 ARouter的基本使用请参考这篇博客 AR
  • 分治03--二叉搜索树和双向链表

    分治03 二叉搜索树和双向链表 jz26 题目概述 解析 参考答案 注意事项 说明 题目概述 算法说明 输入一棵二叉搜索树 将该二叉搜索树转换成一个排序的双向链表 要求不能创建任何新的结点 只能调整树中结点指针的指向 测试用例 输入 10
  • Thinkcmf 后台弹框页面代码

    thinkcmf是基于layer做的弹出层 https www layui com doc modules layer html 可以看layer的文档学习 选择信息 列表展示 html页面
  • Failed to remove the service because the service is running Stop the service and try again解决方法

    解决方法 Failed to remove the service because the service is running Stop the service and try again mysqld remove 报错 在Window
  • 微信回调 java_详解APP微信支付(java后台_统一下单和回调)

    1 微信配置信息 global properties 2 方法wxpay用于生成预支付订单信息 方法notifyWeiXinPay用于微信支付成功后的回调 注意 在手机端使用微信支付成功后 微信服务器会根据提供的回调地址进行回调 param
  • JavaWeb笔记:第07章 MVC

    JavaWeb笔记 第07章 MVC EL JST Filter Listener JQuery AJAX Maven JSON Redis Linux Nginx 1 MVC 开发模式 2 EL表达式 2 1 概念 作用 语法 2 2 E
  • Springboot初识--Bean的理解

    注解下的Spring Ioc Spring所提供的两个核心理念 一个是控制反转 Inversion of Control IoC 另一个是面向切面编程 Aspect Oriented Progarmming AOP IoC容器是spring
  • Mybatis中parameterType的用法

    在mybatis映射接口的配置中 有select insert update delete等元素都提到了parameterType的用法 parameterType为输入参数 在配置的时候 配置相应的输入参数类型即可 parameterTy
  • rsync安装及使用详细步骤

    目录 1 介绍rsync 2 rsync的安装以及操作方法 3 启动rsync 4 文件传输 5 效验 6 总结 rsync 是一个开源的命令行工具 用于在不同的主机之间同步文件和目录 它可以通过远程 shell 或 rsync 协议 默认
  • SQL语句学习系列(1)

    目录 查询语句 1 查询所有列的所有行 2 查询指定列的所有行 3 查询满足条件的行 4 查询满足多个条件的行 6 查询满足条件的行数 7 查询满足条件的唯一值 8 查询满足条件的分组统计 9 查询满足条件的平均值 10 查询满足条件的最大
  • C语言练习题(14) 有以下函数,该函数的功能是( )int fun(char *s) { char *t = s; while(*t++); return(t-s); }(非常详细的讲解)

    1 有以下函数 该函数的功能是 int fun char s char t s while t return t s A 比较两个字符的大小 B 计算s所指字符串占用内存字节的个数 C 计算s所指字符串的长度 D 将s所指字符串复制到字符串