数组和指针并不相同

extern int *x;

extern int  y[];

x是一个指向int类型的指针,y是一个int型数组,没有给出数组长度,是不完整类型,但是声明的时候数组的长度并不是必须,但我还是建议加上数组的维数,那样只看声明就能知道数组有多大。上面两个声明是不同的数据类型。

什么是声明,什么是定义?

声明相当于普通的声明:它所说明的并非自身,而是描述其他地方创建的对象。

定义相当于特殊的声明:它为对象分配内存。

这就是为什么一个函数在main函数之前定义,我们不用再声明,main也可以调用这个函数,因为定义是特殊的声明。

 但是C语言,它本身为了和老代码兼容以及一些历史遗留问题,让它变得有些缺陷。比如,都知道定义只能有一次,声明可以有多次。

eg:

#include<stdio.h>
int a;
int a;
int main(void)
{
    int b;
    int b;
    
    return 0;
}

变量b会报重复定义,但是变量a却不会,奇怪么?局部变量,和上面说的一样,定义只能一次,声明可以多次,所以变量b重复定义,但是为什么变量a编译器通过了这种写法呢?这里是定义了两次还是其他情况?

我们把上面的变量b去掉,只测试变量a:

#include<stdio.h>
int a=3;
int a;
int main(void)
{

    
    return 0;
}

 

#include<stdio.h>
int a;
int a=1;
int main(void)
{

    
    return 0;
}

 

这样三种写法,编译都通过,那么我们再测试:

#include<stdio.h>
int a=3;
int a=1;
int main(void)
{

    
    return 0;
}

终于,报错了。从测试过程来看,gcc还是不允许多次定义同一个变量的。那么为什么前面的测试看起来像是重复定义了呢?这是因为c语言的全局变量,默认有外部属性,int a;int a=1;这样的,第一个是声明,第二个是定义,只有在全局变量时才是这样,上面的int a,相当于extern int a;所以前面三种测试没报错。这个缺陷,在c++中已经修复,c++中绝对不允许这样的写法。

#include<iostream>

int a;
int a=1;
int main(void)
{

    return 0;
}

像这样的C语言灰色地带还有很多。

 

所以,使声明和定义相匹配是很重要的。

经过gcc检测,形如:

 

extern char *p;
char p[10]="abcd";

这样的声明和定义是不能通过编译器的,或许c专家编程还是有点古老了吧。

 

 

 

posted @ 2017-06-01 15:24  Crystal_Guang  阅读(341)  评论(0编辑  收藏  举报