我写了一个程序来反转一个字符串。但是,当我输入任何内容时,只需按“回车”键,就会打印出“@”。
代码如下:
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”的含义。如果真的导致初始化,为什么程序一行一行地运行会发生这样的事情?
答案 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);