2015-04-01 38 views
2

请看下面的代码片段 -了解警告和编译错误,而初始化和声明指针变量

int main(){ 

    int *i_ptr = 5; 
    printf("%d", *i_ptr); 

    return 0; 
} 

在这里,我想声明和初始化变量i_ptr的指针。它给了我下面的警告,而它编译罚款 -

警告:初始化时将整数指针不进行强制转换 [默认启用]

但是,当我要执行的代码它给我下面的错误 -

分割故障(核心转储)

我知道正确的方式来做到这一点 -

int n = 5; 
int *ptr = &n; 

现在我有一些问题 -

虽然第一代码在执行时失败,为什么不给编译错误,而不是警告?

2.我们可以初始化和声明指针变量这样的 - 事先

int n = 5 // both declaration and initialization of int type variable n 

感谢。

+2

'INT * i_ptr = 5'装置的地址,该地址的不是内容,被5.一点也没有”因为5是有效的地址,所以发出错误。 – m0skit0 2015-04-01 18:40:56

+0

“我们可以初始化并声明指针变量吗?” - 是的,你已经知道它:'int * ptr =&n;' – immibis 2015-04-01 18:45:35

+0

你可能想要的是'int * i_ptr = new int(5);' – vsoftco 2015-04-01 18:46:36

回答

3
  1. 虽然第一代码在执行时失败,而不是警告为什么不给编译错误,?

错误和警告之间的差异取决于您传递给编译器的标志。

这是一个好主意,使设置更偏执的开发过程中(-Wall-Wextra,甚至可能铿锵-Weverything),除了通过-Werror使得警告变为错误(你可能不应该被默认发货代码时设置)。

  • 我们可以初始化和声明指针变量这样
  • 指针变量存储地址,您需要声明的可寻址的东西,你可以存储值5。

    自C99,它是能够使用文字,而不是一个命名的变量的化合物:

    int *p = &(int){ 5 }; 
    
    2

    *在代码中有不同的含义。

    它不是用于指针取消引用,而是用于指针声明,因此您声明了一个指针并为其指定一个整数,指针将该整数存储为它指向的地址。

    这可能是未定义行为,因为您不知道5是否为有效地址,而且很可能不是。

    如果拆分从初始化声明将成为明显的是,该代码具有不同的含义,例如

    int *pointer; /* here the `*' is used for pointer declaration */ 
    int value; 
    
    pointer = &vaule; /* we store the address of value */ 
    *pointer = 5; /* we dereference the pointer and write to that location */ 
    /*^here the `*' is used for pointer dereference */ 
    
    printf("%d\n", value * 5); /* this will print 25 */ 
    /*     ^here the `*' is used for multiplication */ 
    

    现在你看,我说,你的代码是令人困惑,因为

    int *pointer = 5; 
    

    似乎相当于

    *pointer = 5; 
    

    但它不是。

    1
    1. 从技术上说int *n = 5没有问题。这是一个有效的指针,指向地址为5的内存,这就是为什么它可以让你编译它。段错误的原因是您的程序无法访问此内存。
    +1

    “没有错”?在C和C++语言中,它是非法的*,用非零整数初始化一个指针值。代码格式不正确。这种初始化(如果你出于某种原因需要它)需要明确的转换。 – AnT 2015-04-01 18:52:12

    +0

    我不会捍卫初始化指向静态整数值的指针。我只是说,“技术上”没有什么问题。这就是为什么它被编译的原因,以及编译器为什么会打印Warning的原因。 – 2015-04-01 19:04:33

    +0

    @MartinKalcok:它在技术上是错误的,因为它不遵循ISO标准规定的C语言规则(参见C11 6.5.16.1,根据6.7.9§11也适用于初始化) – Christoph 2015-04-01 19:11:14

    1

    当你在做

    int *i_ptr = 5; 
    

    ,因为这个地址要指定地址5 i_ptr.But当你去参考i_ptr它给你分段故障不属于你的程序,因此, 。只尝试访问属于你的程序的那些内存位置。

    1

    编译器不需要使其成为一个错误,所以它不会。

    你正在寻找的语法是:int *i_ptr = new int(5);

    这种分配新的内存足够大的整数,将值设置为5,并将在i_ptr内存点。记得在完成记忆时做delete i_ptr;

    1

    您的代码在C和C++语言中都是非法的。您不允许使用整数值初始化指针。这

    int *i_ptr = 5; 
    

    是非法的。它不是“将地址5分配给指针”,因为其他答案似乎暗示了这一点。上述初始化在标准C和C++语言的领域内显然是不可编译的。

    您收到的诊断消息表明您的代码中有错误。之后,C和C++都不会对您的代码的含义做任何保证,即您的代码既不是C也不是C++。

    不要忽略由编译器发出的诊断消息。 C和C++不区分“警告”或“错误”。任何诊断消息应视为潜在的错误。您应该认识到看似“仅仅是警告”的错误。使用GCC,您还可以尝试使用-pedantic-errors选项使其将错误报告为错误。