【问题标题】:How to store and use a value again in C如何在 C 中再次存储和使用一个值
【发布时间】:2021-05-22 01:46:32
【问题描述】:

我想通过scanf()在函数lorem()中存储一个值value,并在函数ipsum()中使用它。我用了static int,但是不行。

static int *value;
void lorem(){
  static int *value;
  scanf("%d", value);
}

void ipsum(){
  static int *value;
  printf("%d", value);
}

void main(){
  lorem();
  ipsum();
}

这是我的代码,但它总是忘记value int 的值。

【问题讨论】:

  • 这是非常基本的 C 语言,可以/应该从任何 C 书籍或教程中学习——在函数之间传递值。 lorem 可以返回一个值,然后将其传递给ipsum。或者lorem 可以获取一个指向它可以直接写入的整数的指针,然后将其传递给ipsum
  • 你还没有将value指向任何地方
  • 尽管名称相同,但在函数lorem() 中声明的value 与在ipsum() 中声明的对象是不同的对象,并且两者都与在文件范围内声明的对象不同.删除两个函数内部的声明,让它们使用在文件范围内声明的对象。

标签: c pointers gcc


【解决方案1】:

这样做:

#include <stdio.h>

static int value;

void lorem() {
    // Note: `&` here should be read as "address of". This takes the
    // address of `value` and passes it to scanf as type `int*`, or
    // "pointer to int", AKA: "address of this int". `scanf()` then starts  loading the
    // number you type, byte-by-byte, into the memory at this address.
    // Since that's the address for `value`, you end up putting a
    // numerical value into `value.` Again, the address of `value` is also
    // called a "pointer" to `value`, and `&value` is of type `int*` since
    // `value` is of type `int`. And, ironically enough, passing by
    // pointer is commonly called "pass by reference," and is the
    // alternative to "pass by value".
    scanf("%d", &value);
}

void ipsum() {
    printf("%d", value);
}

int main() {
    lorem();
    ipsum();

    return 0; // no error: program finished successfully
}

你有几个错误。

  1. 首先,不要做static int *value;,做static int value;int* 说要为 指向 int 的指针分配足够的内存,这是一个将 RAM 内存地址 存储到 int 的数字,但你没有想要那个,你需要足够的内存来存放 实际的 int

  2. 其次,每次你在一个函数中执行static int *value;,你就是在告诉该函数使用value变量的这个本地版本,而不是全局版本,这不是什么你想要的。

  3. (技术性问题):main() 应该是 int main() 而不是 void main()。将-Wpedantic 添加到您的构建标志中,否则您会看到警告:

    main.c:32:6: warning: return type of ‘main’ is not ‘int’ [-Wmain]
    
    1. 在此注释中,还要将return 0; 添加到main() 函数的末尾,以表明它运行时“没有错误”(0 按流行惯例在这里表示“没有错误”)。李>
    2. 我在我的仓库中记录了一些关于编译器构建标志的注释:https://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world#additional-c-and-c-build-notes-ex-wgcc-or-clang-compilers

还有:

  1. 也许在我下面的示例中存在问题,但不适用于您的原始代码):通过打印换行符 (\n) 或调用 fflush(stdout) 来刷新 stdout在调用scanf() 之前。请参阅此处 (Why does printf not flush after the call unless a newline is in the format string?),另请参阅我的答案下方的 cmets。

带全局变量

在此处在线实时运行此代码:https://onlinegdb.com/HJ3bqfmtD

更好的是:还可以通过说Enter an integerYou entered 来告诉用户您想要什么:

#include <stdio.h>

static int value;

void lorem() {
    printf("Enter an integer: ");
    // Ensure the above printf is fully printed BEFORE waiting for 
    // user input. See my references below. Essentially, you may need
    // to **either** have a `\n` at the end of the printf cmd, OR
    // call `fflush(stdout)` like this, to ensure the stdout buffer
    // is fully flushed (printed to screen), before the `scanf()` 
    // call reads in the user's input. 
    fflush(stdout);
    scanf("%d", &value);
}

void ipsum() {
    printf("You entered: %d\n", value);
}

int main() {
    lorem();
    ipsum();

    return 0; // no error: program finished successfully
}

没有全局变量

在此处在线实时运行此代码:https://onlinegdb.com/ge-LVSsx7

更好的是,避免在这种简单的情况下使用全局变量。全局变量在某些情况下很有用而且很好,但这不是其中之一。

#include <stdio.h>

int lorem() {
    int value;
    printf("Enter an integer: ");
    // Ensure the above printf is fully printed BEFORE waiting for 
    // user input. See my references below. Essentially, you may need
    // to **either** have a `\n` at the end of the printf cmd, OR
    // call `fflush(stdout)` like this, to ensure the stdout buffer
    // is fully flushed (printed to screen), before the `scanf()` 
    // call reads in the user's input. 
    fflush(stdout); 
    scanf("%d", &value);
    return value;
}

void ipsum(int value) {
    printf("You entered: %d\n", value);
}

int main() {
    int val = lorem();
    ipsum(val);

    return 0; // no error: program finished successfully
}

参考资料:

  1. http://www.cplusplus.com/reference/cstdio/scanf/
  2. http://www.cplusplus.com/reference/cstdio/printf/
  3. Why does printf not flush after the call unless a newline is in the format string?
  4. https://www.cplusplus.com/reference/cstdio/fflush/
  5. What should main() return in C and C++?

【讨论】:

  • 请注意,scanf 中的%i%d 不同(如果您不知道有什么区别,您可能想要%d
  • @MM,啊!你说得对。现在修复它。讽刺的是,我实际上从未使用过scanf。微控制器和微型嵌入式系统上不存在。
  • @NateEldredge,说得好。添加刷新命令。
  • @user3386109:是的,显然是这样。谢谢。
  • 请不要使用 cplusplus.com 并链接到 en.cppreference.com/w/c 而是更正确和更新 What's wrong with cplusplus.com?
猜你喜欢
  • 2017-12-04
  • 1970-01-01
  • 2016-05-23
  • 1970-01-01
  • 2020-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-13
相关资源
最近更新 更多