为什么第一个代码给出错误而第二个没有?

时间:2014-01-03 15:31:30

标签: c output

这是第一个代码:

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

void test(int,int);

int main()
{
  int p=23,f=24;
  test(&p,&f); 
  printf("%d %d\n",p,f);
  return 0;  
}

void test(int q,int g)
{
  q=q+q;  
  g=g+g;
}

此代码生成TYPE MISMATCH ERROR可能是因为我在函数调用期间将变量的地址作为参数传递,而形式参数不是指针。

这是第二个代码:

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

int main()
{    
  int p=23,f=24,q,g;
  q=&p;
  g=&f;
  printf("%d %d\n",q,g);
  return 0;
}

第二个代码的输出是

1638220 1638228

在此代码中,qg不是指针。那么为什么他们提供正确的输出,而不是错误?

1 个答案:

答案 0 :(得分:3)

注意:
您的评论:“第二个代码打印正确的p和f地址,其中第一个代码给出错误”在各个级别上都是错误的。
您声称您的printf语句打印变量的内存地址?错了,它没有这样的事情。不能。不可能。不会发生。
要打印变量的内存地址,printf语句应如下所示:

printf("p @ %p\nf @ %p\n", (void *) &p, (void *) &f);//one of few cases where you SHOULD cast

您只打印一个数字:

printf("%d %d", p, f);

那些不是同一件事。请看一下这个答案底部的例子,但也要读一下中间的位

嗯,您将qg声明为整数,并为其分配了pf的内存地址。它是未定义的行为(即标准不确定如何处理它,因此它可能会因编译器而异,WCS:您的应用程序崩溃)。在你的情况下,我会说这种情况发生了:
基本上,内存地址看起来像这样:

0x213ABC

十六进制值,可以解释为数字,因此无法阻止您将其分配给charsize_t或其他任何内容。
HOWEVER ,如果您使用-Wall编译代码,则会收到有关从int *类型到int隐式转换的警告。除此之外,你“安全”。请注意:程序的输出将是不可预测的,因此毫无意义。

第一个代码段包含一个更大的问题:您将一个值传递给一个只是不存在的函数test函数无法处理您传递的内容,因为它的原型显示它需要2个整数,而不是2个指针

test(&p,&f);
//to:
test((int) &p,(int) &f);

但是,它 编译,as you can see here,但结果是不可预测的(未定义的行为)。

调用test(&p, &f)时,您调用的函数应如下所示:

void test(int *, int *)

然而,这个签名/原型无处可寻,因此编译器无法继续。将内存地址转换为int会改变所有这些,并让编译器知道该函数看起来像void test (int, int),并且该函数 存在,因此它会编译。

这样想:

  

你:你的电话号码是什么?   我:abc
  你:那不是电话号码   我:我的意思是1-11-111(短信的数字键,那些日子)

这就是你在这里做的事情:

test(&p, &f);
//compiler: can't find function test(int *, int *)
//you: I expect you to call test(int, int), and implicitly cast the pointers to ints

这不是C的工作原理。

注意:
正如我在内容中指出的那样:将指针分配/转换为 int 是未定义的行为(即:这些操作的结果未由标准定义)


打印指针的示例程序,以及应打印的unsigned long和int:

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

int main( void )
{
    int p = 2, f = 4, q;
    q = (int) &f;
    printf("p @ %p\nf @ %p\n", (void *) &p, (void *) &f);
    //int is too small for 64bit address, use unsigned long here
    printf("%d != %ul != %p\n", q, &f, (void *) &f);
    return EXIT_SUCCESS;
}

当我通过this codepad运行时,我得到了以下输出:

p @ 0xbf70e1d8
f @ 0xbf70e1d4
-1083121196 != 3211846100l != 0xbf70e1d4