简体   繁体   English

printf 在不为格式字符串 C 传递变量的情况下以某种方式工作

[英]printf somehow works without passing in variable for the format string C

So I'm currently learning C and had to write a program that took in a character and checked if it was a vowel or consonant.所以我目前正在学习 C 并且必须编写一个程序来接收一个字符并检查它是元音还是辅音。 While doing this I compiled but forgot the pass the char into printf and yet it still somehow worked and even displayed the char.在执行此操作时,我编译但忘记将字符传递给 printf ,但它仍然以某种方式工作,甚至显示字符。 Any clue how this could have happened or why?任何线索这怎么可能发生或为什么?

#include <stdio.h>
#include <ctype.h>

int main() {
    char chr;
    int ascii;

    printf("Enter a character: ");
    scanf(" %c", &chr);

    ascii = (int) toupper(chr);

    if (ascii == 65 || ascii == 69 || ascii == 73 || ascii == 79 || ascii == 85) {
        printf("%c is a VOWEL.\n");
    } else if (ascii >= 65 && ascii <= 90) {
        printf("%c is a CONSONANT.\n");
    } else {
        printf("%c is not a letter.\n");
    }

    return 0;
}

When a function is called, arguments are passed to it.当调用 function 时,会将 arguments 传递给它。 These arguments are passed according to some specification that says where they are passed, commonly in processor registers or on the stack.这些 arguments 是根据一些说明它们传递位置的规范传递的,通常在处理器寄存器或堆栈中。

In the simplest implementation, the called function takes the values for its parameters from the locations where you are supposed to pass arguments.在最简单的实现中,被调用的 function 从您应该传递 arguments 的位置获取其参数的值。 When you do not put a desired value in the right place, the function uses whatever value is there.当您没有将所需的值放在正确的位置时,function 会使用那里的任何值。 If the program happened to use the same register for some variable, say ascii , that would be used for passing the argument, then it is possible that printf happens to get the desired value and print it.如果程序碰巧对某个变量使用相同的寄存器,比如ascii ,用于传递参数,那么printf可能恰好获得了所需的值并打印出来。

However, that is just the simplest behavior.然而,这只是最简单的行为。 Modern compilers optimize programs considerably and may transform function calls into code that would be equivalent if your program had defined behavior.现代编译器大大优化了程序,并且可以将 function 调用转换为如果您的程序具有定义的行为则等效的代码。 When you have undefined behavior, this optimization can result in your program misbehaving in surprising ways.当您有未定义的行为时,这种优化可能会导致您的程序以令人惊讶的方式行为不端。 It may print incorrect values, terminate with an error, or execute code other than what you expected.它可能会打印不正确的值、以错误终止或执行与您预期不同的代码。

To avoid some of these problems, compile with most warnings enabled ( -Wall in GCC and at least -Wmost in Clang) and elevated to error messages ( -Werror with GCC and Clang).为了避免其中一些问题,编译时启用大多数警告(GCC 中的-Wall和 Clang 中的至少-Wmost )并提升为错误消息( -Werror和 Clang 中的 -Werror)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM