阅读背景:

C整数/浮点数组奇怪的行为

来源:互联网 

Okay so i was just fooling around making random programs and seeing their outputs to understanding how things work and i noticed a strange thing about integer/float arrays. Unlike char array the '

Okay so i was just fooling around making random programs and seeing their outputs to understanding how things work and i noticed a strange thing about integer/float arrays. Unlike char array the '\0' character is not stored directly after the last entered element into the array. In integer array it is stored two elements after the last element and in float its four elements. Here's the code to demonstrate this strange fact. Please help me understand why this happens.

好吧,所以我只是在制作随机程序并看到他们的输出来理解事情是如何工作的,我注意到整数/浮点数组的一个奇怪的事情。与char数组不同,'\ 0'字符不会在最后输入的元素之后直接存储到数组中。在整数数组中,它在最后一个元素之后存储两个元素,在float中存储它的四个元素。这是展示这个奇怪事实的代码。请帮我理解为什么会这样。

#include <stdio.h>
#include <string.h>

void foo(int* x)
{
    while ( *(x) != '\0' )
    {
        printf("%i ",*x);
        ++x;
    }
} 

void foo1(float* x)
{
    while ( *(x) != '\0')
    {
        printf("%.1f ",*x);
        ++x;
    }
} 

void foo2(char* x)
{
    while( *(x) != '\0' )
    {
        printf("%c",*x);
        ++x;
    }
} 

int main(void)
{
    int a[4] = {1,2,3,4};
    float b[4] = {1.1,2.2,3.3,4.4};
    char name[] = "Muneeb";

    foo(a);
    printf("\n\n");

    foo1(b);
    printf("\n\n");

    foo2(name);
    return 0;
  }

Output:

输出:

1 2 3 4 -12345677723 -1623562626
1.1 2.2 3.3 4.4 0.0 0.0 0.0 0.0 -0.0 -1.3

2 个解决方案

#1


10  

In general, there is no zero element after the end of an array. You cannot assume there is; this kind of code could just as easily segfault. You are finding a zero which is only there by coincidence.

通常,在数组结束后没有零元素。你不能假设有;这种代码可以很容易地段错误。你发现零只是巧合。

In char arrays in particular, this rule is the same. However, a literal string like "Hello, world!" is actually one char longer than what you’d get just by counting characters. This is equivalent to an unmodifiable char[13] of {'H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!', '\0'}. A lot of library functions for working with chars expect a terminating '\0'; no such expectation usually exists for other types of arrays and you need to pass the length explicitly.

特别是在char数组中,此规则是相同的。但是,像“Hello,world!”这样的文字字符串。实际上是一个字符比你通过计算字符得到的更长。这相当于{'H','e','l','l','o',',','','w','o','r'的不可修改的字符[13] ,'l','d','!','\ 0'}。很多用于处理字符的库函数都需要终止'\ 0';对于其他类型的数组通常不存在这样的期望,您需要明确地传递长度。

Also note that your *(x) != '\0' treats the '\0' as an int or float zero, and is equivalent to *x != 0 or *x != 0.0f (for the different types of x in the different functions). If you had stored an actual 0 in one of the arrays, it would have just counted to that.

另请注意,*(x)!='\ 0'将'\ 0'视为int或float零,相当于* x!= 0或* x!= 0.0f(对于不同类型的x在不同的功能)。如果你已经在其中一个数组中存储了一个实际的0,它就会计算到那个。


Since there is no special sentinel convention for int or float arrays (because 0 and 0.0f are usually perfectly reasonable values to put in the array), you should create a separate size_t variable to keep track of the array’s length. Then, if you ever need to create a function acting on an array, you can also give it a length parameter and have it iterate up to that. For example:

由于int或float数组没有特殊的sentinel约定(因为0和0.0f通常是放在数组中的完全合理的值),所以你应该创建一个单独的size_t变量来跟踪数组的长度。然后,如果你需要创建一个作用于数组的函数,你也可以给它一个长度参数并让它迭代到那个。例如:

void foo(int* x, size_t length)
{

    for (size_t i = 0; i < length; ++i)
    {
        printf("%i ", x[i]);
    }

} 

(I use size_t here because it typically represents the size of structures in memory).

(我在这里使用size_t,因为它通常表示内存中结构的大小)。

Then you can call this with foo(a, 4);. If you need a variable-sized array, you can create a size_t a_length variable when you create a, and update it whenever a’s size changes.

然后你可以用foo(a,4);来调用它。如果需要可变大小的数组,可以在创建时创建size_t a_length变量,并在每次更改时更新它。

You might even want to do this with char arrays sometimes, such as if you have binary data which might contain zero bytes, or because scanning for the end of the string takes time and you usually don’t need to look at each character.

您甚至可能希望有时使用char数组执行此操作,例如,如果您有可能包含零字节的二进制数据,或者因为扫描字符串的结尾需要时间而您通常不需要查看每个字符。

#2


2  

You are confusing a character array with a character string. In C, strings are not a specific data type; they are implemented using character arrays. The end of a string is indicated by a NUL terminator, but end of the string is not necessarily the end of the array which may be larger, and a character array need not represent string at all.

您将字符数组与字符串混淆。在C中,字符串不是特定的数据类型;它们是使用字符数组实现的。字符串的结尾由NUL终结符指示,但字符串的结尾不一定是可能更大的数组的结尾,并且字符数组根本不需要表示字符串。

Your observation that other array types have zero terminators (past the end of the array or otherwise) is a false conclusion - the zeroes you have observed in proximity to the end are purely coincidental.

您观察到其他数组类型具有零终止符(超过数组末尾或其他类型)是错误的结论 - 您在末尾附近观察到的零纯属巧合。


' character is not stored directly after the last entered element into the array. In integer array it is stored two elements after the last element and in float its four elements. Here's the code to demonstrate this strange fact. Please help me understand why this happens.Okay so i was just fooling around making random




你的当前访问异常,请进行认证后继续阅读剩余内容。

分享到: