用C语言编写的scanf

时间:2018-08-31 21:06:41

标签: c scanf

我将scanf函数分组并命名为该函数 eno ,并在我的 C 代码中调用了此函数后,它无法正常运行。如果我在代码中单独使用scanf函数,它将在哪里工作。所以我的问题是为什么功能不起作用?在这里,我总是显示a = 0和b = 1。 :

    #include <stdio.h>
    #include <string.h>
    #include <math.h>
    #include <stdlib.h>

    int eno(int, int);

    int main() {
        int a, b;
        eno(a, b);
        printf("%d  %d", a, b);
    }

   int eno(int j, int k) {
       scanf("%d", &j);
       scanf("%d", &k);
   }

5 个答案:

答案 0 :(得分:6)

jk是内存中与ab不同的对象,因此写入jkab

要让eno修改ab,您需要将 pointers 传递给ab,如下所示:

eno( &a, &b );
...
void eno( int *j, int *k ) // use void instead of int here; eno doesn't return a value
{
  scanf( "%d", j ); // no & operator on j or k, they're already pointers
  scanf( "%d", k );
}

答案 1 :(得分:6)

这是有关C的非常重要的基本方面。

  

C通过

传递所有函数参数

用一个简单的例子最好地说明什么意思:

void foo(int x)
{
    x = 42;             // Changes x inside foo but NOT x inside bar
    printf("%d\n", x);  // Prints 42
}

void bar()
{
    int x = 5;
    foo(x);
    printf("%d\n", x);  // Prints 5 
}

输出:

42
5

在这里需要理解的是,x内的bar是另一个变量,而不是x内的foo。在x中对foo所做的任何更改都不会更改x中的bar

呼叫foo(x) x的值传递给foo。因此,在这种情况下,它与foo(5)相同。

要从x内部更改barfoo的{​​{1}}的值,您需要将指针传递给x

也就是说:

void foo(int *x)         // Notice the * - Means that foo receives a pointer to int
{
    *x = 42;             // Notice the * - Change the value of x in bar
    printf("%d\n", *x);  // Notice the * - Read the value of x in bar
}

void bar()
{
    int x = 5;
    foo(&x);      // Notice the & - it takes the address of x so &x is a pointer to x
    printf("%d\n", x);
}

输出:

42
42

因此,要使您的代码正常工作,您需要更改eno,以便它接收指向int而不是int的指针。喜欢:

int eno(int*, int*);

称呼为:

eno(&a, &b);

答案 2 :(得分:2)

$ git remote set-url origin git@github.com:github/hub.git
origin  git@github.com:github/hub.git (fetch)
origin  git@github.com:github/hub.git (push)

eno(a, b); ^ ^ int eno(int j, int k) ^ ^ a分别复制到bj中。
当函数k返回时,的值已被修改。


这是指针进入图片的地方。

eno

答案 3 :(得分:1)

因为您要将ab的值传递给eno。您需要通过引用传递它们,如下面的代码所示。您需要使用指针通过引用传递。

#include <stdio.h> 

int eno(int *,int*); 

int main(){ 
   int a,b; 
   eno(&a,&b); 
   printf("%d %d",a,b); 
}

int eno(int *j,int *k)
{ 
   scanf("%d",j); 
   scanf("%d",k); 
}

答案 4 :(得分:0)

编译时,始终启用警告,然后修复这些警告。

gcc,至少使用:-Wall -Wextra -Wconversion -pedantic -std=gnu17

注意:其他编译器使用不同的选项来实现相同的结果。

编译发布的代码将导致:

gcc -ggdb -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled.c" 

untitled.c: In function ‘eno’:
untitled.c:17:4: warning: control reaches end of non-void function [-Wreturn-type]
    }
    ^

untitled.c: In function ‘main’:

untitled.c:10:9: warning: ‘a’ is used uninitialized in this function [-Wuninitialized]
         eno(a, b);
         ^~~~~~~~~

untitled.c:10:9: warning: ‘b’ is used uninitialized in this function [-Wuninitialized]

请注意,编译器会告诉您有关所发布代码的三个问题。

这是可以根据需要工作的代码版本。

请注意传递变量地址的正确使用方法以及函数的正确声明:eno()

请注意正确检查对scanf()的调用,以确保操作成功。

包括不使用那些内容的头文件是非常糟糕的编程习惯。即math.hstring.h

变量(和参数)名称应表示contentusage(或更好的是,两者)

通常,函数名称应该是“活动的”,而不是“神秘的”。它们应该向代码的读者表明该函数的作用。

现在,提出的代码仅解决了编译器问题,而没有使代码变得更出色的更微妙的事情:

#include <stdio.h>
//#include <string.h>
//#include <math.h>
#include <stdlib.h>  // exit(), EXIT_FAILURE

void eno( int *, int * );

int main( void )
{
    int a, b;
    eno( &a, &b);
    printf("%d  %d", a, b);
}

void eno(int *j, int *k) 
{
    if( scanf("%d", j) != 1 )
    {
        fprintf( stderr, "scanf to read the variable j failed" );
        exit( EXIT_FAILURE );
    }

    if( scanf("%d", k) != 1 )
    {
        fprintf( stderr, "scanf to read the variable k failed" );
        exit( EXIT_FAILURE );
    }
}