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

Chkdsk误删文件?5步教你从FOUND.000文件夹找回重要数据(附工具推荐)

本文详细介绍了当Chkdsk误删文件后,如何从FOUND.000文件夹中找回重要数据的5个步骤。包括理解Chkdsk与FOUND.000的关系、定位与访问FOUND.000文件夹、手动恢复CHK文件的技巧、使用UnCHK工具自动化恢复以及预防数据丢失的关键措施。适用于Windows用户解决数据丢失问题,特别是NTFS文件系统下的文件恢复。

weixin_30687051的博客 384

自然语言处理:稀疏向量表示

稀疏向量表示是指运用特定的方法和技术,将数据(如文本、图像、信号等)转化为向量形式,且该向量具有大部分元素值为零,仅少数元素值非零的特征,以此来实现对数据的高效存储、处理和分析。

老赵爱学习的博客 1443

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

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

marken 7313

射频工程师笔记---射频通信基础

回顾一下移动通信技术的发展,其实是互联网和通信技术的融合过程。在这个过程中,很多应用都在不断加入其中。比如计算机跟通信的融合产生了互联网、互联网跟手机的融合带来了移动互联网。手机可以看杂志、看视频、听音乐,于是又出现了内容服务产业;再后来,电视音箱等设备也能联网,于是网络跟家电又产生了融合。所以应用的出现总是在融合其他产业。在1995年,比尔·盖茨在《未来之路》一书中首次提出:在未来...

多年硬件从业经历,热爱学习,记录生活! 2万+

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

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

sinat_17700695的博客 3万+

C# Socket网络通信UDP(关键字:Socket)

简单Socket-Udp通信 在本文中涉及到通信,仅做简单的通信(服务端接受消息,由客户端发出消息) 如有需要,根据需求可直接copy使用 关键字Socket 需要引用命名空间: using System.Net; using System.Net.Sockets; 服务端: using System; using System.Net; using System.Net.Sockets; u...

MelanceXin的博客 3885

SIwave:在 SIwave 中释放计算频率扫描的强大功能

AEDT 的电路工具允许注入正确的电压和电流。要使用电路工具,SIwave 必须首先使用 PI 求解器求解结构的 S 参数。

jkh920184196的博客 1475

C语言的谜题

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

82

如何在 Mac 上下载安装 Xcode——并为 iOS 开发更新它原文

下载 Xcode安装命令行工具打开新版本删除文件注意,我在下面的步骤中列出了一些终端命令。这些命令可以被输入到你现在的工作目录中。这意味着你不需要导航到任何特定的文件夹。如果你真的想这样做,你可以在输入下面的步骤中的命令之前先输入== cd==。这将使你返回到主文件夹。

专注于AI领域前沿知识,业余爱好开发软件 4666

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

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

weixin_32950759的博客 180

【RT-DETR涨点改进】小目标检测、特征融合改进篇 | TGRS 2024 | RT-DETR引入CSFM上下文选择融合模块,适合多模态检测、红外小目标检测、小目标检测、遥感目标检测等任务有效涨点

本文提出了一种改进RT-DETR目标检测模型的方法,通过引入上下文选择融合模块(CSFM)显著提升复杂背景下小目标和低对比度目标的检测精度。CSFM模块采用多尺度特征融合和动态特征选择机制,有效增强模型的全局上下文感知能力,同时保留细节特征。该模块通过通道减少机制和空间信息调节,实现从粗到细的特征聚合,减少误报并提高轮廓检测精度。实验表明,改进后的RT-DETR模型在多个基准测试中表现优异,计算效率与检测精度均优于现有方法。文章还详细介绍了模块配置和yaml文件修改方法,为模型部署提供指导。

Ai缝合怪、助力小伙伴高效发论文 1723

windows 配置 libxml2

路径:\libiconv-1.9.2-1-src.zip\src\libiconv\1.9.2\libiconv-1.9.2\include\。执行完后,在当前win32目录中会生成了一个bin.msvc目录,其中就有开发需要的libxml2.lib和libxml2.dll文件。将 libiconv.la 复制到 新建的 lib 目录,并将其改名为 iconv.lib。路径:libiconv-1.9.2-1-bin.zip\lib\。将如下的 iconv.h 复制到新建的 include 目录。

SHELLCODE_8BIT的博客 3884

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

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

weixin_52397329的博客 200

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

十六进制数用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

VB摄像头监控

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

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

C语言的歧义

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

1163

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

陈皓的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、付费专栏及课程。

余额充值