C语言中char数组的奇怪输出行为 [英] Weird output behavior with char array in C

查看:258
本文介绍了C语言中char数组的奇怪输出行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个函数,当我用 printf(%c,*(k + i)); 打印时,返回char *;

I have a function that returns char* when I print it with printf("%c", *(k+i)); on the main it prints;

0'10101001 Q-> Q

但是如果我使用 printf(%c,*(k + i))打印; 问题较少。
如果在二进制函数中打印,输出将像这样完美;

but if I print with printf(" %c", *(k+i)); there are less problem. If I print inside the tobinary function, output comes perfect like this;

1010.011010011011101001011110001101010011111101111100111 -> 111011

我在做什么错?

char *tobinary(double num) {
    int length = 62;
    char bin[length];
    int intpart = (int)num;
    double decpart = 1000*(num - intpart);

    int i = 0;
    while (intpart!=0) {
        if(intpart%2 == 1) bin[3-i] = '1';
        else bin[3-i] = '0';
        intpart /= 2;
        i++;
    }

    bin[i++] = '.';
    while (i <= length) {
        decpart *= 2;
        if (decpart >= 1000) {
            bin[i] = '1';
            decpart -= 1000;
        }
        else bin[i] = '0';
        i++;
    }
    char *k = bin;
    return k;

}


int main(int argc, char **argv) {
    char *k = tobinary(10.413);
    for(int i = 0; i <= 62; ++i) {
        printf("%c", *(k+i));
        if (i==56) printf(" -> ");
    }
}


推荐答案

何时您可以在函数中声明局部变量,例如

When you declare a local variable in a function, like this

char *tobinary(double num) {
    int length = 62;
    char bin[length];

    /* ... */
}

it存储在名为 stack 的特殊存储区域中。每当调用函数 func()时,CPU都会在其中保存一些有用的数据,例如调用函数的地址,在之后将恢复执行。 func()以及 func()的参数以及上面声明的任何局部变量都将返回。

it is stored in a special memory area called stack. Whenever a function func() is called, the CPU saves there some useful data such as the address of the calling function where the execution will be restored after func() returns, along with the parameters of func() and, as I wrote above, any local variable declared in it.

所有这些数据都使用LIFO条件(后进先出)进行堆叠,以便在函数返回时更改特殊指针(堆叠指针)指向有关调用函数的数据。 func()的数据仍然存在,但是只要调用调用程序调用了另一个函数或声明了其他局部变量,就可以覆盖该数据。 ()请注意,它符合以下事实:局部变量的生存期仅限于声明它们的函数。

All this data is stacked with a LIFO criteria (Last In, First Out), so that when function returns a special pointer (stack pointer) is changed to point back to the data regarding the calling function. func()'s data is still there, but it can be overwritten whenever another function is called or other local variables are declared by caller(). Please note that it is compliant with the fact that local variables have a lifetime limited to the function in which they are declared.

这就是您的情况。由于执行继续进行,因此您的 bin [] 数组不保证保持安全:

That's what happen in your scenario. Since the execution goes on, your bin[] array is not guaranted to stay "safe":


  • int i 在for循环节中声明

  • printf()被称为

  • int i is declared in the for-loop section
  • printf() is called

这就是破坏您的数据的原因(我使用了双引号,因为它不再是您的了)

This is what corrupts "your" data (I used double quotes because it is not yours anymore).

每当需要返回由函数操作的数据时,都有以下三种选择:

Whenever you need to return data manipulated by a function, you have three options:


  1. 声明其外部的数组,并在更改其原型后将其传递给函数: int tobinary(char * arr,unsigned int arrsize,double num ); 。这样,函数可以修改调用方传递的数据(最多更改 arrsize 个字符)。返回值可以成为错误代码;类似于0表示成功,-1表示失败。

  2. 使用 malloc()在函数内部动态分配数组。在这种情况下,释放内存(使用 free())是调用方函数的责任。

  3. 在函数中将数组声明为静态。实际上,此限定符告诉编译器变量的 lifetime 是程序的整个生命周期,并且使用另一个特定的内存区域来存储它而不是堆栈。请注意,在这种情况下,您的函数将不再是线程安全的(不同的线程访问同一内存区域将导致奇怪的结果)。

  1. Declare the array outside it and pass it to the function after changing its prototype: int tobinary(char *arr, unsigned int arrsize, double num);. In this way the function can modify the data passed by the caller (changing at most arrsize characters). The return value can become an error code; something like 0 on success and -1 on failure.
  2. Dynamically allocate the array inside your function using malloc(). In this case freeing the memory (with free()) is responsability of the caller function.
  3. Declare the array in your function as static. This qualifier, in fact, tells the compiler that the lifetime of the variable is the whole life of the program, and a different specific memory area is used to store it instead of the stack. Be aware that in this case your function won't be thread safe anymore (different thread accessing the same memory area would lead to bizarre results).

这篇关于C语言中char数组的奇怪输出行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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