- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
#include <stdio.h>
#include <stdlib.h>
int main() {
char a;
printf("What? \t");
scanf("%s", &a);
printf("U have to %s", a);
return 0;
}
%s
中输入值时,都会出现错误,调试程序将停止工作并关闭。但是当我像这样使用&符号时:
#include <stdio.h>
#include <stdlib.h>
int main() {
char a;
printf("What? \t");
scanf("%s", &a);
printf("U have to %s", &a);
return 0;
}
printf
...中它起作用。这是为什么?格式说明符之间也有所不同,例如,当一个人在
&
中使用
printf
或
%c
时,不需要在
%d
中放入
scanf
(与号)符号。为什么会发生这种情况,并且它与数据类型有关,并且哪种格式说明符可以得出此结果?
最佳答案
您在这里拥有的是一个经典的代码示例,该代码似乎可以工作,但是原因不正确。
让我们回顾一下有关printf
和scanf
的一些信息。格式说明符%d
用于类型int
的值。您可以读取这样的整数:
int i;
scanf("%d", &i);
printf("%d\n", i);
&
而一个人不使用?好吧,C使用了所谓的“按值传递”。如果我们写
scanf("%d", i); /* WRONG */
i
的值传递给
scanf
。但是我们不想将
i
的(旧)值传递给
scanf
,我们希望
scanf
读取一个新值,并将其存储到
i
中。换句话说,实际上,我们希望
scanf
将
i
的新值传回给我们。为此,我们改为传递
scanf
指向变量
i
的指针,在该变量中我们希望它存储刚读取的整数。这就是
&
的作用-它生成指向
i
的指针。
printf
时,常规的参数传递方式就可以了。我们确实希望将
i
的值传递给
printf
,以便它可以将其打印出来。如果我们打电话给
printf("%d\n", &i); /* WRONG */
printf
需要一个
int
,在这里我们错误地将其传递给
int
指针。
%d
的整数,
printf
需要一个
int
,而
scanf
需要一个指向
int
的指针。
%c
用于字符。我们可以用
scanf
读取一个字符:
char c;
scanf("%c", &c);
printf
打印它:
printf("%c\n", c);
scanf
需要一个指针,以便它可以填写值,因此我们传递
&c
。但是
printf
只需要该值,因此我们传递普通的
c
。
'\0'
终止,该空字符标记字符串的结尾。因此,如果我们想声明一个变量,它可以包含最长9个字符的字符串,则可以编写
char s[10];
'\0'
。
scanf
和
%s
读取字符串,我们可以调用:
scanf("%s", s);
&
在哪里?” “我认为您在呼叫
&
时总是需要一个
scanf
!”
scanf
时始终需要一个指针。实际上,当您调用
scanf("%s", s)
时,就好像您已经编写了
scanf("%s", &s[0]);
%s
与
scanf
一起使用时,它期望指向多个字符中第一个字符的指针,即指向字符数组开头的指针,并应在此处开始写入读取的字符串。 (它怎么知道数组有多大?如果用户键入的字符串太长而无法放入数组中,该怎么办?我们稍后会谈到这些点。)
%s
打印字符串,它看起来像这样:
printf("%s\n", s);
printf("%s\n", &s[0]);
%s
与
printf
一起使用时,它会期望一个指向应该开始打印的几个字符中的第一个的指针,直到找到终止的
'\0'
字符为止。
%s
对于
printf
和
scanf
是特殊的,因为字符串是特殊的(因为数组是特殊的)。使用
%d
和
%c
以及几乎所有其他格式说明符,在调用
&
时通常需要一个
scanf
,而在调用
&
时通常不希望该
printf
。但是对于
%s
,通常不希望
&
或
printf
使用
scanf
。
scanf
和
%s
不需要
&
。请记住,规则确实是
scanf
始终需要指针。唯一的
scanf
和
%s
不需要
&
的原因是,当您传递数组时,会自动获得一个指向数组第一个元素的指针,因此
printf
和
%s
的确是例外:< cc>和
printf
确实希望有一个指针,而
%s
和
printf
设计为希望有一个指针的原因是,没有办法不给它一个:它必须接受一个指针,因为对于字符串,那是你总是给它的东西。)
%s
的规则是
%s
期望指向多个字符中第一个字符的指针,而
scanf
也期望指向多个字符中的第一个字符的指针。
char c;
scanf("%s", &c);
printf
和
scanf
需要一个指向字符的指针,而您给了它
%s
,它是一个指向字符的指针。但是
&c
确实想要一个指向几个字符中第一个字符的指针。但是您给它提供了一个指向单个字符的指针。因此,当用户键入字符串时,键入的第一个字符将存储在
%s
中,而其余字符以及终止的
c
将被写入未分配的内存中,该内存位于变量
'\0'
的右侧。 。他们将覆盖(“智能”)可能用于其他用途的内存。这是一个严重的问题,但可能不会立即显现出来。
c
重新打印出来。你第一次尝试
printf("%s\n", c); /* WRONG */
printf
的
%s
需要一个指向
printf
的指针,但是您给它一个普通的
char
。假设
char
包含字母
c
。这最终将要求
'A'
转到地址65并开始打印字符,直到找到终止的
printf
。为什么要地址65?因为65是
'\0'
的ASCII码。但是在内存中可能没有一个正确的,以零结尾的字符串,它从地址65开始。实际上,您的程序很有可能根本没有权限读取地址65。
printf("%s\n", &c); /* ALSO WRONG */
A
中,并且未分配的内存位于它的右侧,并且如果以某种方式破坏了该内存没有导致(太多)其他问题,那么当您通过将指针
c
指向
&c
,printf可以找到这些字符,组成一个字符串,然后将它们打印出来。
char s[10];
scanf("%s", s);
printf("%s\n", s);
printf
获得指向数组
scanf
的第一个元素的指针时,它将具有10个字符。
s
允许读取一个字符串多长时间,允许将多少个字符写入我们处理过的数组:
scanf("%9s", s);
scanf
告诉
9
不允许用户读取超过9个字符。而且由于9小于10,因此仍有终止
scanf
字符的空间。
'\0'
还有更多可以说的。正如chqrlie在评论中指出的那样,检查其返回值很重要,以确保它成功转换了所需的任意数量的值。关于空格有一些奇怪的规则。除非您知道自己在做什么,否则就无法将对
scanf
的调用与对诸如
scanf
或
getchar
之类的其他输入读取功能的调用混合在一起-您会得到奇怪的结果。最后,scanf如此顽强,(最后)如此缺乏真正有用的功能,因此根本不值得使用。但是这些是第二天的话题,因为这个答案已经是
tl;dr了。
关于c - 在&#f;和printf&格式说明符中的用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50074855/
有没有办法使用 Clojure format(基于 java.util.Formatter)或 cl-format(基于 Common Lisp 的format) 以编程方式设置空格填充?如果您事先知
我正在尝试创建一个用户实体以及数据/文件(pdf格式)。上传并保存到数据库很好,但是当我让用户进入 postman 时尝试发送获取请求方法,然后在数据字段中显示一些糟糕的数据,而且我无法在数据库中看到
我必须将值为 {"STX","ETX"} 的普通字符串数组转换为十六进制值,并且我应该根据 http://www.asciitable.com/ 得到 {2,3} . 最佳答案 听起来你想要一个 Ma
我想格式化我的代码,但不确定哪种格式类型最适合我的项目需要。 我发现仅对于 dart 和 flutter 项目(我都有),有不止一个选项可用于格式化编程语言/框架中预先构建的代码。 Dart : da
我已经尝试了多个代码,例如这样 Sub DateFixer() Application.ScreenUpdating = False Application.Calculation =
SolrQuery query = new SolrQuery(); query.setQuery("*:*"); query.add("wt","csv"); server.query(query)
我有一个包含多个字符串的数据库,我从查询中获取了这些记录,并且我在 QString 中收到了这种格式的数据: "Mon, 13 Nov 2017 09:48:45 +0000" 所以,我需要根据文化来
我有一个 Delphi 2007 DBGrid,我想让用户以更新的 Excel 格式 (OOXML) 保存它,但我的标准是用户不需要安装 Excel。有没有人知道任何已经这样做的组件?是的,我已经搜索
我正在我们的普通 html 站点旁边创建一个移动站点。使用 rails 3.1。移动站点在子域 m.site.com 中访问。 我已经定义了移动格式(Mime::Type.register_alias
我正在尝试使用 xmlstarlet 格式化 xml 文件,但我不想创建新的 xml 文件。 我试过了 xmlstarlet fo --inplace --indent-tab --omit-decl
我在 A 列中有一个带有文本的电子表格。 例如 A1=MY TEXT1 A2=MY TEXT2 A3=MY TEXT3 A4=MY TEXT4 A5=MY TEXT5 我想在文本的前后添加撇号 结果是
我想做一些源代码转换(自动导入列表清理),我想保留注释和格式。我听说过一些关于解析器这样做的事情,我认为是 ghc 解析器。 看起来我可以通过从文件中提取内容来使用 hs-src-exts Langu
我在 Excel 中工作,我想根据另一张表中的列表找出一张表中是否有匹配项。 我已将值粘贴到列表中,并希望从另一张表中返回它们的相应值。包含字母和数字的单元格可以正常工作(例如:D5765000),但
我有一个 DurationField在我的模型中定义为 day0 = models.DurationField('Duration for Monday', default=datetime.time
我正在为我的应用程序开发 WMI 查询。它需要为给定的 VID/PID 找到分配的虚拟 COM 端口。使用 WMI Code Creator 我发现...... 命名空间:root\CIMV2 类:W
我试图弄清楚如何使用 NSTextList,但除了 this SO question 之外,在网上几乎没有找到有用的信息。和 the comment in this blog . 使用这个我已经能够创
我要查询all_objects表在哪里last_ddl_time='01 jan 2010'但它拒绝日期格式... 任何机构给我查询的确切格式? 最佳答案 正如 AKF 所说,您应该使用 Trunc除
我试图在我的应用程序中实现聊天功能。我使用了 2 个 JEditorPane。一个用于保存聊天记录,另一个用于将聊天发送到前一个 JEditorPane。 JEditorPane 是 text/h
我在大学里修了一个编译器类(class),内容非常丰富,很有趣,尽管也很多工作。既然给了我们要实现的语言规范,所以我学不到的一件事就是语言设计。我现在正在考虑创建一种有趣的简单玩具语言,以便我可以玩耍
Closed. This question does not meet Stack Overflow guidelines。它当前不接受答案。 想改善这个问题吗?更新问题,以便将其作为on-topic
我是一名优秀的程序员,十分优秀!