C语言谜题解析

【C 语言】从代码示例入手(七)指针入门 C 语言从代码示例入手》系列文章将带你开启 C 语言编程的探索之旅。通过大量简单且实用的代码示例,由浅入深地展现 C 语言的核心知识点,包括变量、数据类型、运算符、控制结构、函数等。每一个代码示例都有详细的解释和注释,让你能轻松理解代码的功能和运行原理,助你逐步掌握 C 语言的编程技巧,快速提升编程能力,为后续深入学习和开发打下坚实基础。 阅读详情

本文汇总了一些容易犯错、不易察觉的C编程错误。有时候,你会遇到莫名其妙的错误而不知所措,本文中的一些例子可以给你提供经验,防患于未然。

 

宏

#include <stdio.h>
#define f(a,b) a##b
#define g(a)   #a
#define h(a) g(a)

int main()
{
        printf("%s\n", h(f(1,2)));
        printf("%s\n", g(f(1,2)));
        return 0;
}

说明:输出结果为
12
f(1,2)
宏的解开不像函数那样执行;函数是由里及外展开,而宏则不是。

 

sizeof返回值

#include <stdio.h>
#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
int array[] = {23,34,12,17,204,99,16};
int main()
{
    int d;

    for(d=-1;d <= (TOTAL_ELEMENTS-2);d++)
        printf("%d\n",array[d+1]);

    return 0;
}

说明:无任何输出。sizeof的返回值是一个unsinged int,为此在比较int d 和TOTAL_ELEMENTS两个值都被转换成了unsigned int来进行比较,这样就导致-1被转换成一个非常大的值,以至于for循环不满足条件。

 

void参数

#include <stdio.h>
void foobar1(void)
{
        printf("In foobar1\n");
}

void foobar2()
{
        printf("In foobar2\n");
}

int main()
{
        char ch = 'a';

        foobar1();
        foobar2();
        foobar2(33, ch);
        foobar1(33);

        return 0;
}

说明:在foobar1(33);报错error: too many arguments to function ‘foobar1’。func(void)是没有参数,而func()等于参数类型未知,其调用者可以传入若干个参数,但在func()中,所有的参数将被忽略

 

块设备缓冲区

#include <stdio.h>
#include <unistd.h>
int main()  
{
    while(1)
    {
        fprintf(stdout,"hello-std-out");
        fprintf(stderr,"hello-std-err");
        sleep(1);
    }
    return 0;
}


说明:stdout和stderr是不是同设备描述符。stdout是块设备,stderr则不是。对于块设备,只有当下面几种情况下才会被输入,1)遇到回车,2)缓冲区满,3)flush被调用。而stderr则会直接输出。

 

printf返回值

#include <stdio.h>
int main()
{
    int i=43;
    printf("%d\n",printf("%d",printf("%d",i)));
    return 0;
}

说明:程序会输出4321,因为printf返回值是输出的字符个数。

 

switch内部定义

#include <stdio.h>
int main()  
{      
    int a=1;      
    switch(a)      
    {   
        int b=20;          
        case 1: 
            printf("b is %d\n",b);
            break;
        default:
            printf("b is %d\n",b);
            break;
    }
    return 0;
}

说明:该程序在编译时,可能会出现一条warning: unreachable code at beginning of switch statement。我们以为进入switch后,变量b会被初始化,其实并不然,因为switch-case语句会把变量b的初始化直接就跳过了。所以,程序会输出一个随机的内存值。

 

数组越界

#include <stdio.h>
int main()  
{      
    char str[80];
    printf("Enter the string:");
    scanf("%s",str);
    printf("You entered:%s\n",str);
    return 0;
}


说明:这个程序的潜在问题是,如果用户输入了超过80个长度的字符,那么就会有数组越界的问题了,你的程序很有可以及会crash了。

 

sizeof操作符

#include <stdio.h>
int main()  
{
    int i;
    i = 10;
    printf("i : %d\n",i);
    printf("sizeof(i++) is: %d\n",sizeof(i++));
    printf("i : %d\n",i);
    return 0;
}

说明:sizeof不是一个函数,是一个操作符,其求i++的类型的size,这是一件可以在程序运行前(编译时)完全的事情,所以,sizeof(i++)直接就被4给取代了,在运行时也就不会有了i++这个表达式。所以输出是
i : 10
sizeof(i++) is: 4
i : 10

 

八进制

#include <stdio.h>
#include <stdlib.h>
 
#define SIZEOF(arr) (sizeof(arr)/sizeof(arr[0]))
#define PrintInt(expr) printf("%s:%d\n",#expr,(expr))
 
int main()
{
    /* The powers of 10 */
    int pot[] = {
                    0001,
                    0010,
                    0100,
                    1000
                };
 
    int i;
    for(i=0;i<SIZEOF(pot);i++)
        PrintInt(pot[i]);
         
    return 0;
}


说明:在C/C++中,以0开头的数字都是八进制的。所以,输出是
pot[i]:1
pot[i]:8
pot[i]:64
pot[i]:1000

 

scanf结束符

#include <stdio.h>
int main()  
{ 
    char dummy[80];
    printf("Enter a string:\n");
    scanf("%[^r]",dummy);
    printf("%s\n",dummy);
    return 0;
}


说明:输入输入 Hello, World;那么输出为Hello, Wo;scanf中的”%[^r]“的意思是遇到字符r就结束了。

 

 

extern数组问题

//file1.c
int arr[80];
//file2.c
extern int *arr;
int main()  
{      
    arr[1] = 100;
    printf("%d\n", arr[1]);
    return 0;  
}


说明:该程序可以编译通过,但运行时会出错。原因是,在另一个文件中用 extern int *arr来外部声明一个数组并不能得到实际的期望值,他们的类型并不匹配。所以导致指针实际并没有指向那个数组。注意:一个指向数组的指针,并不等于一个数组。修改:extern int arr[]。

 

 

类型转换

#include <stdio.h>
int main()  
{
    float a = 12.5;
    printf("%d\n", a);
    printf("%d\n", (int)a);
    printf("%d\n", *(int *)&a);
    return 0;  
}

 


说明:
该项程序输出如下:
594771784(经多次运行,该数为随机数)
12
1095237632
原因是:浮点数是4个字节,12.5f 转成二进制是:01000001010010000000000000000000,十六进制是:0×41480000,十进制是:1095237632。

float: 1位符号位(s)、8位指数(e),23位尾数(m,共32位)
double: 1位符号位(s)、11位指数(e),52位尾数(m,共64位)

然后,我们还需要了解一下printf由于类型不匹配,所以,会把float直接转成double,注意,12.5的float和double的内存二进制完全不一样。
我的电脑是小端序字节。
double型表示12.5f的十六进制为:
而我们的%d要求是一个4字节的int,对于double的内存布局,我们取用前四个字节。
这个示例向我们说明printf并不是类型安全的,这就是为什么C++要引如cout的原因了。

C语言经典谜题 超级经典的C语言谜题 适合C语言入门者学习使用以及面试使用 立即下载

相关推荐

C语言谜题.

C语言谜题.很有趣,不错的c语言的小知识,

从一段小小的C语言程序说起(3)

stdout是块设备,stderr则不是。对于块设备,只有当下面几种情况下才会被输入…………

飞思卡尔 汽车电子 914

C语言的谜题 | | 酷 壳 - CoolShell1

C语言的谜题 | | 酷 壳 - CoolShell1

C的语言游戏

这几天,本站推出了几篇关于C语言的很多文章如下所示:语言的歧义 [酷壳链接] [优快云链接] 谁说C语言很简单? [酷壳链接] [优快云链接] 6个变态的C语言Hello World程序 [酷壳链接] [优快云链接] 如何加密/弄乱C源代码 [酷壳链接] [优快云链接] C语言的谜题 [酷壳链接] [优快云链接] 我们可以看到很多C语言相关的一些东

z0203153008的专栏 703

ego-planner启动参数深度解析:从配置到实战避障应用

本文深入解析EGO-Planner启动参数的配置与实战应用,重点探讨无人机自主导航中的避障性能优化。通过环境感知、运动约束和算法控制三类参数的详细说明,结合ROS和RViz工具,提供从基础配置到高级调优的完整指南,帮助开发者提升无人机在复杂场景下的规划效率和安全性。

rum55的博客 246

保姆级教程:用Python+OpenCV搞定Orbbec Gemini深度与彩色流对齐(附完整代码)

本文提供了一份详细的Orbbec Gemini深度与彩色流对齐教程,涵盖从环境配置到完整代码实现的每一步。通过解析深度流对齐原理,对比不同对齐模式,并提供工业级应用中的问题排查方法,帮助开发者快速掌握Orbbec Gemini相机的使用技巧。文章还包含进阶应用如点云生成与三维重建的实战代码。

weixin_29090917的博客 470

linux /dev 常见特殊设备介绍与应用

linux是文件型系统,所有硬件如软件都会在对于的目录下面有相应的文件表示。对于dev这个目录,我们知道它下面的文件,表示的是linux的设备。在windows系统中,设备大家很好理解,象硬盘,磁盘指的是实实在在硬件。而在文件系统的linux下面,都有对于文件与这些设备关联的。访问它们就可以放到实际硬件,想想还是linux灵活了。变成文件,操作该多简单了。不用调用以前com,prt等接口了。直接读

marken 7313

GD32F470实战:如何用EXMC+SDRAM为LVGL打造超大内存池(附完整配置代码)

本文详细介绍了如何利用GD32F470的EXMC接口与SDRAM深度整合,为LVGL构建高性能内存解决方案。通过硬件架构设计、EXMC接口配置、高级内存管理策略及LVGL性能优化技巧,开发者可以突破微控制器内存限制,实现高分辨率显示和复杂动画效果。附完整配置代码,助力嵌入式GUI开发。

rrr55的博客 546

什么是标准输入、标准输出(stdin、stdout)?

原文地址:什么是标准输入、标准输出(stdin、stdout)? 要弄清什么是标准输入输出。首先需要弄懂什么是IO。 IO的I是Input的意思,O是output的意思。 意味着输入和输出。 更确切的含义是: I:从外部设备输入到内存 O:从内存输出到外部设备 而标准输入和标准输出是干什么的?它们是用于IO的。 那么它们属于IO的哪个部分? 内存?还是外部设备? 答案显然是外部设备(逻辑上的外部设...

sinat_17700695的博客 3万+

Python量化投资入门教程:从零构建你的第一个交易策略

量化投资教程以数学模型和计算机程序实现超额收益,选用Python工具链完成数据获取、策略构建及回测。通过移动平均线交叉策略示例,展示数据预处理、信号生成、收益计算及可视化全流程,结合收益率、最大回撤和夏普比率评估策略,并建议参数优化与策略融合提升稳健性。

ylmx5201314的博客 2454

保姆级图解:HKMG工艺中的‘覆盖层’(Cap Layer)到底怎么调阈值电压?

本文深入解析了HKMG工艺中覆盖层(Cap Layer)如何精准调控阈值电压的关键技术。通过原子级精度的ALD工艺和材料选择,覆盖层在半导体制造中扮演着隐形调节器的角色,直接影响晶体管的电气特性。文章详细介绍了La2O3和Al2O3等材料的特性对比、ALD工艺的原子级控制,以及实战调试中的关键步骤和问题排查方法。

weixin_27032989的博客 496

C语言的谜题

C语言的谜题 C语言的谜题 | 酷壳 - CoolShell.cnC语言的谜题 posted on 2011-11-04 18:40lexus 阅读(...)...

82

银行一表通监管报送系统详解

国家金融监管总局对于“一表通”的总体描述为:通过建立一套明细级、标准化的数据体系和汇总计算规则,将银行机构传送至监管可信区的业务明细数据汇总生成财务指标、监管指标和监管报表,大幅提升监管数据时效性,统一数据标准,实现数据间的穿透和整合,同时改变机构多头报送数据模式,减轻机构报送负担。

银行信息系统应用架构详解 2516

c语言语句加密转换成符号,C 语言的谜题[转]

转者注:在文章开头看觉得蛮有意思,一直看下去就会发现了自己对C语言的了解太小了。转自:http://blog.youkuaiyun.com/haoel/archive/2009/06/02/4231029.aspx这几天,本站推出了几篇关于C语言的文章如下所示:语言的歧义 [酷壳链接 ] [优快云链接 ]谁说C语言很简单? [酷壳链接 ] [优快云链接 ]6个变态的C语言Hello World程序 [酷壳...

weixin_32950759的博客 181

概念解析 | 雷达动态范围

这里存在一个动态范围的问题:强雷达发射信号和弱目标反射信号存在非常大的功率差异,比如传统的脉冲多普勒雷达动态范围可达90dB以上。随着上述技术的发展,预计未来十年雷达接收机动态范围将达到120dB以上,届时雷达的监视能力将得到极大增强。简单来说,雷达动态范围越大,表示接收机噪声越低,对强信号过载保护能力越强,就越能检测到弱信号目标。此外,部分新概念雷达对动态范围提出新的需求,如被动雷达动态范围需大于100dB。当前,随着阵列雷达和数字雷达技术的发展,对雷达接收机动态范围提出了更高要求。

NLOS的博客 1051

PCL 提取两片点云的非重叠部分【2025最新版】

PCL 提取两片点云的非重叠部分。博客长期更新,本文最近一次更新时间为:2025年9月1日。

点云侠的博客 36万+

C语言太简单?这14道C语言谜题,你能答对几个?

本文展示了14个C语言的迷题以及答案,代码应该是足够清楚的,而且有相当的一些例子可能是我们日常工作可能会见得到的。通过这些迷题,希望你能更了解C语言。 如果你不看答案,不知道是否有把握回答各个谜题?让我们来试试。 1. 下面的程序并不见得会输出"hello-std-out",你知道为什么吗? #include#includeint main(){ while(1) { fprintf(stdout,"hello-std-out"); f

weixin_52397329的博客 200

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

十六进制数用int吗_你真的精通C语言吗?来解这十道C语言迷题试试吧!

本文展示了10个C语言的迷题以及答案,而且有相当的一些例子可能是我们日常工作可能会见得到的。通过这些迷题,希望你能更了解C语言。如果你不看答案,不知道是否有把握回答各个谜题?让我们来试试。1、会输出"hello-std-out"?#include<stdio.h>int main(){while (1) { fprintf(stdout, "hello-std-ou...

weixin_39998881的博客 467

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

C语言的歧义

转自:http://www.kuqin.com/language/20090529/53686.html 本文来自:http://cocre.com/?p=830 语言是人与人相互沟通的途径,而计算机语言则是人和计算机沟通的途径。就算是任何再完美的自然语言都会有歧义,但是又是什么让人和计算计算机间产生了歧义呢? 下面这篇文章来自Gowri Kumar的Puzzle C一文。我做了

1163

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

陈皓的C语言系列文章合集

单看这文章的标题,你可能会觉得好像没什么意思。你先别下这个结论,相信这篇文章会对你理解C语言有帮助。这篇文章产生的背景是在微博上,看到@Laruence同学出了一个关于C语言的题,微博链接。微博截图如下。我觉得好多人对这段代码的理解还不够深入,所以写下了这篇文章。 为了方便你把代码copy过去编译和调试,我把代码列在下面: #include struct str{ int len

gdut_abc 1081

日本某地发生了一件谋杀案,警察通过排查确定杀人凶手必为4个嫌疑犯的一个。以下为4个嫌疑犯的供词。 A说:不是我。 B说:是C。 C说:是D。 D说:C在胡说 已知3个人说了真话,1个说了假话

#define _CRT_SECURE_NO_WARNINGS 1 #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; int main() { int murder = 0; for (murder = 'A'; murder &lt;= 'D'; murder++) { { if (((murder != 'A') + (mu...

C_U_N_Z的博客 439

1987年国际C语言混乱代码大赛获奖的一行代码

macb() ? lpcbyu(&gbcq/_\021%ocq\012\0_=w(gbcq)/_dak._=}_ugb_[0q60)s+                      这是CoolShell博主之前做了一个很有意思的在线puzzle,仿照一些前端过关的游戏,做了几个和程序员有关的迷题,一个通关游戏,这个事测试的第二题。并为通关的前十名送上《Unix环境高级编程(第三版)》(感

小刘同学_iOS的专栏 5073
上一篇: 查看进程内存映像命令pmap
下一篇: 整型溢出问题
IT_Linux
博客等级 码龄14年 31粉丝 77原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值