| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1185 人关注过本帖
标题:static 奇怪的用法
只看楼主 加入收藏
feng00055
Rank: 2
等 级:论坛游民
帖 子:56
专家分:27
注 册:2009-8-26
结帖率:100%
收藏
 问题点数:0 回复次数:10 
static 奇怪的用法
main()
{
static int a[5]={1,3,5,7,9};
int *num[5]={&a[0],&a[1],&a[2],&a[3],&a[4]};
int **p;
for(p=num;p<num+5;p++)
printf("%d ",**p);
printf("\n");
getch();
}

为什么“static”取掉后出错?
搜索更多相关主题的帖子: static 用法 
2009-10-07 10:22
lonmaor
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:郑州
等 级:版主
威 望:75
帖 子:2637
专家分:6423
注 册:2007-11-27
收藏
得分:0 
去掉static后用gcc编译成功,无错。

从不知道到知道,到知道自己不知道,成长的道路上脚步深深浅浅
2009-10-07 10:29
Devil_W
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
威 望:9
帖 子:1160
专家分:1797
注 册:2009-9-14
收藏
得分:0 
程序代码:
#include<iostream> 
#include<cstdio> 
using namespace std; 
int main() 
{ 
    int a[5]={1,3,5,7,9}; 
    int *num[5]={&a[0],&a[1],&a[2],&a[3],&a[4]}; 
    int **p; 
    for(p=num;p<num+5;p++) 
    printf("%d ",**p); 
    printf("\n"); 
    return 0; 
} 


我这里不报错。
2009-10-07 10:31
jig
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
帖 子:530
专家分:242
注 册:2005-12-27
收藏
得分:0 
是这样理解,恐怕LZ是在TC这类编译器上编译吧?

在开辟变量时,编译器是静态分配其值的,这个站在编译原理角度来看就很好理解。

int *num[5]={&a[0],&a[1],&a[2],&a[3],&a[4]};
此声明语句,要对num[5]每个元素都赋值。TC这类编译器在做此工作时,是将其视作在编译期静态对待的,即他认为a[0]-a[4]都是已经开辟好的元素。

static int a[5]={1,3,5,7,9};
就将a[0]-a[4]都申请为静态变量,即在编译期就固定了其在内存做的位置。而如果我们将其改成
int a[5]={1,3,5,7,9};
那么a[0]-a[4]就将在main函数执行时动态开辟,那么在 int *num[5]={&a[0],&a[1],&a[2],&a[3],&a[4]}; 时TC编译器认为找不到a[0]-a[4]所以报错。

解决方法:
你可以手动赋值,不要放在元素开辟处
main()
{
static int a[5]={1,3,5,7,9};
int *num[5];/*={&a[0],&a[1],&a[2],&a[3],&a[4]};*/
int **p;
 
num[0] = &a[0];
num[1] = &a[1];
num[2] = &a[2];
num[3] = &a[3];
num[4] = &a[4];
 
for(p=num;p<num+5;p++)
printf("%d ",**p);
printf("\n");
getch();
}

这样应该就不会报错。


通过这个例子,我们充分的可以了解到编译器在对待语句时将是个如何的处理过程。这也说明,其实TC不是标准的C89语法,而GCC编译器是严格兼容C99语言的,所以在处理类似静/动态语句时能做到绝对正确。

这也反映出语言的发展就是这样走过来,TC作为一个先辈的确为软件工程作出了巨大的贡献,可以这样说,我们后期的语言规范和理论化研究都得益于TC这类古老编译器的开创性作用。

也向安德森这样的计算机科学家致敬。

个人网站 -  http://.h001.
2009-10-07 10:44
入门
Rank: 1
等 级:新手上路
帖 子:13
专家分:0
注 册:2009-10-6
收藏
得分:0 
回复 楼主 feng00055
当前的C++版本以及ANSI C 都允许对函数中定义的常规数组进行初始化。不过,在一些使用C++翻译器(老式),而不知真正的编译器的,C++翻译器将为不完全与ANSI C 兼容的C编译器创建C代码,在这种情况下酒会出错。
补救的办法就是在数组声明中使用STATIC,关键字static导致编译器使用另一种内存方案来存储数组,即在ANSI C 之前版本中,这种方案也允许初始化。
2009-10-07 11:00
入门
Rank: 1
等 级:新手上路
帖 子:13
专家分:0
注 册:2009-10-6
收藏
得分:0 
回复 4楼 jig
很厉害啊呵呵,知其所以然的高手啊!!
2009-10-07 11:03
Devil_W
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
威 望:9
帖 子:1160
专家分:1797
注 册:2009-9-14
收藏
得分:0 
回复 6楼 入门

囧,你是没见到真正的高手。
2009-10-07 11:47
lovevista
Rank: 2
来 自:四川成都市
等 级:论坛游民
帖 子:41
专家分:13
注 册:2009-9-24
收藏
得分:0 
呵呵· · 努力的去向他们学习。
2009-10-07 14:01
入门
Rank: 1
等 级:新手上路
帖 子:13
专家分:0
注 册:2009-10-6
收藏
得分:0 
回复 7楼 Devil_W
现在是见到一个就比我强啊呵呵,都是高手啊
2009-10-07 14:59
jig
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
帖 子:530
专家分:242
注 册:2005-12-27
收藏
得分:0 
呵呵,高手?不知道怎么样才算真正的高手

个人网站 -  http://.h001.
2009-10-08 21:26
快速回复:static 奇怪的用法
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.016734 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved