打印

搞到今天都没弄懂的C语言问题...

[复制链接]
12302|69
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zq1987731|  楼主 | 2010-2-26 00:04 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
一个有10个指针的数组,该指针是指向一个整型数的
int *p[10];
上面这个比较好理解,平时用得也比较多,问题是下面....


如果一个数组如下定义:
int a[10];
那么找个指针指向它只要int *p = a;就定义完成了...可以理解为“一个指向有10个整形数组的指针”
同样,有如下定义:
int (*p)[10];
该定义含义也是“一个指向有10个整型数数组的指针”,这个定义有点让我莫名其妙...写了那么多的C我还真没见过谁这么用的,因此想问个明白

请教高人指点...

相关帖子

沙发
xlsbz| | 2010-2-26 08:05 | 只看该作者
int *p[10];
我都觉得不容易理解啊 !!

数组 指针混着用么??

不太好吧!

我觉得把自己最熟悉的使用好了就OK了!
还有那些容易出错的用法刚开始最好不去学他。如共用体。

int (*p)[10];我觉得这种写法真的很差劲!所以我建议你不要弄这个了。
不要过于注重形式。
只要理解了就行了!
还有总结一下 如何少犯错。

使用特权

评论回复
板凳
tcc8073| | 2010-2-26 08:24 | 只看该作者
尽量用最简单方式做最复杂的工作,不需要把问题复杂化,做产品需要的是稳定,不要太强所谓技巧

使用特权

评论回复
地板
yewuyi| | 2010-2-26 08:36 | 只看该作者
int (*p)[10];

很多人都用的把?呵呵,你没见到过,要么是你认识的人少,要么是你认识的人都不会用这个。

这也不是什么技巧,也属于基本内容。

使用特权

评论回复
5
sj_dai| | 2010-2-26 09:51 | 只看该作者

2

赞同2楼3楼朋友的说法,开发讲求实用,做产品应该是在规定的条件下用你最拿手的技能最稳定可靠的实现,可以不断追求自己在某些技能上的提升,但没必要玩技术,玩技术拿是兴趣小组的事。

你说的问题,单片机的C编程可以说我的理解算是比较深的,真的从来没用过,也没见过,可以这么说,这种用法可能有不少单片机的编译器并不支持。

当然你想弄清楚这个问题的想法是好的,至少是能进一步理解C语言的某个知识点,我用这样一个例子来给你做一个解释,相信你就不会再觉得这种写法奇怪。
我们想用一个指针指向一段字符的首地址,可以这么定义
char *p;
char str[]={'a','b','c','d','e'};
p=(char*)str;
实际上我们也能这么定义
char *p="abcde";
后一种定义就类似你提的问题,实际程序是隐含定义了一个应用程序不可见的字符串数组str[]={'a','b','c','d','e'},明白了吗?

使用特权

评论回复
6
sharpstar| | 2010-2-26 09:53 | 只看该作者
int *p[10]    10个指针构成的数组
int (*p)[10]  指向整形数组的指针

使用特权

评论回复
7
machunshui| | 2010-2-26 09:55 | 只看该作者
本帖最后由 machunshui 于 2010-2-26 09:57 编辑

呵呵,
两者区别不小啊!

int (*p)[10];
限定了p必须指向10个元素的数组,而不能指向别的。
例如不能指向9个元素的数组

两者赋值方式也不同,

int a[10];
int (*p)[10];
int *p1;

p1 = a;//正确
p = a;//错误

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
Green_Hand + 1 这个确实没注意到。
8
yewuyi| | 2010-2-26 10:00 | 只看该作者
呵呵,5楼不要激动,LZ和后面的跟贴从来没谁说过这是在单片机上用C 。
而且,即使在单片机上用C,这个用法也是很常见的用法,呵呵,基本上只要是个C编译器应该都会支持它。

使用特权

评论回复
9
HWM| | 2010-2-26 10:04 | 只看该作者
关于数组:

数组本是由一个“常指针”所指引的一串“定长”单元的线性表(存在于内存中的一段连续空间)。通常表为:

<type> <array-name>[N];

如具体可表为:

int A[10];

其中,<type> (int)表明的单元类型且决定了“定长”的具体长度,<array-name> (A)为“常指针”。

结合楼主的问题,给出一个“数组”:

int (*p)[10];

同样是由一个“指针”所指引的一串“定长”单元的线性表——数组,由于采用的是非“常指针”(即指针变量),因此必须用“(*p)”定义和引用相关数组。具体见下例

int A[10];  // 实际分配一个含10个int单元的数组
int (*p)[10];  // 定义一个指针,注意尚未有实际空间被指定

int main(void)
{
    p = A;  // 获得数组内存空间

    (*p)[1] = 1;  // 等价于 A[1] = 1;
    (*p)[2] = 2;  // 等价于 A[2] = 2;

    while(1) ;
}

注意:引用是必须是(*p)[n],而非*p[n]。

使用特权

评论回复
10
冷漠| | 2010-2-26 10:07 | 只看该作者
本帖最后由 冷漠 于 2010-2-26 10:12 编辑
如果一个数组如下定义:
int a[10];
那么找个指针指向它只要int *p = a;就定义完成了...可以理解为“一个指向有10个整形数组的指针”
同样,有如下定义:
int (*p)[10];
该定义含义也是“一个指向有10个整型数数组的指针”,这个定义有点让我莫名其妙...写了那么多的C我还真没见过谁这么用的,



唉!中国的教授确实多数没把这个问题讲清。
1、int (*P)[10]和int a[10]的差别: a 是指针常量,也就是说:a只能固定指向所说明的那个(唯一)数组。但是P是指针变量,P不仅可以指向a 数组,还可以指向其它任何同类型数组,例如指向int  b[10]。
2、int   *P[10]; 和上面int  (*P)[10]; 的差别已经很清楚了:上面叫做“数组的指针”;下面叫做“指针数组”。变换一下写法就清楚了:在一定条件下:
         *P <——> P[ ]
老师没教?书上也写了。 所以:

char   *P[10];——>char   P[ ][10];  // 二维数组就是个指针数组。字符串数组中很常用的写法。

所以,把凡是C语言关于“字符串”用法的教材内容都找来看一遍,就不再陌生了。
还有:......能提出如此问题,已经高人一筹了,......

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
zq1987731 + 1
11
machunshui| | 2010-2-26 10:16 | 只看该作者
9楼HWM给出的例子语法是错的!

int A[10];  // 实际分配一个含10个int单元的数组
int (*p)[10];  // 定义一个指针,注意尚未有实际空间被指定

int main(void)
{
    p = A;  // 获得数组内存空间

    (*p)[1] = 1;  // 等价于 A[1] = 1;
    (*p)[2] = 2;  // 等价于 A[2] = 2;

    while(1) ;
}


其中
p = A; //不能如此赋值!

使用特权

评论回复
12
machunshui| | 2010-2-26 10:17 | 只看该作者
应该

p = &A;

使用特权

评论回复
13
machunshui| | 2010-2-26 10:19 | 只看该作者
其实int (*p)[10],主要可用于2维数组的情况。

例如

        int A[2][10];
        int (*p)[10];

        p = &A[1];

使用特权

评论回复
14
HWM| | 2010-2-26 10:24 | 只看该作者
作为补充,再看一个例子:

int A[10];  // 实际分配一个含10个int单元的数组
int (*p)[5];  // 定义一个指针(类型为int [5]),注意尚未有实际空间被指定

int main(void)
{
    p = A;  // 获得数组内存空间

    (*p)[1] = 1;  // 等价于 A[1] = 1;
    (*p)[2] = 2;  // 等价于 A[2] = 2;
    (*(p+1))[0] = 5; // 等价于 A[5] = 5;

    while(1) ;
}

这说明指针p的类型为“int [5]”,而非A(作为指针)的类型int。

使用特权

评论回复
15
machunshui| | 2010-2-26 10:31 | 只看该作者
敢问HWM的例子哪种编译器上能编译通过?

使用特权

评论回复
16
machunshui| | 2010-2-26 10:33 | 只看该作者
14的例子用keil编译,错误提示如下:
main.c(6): error:  #513: a value of type "int *" cannot be assigned to an entity of type "int (*)[5]"

使用特权

评论回复
17
HWM| | 2010-2-26 10:36 | 只看该作者
回11楼:

严格确实应该是

  p = &A;

但A和&A同指一个相同的地址,只是类型不同。A的类型是int,而&A的类型是int [10];

使用特权

评论回复
18
yewuyi| | 2010-2-26 10:39 | 只看该作者
应该

p = &A;
machunshui 发表于 2010-2-26 10:17


不加这个&,我所知道的也是可以的,加&则可以看的更清晰点。

呵呵,这个A就是一个地址。

使用特权

评论回复
19
HWM| | 2010-2-26 10:40 | 只看该作者
回15,16楼:

同样是Keil,是warning而非error:
TEST_FOO_1.C(13): warning C182: pointer to different objects

使用特权

评论回复
20
machunshui| | 2010-2-26 10:41 | 只看该作者
你的例子
p = &A;
这一句,

keil,
VC,
编译皆通不过。

就不要再**错误了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:PCB Layout(1~12,HS/RF),802.11abgn,EFT/ESD/Surge...EMC:GR1089/60950/ITU... Linux/ThreadX/RexL4/Nucleus Driver(ARM11/A8/MIPS/i.MX...) 软硬兼修不可能?呵呵...井底之蛙们...

95

主题

759

帖子

3

粉丝