问几个一直感到困惑的问题

bennyzlm 2005-10-20 12:55:41
1。
int a[10][10];
int** p;
p=a;

编译器报错。我的目的是可以用p[i][j]这样的方式来访问a里的元素,不知可不可能。
希望详细解释。

2。
关于include

个人理解include在编译的时候会把整个包含的文件替换在相应的include语句的位置,不知这样理解是否正确。
如果正确,那么如果我在一个头文件里包含了一个全局变量的定义,就相当于在所有包含该头文件的文件中都定义了这个同名变量。
在gcc的环境下,我试着在两个文件里定义一个同名的全局变量。如果在定义时(比如int i=0) 没有对其进行初始化,或者只对其中一个进行初始化,gcc可以编译,而且正常运行。如果对两个都在定义时初始化,则在link的时候报错。
假设我又创建了一个头文件,并在两个源文件中都包含了这个头文件,那么如果我在头文件里定义那个全局变量,而不在两个源文件中定义。如果我在定义时初始化,link时报错。如果不初始化,通过。

不知道什么原因。望达人解惑
...全文
143 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
allen_wang 2005-10-20
  • 打赏
  • 举报
回复
我来说说第二个问题把。
include确实是会在当前位置展开对应文件。

如果全局变量没有加上static,则是整个project(或者说所有连接在一起的obj里)可见的。
因此,是不允许有同名的全局变量的。

但是gcc在处理时,有一点做的很奇怪(个人认为不好),如果有2个或2个以上同名全局变量,且都没有初值,gcc把他们处理成1个。而当他们有初值时(不管是否相同),gcc就认为是有多个同名全局变量,报错。(实际上,这应该是ld报的错)。

于是乎就会出现你所见到的情况了。
lxpws 2005-10-20
  • 打赏
  • 举报
回复
从数组的内存布局上讲,不论是几维数组,都是由一维数组来模拟的,即它并不真的是所谓的数组的数组或指针的数组。拿二维数组来讲,虽然在语义上可以解释为一维数组的数组或指针的数组,但它的内存布局仍是一个大的连续的一维数组,而不是一个存储了若干个指针的数组,即指针的数组(或指针的指针)。所以解释成数组的指针(如峰兄所言)是贴切的。
另:数组的数组其语义在C#里定义比较准确。
improgrammer 2005-10-20
  • 打赏
  • 举报
回复
楼主两个问题问得非常好。自己努力解决这两个疑惑罢,收获将是实实在在的。

办法:
写大量的简单程序,想尽各种办法把数组(多维)、指针、include摆弄来摆弄去,再看看教材,直到明白为止。

张晓博 2005-10-20
  • 打赏
  • 举报
回复
int main()
{
int aa[10][10];
int** p;
int cr = 1;
p = (int**)aa;

for(int j=0;j<100;j++){
*((int*)p++) = cr++;
}
return 0;
}
你自己研究一下这段代码先:首先类型强制转换,之后用的时候必须是指针指向的值,否则是无法负值的,因此也用了一次类型强制转换
Flood1984 2005-10-20
  • 打赏
  • 举报
回复
第二个问题:
首先明白:声明和定义是两个不同的概念.

然后如下语法例子:
int a ; //声明
int a = 0; //定义
extern int a;//声明
extern int a=0;//定义
static int a;//定义
static int a=0;//定义
Flood1984 2005-10-20
  • 打赏
  • 举报
回复
贴得有点多,呵呵,第一个问题你去这看看吧
http://blog.csdn.net/Flood1984/archive/2005/09/26/489575.aspx
写的不怎么精彩,请包涵.
Flood1984 2005-10-20
  • 打赏
  • 举报
回复
char array[5];
char arrayMulti[3][5] ;

数组在作为函数参数时,数组名将蜕化为指针。C语言的书上是这么说的,我这里要说得是:这句话是不完全正确的!我们知道指针是占用内存的,但是这个蜕化而成的家伙是不占有内存的,仍然只是个标签。书上为什么这么说呢?书上的意思是说这家伙已经蜕化得不知道自己有几个元素了。举个例子:
void fun(char array[5]);
在编译时编译器会当成是:void fun(char *array);你在这个函数中使用sizeof(a)得到的值是4,而在定义char array[5]的函数中sizeof(array) = 5,说明确实已经蜕化为指针了。所以你写:
char *pa = array ; //正确,指针到指针

数组名退化为指针,在这里强调一下:数组的元素类型仍然存在!这里要注意的是多维数组的情况。
以2维数组为例:
void fun2(char arrayMulti[3][5]);
那么在函数fun2中,arrayMulti蜕化成的是char (*)[5],即:指向char[5]类型的指针,因为前面分析过arrayMulti的元素的类型是char[5],所以在程序中:
char **pm = arrayMulti ; //错误:从char (*)[5]到 char **的赋值
char (*pm5)[5] ;
pm5 = arrayMulti ; //正确。

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧