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()
)是调用方函数的责任