当我什么都没输入时,为什么程序打印出“@”?

时间:2016-12-01 13:15:30

标签: c

我写了一个程序来反转一个字符串。但是,当我输入任何内容时,只需按“回车”键,就会打印出“@”。

代码如下:

printf()

我尝试使用printf("%d\n", i);函数查看按“Enter”键时会发生什么。

但是,添加printf("%d\n", sizeof(str));后,输出变为“3 @”。

添加char str[80]后,输出变为“0 80”。

好像“sizeof”自动“修复”了这个问题。

我的室友说这个问题可能是初始化造成的。我尝试将代码char str[80] = {0}更改为 class CreatePages < ActiveRecord::Migration[5.0] def change create_table :pages do |t| t.string :name t.text :description t.text :address t.text :contact t.string :profile_image t.string :cover_image t.string :look_book t.integer :seller_id t.timestamps end end end ,一切正常。但我仍然不明白代码中存在“sizeof”的含义。如果真的导致初始化,为什么程序一行一行地运行会发生这样的事情?

2 个答案:

答案 0 :(得分:1)

如果在未初始化数组的任何部分的情况下声明数组,则会收到指向尚未初始化的内存位置的指针。该内存位置可能包含任何。事实上,你很幸运它只停留在@

通过指定char str[80] = {0},您实际上是在说:

char str[80] = {0, 0, 0, /* 77 more times */ };

从而将字符串初始化为所有null值。这是因为如果部分初始化,编译器会自动使用null s填充数组。 (但是,当你从堆中分配内存时,这,只是一个警告)。

要理解为什么一切都在发生,让我们按照您的代码进行操作。

当您将i设置为strlen(str)返回的值时,strlen会迭代从str指向的内存位置开始的位置。由于您的内存未初始化,因此会在位置0找到@,然后在位置1找到0,因此它会正确返回1.

当您不输入任何内容时,循环会发生什么? i设置为0,j设置为0,因此条件j<i/2的计算结果为0<0,这是假的,因此它会转到第二个条件。第二个条件仅测试数组中的当前位置是否为null。巧合的是,您将返回第一个char@的内存位置。它打印出来,幸运的是下一个值为null

当您使用sizeof运算符时,您将获得在堆栈上分配的整个数组的大小(如果您开始使用指针,则可能会遇到此问题,这一点非常重要)。如果您使用strlen,则会收到1

建议

我建议您i = strlen(str);,而不是尝试i = scanf("%[^\n]s", str);。这是因为scanf返回读取并放置在缓冲区中的字符数。此外,尝试使用更具描述性的变量名称,这使得阅读代码变得更加容易。

答案 1 :(得分:0)

做一个str的memset然后它什么也没有,而不是垃圾

char str[80];       
memset(str,0,80);