C语言中字符数组的奇怪输出行为

C语言中字符数组的奇怪输出行为,c,arrays,pointers,char,C,Arrays,Pointers,Char,我有一个函数,当我用printf(“%c”,*(k+I))打印它时,它返回char*在它打印的主屏幕上 0'10101001 Q->Q 但是如果我用printf(“%c”,*(k+I))打印问题较少。 如果我在tobinary函数中打印,输出会像这样完美 1010.011010011011101001011110001101010011111101111100111 -> 111011 我做错了什么?这是代码 char *tobinary(double num) { int le

我有一个函数,当我用
printf(“%c”,*(k+I))打印它时,它返回char*在它打印的主屏幕上

0'10101001 Q->Q

但是如果我用
printf(“%c”,*(k+I))打印问题较少。
如果我在tobinary函数中打印,输出会像这样完美

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(" -> ");
    }
}
char*tobinary(双数值){
整数长度=62;
字符位[长度];
int部分=(int)num;
双depart=1000*(num-intpart);
int i=0;
while(intpart!=0){
如果(内部部分%2==1)bin[3-i]=1';
else bin[3-i]=“0”;
intpart/=2;
i++;
}
bin[i++]=';
而(i=1000){
bin[i]=“1”;
depart-=1000;
}
else bin[i]=“0”;
i++;
}
char*k=bin;
返回k;
}
int main(int argc,字符**argv){
char*k=tobinary(10.413);

for(int i=0;ibin是函数中的字符数组

它不是静态的,因此当您返回指向它的指针时,不能保证保持相同的值


将其更改为静态或返回分配的内存,调用者将需要释放该内存。

bin是函数中的字符数组

它不是静态的,因此当您返回指向它的指针时,不能保证保持相同的值


要么将其更改为
静态
,要么返回分配的内存,调用者将需要释放该内存。

当您在函数中声明局部变量时,如下所示

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

    /* ... */
}
它存储在一个名为堆栈的特殊内存区域中。每当调用函数
func()
时,CPU都会在那里保存一些有用的数据,例如调用函数的地址,在
func()
返回后将恢复执行,以及
func()的参数
以及,正如我在上面所写的,其中声明的任何局部变量

所有这些数据都按照后进先出的标准(后进先出)进行叠加,这样当函数返回一个特殊指针(堆栈指针)时,它会被更改为指向与调用函数有关的数据。
func()
的数据仍然存在,但只要调用了另一个函数或调用方()声明了其他局部变量,它就可以被覆盖。请注意,这符合这样一个事实,即局部变量的生命周期仅限于声明它们的函数


这就是您的场景中发生的情况。由于执行继续,您的
bin[]
数组无法保证保持“安全”:

  • int i
    在for循环部分声明
  • 调用
    printf()
这就是破坏“你的”数据的原因(我使用了双引号,因为它不再是你的了)


每当需要返回由函数操作的数据时,有三个选项:

  • 在数组外部声明数组,并在更改其原型后将其传递给函数:
    int-tobinary(char*arr,unsigned-int-arrsize,double-num);
    。通过这种方式,函数可以修改调用者传递的数据(最多更改
    arrsize
    个字符)。返回值可能成为错误代码;成功时为0,失败时为-1
  • 使用
    malloc()
    在函数中动态分配数组。在这种情况下,释放内存(使用
    free()
    )是调用方函数的责任
  • 将函数中的数组声明为
    static
    。事实上,此限定符告诉编译器变量的生命周期是程序的整个生命周期,并使用不同的特定内存区域来存储它,而不是堆栈。请注意,在这种情况下,函数将不再是线程安全的(不同线程访问同一内存区域会导致奇怪的结果)

  • 当您在函数中声明局部变量时,如下所示

    char *tobinary(double num) {
        int length = 62;
        char bin[length];
    
        /* ... */
    }
    
    它存储在一个名为堆栈的特殊内存区域中。每当调用函数
    func()
    时,CPU都会在那里保存一些有用的数据,例如调用函数的地址,在
    func()
    返回后将恢复执行,以及
    func()的参数
    以及,正如我在上面所写的,其中声明的任何局部变量

    所有这些数据都按照后进先出的标准(后进先出)进行叠加,这样当函数返回一个特殊指针(堆栈指针)时,它会被更改为指向与调用函数有关的数据。
    func()
    的数据仍然存在,但只要调用了另一个函数或调用方()声明了其他局部变量,它就可以被覆盖。请注意,这符合这样一个事实,即局部变量的生命周期仅限于声明它们的函数


    这就是您的场景中发生的情况。由于执行继续,您的
    bin[]
    数组无法保证保持“安全”:

    • int i
      在for循环部分声明
    • 调用
      printf()
    这就是破坏“你的”数据的原因(我使用了双引号,因为它不再是你的了)


    每当需要返回由函数操作的数据时,有三个选项:

  • 在数组外部声明数组,并在更改其原型后将其传递给函数:
    int-tobinary(char*arr,unsigned-int-arrsize,double-num);
    。通过这种方式,函数可以修改调用者传递的数据(最多更改
    arrsize
    个字符)。返回值可能成为错误代码;成功时为0,失败时为-1
  • 使用
    malloc()
    在函数中动态分配数组。在这种情况下,释放内存(使用
    free()
    )是调用方函数的责任