变量声明的行为如何?

2024-02-01

#include<stdio.h>
#include<conio.h>

int main(){

    char i;
    int c;

    scanf("%i",&c);
    scanf("%c",&i);// catch the new line or character introduced before x number
    printf("%i",i);// value of that character

    getch();
    return(0);
}

程序将以与下一个变量声明(而不是上面的变量声明)相同的方式运行:

this:

int c;
int *x;
int i;

or this:

int *x;
int c;
int i;

并且只有这样:c变量和一个x之前的指针i多变的。 我知道最后的声明没有意义int i代替char i,以及一个根本不需要的附加指针。 但这是偶然发生的,我想知道这是否只是巧合。


假设代码的其余部分没有任何问题,声明变量的顺序应该没有任何区别。声明的顺序不需要与它们在内存中的布局方式有任何关系。即使确实如此,您也可以通过名称来引用变量;只要你的代码是正确的,引用i是对i,编译器将生成正确访问变量所需的任何代码。

现在如果你这样做:

int i;
scanf("%c", &i);

那么你做错了什么。scanf with a "%i"格式需要一个char*论点,它指向char将存储值的对象。你给它一个int*而不是一个char*。因此,你的程序的行为是未定义的;语言标准没有说明它的行为方式。

那么为什么它看起来工作正常呢?可能发生的情况是scanf处理的地址int object i就好像它是一个指向char。它可能会指向表示的第一个字节i;例如,i可能是 32 位,指针将指向这些位的前 8 位。 (它们可能是高位或低位,具体取决于系统。)

现在当你打印的值i:

printf("%d\n", i);

的内容i例如,1 个字节由您刚刚读入的任何字符组成,3 个字节是垃圾。这 3 个垃圾字节很可能全部为零,但它们可以是任何东西。如果垃圾字节恰好为 0,并且第一个字节恰好是高位字节(即,您位于大尾数法 http://en.wikipedia.org/wiki/Big_endian机),那么您很可能会得到“正确”的输出。

但不要这样做。由于行为是未定义的,它可以“正确”工作多年,然后在最糟糕的时刻彻底失败。

这里的教训是,C 倾向于假设你知道自己在做什么。有一个lot具有未定义行为的构造,这意味着它们无效,但编译器和运行时系统都不需要告诉您存在问题。与大多数其他语言相比,C 语言更需要程序员将事情做好。编译器(和其他工具)会告诉你some错误,但不是全部。

在存在未定义行为的情况下,声明变量的顺序can做出改变。例如,如果您编写的代码读取或写入超过变量的末尾,那么那里存储的内容可能很重要。但是,在程序运行之前,不要试图随意更改声明。摆脱未定义的行为,以便顺序doesn't matter.

解决方案:首先不要犯错误。 (当然,说起来容易做起来难。)

命名约定会很有帮助。如果你打电话给你的char多变的c, 和你的int多变的i,而不是反之亦然,这样可以更容易地跟踪哪个是哪个。

But c是一个合理的名称int用于保存输入字符值的变量——不适用于scanf, 但对于getchar(), as in:

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

变量声明的行为如何? 的相关文章

  • 使 minGW 控制台程序在没有控制台的情况下运行

    我在 MinGW 中制作了一个控制台程序 它执行网络和文件操作 然而 它是一个控制台程序 如何让它安静地运行 没有控制台 没有窗口 尝试这个 ShowWindow GetConsoleWindowHandle SW HIDE GetCons
  • 解决方案将无法构建,因为它无法从服务生成的类型转换为我的类型

    我有一个 WCF 服务项目 它构建得很好 可以生成可访问的 WSDL 并且 svcutil exe 不会生成任何错误 我有一个访问该 Web 服务的 服务管理器 项目 并且我已成功向其中添加了服务引用 ABCService 第三个项目包含我
  • 将 void* 作为函数调用而不声明函数指针

    我已经搜索过 但找不到任何结果 我的术语可能有问题 所以如果以前有人问过这个问题 请原谅我 我想知道是否有一种简单的方法可以调用void 作为 C 中的函数 无需首先声明函数指针 然后为函数指针分配地址 IE 假设要调用的函数是类型void
  • 提升解析器中的 Spirit 段错误

    我一直在尝试将我在本科编译器中编写的一些 lex 和 yacc 代码转换为精神代码以学习精神 我发现了一个我似乎无法弄清楚的段错误 我这样写了词法分析器 namespace lex boost spirit lex enum Tokens
  • 是否可以将向量的一部分作为向量发送给函数? [复制]

    这个问题在这里已经有答案了 我想看看是否可以将向量的一部分传递给函数 以便它显示为函数的法线向量 更重要的是 我希望这可以在 O 1 的常数时间内完成 我不想迭代向量来创建一个新向量 事实上 我还希望在下面的示例中将新向量的大小更改为 40
  • 如果文本框不为空,如何添加并显示工具提示文本框 WPF

    需要显示提示 其中包含文本字段中的数据 文本框有数据时出现提示 只需使用绑定到 ToolTipService 附加属性即可 XAML
  • Task.WaitAll 保持循环

    我正在尝试这个异步代码只是为了测试 async 关键字 public async Task
  • Windows 消息

    我需要发送带有自定义 ID 的自定义 Windows 消息 其他应用程序将侦听该消息 Windows 是否为内部消息保留任何预定义的消息 ID 范围 如 SQL Server 那样 内部消息最多为 50 000 The 文档 https m
  • std::vector 错误 C2582:“operator =”函数在以下位置不可用

    我使用简单的向量push back到类型A的对象 并收到此错误 这是我的代码 class A public A int a int b int c include A h std vector a vec objects new std v
  • fgets 和 fread 之间的区别

    我有以下代码 include
  • 包含不同类型的两个集合相交

    假设我有一个集合 称之为ids它是类型IEnumerable
  • 如何使用最小起订量模拟 Controller.User

    我有几个 ActionMethods 查询 Controller User 的角色 如下所示 bool isAdmin User IsInRole admin 在这种情况下可以方便地行事 我开始使用这样的代码对这些方法进行测试 TestMe
  • Java 中的引用变量里面有什么?

    我们知道对象引用变量保存表示访问对象的方式的位 它不保存对象本身 但保存诸如指针或地址之类的东西 我正在阅读 Head First Java 第 2 版 一书 书中写道 第 3 章第 54 页 在 Java 中我们并不真正知道什么是 在引用
  • 如何从与桌面交互的应用程序与 Windows 服务进行通信?

    使用 Net 与服务交互的最佳方式是什么 即大多数托盘应用程序如何与其服务器通信 如果这个方法也是跨平台的 那就更好了 在 Mono 中工作 所以我猜远程处理已经过时了 Edit 忘了说了 我们仍然需要在现场支持 Windows 2000
  • 位运算符,而不是在分支中使用异或

    问完后这个问题 https stackoverflow com questions 22336015 why use xor with a literal instead of inversion bitwise not 我收到了 Ando
  • 将 tiff 像素长宽比更改为正方形

    我正在尝试对多页 tiff 文件执行条形码识别 但是 tiff 文件是从传真服务器 我无法控制 发送给我的 该服务器以非方形像素长宽比保存 tiff 这导致图像由于纵横比而被严重挤压 我需要将 tiff 转换为方形像素长宽比 但不知道如何在
  • Security.h 中结构的 macOS 文档

    我正在尝试使用Security h通过 Java 和 JNA 的 macOS 框架 这意味着我需要将某些结构重建为 Java 类 问题是 当我查看文档中的结构时 this one https developer apple com refe
  • 生成唯一随机数的智能方法

    我想生成 00000001 到 99999999 范围内的唯一随机数序列 所以第一个可能是 00001010 第二个可能是 40002928 等等 最简单的方法是生成一个随机数并将其存储在数据库中 下次再执行一次并检查数据库中该数字是否已存
  • C++ 模板类问题中的类型条件

    使用海湾合作委员会4 2 我有这个条件类型的元模板 template
  • Phong 着色问题

    我正在根据以下内容编写着色器冯模型 http en wikipedia org wiki Phong reflection model 我正在尝试实现这个方程 其中 n 是法线 l 是光线方向 v 是相机方向 r 是光反射 维基百科文章中更

随机推荐

  • 使用模型时 CakePHP AJAX Json 解析错误

    我正在使用 CakePHP 2 5 3 0 开发一个应用程序 然后我偶然发现了 AJAX 的一个问题 我使用从 jQuery 到 CakePHP 的 AJAX 请求来发送用户的登录名和密码 然后 CakePHP 应该返回经过验证的 JSON
  • 展开可选 IBOutlet 值时为 Nil

    我有一个fatal error unexpectedly found nil while unwrapping an Optional value for an IBOutlet 在我的自定义视图中 我已将我的插座与XIB文件 我已经仔细检
  • 在 Objective-C 中打乱 NSString 中的字母

    我写了这个函数 它会打乱 a 的内容NSString 它似乎可以工作 但时不时会崩溃 这可能是一种迂回的方式 但我将字符放入一个数组中 随机交换数组中的元素 然后将数组转回字符串 我不确定我正在做的事情是不安全的 这会导致它崩溃 我想这可能
  • 从视图控制器返回到表视图控制器时,表视图单元格“跳转”

    我有一个TableViewController 然后单击自定义单元格会将您带到相关的WebViewController 我遇到的问题是 当我点击 返回 时WebViewController中的表视图单元格TableViewControlle
  • pandoc 文档转换失败,错误 2

    当我在 R studio 中编写 HTML 时 我得到以下结果 C Users Susan ANACON 1 Scripts pandoc RTS K512m RTS Lesson3 student utf8 md to html from
  • Ruby:KML 库?

    我正在寻找一个 ruby 库来将位置数据导出到 KML 文件中 要导出的数据主要包含带有纬度和经度的简单点 但我也希望能够导出更复杂的多边形 I tried 龟豹 http rubygems org gems kamelopard 但觉得不
  • Python __dict__

    属性 dict 应该包含用户定义的属性 但是如果我们打印 dict 一个空的类 我还会得到 module dict weakref doc 哪些是由 Python 预先填充的 dict 相应于类对象类型的属性 Now base and cl
  • 主 NSWindow 阴影不会像子窗口那样改变

    我的应用程序中的主窗口是无边框的 self window setStyleMask NSBorderlessWindowMask 从该窗口 我还打开其他子窗口 当我在其他子窗口之间单击时 我看到当该子窗口被单击并成为焦点窗口时 这些子窗口的
  • 如何使嵌套双引号在 bash 解释器中幸存下来?

    鉴于下面的上下文 是否存在任何可以插入到 WGETOPT 定义中的神奇语法 以允许 吸收 USERAGENT 变量 并且仍然允许调用 wget 命令 如下所示syntax 1 我目前已经求助于使用 eval 但我对此并不满意 但也许这是我可
  • 根据 React.Js 中第一个下拉列表中的选择填充第二个下拉列表

    我正在学习反应并努力根据从第一个下拉列表中单击的选项来填充第二个下拉列表 我在下面包含了我的代码 我认为问题在于我尝试设置的位置this state selected param tableName 我认为这行不通 但我不知道该用什么来代替
  • SVG 作为 CSS 背景 - 有没有办法重复 x 且中间没有空格?

    在基于 Webkit 和 Blink 的浏览器中 SVG 无法正确平铺 不同缩放级别的图像之间存在间隙 StackOverflow 上有许多主题解决了这个问题 所有主题都标记为已解决 但这些人一定没有足够彻底地测试他们的解决方案 我的 SV
  • Groovy Abstract ConcurrentMap 中的错误?

    抽象ConcurrentMap http grepcode sadcom file repo1 maven org maven2 org codehaus groovy groovy all 2 4 3 org codehaus groov
  • 是否可以使用VBA单击报表记录以在Access中打开相关表单

    我有一份包含工作 任务详细信息的报告 还有一个为该报告提供大部分数据的表格 鉴于报告是查看数据大图的好方法 而表单是编辑数据的最佳方法 我希望能够单击一行 并让它打开相关记录表单视图 有谁知道如何通过VBA 做到这一点 在我看来 这应该是可
  • 我可以在不可变类中使用 StringBuilder

    如果我创建一个不可变的类 所有字段都必须是最终的 如果我像这样使用 stringbuilder 最终 StringBuilder s new StringBuilder Hello 那么append函数可以追加s的值并且类不会是不可变的 请
  • 如何通过排序、分区和分组进行行编号

    我需要通过排序 分区和分组进行行编号 订购依据IdDocument DateChange 划分为IdDocument并分组依据IdRole 问题尤其出在分组上 从例子中可以看出 NumberingExpected DENSE RANK 必须
  • ASP.NET MVC Web 应用程序无法通过 Arvixe 托管的 IIS 服务器上的 SMTP 发送电子邮件

    我迫切需要帮助解决这个问题 如何让我部署的应用程序通过 SMTP 将电子邮件发送到任何地址 我正在 Visual Studio 2015 ASP NET MVC 中开发基于 Web 的销售跟踪应用程序 该网站将托管在 Arvixe Busi
  • 我想使用 StringTokenizer 搜索字符串,但我正在查找的字符串中有分隔符 - Java

    我有一个名为quotes txt 的外部文件 我将向您展示该文件的一些内容 1 Everybody s always telling me one thing and out the other 2 I love criticism jus
  • Java编译器的内部架构[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我一直在努力Java从8年多开始 上周 在我公司的一次小型会议上 我的一位同事问我到底如何Java Compiler工作 我无言以对
  • C++ 中整数可以是 NaN 吗?

    我可以设置一个int to NaN 如果是 那么我如何检查是否int is NaN or not 不 NaN 是浮点值 每个可能的值int是一个数字 Edit 标准说 6 2 6 240 某些填充位组合可能会产生陷阱 表示 例如 如果一个
  • 变量声明的行为如何?

    include