如何产生输出解释 [英] how the output is produced explain

查看:80
本文介绍了如何产生输出解释的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  #include   <   stdio.h  >  
int main()
{
char a [ 9 ] = abcefghij;
int i = 0 ;
while (a [i]!= ' \0'
{
printf( %d \吨,A [1]);
i ++;
}
}





输出 97 98 99 100 101 102 103 104 105 106 9

解决方案

问题在于您宣布 a 作为一个9字节长度的变量,有9个字符,因此没有尾随空字节'\0',因为没有剩余空格。这意味着你有一个非空终止的字符串。



声明:



char a [9] =abcdefghij;



将导致在堆栈中分配9个字节(因为你强制它声明9个元素的数组)并填充字符串abcdefhij而没有空字节。无论你向该字符串添加多少个字母,该变量都不会包含超过9个字符,并且将丢弃附加字母(在这种情况下,没有字母被丢弃,但是空字节是)。



然后我们声明:



int i = 0;



这将在堆栈内存中保留4个附加字节。所以我们在内存中有以下连续的字节(用十六进制格式表示,请注意0x61是字母'a',0x62字母'b',依此类推):

 0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x68 0x69 0x00 0x00 0x00 0x00 
\ _____________________ a ____________________ / \ _________ i ________ /
^
| ___指针 a [i] i 在第一次迭代时等于0时。



当您遍历该数组并到达字符串的最后一个位置(数字8)时,while循环将继续迭代,因为它不是以空值终止,导致位置9处的缓冲区溢出。



所以让我们来看看第9次迭代时内存的情况:

 0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x68 0x69  0x08  0x00 0x00 0x00 
\ _____________________ a ____________________ / \ _________ i ________ /
i 等于 8

时,^
| ___指针 a [i] >


溢出将到达堆栈中声明的下一个变量,在本例中为 i ,这是一个整数(4个字节)。

此时的价值为9.



显示图形:

 0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x68 0x69  0x09  0x00 0x00 0x00 
\\ \\ _____________________ a ____________________ / \ _________ ________ /
^
| ___ a [i] 的指针等于 9





最后一次迭代将保持不变这个:



 0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x68 0x69  0x10  0x00 0x00 0x00 
\ _____________________ a ____________________ / \ _________ ________ /
^
当_ b> i 10 时,___指针 a [i]



指向循环将停止,因为 a [10] 为空,尽管它正在访问属于其他变量的内存( i )。



C语言不检查任何数组边界(就像Java,C#,......确实抛出异常),并且溢出该边界将导致访问或覆盖可由变量使用的其他内存,如本例所示。



这就是程序显示最后一个'9'然后停止的原因。


printf ref http://www.cplusplus.com/reference/cstdio/printf/ [ ^ ]



字符值有小数ASCII值。这些是您所看到的价值观。



http://www.asciitable.com / [ ^ ]





你应该看到的最后一个数字是106.不知道为什么你有9。



循环设置为运行,直到索引'i'到达字符串的末尾(在这种情况下我将是9)。字符串的结尾由 null [ ^ ]'\ 0'的值。由于字符数组是用字符串初始化的,因此第9个索引填充为null,因此'\ 0'。





由于数组在初始化时已满并且没有给出空终止符的空间,因此循环停止不是因为从字符数组读取空值而是因为它在整数存储器中看到空值(0) i。

首先读取i的第一个字节(即'09')并输出。当我再次被执行时,数组将依赖于'00',这对于char来说是nul(即'\ 0'),然后将终止循环。


这是因为你有你的printf语句中的%d表示它会显示一些整数值...

因为你有一个字符数组,所以字符的ASCII值就是你的输出...



参考:

ASCII值 [ ^ ]



Printf [ ^ ]



为什么它以9结束,所以请注意r 这个 [ ^ ] link ...;)

#include<stdio.h>
int main()
{
    char a[9]="abcefghij";
    int i=0;
    while(a[i]!='\0')
    {
        printf("%d\t",a[i]);
        i++;
    }
   }



the output is 97 98 99 100 101 102 103 104 105 106 9

解决方案

The problem is that you're declaring a as a 9 byte length variable with 9 characters, so there is no trailing null byte '\0' because there is no space left. That means you have a string that isn't null-terminated.

The declaration of:

char a[9]="abcdefghij";

will result in the allocation of 9 bytes in the stack (because you force it declaring the array of 9 elements) and filled with the string "abcdefhij" without a null byte. No matter how many letters you add to that string, the variable will never contain more than 9 characters, and aditional letters will be discarded (in this case no letter has been discarded, but null-byte was).

Then we have declaration of:

int i=0;

That will reserve 4 aditional bytes in the stack memory. So we have in memory the following contiguous bytes (represented in hexadecimal format, please note 0x61 is letter 'a', 0x62 letter 'b', and so on):

0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x68 0x69 0x00 0x00 0x00 0x00
\_____________________a____________________/ \_________i________/
  ^
  |___ pointer of a[i] when i is equal to 0, at the first iteration.


When you iterate through that array and reach the last position of your string (number 8), while-loop will continue iterating because it isn't null-terminated, causing a buffer overflow at position 9.

So let's take a look what is the situation of the memory at the 9th iteration:

0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x68 0x69 0x08 0x00 0x00 0x00
\_____________________a____________________/ \_________i________/
                                         ^
                                         |___ pointer of a[i] when i is equal to 8



That overflow will reach the next variable declared at the stack, in this case i, which is an integer (4 bytes).
i at that moment will have the value of 9.

Showing that graphical:

0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x68 0x69 0x09 0x00 0x00 0x00
\_____________________a____________________/ \_________i________/
                                               ^
                                               |___ pointer of a[i] when i is equal to 9



And finally the last iteration will remain like this:

0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x68 0x69 0x10 0x00 0x00 0x00
\_____________________a____________________/ \_________i________/
                                                    ^
                                                    |___ pointer of a[i] when i is 10


At that point the loop will stop because a[10] is null, although it's accesing memory that belongs to other variable (i).

C language doesn't check any array boundaries (just like Java, C#,... does throwing an exception), and overflowing that boundaries will result in access or overwriting of other memory that could be used by variables, as in this case.

That's the reason why the program is displaying the last '9' and then stops.


printf ref http://www.cplusplus.com/reference/cstdio/printf/[^]

Character values have decimal ASCII values. Those are the values you are seeing.

http://www.asciitable.com/[^]

[Edit]
The last number you should see is 106. Not sure why you have a 9.

The loop is set up to run until the index 'i' reaches the end of the string (i will be 9 in this case).End of a string is identified by the null[^]value of '\0' . Since the character array is initialized with a string, it has the 9th index filled with null, thus '\0'.

[Edit]
Since the array is full when initialized and no room for the null terminator was given, the loop is stopping not because of the null read from the character array but because it sees a null value (0) with in the integer memory of i.
It first reads in the first byte of i (which is '09') and outputs that. When i is incrimented again the array will deference to '00' which is nul for char (i.e. '\0') and will then terminate the loop.


This is because you have "%d" in your printf statement that means it will display some integer value...
Since you have a character array, so ASCII values of the characters is your output...

Refer:
ASCII Value[^]
And
Printf[^]

And why it is ended with "9", so refer this[^] link...;)


这篇关于如何产生输出解释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆