感谢您的回复,每个人都对帮助我理解这是如何工作的很有用。
一个朋友发给我这段C代码问它是怎么工作的(他也不知道)。我通常不使用 C,但这激起了我的兴趣。我花了一些时间试图了解发生了什么,但最后我无法完全弄清楚。这是代码:
void knock_knock(char *s){
while (*s++ != '\0')
printf("Bazinga\n");
}
int main() {
int data[5] = { -1, -3, 256, -4, 0 };
knock_knock((char *) data);
return 0;
}
最初我认为这只是打印数组中数据的一种奇特方式(是的,我知道 :\),但当我看到它没有打印“Bazinga”5 次,而是 8 次时,我感到很惊讶。我搜索了一些东西,发现它正在使用指针(对于 c 来说完全是业余爱好者),但我仍然不明白为什么是 8。我搜索了更多,发现通常指针的长度为 8 个字节C,我通过在循环之前打印 sizeof(s) 验证了这一点,果然它是 8。我以为就是这样,它只是在指针的长度上迭代,所以它打印 Bazinga 8 是有意义的次。现在我也很清楚为什么他们会使用 Bazinga 作为要打印的字符串——数组中的数据只是为了分散注意力。所以我尝试向数组中添加更多数据,果然它一直打印 8 次。然后我更改了数组的第一个数字-1,以检查数据是否真的没有意义,这就是我感到困惑的地方。它不再打印 8 次,而只打印一次。阵列中的数据肯定不仅仅是一个诱饵,但对于我来说,我无法弄清楚发生了什么。
使用以下代码
#include<stdio.h>
void knock_knock(char *s)
{
while (*s++ != '\0')
printf("Bazinga\n");
}
int main()
{
int data[5] = { -1, -3, 256, -4, 0 };
printf("%08X - %08X - %08X\n", data[0], data[1], data[2]);
knock_knock((char *) data);
return 0;
}
可以看到
data
数组的HEX值是
FFFFFFFF - FFFFFFFD - 00000100
函数
knock_knock
打印Bazinga
直到指向的值为0x00
由于
while (*s++ != '\0')
但是这里的指针指向字符,因此每个循环指向一个字节,因此,第一个
0x00
到达访问数组第三个值的“第一个”字节。
您需要查看整数数组中数据的字节表示
data
。假设一个整数是 4 个字节,下面的表示给出了十六进制的数字
-1 --> FF FF FF FF
-3 --> FF FF FF FD
256 --> 00 00 01 00
-4 --> FF FF FF FC
0 --> 00 00 00 00
数组
data
是以Little-Endian格式存储的这些数字。 IE。 LSbyte 排在第一位。所以,
data ={FF FF FF FF FD FF FF FF 00 01 00 00 FC FF FF FF 00 00 00 00};
函数
knock_knock
按字节遍历此数据并为每个非零打印Bazinga
。它在找到的第一个零处停止,这将在 8 个字节之后。
(注意:整数的大小可以是 2 或 8 个字节,但鉴于您的指针大小是 8 个字节,我猜整数的大小是 4 个字节)。
如果将十六进制的数组输出为字符数组,很容易理解这里发生了什么。这里展示了如何做到这一点
#include <stdio.h>
int main(void)
{
int data[] = { -1, -3, 256, -4, 0 };
const size_t N = sizeof( data ) / sizeof( *data );
char *p = ( char * )data;
for ( size_t i = 0; i < N * sizeof( int ); i++ )
{
printf( "%0X ", p[i] );
if ( ( i + 1) % sizeof( int ) == 0 ) printf( "\n" );
}
return 0;
}
程序输出为
FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
FFFFFFFD FFFFFFFF FFFFFFFF FFFFFFFF
0 1 0 0
FFFFFFFC FFFFFFFF FFFFFFFF FFFFFFFF
0 0 0 0
所以字符串
"Bazinga"
将输出与数组中整数表示中的非零字节一样多的次数。正如所见,前两个负数在其表示中没有零字节。
但是数字
256
在任何情况下在其内部表示的最开始都有这样一个字节。因此,如果 sizeof( int )
等于 4
.,则字符串将精确输出八次