免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 6837 | 回复: 16
打印 上一主题 下一主题

不完全类型 [复制链接]

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:49:03
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-03-09 23:13 |只看该作者 |倒序浏览
本帖最后由 shihyu 于 2010-03-09 23:20 编辑
  1. #include <stdio.h>

  2. char str[];

  3. int main()
  4. {
  5.        
  6.         char str[10];
  7.         return 0;

  8. }
复制代码
为什么上面代码不会出现重复定义 , 改成下面就出现重复定义


  1. #include <stdio.h>

  2. int main()
  3. {
  4.         char str[];
  5.         char str[10];
  6.         return 0;

  7. }
复制代码
http://learn.akae.cn/media/ch23s09.html

具有不完全类型的变量可以通过多次声明组合成一个完全类型,比如数组str声明两次:

char str[];
char str[10];

当编译器碰到第一个声明时,认为str是一个不完全类型,碰到第二个声明时str就组合成完全类型了,如果编译器处理到程序文件的末尾仍然无法把str组合成一个完全类型,就会报错。读者可能会想,这个语法有什么用呢?为何不在第一次声明时就把str声明成完全类型?有些情况下这么做有一定的理由,比如第一个声明是写在头文件里的,第二个声明写在.c文件里,这样如果要改数组长度,只改.c文件就行了,头文件可以不用改。


他意思我还是不太懂?  是.c很多文件只是用str 才这样做吗?  在头文件用extern char str[]; 不行吗?


谢谢

论坛徽章:
0
2 [报告]
发表于 2010-03-09 23:21 |只看该作者
本帖最后由 xyfree 于 2010-03-09 23:22 编辑

在第一段代码里面
两个str不是同一个东西
第一个是全局的,第二个是只在main里面的,覆盖了全局的str的名字.


第二段里面,同一个域(main函数)里面有两个同名的东西
当然出错

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:49:03
3 [报告]
发表于 2010-03-09 23:24 |只看该作者
恩恩~ 不过在http://learn.akae.cn/media/ch23s09.html 里面说

当编译器碰到第一个声明时,认为str是一个不完全类型,碰到第二个声明时str就组合成完全类型了,如果编译器处理到程序文件的末尾仍然无法把str组合成一个完全类型,就会报错。读者可能会想,这个语法有什么用呢?为何不在第一次声明时就把str声明成完全类型?有些情况下这么做有一定的理由,比如第一个声明是写在头文件里的,第二个声明写在.c文件里,这样如果要改数组长度,只改.c文件就行了,头文件可以不用改。

两个str好像又有相关

论坛徽章:
1
午马
日期:2013-08-23 23:39:47
4 [报告]
发表于 2010-03-09 23:36 |只看该作者
不带typedef的声明可以放在函数体内?

论坛徽章:
0
5 [报告]
发表于 2010-03-09 23:50 |只看该作者
本帖最后由 xyfree 于 2010-03-10 00:01 编辑

不完全类型是用来这么用的

  1. struct A {
  2.     struct B *pB;
  3. };

  4. struct B {
  5.     struct A *pA
  6. };
复制代码
也可以这么用

  1. int main ( int argc, char* argv[]) {
  2. //...
  3. }
复制代码
例子全是抄C用户指南的
事实上你给的链接内容里,后面也说到了


通过在表示相同对象的相同作用域中的后面声明中指定数组大小,可完成数组类型。当声明并在相同声明中初始化不具有大小的数组时,仅在其声明符的末尾与其初始化函数的末尾之间,数组才具有不完全类型。

以上这句话,sun C用户指南有

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:49:03
6 [报告]
发表于 2010-03-10 00:50 |只看该作者
  1. #include <stdio.h>

  2. char str[];
  3. char str[10];

  4. int main()
  5. {


  6.         return 0;

  7. }
复制代码
  1. #include <stdio.h>


  2. int main()
  3. {

  4.                
  5.             char str[];
  6.             char str[10];
  7.         return 0;

  8. }
复制代码
为什么第一个代码可以编译过 , 第二个代码不行

论坛徽章:
0
7 [报告]
发表于 2010-03-10 03:21 |只看该作者
本帖最后由 xyfree 于 2010-03-10 04:02 编辑

这不奇怪
因为第二句
  1. char str[10];
复制代码
被视作对 char str[]的初始化/类型完成。

不然你觉得在全局的范围里面,如果你一定要分开写的话
怎样对一个已经声明过的 不完全类型的名字进行赋值或者完成定义呢?

如果你是这样写


  1. int k;
  2. int k=19;

  3. int main()
  4. {
  5.         return 0;
  6. }
复制代码
编译就不会通过了,因为k是完全类型。

但是在main函数里面不适用,因为在局部已经声明过的对象,要求明确的语法做这个赋值或完成类型。
如果你在main里面仅仅有一个 char str[]; 也是会直接报错的。
看Sun的C用户指南吧,这里说得比较清楚

论坛徽章:
1
射手座
日期:2013-08-21 13:11:46
8 [报告]
发表于 2010-03-10 09:57 |只看该作者
那俩str不是同一个scope里面的,里面的会覆盖外面的......

论坛徽章:
0
9 [报告]
发表于 2010-03-10 10:21 |只看该作者
{:3_190:},还是一切声明为 word类型比较合适

论坛徽章:
0
10 [报告]
发表于 2010-03-10 10:47 |只看该作者
一个全局,一个局部
两个局部
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP