C语言易错点整理

news2024/11/19 22:34:02

前言:

本文涵盖了博主在平常写C语言题目时经常犯的一些错误,在这里帮大家整理出来,一些易错点会帮大家标识出来,希望大家看完这篇文章后有所得,引以为戒~

一、

题目:

解答:

首先在这个程序中有两个x,y,一个是在主函数中定义的局部变量,另一个是全局变量。

而在swap函数中将两个值进行了交换,因为在主函数中定义的变量只在主函数中有效,因为主函数也是一个函数,它与其他函数是平行关系!所以swap函数是将在主函数外部的全局变量进行了交换。

其次在主函数中我们需要打印x,y,根据输出语句,局部变量优先的原则,所以最后的结果就是3,8

易错点:

  1. 不知道在主函数中定义的变量只在主函数中有效
  2. 不知道在输出语句中,局部变量优先的原则

二、

题目:

解答:

本题选择B,

\ddd ddd表示13个八进制数(d用八进制数表示才合法

\xhh hh表示12位十六进制数 (h用十六进制数表示才合法

原因是 '\8' 表示错误,因为转义字符\后面只要跟了十进制的数字,就是表示八进制数,但是八进制表示的范围是0~7, 所以'\8' 表示错误。

易错点:

不知道常见转义字符的形式,\后面直接跟数字,表示是一个八进制数,但表示形式必须要用0~7;同理/后面跟x表示是一个十六进制数,表示形式也必须使用十六进制~

小总结:

以后看到字符表示中有\在前面就表示它是一个转义字符,看\后面的字母来判断这是什么样的字符。

三、

题目:

解答:

本题要求根据输入的日期,计算是这一年的第几天。

我们可以每一月的月数存放在一个数组中,根据输入的月份for循环累加,特殊情况判断闰年的情况

源码:

int main()
{
    int year = 0;
    int month = 0;
    int day = 0;
    int sum = 0;
    int num[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    //直接用数组创建,比switch语句简洁了不少
    while(scanf("%d %d %d",&year,&month,&day) != EOF)
    {
        if(year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))
            num[1] = 29;
        //累加月份,这种事就让电脑干
        for(int i = 0;i < month-1;i++)
        {
            sum += num[i];
        }
        sum += day;
        printf("%d\n",sum);
    }

    return 0;
}

四、

题目:

 解答:

\\表示一个 '\' 字符,\123表示一个八进制数,\t 表示水平制表。所以最后的结果是12.

易错点:

 \\ \' \'' \ddd \xhh

以上这几个比较容易出错,需要多加注意

五、

题目:

如下函数f(1)的值是多少

解答:

首先明确i是一个局部变量,此题注意静态局部变量的使用,改变局部变量的销毁时期

static改变了i的生命周期,第一次调用函数:i初值是1,递归第二次调用函数时,i还是第一次那个变量,值已经变成了2,再一次调用函数时i就是3,以此类推

易错点:

不清楚静态局部变量的意义。静态局部变量存储在静态存储区,当静态局部变量离开作用域后,并没有被销毁,被修饰变量的值没有改变,比如本题的i变量的值不会改变,会一直++

六、

题目:

解答:

本题关键在于知道规律后,能够找到第 n 个数据立方的起始奇数,

但我觉得最重要的是如何将一个整型表达式转化为字符串类型

这里需要引用一个新函数sprintf函数,它可以直接将整型类型转换为字符串类型。

sprintf函数的用法

格式化字符串但是不用于打印而是放到一个buf中,所以需要提前创建一个char类型的数组。

可以直接将整型全部转换为字符串类型:

int main()
{
	char buf[100];
	int a = 100;
	int b = 20;
	//sprintf(buf, "%d", a);
	sprintf(buf, "%d+%d", a, b);
	printf("%s", buf);
	return 0;
}

 可以部分转换,以本题举例:

int main()
{
int m;
while(~scanf("%d", &m)){
int start = m * (m - 1) + 1;//找到对应m^3的起始奇数
char buf[10240] = {0};
//sprintf(buf, format, ...) 与printf用法类似,格式化字符串但是不用于打印而是放到一个buf中
sprintf(buf, "%d", start);//先将起始奇数转换成为字符串存入buf中
for (int i = 1; i < m; i++) {
//然后将紧随随后的m-1个奇数数字转换为字符串,按照指定格式放入buf中
//%s+%d, 要求先有一个字符串,然后是+符号,然后是个数字的格式,对应是buf原先的数据,和奇数
sprintf(buf, "%s+%d", buf, start+=2);
}
printf("%s\n", buf);
}
return 0;
}

七、

题目:

若运行以下程序时,从键盘输入 ADescriptor< 回车 > ,则下面程序的运行结果

易错点:

  • getchar()读取所有字符,所以最后的回车也会被读入
  • 代码switch语句中没有break,则每次找到入口进入后,顺序执行到代码块结束为止

八、

题目:

以下程序的功能:

 

解答:

一个字母对应的大写和小写之间的 ASCII 码值相差 32 ,而且 小写的ASCII码值大于大写 的。所以题中 'e' 'E' 之间的 ASCII 码值相差 32( ch[j]+'e'-'E' 相当于 ch[j]+32 )。可以直接+32

总结:

一个字母从大写转化为小写就是在它自身上 +32 ,小写转大写则是 -32。(相反)

九、

题目:

数字在升序数组中出现的次数_牛客题霸_牛客网 (nowcoder.com)

注意题目中要求时间复杂度在O(logN),并且还是非降序,很明显这题要使用二分思想。

思路:

采用遍历也能搞定,不过数组为非降序,采用 二分查找 的思想最优,先二分找到最左边的数字位置,再二分查找最右边的数字位置,两个位置相减+1 就是长度了。
  • 中间比找的值大:则要找的数字肯定在右边, left = mid + 1;
  • 中间比找的值小:则要找的数字肯定在左边, right = mid - 1
  • 中间值与找的值相同:
找的最左边数字:如果 mid 就是 left ,则返回 mid 就行,否则重置 right=mid-1 ,把中心不断向左偏移
找的最右边数字:如果 mid 就是 right ,则返回 mid 就行,否则重置 left=mid+1 ,把中心不断向右偏移

源码:

int GetNumberOfK(int* nums, int numsLen, int k ) {
    // write code here
    //先二分找到最左边的数字位置,再二分查找最右边的数字位置,两个位置相减+1就是长度
    int cnt = 0;
    int left = 0;
    int right = numsLen - 1;
    int mid;
    while(left <= right) 
    {
        mid = (left+right)/2;//每次循环都需要放在中间
        if(nums[mid] > k)
        {
            right = mid-1;
        }
        else if (nums[mid] < k)
        {
            left = mid+1;
        }
        else 
        {
            int ret = mid;
            while(nums[ret] == k)
            {
                ret--;
            }
            left = ret+1;
            ret = mid;
            while(nums[ret] == k)
            {
                ret++;
            }
            right = ret-1;
            return right - left + 1;
        }
    }
    return 0;
}

十、

题目:

解答:

|| 操作符表示只要有一个为真就是真,刚开始0<5,执行i++,当i = 1时,

逻辑或操作符前表达式为真,后表达式不计算!所以前表达式i = 1,后面的i++,就不计算,因此i恒为1,所以是死循环!

易错点:

不知道逻辑或操作符当前表达式为真,后表达式不计算这个特点

十一、

题目:

c 语言中,一个函数不写返回值类型,默认的返回类型是?

解答:

一个函数不写返回值类型, 默认的返回类型是int ,但不提倡这么做。

十二、

题目:

解答:

字符数组定义的两种方式:

arr1和arr2都是合法的,arr3报错是字符数组初始化需要带括号的初始化表达式

十三、

题目:

169. 多数元素​​​​​​z

解答:

注意本题的要求是时间复杂度在O(N),所以不能简单的使用暴力双层循环的办法。

采用互拼的思想。 

一个数组中有一个数字出现次数大于 n/2 ,从第 0 个字符开始,假设它就是最多的那个数字,遇到相同的数字则计数 +1 ,遇到不同的则计数 -1 ,其实就是互相消耗,等到计数为 0 的时候,表示本次互拼完毕,从下一个字符重 新开始互拼, 但是归根结底出现次数大于 n/2 的这个数字数量更多,因此也是最后保留的字符

源码:

int majorityElement(int* nums, int numsSize)
{
    //利用互拼的思想
    int n = nums[0];
    int cnt = 1;
    for(int i = 1;i<numsSize;i++)
    {
        if(n == nums[i])
            cnt++;
        else
            cnt--;
        if(cnt == 0)
            n = nums[i+1];
    }
    return n;
}

十四、

题目:

解答:

逗号表达式是 从前到后依次计算子表达式,而其结果是最后一项的值 ,本题的括号无用,所以最后的结果就是25.

十五、

题目:

238. 除自身以外数组的乘积

思路:

题目中要求使用O(N)的算法进行计算,我的第一想法是将所有数据相乘,遍历一遍数组元素,然后分别相除,但题目中有要求不能使用除法,但是除法与乘法互相转换的。

我们可以将乘积分为两次进行,第一次先将每个位置左边的数据乘积计算出来放到返回数组中,后边第二次循环将对应位置右边的数据乘积计算出来与返回数组对应位置的左半边乘积相乘得到结果。

源码:

int* productExceptSelf(int* nums, int numsSize, int* returnSize)
{
    int left[numsSize];
    int right[numsSize];
    *returnSize = numsSize;
    int* arr = (int*)malloc(sizeof(int)*(*returnSize));
    //分别计算每个元素左边的乘积
    left[0] = 1;
    int ret = 1;
    for(int i = 1;i<numsSize;i++)
    {
        ret*=nums[i-1];
        left[i] =  ret;
    }
    //分别计算每个元素右边的乘积
    ret = 1;
    right[numsSize-1] = 1;
    for(int i = numsSize-2;i>-1;i--)
    {
        ret*=nums[i+1];
        right[i] = ret;
    }

    for(int i = 0;i<numsSize;i++)
    {
        printf("%d ",left[i]);
    }
    printf("\n");
    for(int i = 0;i<numsSize;i++)
    {
        printf("%d ",right[i]);
    }

    //最后计算两者相乘
    for(int i = 0;i<numsSize;i++)
    {
        arr[i] = left[i] * right[i];
    }
    return arr;
}

十六、

题目:

448. 找到所有数组中消失的数字

 题目中要求时间复杂度O(N),空间复杂度是O(1)。

思路:

以数组元素的 绝对值 作为下标,(因为前面有可能将后面的数值变为负数,负数访问数组下标会越界)。
将对应位置的数据置为负数,比如 0 号位置是 3 ,则把 3 号位置的数据重置为负值,等到数组遍历重置完毕,只有缺失的这个数字对应的位置保留正数,其他出现过的数字位置都会是负数, 要注意不要重复设置负数,因为负负得正。
为什么会想到这个思路?
因为数组的内容和数组的下标相对应

TIP:

 ++ 的优先级要比 解引用* 操作符优先级高,为了避免这个问题可以直接用括号,或者*returnsize+=1。

源码:

int* findDisappearedNumbers(int* nums, int numsSize, int* returnSize){
    *returnSize = 0;
    int* arr = (int*)malloc(sizeof(int)*numsSize);
    //注意遍历到后面的值可能是负数,下标访问会越界,所以需要绝对值函数
    for(int  i =0;i<numsSize;i++)
    {
        int ret = abs(nums[i])-1;
        if(nums[ret] < 0)
            continue;
        else
        {
            nums[ret] = -nums[ret];
        }
    }
    for(int i = 0;i<numsSize;i++)
    {
        if(nums[i] > 0)
        {
            arr[*returnSize] = i+1;
            // ++ 的优先级要比 解引用* 操作符优先级高
            //*returnSize++;  error!
            *returnSize+=1;
        }
    }
    return arr;
}

十七、

题目:

 解答:

一般表达式的运算是在运行时执行的,而 sizeof 是一个编译阶段就执行的运算符,在其内的任何运算 都不执行 ,只推测出其中表达式结果的类型求其大小,故前后i 的值不变。

易错点:

不知道sizeof内部的任何运算都不执行。

十八、

题目:

解答:

0'<=c<='9' 并非判断 x 大于等于字符 0, 小于等于字符 9 ,而是 先执行'0'<=c ,使用这个表达式的结果再和 '9' 比较, '0' ASCII 码值是48 'A' ASCII 码值是 '65' ,故 '0'<c 是真值 1 1 无疑是小于字符 '9' 的,最终是真

易错点:

0'<=c<='9' 这个表达式并不是真正数学意义上的比较,在计算机语言中应该从右到左一一进行计算。

十九、

题目:

思路一:

将这个正数取余取出每一位,然后将每一位整型+'0',变为字符型即可

源码:

int main()
{
    long long n = 0;
    scanf("%lld",&n);
    char* arr = (char*)malloc(sizeof(char)*1000);
    int num = 0;
    if(n == 0)
            printf("%d",n);
    while(n)
    {
        arr[num++] = n%10 + '0';
        n/=10;
    }
    for(int i = 0;i<num;i++)
    {
        printf("%c",arr[i]);
    }
    return 0;
}

 思路二:

利用sprintf函数,不需要一个一个的进行取余,直接将整个整型的数字转换为字符型。

源码:

int main()
{
    int n = 0;
    scanf("%d",&n);
    char buf[1000];
    sprintf(buf,"%d",n);
    int len = strlen(buf);
    for(int i = len-1;i>-1;i--)
    {
        printf("%c",buf[i]);
    }
    return 0;
}

二十、

题目:

单词倒排_牛客题霸_牛客网 (nowcoder.com)

思路:

定义一个字符指针数组,用于保存每个单词的 起始字符地址 ,接下来将 非字母字符全部替换成为字符串结尾标志 ,则单词字符字母遇到结尾就结束了,相当于把一个字符串以非字母字符进行切割成为了多个字符串,最终对字符指针数组进行逆序打印每个单词即可。

源码:

int main()
{
    char arr[10005];
    char* ret[10005];//记录每一个单词的首元素地址
    int cnt = 0;//记录首元素地址的个数
    gets(arr);
    int len = strlen(arr);
    //单独判断首元素
    if((arr[0]>='a' && arr[0]<='z') ||(arr[0] >= 'A' && arr[0]<='Z'))
    {
        ret[cnt++] = &arr[0];
    }
    else 
    {
        arr[0] = '\0';
    }
    for(int i = 1;i<len;i++)
    {
        if((arr[i]>='a' && arr[i]<='z') ||(arr[i] >= 'A' && arr[i]<='Z'))
        {
            if((arr[i-1]>='a' && arr[i-1]<='z') || (arr[i-1] >= 'A' && arr[i-1]<='Z'))
                continue;
            else
            {
                ret[cnt++] = &arr[i];//将单词的首元素地址进行存储
            }
        }
        else
        {
            arr[i] = '\0';
        }
    }
    for(int i = cnt-1;i>-1;i--)
    {
        printf("%s ",ret[i]);
    }
    return 0;
}

二十一、

题目:

解答:

x=x|(x+1);的作用是每次循环把x的二进制中从右往左数的最后一位0变成1 ,直到变成
全1的时候x+1就溢出为全0 ,循环结束

易错点:

不知道当二进制位每一位都是1,之后再进行+1结果会变成全0。

二十二、

题目

 解答:

本题首先是执行后置++,但是是后置++,实际的++操作是在本条语句的最后 然后就是*pa = *pa * 3;然后进行++

易错点:

忘记后置++的计算顺序,应该是最后再算++。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/927750.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

动捕设备助力打造沉浸式虚拟现实体验

在纪录片《超时空寻找》中&#xff0c;借助了实时动捕设备&#xff0c;基于三维数字人技术进行老战士与历史场景还原&#xff0c;让抗美援朝老战士可以通过虚拟现实技术&#xff0c;跨越时空与战友实现隔空对话。 随着动捕设备的不断发展&#xff0c;虚拟现实技术越来越成熟&a…

clickhouse ssb-dbgen数据构造 及 clickhouse-benchmark简单压测

一、 测试数据构造 1. 数据样例 官方文档有给出一批数据样例。优点是比较真实&#xff0c;缺点是太大了&#xff0c;动辄上百G不适合简单小测试 Anonymized Yandex.Metrica DatasetStar Schema BenchmarkWikiStatTerabyte of Click Logs from CriteoAMPLab Big Data Benchma…

超实用的小红书种草方案分享!纯干货

小红书以“生活、时尚、美妆”等主题内容吸引了大量用户&#xff0c;成为了品牌方的种草宝地。那么&#xff0c;如何在小红书上打造爆款内容&#xff0c;吸引万千粉丝呢&#xff1f;本文伯乐网络传媒将从独特的角度深度剖析小红书种草方案&#xff0c;为你提供新知。 制定小红书…

SEMIDRIVE X9U 插入 USB 不识别调试要点

一、前言 客户用芯驰 X9U 平台做的智能座舱产品&#xff0c;在烧写固件时发现&#xff0c;通过 USB 连接到 SSA 的 USB 接口&#xff0c;Windows 上无法识别出 USB 设备&#xff0c;一直处在 Ready 状态。 二、SEMIDRIVE X9U 插入 USB 不识别调试要点 ① 建议客户测量 SoC 的…

PDF校对:让您的文件无瑕疵

无论您是企业家、学生、教育者还是作家&#xff0c;我们都知道&#xff0c;提交或发布一个充满错误的PDF文件可能会给您的声誉或品牌带来严重损害。这就是为什么PDF校对如此关键的原因。现在&#xff0c;让我们深入了解PDF校对的重要性&#xff0c;以及如何确保您的文件尽可能完…

RabbitMQ默认监听的ip地址

RabbitMQ 默认监听所有可用 ip 地址&#xff0c;当Rabbitmq 所在的服务端节点上存在多 ip 时&#xff0c;只要客户端能与服务端任一 ip 通信&#xff0c;即可向 RabbitMQ 发送消息

黑马 小兔鲜儿 uniapp 小程序开发- 02首页模块

黑马 小兔鲜儿 uniapp 小程序开发- 01项目起步_软工菜鸡的博客-CSDN博客 本课程是全网首套用 vue3 加 TS 写的 uniapp 项目&#xff0c; 里面大量封装自己的组件库&#xff0c;课程从 uni-app 基础入手&#xff0c;按照9大电商业务模块逐步实现完整的电商购物流程业务&#xff…

【LeetCode-中等题】73. 矩阵置零

题目 题解一&#xff1a;使用标记数组 public void setZeroes(int[][] matrix) {int m matrix.length;int n matrix[0].length;boolean[] row new boolean[m];boolean[] col new boolean[n];for(int i0; i< m;i){for(int j 0;j<n;j){if (matrix[i][j] 0) row[i]col…

【SQL中DDL DML DQL DCL所包含的命令】

SQL中DDL DML DQL DCL所包含的命令 关于DDL、DML、DQL、DCL的定义和适用范围如下&#xff1a; 数据定义语言&#xff08;Data Definition Language&#xff0c;DDL&#xff09;&#xff1a; DDL用于创建、修改和删除数据库中的表、视图、索引等对象。它的主要命令包括CREATE、A…

230814期优橙5G网络优化就业班开班啦!这样的学习环境泰酷辣!~

230814期为期8天的基础班顺利结束&#xff01; 接下来就是为期3个月的就业班 小优橙一点都不敢耽搁时间 紧跟优橙老师教学节奏 今日通知 230814期优橙就业班今天已经正式开班&#xff01; 本次就业班有哪些新收获&#xff01; 快来跟着学员视角看看8天在优橙真实感受吧~…

2831. 找出最长等值子数组

2831. 找出最长等值子数组 C代码&#xff1a; int longestEqualSubarray(int* nums, int numsSize, int k){int* a calloc(numsSize 1, sizeof(int));int ans 0, cnt 0;int l 0;for (int r 0; r < numsSize; r) {a[nums[r]]; // 滑动窗口中的字符次数if (ans <…

解读:未来汇全新商业模式,消费+增值包模式营销方案套路?

解读&#xff1a;未来汇全新商业模式&#xff0c;消费增值包模式营销方案套路&#xff1f; 大家好&#xff0c;我是微三云营销策划总监胡佳东&#xff0c;一家软件开发公司负责人。 在如今竞争激烈的商业环境中&#xff0c;传统的实体经营方式面临着越来越大的挑战。无论是哪个…

Module not found: Error: Can‘t resolve ‘less-loader‘解决办法

前言&#xff1a; 主要是在自我提升方面&#xff0c;感觉自己做后端还是需要继续努力&#xff0c;争取炮筒前后端&#xff0c;作为一个全栈软阿金开发人员&#xff0c;所以还是需要努力下&#xff0c;找个方面&#xff0c;目前是计划学会Vue&#xff0c;这样后端有java和pytho…

什么是数据中心IP,优缺点是什么?

如果根据拥有者或者说发送地址来分类的话&#xff0c;可以将代理分为三类&#xff1a;数据中心ip,住宅ip,移动ip 本文我们来了解数据中心ip的原理以及他们的优势劣势&#xff0c;才能选择适合自己的代理。 一、什么是数据中心ip代理&#xff1f; 数据中心ip是由数据中心拥有…

晨控CK-GW208与三菱L系列PLC以TCP通讯手册

晨控CK-GW208是一款支持标准工业以太网协议的IO-LINK主站网关&#xff0c;方便用户快速便捷的集成到 PLC 等控制系统中。 CK-GW208主站网关集成 8 路 IO-LINK 通信端口&#xff0c;采用即插即用模式&#xff0c;无需繁琐的配置&#xff0c;减轻现场安装调试的工作量。为了满足…

【2023】Spring Validation中@NotNull注解、@NotBlank注解介绍以及使用

【2023】Spring Validation中NotNull注解、NotBlank注解介绍以及使用 前言一、简介spring-validation框架的常用注解 二、代码实现添加依赖1、实体举例2、Controller层:3、统一异常处理4、结果返回验证通过返回验证失败返回 前言 平常我们在编写代码的时候总需要很多if判空&am…

【docker】运行registry

registry简介 Docker registry是docker镜像仓库的服务,用于存储和分发docker镜像。 Docker registry主要特点和功能: 存储docker镜像:提供持久化存储docker镜像的功能,存储镜像的各个layer。 分发镜像:拉取和推送镜像的去中心化存储和分发服务。 支持版本管理:给镜像打标签…

编码基础一:侵入式链表

一、简介概述 1、普通链表数据结构 每个节点的next指针指向下一个节点的首地址。这样会有如下的限制&#xff1a; 一条链表上的所有节点的数据类型需要完全一致。对某条链表的操作如插入&#xff0c;删除等只能对这种类型的链表进行操作&#xff0c;如果链表的类型换了&#…

网约车平台如何开发?需要多少钱?

随着共享经济的兴起&#xff0c;网约车行业迅速发展&#xff0c;并成为人们生活中不可或缺的一部分。为了满足市场需求和提供更好的服务&#xff0c;开发一款高质量的网约车源码平台至关重要。本文将深入探讨网约车源码平台的开发方案&#xff0c;从技术架构、安全性和用户体验…

Python数据分析实战-DataFrame按照某列指定的顺序排序(附源码和实现效果)

实现功能 dataframe按照某列指定的顺序排序 实现代码 import pandas as pd# 创建一个示例 DataFrame df pd.DataFrame({name: [Alice, Bob, Charlie, David, Eva],age: [25, 30, 35, 40, 45],gender: [F, M, M, M, F]})# 按照指定顺序排序 sort_order [Eva, David, Charli…