【问题标题】:How to assign a value from an address to a pointer on the go?如何在旅途中将地址中的值分配给指针?
【发布时间】:2019-01-20 06:42:58
【问题描述】:

导致分段错误:

int n;
int *variable = scanf("%d",&n);
printf("Printing :%d",*variable);

没问题:

int n;
scanf("%d",&n);
int *variable = &n;
printf("Printing :%d",*variable);

如何在没有分段错误的情况下实现第一个?

【问题讨论】:

  • variable 是一个 int 指针,但您在其中存储了一个整数。
  • 这段代码不应该编译,因为int *variable = scanf("%d",&n);这一行不是有效的C。你的编译器可能配置错误。
  • scanf 返回成功读取的项目数,而不是正在读取的内容的地址(如果您同时读取多个项目,这很有意义)。不过,您可以在阅读之前获取n 的地址。
  • 改进语法&标签&标题
  • 如果scanf()由于非数字输入、文件结尾或输入错误而没有扫描int,代码应该怎么做?

标签: c pointers segmentation-fault scanf


【解决方案1】:

假设scanf 成功,它返回 1(通常它返回设置的变量数)。

在您的第二个 sn-p 中,您丢弃了该(有用的)信息,并且您将指针 varaible 设置为 n 的地址,这是完全有效的。 (如果 scanf 返回 0 则 n 将未初始化,并且您的 printf 调用的行为未定义。)

在第一个 sn-p 中,您将 指针 设置为 int 常量 01,具体取决于 scanf 的返回值。这也很好,但是取消引用该指针的行为

*variable

未定义

如果你想要华丽,并与你的代码审查员进行强有力的对话,你可以使用 表达式分隔符运算符 并编写

int n;
int *variable = (scanf("%d",&n), &n);

但这很不礼貌,因为您再次丢弃了scanf 的返回值,而n 可能未初始化。

【讨论】:

  • 我认为最后一个示例超出了 OPs C 的知识范围,可能会使他感到困惑。他需要了解什么是指针,什么是引用的对象以及如何为其分配内存
  • @P__J__:我们需要停止假设所有(如果有的话)答案仅针对 OP。这是一个问答网站,不是为需要帮助的人们提供的论坛,尽管后者是必然的结果。让我们不要养成提交与某种最低公分母有关的答案的习惯。最重要的是,我们不要光顾 OP。
  • &(scanf("%d",&n), n) 看起来无效。 C 中的逗号运算符不会计算为左值。
  • 我怀疑你想要int *variable = &(scanf("%d",&n), &n);(并添加)
  • @chux 我觉得应该是int *variable = (scanf("%d",&n), &n);
【解决方案2】:

scanf("%d",&n); 返回整数而不是指向整数的指针。下面是scanf的原型。

int scanf(const char *format, ...);

当您像下面这样指向时,您实际上指向的是无效地址,这将导致未定义的行为。

int *variable = scanf("%d",&n);

【讨论】:

    【解决方案3】:

    当您声明和初始化指针时,您将值分配给指针本身。需要* 来向编译器显示您正在声明指向某种类型的对象的指针,而不是对象本身

    当您稍后在代码中使用* 时,您取消引用该指针。

    void foo(void)
    {
       int a;
       int *b = &a;     //you assign the pointer `b` itself - no dereferencing
    
       *b = 5;          //you dereference the pointer and asssign the the referenced object
    }
    

    “新鲜”声明的指针(除非使用对有效对象的引用进行初始化)不指向有效对象,并且其取消引用会调用未定义行为

    void foo(void)
    {
       int a;
       int *b = &a;     //b is pointing to the valid object -> the variable `a`
       int *c;     //c is not pointing to valid object
       int *d;     //d is not pointing to valid object
    
       c = malloc(sizeof(*c));     //now c is pointing to the valid object (if malloc has not failed of course)
       *c = 5      // correct no UB
       *d = 5;         // incorrect - UB
    
    
       *b = 5;          //correct no UB 
    }
    

    语法类似(指针名称前的*),但它的作用完全不同。我注意到这对初学者来说有点混乱

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-18
      • 2011-08-23
      • 1970-01-01
      • 1970-01-01
      • 2015-06-11
      • 1970-01-01
      相关资源
      最近更新 更多