2016-03-06 69 views
0

我知道这是使用scanf()的不正确方法。但我想用C的专家来回答这个问题:scanf指针传递地址的行为(地址变量)

#include <stdio.h> 
int main(int argc, char *argv[]) 
{ 
    int *a; 
    printf("please input one number:\n"); 
    scanf("%d", &a); 
    printf("your input is %d\n", a); 
    return 0; 
} 

输出:

please input one number: 
30 
your input is 30 

因为*一个已经存在,它不会在执行带来段故障。 ()将(*)中的正确数据奇迹般地填充到* a中,使得(int *)变成(int);那么printf()会正确输出。

我认为这个代码可以工作,因为sizeof(int *)和sizeof(int)在我的系统上是相同的值。所以我也检查我的系统上的一些类型的大小:

sizeof(short) return 2 
sizeof(short*) return 4 
sizeof(int) return 4 
sizeof(int*) return 4 
sizeof(long) return 4 
sizeof(long*) return 4 
sizeof(float) return 4 
sizeof(float*) return 4 
sizeof(double) return 8 
sizeof(double*) return 4 
sizeof(char) return 1 
sizeof(char*) return 4 

似乎这个代码也可以工作时浮动,但它没有。我尝试的代码是在这里:

#include <stdio.h> 
int main(int argc, char *argv[]) 
{ 
    float *a; 
    printf("please input one number:\n"); 
    scanf("%f", &a); 
    printf("your input is %f\n", a); 
    return 0; 
} 

输出:

please input one number: 
3.5 
your input is -0.034267 

的scanf()应该工作,因为我用%F调用时的scanf()。因为我仍然给它一个4字节的内存地址。

我找不出来。那些知道整个scanf()的人能解释为什么这两个代码(几乎相同)以不同的方式工作?

+0

我认为'float'作为可变长度参数之一传递时被提升为'double'。 – zch

+0

你期望的结果是什么,实际结果是什么?地址应该是一个整数,因此使用%f来读取它,因为float看起来不正确。 – Filkolev

+0

您调用了*未定义行为*并且它发生了*工作。 – MikeCAT

回答

0

通常数据类型为float作为变量长度自变量被提升为double,如@zch所示,并且printf()期望它。

在这种情况下,通过的是float*,它不会神奇地变为double

这就是为什么printf()得到错误的数据 - 数据和大小都是错误的。

+0

对。一个四字节的'float *'会被传递,但'printf'会尝试读取一个8字节的double,这样就可以将它打印为'%f'。 –

+0

谢谢,你是对的。我搜索整个论坛得到这个线程: http://stackoverflow.com/questions/210590/why-does-scanf-need-lf-for-doubles-when-printf-is-okay-with-just-f? RQ = 1 – Wally