- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想知道为什么 printf()
在提供数组且没有格式化选项时成功打印字符数组,但在使用整数数组时编译器会抛出警告并打印垃圾值。
这是我的代码:
#include <stdio.h>
int main()
{
char cr[3] = { 'a', 'b' };
int ar[3] = { 1, 2 };
printf("character array output using printf() : ");
printf(cr);
printf("\n\nInteger array output using printf() : ");
printf(ar);
printf("\n");
return 0;
}
这是我的输出:
../main.c: In function ‘main’:
../main.c:12:4: warning: passing argument 1 of ‘printf’ from incompatible pointer type [enabled by default]
printf(ar);
^
In file included from ../main.c:1:0:
/usr/include/stdio.h:362:12: note: expected ‘const char * restrict’ but argument is of type ‘int *’
extern int printf (const char *__restrict __format, ...);
^
Finished building: ../main.c
最佳答案
为了回答到底发生了什么,我想首先展示你的数组初始化的作用。您的数组初始值设定项列表不完整,由于大小大于列表而缺少元素。这将导致 zero initialization for the missing elements .
<强>1。 char cr[3]
数组:
char cr[3] = { 'a', 'b' };
将导致:
character represantation == decimal representation
-+----+----+----+----+----+----+- -+----+----+----+----+----+----+-
| | a | b | \0 | | | | | 97 | 98 | 0 | | |
-+----+----+----+----+----+----+- -+----+----+----+----+----+----+-
^~~~ ^~~~
| char | char
cr cr
printf()
函数定义为:int printf( const char* format, ... );
。这意味着它需要一个 char
指针,并且不会更改所指向的元素。
如果您现在将 cr
数组传递给 printf()
函数 the array name will decay to a pointer 。 printf()
函数将 format
参数解释为 null terminated character array which is called a C-string 。您的 cr
数组是一个以 null 结尾的 C 字符串,因为它由 { 'a', 'b', '\0' }
组成。这意味着 printf()
函数可以成功地将字符串 "ab"
打印到 stdout。
<强>2。 int ar[3]
数组:
int ar[3] = { 1, 2 };
将导致:
-+----+----+----+----+----+----+-
| | 1 | 2 | 0 | | |
-+----+----+----+----+----+----+-
^~~~
| int
ar
与第一种情况相比,现在您看不出有什么大的区别(只是类型和内容)。但现在您将 ar
数组传递给 printf()
函数。数组名称将衰减为 int*
并隐式转换为 const char*
(这将为您带来编译器警告) )。如果 printf()
函数现在取消引用内存,则如下所示(假设 int
由 4 个字节组成,并且您的机器使用 little endian memory representation ):
-+----+----+----+----+----+----+----+----+----+----+----+----+----+-
| | 1 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
-+----+----+----+----+----+----+----+----+----+----+----+----+----+-
^~~~~~~~~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~
| int int int
^~~~ ^~~~ ^~~~ ^~~~ ^~~~ ^~~~ ^~~~ ^~~~ ^~~~ ^~~~ ^~~~ ^~~~
| char char char char char char char char char char char char
ar
它不会打印像 "12"
这样的字符串,而是会消耗两个左边的字符,即十进制值 1 和 0(空终止符),请参见上图。 1 和 0 之后的剩余十进制值无法被识别,因为它们位于空终止符之后。假设您的机器使用 the ASCII table小数点 1 不是可打印字符,会导致打印垃圾值。
概念证明:
为了证明我写的内容,您可以使用以下函数,该函数采用与 printf()
相同的第一个参数,即 const char*
:
void printhexchars(const char* str)
{
while(*str)
{
printf("%03d ", *(str++));
}
/* print last character after while loop: '\0' */
printf("%03d ", *str);
}
此函数打印以 null 结尾的 C 字符串的整数表示形式。请参阅example with your arrays char cr[3]
and int ar[3]
on ideone.com 。当然,将整数数组传递给上面的函数将生成与之前相同的编译器警告。
输出:
character array output using printf() : 097 098 000
Integer array output using printf() : 001 000
如您所见,您得到 097 098 000
,它是字符数组的 "ab"
。
您的整数数组导致 001 000
导致十进制值为 1 的不可打印字符。
关于c - printf() 无格式字符串打印字符和整数数组 --> 垃圾,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46110952/
如何使用 SPListCollection.Add(String, String, String, String, Int32, String, SPListTemplate.QuickLaunchO
我刚刚开始使用 C++ 并且对 C# 有一些经验,所以我有一些一般的编程经验。然而,似乎我马上就被击落了。我试过在谷歌上寻找,以免浪费任何人的时间,但没有结果。 int main(int argc,
这个问题已经有答案了: In Java 8 how do I transform a Map to another Map using a lambda? (8 个回答) Convert a Map>
我正在使用 node + typescript 和集成的 swagger 进行 API 调用。我 Swagger 提出以下要求 http://localhost:3033/employees/sear
我是 C++ 容器模板的新手。我收集了一些记录。每条记录都有一个唯一的名称,以及一个字段/值对列表。将按名称访问记录。字段/值对的顺序很重要。因此我设计如下: typedef string
我需要这两种方法,但j2me没有,我找到了一个replaceall();但这是 replaceall(string,string,string); 第二个方法是SringBuffer但在j2me中它没
If string is an alias of String in the .net framework为什么会发生这种情况,我应该如何解释它: type JustAString = string
我有两个列表(或字符串):一个大,另一个小。 我想检查较大的(A)是否包含小的(B)。 我的期望如下: 案例 1. B 是 A 的子集 A = [1,2,3] B = [1,2] contains(A
我有一个似乎无法解决的小问题。 这里...我有一个像这样创建的输入... var input = $(''); 如果我这样做......一切都很好 $(this).append(input); 如果我
我有以下代码片段 string[] lines = objects.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.No
这可能真的很简单,但我已经坚持了一段时间了。 我正在尝试输出一个字符串,然后输出一个带有两位小数的 double ,后跟另一个字符串,这是我的代码。 System.out.printf("成本:%.2
以下是 Cloud Firestore 列表查询中的示例之一 citiesRef.where("state", ">=", "CA").where("state", "= 字符串,我们在Stack O
我正在尝试检查一个字符串是否包含在另一个字符串中。后面的代码非常简单。我怎样才能在 jquery 中做到这一点? function deleteRow(locName, locID) { if
这个问题在这里已经有了答案: How to implement big int in C++ (14 个答案) 关闭 9 年前。 我有 2 个字符串,都只包含数字。这些数字大于 uint64_t 的
我有一个带有自定义转换器的 Dozer 映射: com.xyz.Customer com.xyz.CustomerDAO customerName
这个问题在这里已经有了答案: How do I compare strings in Java? (23 个回答) 关闭 6 年前。 我想了解字符串池的工作原理以及一个字符串等于另一个字符串的规则是
我已阅读 this问题和其他一些问题。但它们与我的问题有些无关 对于 UILabel 如果你不指定 ? 或 ! 你会得到这样的错误: @IBOutlet property has non-option
这两种方法中哪一种在理论上更快,为什么? (指向字符串的指针必须是常量。) destination[count] 和 *destination++ 之间的确切区别是什么? destination[co
This question already has answers here: Closed 11 years ago. Possible Duplicates: Is String.Format a
我有一个Stream一个文件的,现在我想将相同的单词组合成 Map这很重要,这个词在 Stream 中出现的频率. 我知道我必须使用 collect(Collectors.groupingBy(..)
我是一名优秀的程序员,十分优秀!