C编程:为什么printf格式说明符%s对于数字“ 123”无效?

如何解决C编程:为什么printf格式说明符%s对于数字“ 123”无效?

我是一名C编程新手。

有了其他问题的答案,我可以理解“字符”一词可以表示各种元素;例如字母和数字。

我将“字符串”视为字符。

然后,请看以下几行:

#include <stdio.h>

main()
{
    int numbers = 123;
    printf("%c%s\n","N",numbers); 
}

当我尝试编译此代码时,显示了错误消息,并且编译失败。

教科书“ The C Programming Language”第13页像下面这样说到printf格式说明符;

%c代表字符”

%s用于字符串”。

第一个问题:

尽管“ N”是一个字符,但%c说明符为何无效?

第二个问题:

尽管变量“数字”的值为“ 123”,但它们是数字,包含在字符中。

我认为字符等于“字符串”。

然后,尽管我将%s用作“ 123”,但为什么无效?

我知道我的代码可以正常工作,如果我像下面这样修改它们:

#include <stdio.h>

main()
{
    int numbers = 123;
    printf("%s%d\n",numbers); 
}

但是我想了解为什么上面的代码无效。

解决方法

“尽管"N"是一个字符,但为什么%c说明符无效?”

"N"不是字符常量。它是字符串文字。 'N'是一个字符常量,与%c匹配。单引号和双引号之间的区别很重要。

说明符也永远是无效的。只有参数类型可以。

“然后,尽管我将%s用于"123",但为什么无效?”

您没有使用"123",它是字符串文字,并且会发出char *。您使用123123是存储在int numbers类型的对象中的整数值。 int格式说明符不允许使用%s参数,它需要类型为char *而不是int的参数。

那是区别。

,

说明

printf("%c%s\n","N",numbers); 

包含两个错误。

  1. 格式说明符%c期望传递单个字符。我们在C语言中定义字符常量的方式是使用单引号'N'
    通过使用双引号"N",您使用的是语法糖方式 C可以表示一个字符串,即由字符串终止符'\0'

    关闭的字符数组
  2. 123是一个整数,就像您正确编写了%d格式说明符一样

谈到最后一个错误,您给出了一个原始的解释

尽管变量“ numbers”的值为“ 123”,但它们是数字,包含在字符中。

我认为字符等于“字符串”。

然后,尽管我将%s用作“ 123”,但为什么无效?

尽管这显然是错误的解释,但我觉得它很有趣,并且值得解释。

123是一个字符串,是一个字符序列吗?就是这样!但这是源代码中的字符串。编译器将解析此字符序列,将识别整数,并确保此值存储在包含整数的内存位置中。在大多数现代计算机中,它将转换为0/1序列,代表4个字节中的数字123。

0b01111011

源代码的角度来看,"123"不一样吗?好吧,不。该数字用双引号引起来,因此编译器会将其解释为实际的字符串,并以n终止的字符序列存储在内存中

--------------------------
| '1' | '2' | '3' | '\0' |
--------------------------

并在内存中存储代表这些数字的ASCII值(假设使用ASCII编码)

-----------------------------
| 0x31 | 0x32 | 0x33 | 0x00 |
-----------------------------
,

我会直接回答你的问题。

第一个问题:

C编程语言区分双引号和单引号。双引号将创建string文字,而单引号将创建character文字。因此,例如'N'character,而"N"string仅包含一个字符,即N。因此,%c为何不这样有用,因为它需要一个字符,但是您要给它字符串 "N"

第二个问题:

变量numbers的值为“ 123”。使用C语言表示法,“ 123”将是包含字符“ 1”,“ 2”和“ 3”的字符串,而变量numbers现在包含整数 123 ,这就是%s无法为numbers工作的原因。尽管您可以将变量123的值转换为这样的字符串:

#include <stdio.h>

main()
{
    int numbers = 123;
    char numbers_string[4];
    sprintf(numbers_string,"%d",numbers); // conversion happens here
    printf("%s\n",numbers_string); 
}

此外,您的问题中的“字符串”和“字符”这两种类型之间似乎存在混淆。重要的是要了解这两种类型是不同的。字符是一个字节(通常),该字节保存所需字符的ASCII码。例如,字符'A'(ASCII码= 65)。但是“字符串”是字符的集合,例如"Apple",在C语言中,通常使用char*来实现“字符串”,该指针指向存储了字符的内存位置按顺序。 (这就是为什么我使用字符数组来保存将numbers转换为“字符串”的结果的原因)

,

尽管“ N”是一个字符,但%c指定符为何无效?

"N" string ,不是单个字符-双引号表示字符串文字。 'N'(单引号)将是字符常量 1 ,因此

printf( "%c\n",'N' );

将正常工作。要打印"N",您需要使用%s转换说明符:

printf( "%s\n","N" );

%s转换说明符期望其对应的参数具有类型char *(指向char的指针),并且它将告诉printf打印从以下位置开始的字符序列指定的地址,直到看到字符串终止符为止。

表达式"N"的类型为“ char的2元素数组”(char [2]),数组的内容为{'N',0}。在C语言中,字符串是字符值的序列,包括一个用于标记字符串结尾的0值终止符。字符串(包括字符串文字)存储在字符类型的数组中。

在大多数情况下,类型为“ T”(T [N])的N元素数组的表达式将被转换(“衰变”)为类型的表达式“ T的指针”(T *),表达式的值将是数组第一个元素的地址。

在上面的printf语句中,表达式"N"从类型char [2]转换为char *,表达式的值是第一个字符的地址。

尽管变量“数字”的值为“ 123”,但它们是数字,包含在字符中。

让我们看一下numbers的声明:

int numbers = 123;

首先,numbers变量的 type int,而不是char *。它包含什么值都没有关系,它不是%s期望的类型。其次,123不是字符串-也不用引号引起来。而是一个整数常量。

numbers不是字符串-它不是存储字符串的正确类型,并且不包含带有0终止符的字符序列。这是一个整数,存储十进制值123的二进制表示形式。要打印出来(即在输出设备上产生该整数值的文本表示形式),请使用%d%i


  1. 在C中,像'N'这样的字符常量的类型为int,而在C ++中,它们的类型为char

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-