使用 scanf( ) 将字符保存到 int 变量,使意外的 char 等效于 int 值

问题描述 投票:0回答:1

我正在检查库函数 isupper() 以检查函数版本或宏版本 isupper() 的效率取决于使用的存储或运行时,我有这个特殊的问题 当使用 scanf() 将输入字符存储到 int 变量时。 这是我的代码-

#include<stdio.h>

int my_isupper(int );

int main() {
    int c;

    printf("Enter a alphabet to check if it is upper case or not\n");
    
    //c = getchar(); // getchar(), getc() works fine though
        
    scanf("%c", &c);

    /*
    Doesn't work when c is a int but not initialized to 0
    Works fine on some machine no matter c is a char, int or not initialized to 0
    Is it compiler/machine dependent? if so, which part ( scanf()?) has dependency?
    */

    printf("test1: %d\n", c);

    if(my_isupper(c))
        printf("%c is upper case\n", c);

    else
        printf("%c is not upper case\n", c);

    return 0;
}

int my_isupper(int c) {

    printf("test2: %c\n", c);

    int value = (c >= 'A' && c <= 'Z')? 1 : 0;

    printf("test3: %d\n", value);

    return value;
}

当变量 c 设置为 char 时,它工作正常。当它设置为 int 时,程序运行正常 使用 getchar()、getc() 等库函数,但使用 scanf() 时,如果变量设置为 int 且未初始化为 0,则 scanf() 为 char 'A' 存储 32577,为 'A' 存储 32578 字符“B”等等。

当给出输入: A 时,返回值应该是 1,但是我得到的返回值是 0,因为 不满足条件,因为 scanf() 为字符 A 保存 32577,为字符 B 保存 32778 等等。

c scanf
1个回答
1
投票

你用

scanf("%c", &c);
向 scanf 撒谎,说
c
char
,而它实际上是
int
。这是一个未定义的行为错误,所以任何事情都可能发生。

一个可能的结果(不能保证,但有可能)是一个字节被读入

int
的最低地址。如果是小端机器,那么它会工作得很好,因为它期望该字节中的数字 0 到 255 直接对应于值 0 到 255。因此
int
的结果将最终作为该值给出
int
的所有其他字节均为零。或者,在大端机器上,您将写入最高有效字节,从而产生非常大的数字。

但是,您从未初始化过

c
,因此其他字节可能包含垃圾值。或者如果你运气不好的话可能会为零 - 许多调试构建将未初始化的局部变量归零,这绝不是 C 的任何保证。打印没有获取其地址的局部变量的内容也是未定义的行为。好的,您确实在 scanf 调用期间获取了地址。但是假设主流系统没有
int
的陷阱表示,它仍然是 未指定的行为 - 意味着任何组合都可能发生,你可能会得到任何值,但至少程序不会像未定义的行为那样意外崩溃和烧毁.

© www.soinside.com 2019 - 2024. All rights reserved.