鱼C论坛

 找回密码
 立即注册
查看: 1944|回复: 19

[已解决]结构体指针做形参,实参可用结构体数组访问??

[复制链接]
发表于 2018-8-22 23:40:12 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 我是大甲鱼 于 2018-8-22 23:42 编辑
#include <stdio.h>
typedef struct ex
{
        int a;
        int b;
}ex,*p_ex;

void fun(p_ex temp);
ex msg;
int main()
{        
        msg.a=2;
        printf("befor msg.a=%d\n",msg.a);  //msg.a的值
        printf("&(msg.a)=%p\n",&(msg.a));  //msg.a的地址

        fun(&msg);  //经过函数处理  msg.a的值被函数中的temp[0].a=3;改变

        printf("after msg.a=%d\n",msg.a); // 为什么msg.a会被temp[0].a改变呢?可能是他们的地址是一样的

        //可是为什么temp[1].a temp[2].a  可以被赋值,又应该怎么用temp来访问??
        putchar('\n');
        return 0;
}
void fun(p_ex temp)
{
        printf("-------------对应值---------------\n");
        temp->a=1;
        printf("temp->a=%d\n",temp->a);

        temp[0].a=3;
        printf("temp[0].a=%d\n",temp[0].a);

        temp[1].a=4;
        printf("temp[1].a=%d\n",temp[1].a);

        temp[2].a=5;
        printf("temp[2].a=%d\n",temp[2].a);

        temp[0].b=6;
        printf("temp[0].b=%d\n",temp[0].b);

        temp[1].b=7;
        printf("temp[1].b=%d\n",temp[1].b);

        temp[2].b=8;
        printf("temp[2].b=%d\n",temp[2].b);
        printf("-------------对应地址---------------\n");

        printf("&(temp->a)=%p\n",&(temp->a));
        printf("&(temp->b)=%p\n",&(temp->b));
        printf("&(temp[0].a)=%p\n",&(temp[0].a));
        printf("&(temp[0].b)=%p\n",&(temp[0].b));
        printf("&(temp[1].a)=%p\n",&(temp[1].a));
        printf("&(temp[1].b)=%p\n",&(temp[1].b));
        printf("&(temp[2].a)=%p\n",&(temp[2].a));
        printf("&(temp[2].b)=%p\n\n",&(temp[2].b));
}


运算结果:
befor msg.a=2
&(msg.a)=00427E60
-------------对应值---------------
temp->a=1
temp[0].a=3
temp[1].a=4
temp[2].a=5
temp[0].b=6
temp[1].b=7
temp[2].b=8
-------------对应地址---------------
&(temp->a)=00427E60
&(temp->b)=00427E64
&(temp[0].a)=00427E60
&(temp[0].b)=00427E64
&(temp[1].a)=00427E68
&(temp[1].b)=00427E6C
&(temp[2].a)=00427E70
&(temp[2].b)=00427E74

after msg.a=3

Press any key to continue
最佳答案
2018-8-23 11:21:02
claws0n 发表于 2018-8-23 10:53
嵌入式,还没学过
呼叫大神 @无符号整形
程序透过结构体指针改变结构体内容,但 ...

总算明白你要问什么了。
temp[0]就相当于*(temp+0),相当于temp
temp[1]就相当于*(temp+1),相当与temp的下一个地址
以此类推
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-8-22 23:41:28 | 显示全部楼层
为什么不能本地上传图片 ??
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-22 23:46:25 | 显示全部楼层
我是大甲鱼 发表于 2018-8-22 23:41
为什么不能本地上传图片 ??

进入高级模式
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-8-23 00:12:23 | 显示全部楼层

不管他什么模式了,大佬知道这是我为什么吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-23 00:20:14 | 显示全部楼层
当然可以换 *p_ex 与 ex 是属于同一个结构体
没错,因为地址一样,所以被改变了
第二个情况没有遇过,不过这样写是很危险的。结构体本身就可大可小,也许是因为这样,所以编译器让你自由扩充结构体的空间。
可以赋值就可以直接访问了 int a  = 3; printf("%d", a) == 3
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-8-23 00:40:06 | 显示全部楼层
claws0n 发表于 2018-8-23 00:20
当然可以换 *p_ex 与 ex 是属于同一个结构体
没错,因为地址一样,所以被改变了
第二个情况没有遇过,不 ...

(temp+0)->a==temp[0].a    (temp+1)->a==temp[1].a     (temp+2)->a==temp[2].a
(temp+0)->a==temp[0].a的地址相同可以理解为什么可以赋值。感觉传进来的结构体指针变成了一个结构体数组。我是在学嵌入式的时候看到这种写法,看了好久没看懂。百度也不好描述。
typedef struct i2c_msg {
        unsigned int addr;  /* 7bits   地址*/   
        int flags;  /* 0 - write, 1 - read */
        int len;                //数据长度
        int cnt_transferred;
        int err;
        unsigned char *buf;                //存数据
}i2c_msg, *p_i2c_msg;

int s3c2440_master_xfer(p_i2c_msg msgs, int num)
{
        int i;
        int err;
        
        for (i = 0; i < num; i++)        
        {
                if (msgs[i].flags == 0)/* write */
                        err = do_master_tx(&msgs[i]);
                else
                        err = do_master_rx(&msgs[i]);
                if (err)
                        return err;
        }
        return 0;
}

老铁早些睡觉吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-23 10:53:31 | 显示全部楼层
我是大甲鱼 发表于 2018-8-23 00:40
(temp+0)->a==temp[0].a    (temp+1)->a==temp[1].a     (temp+2)->a==temp[2].a
(temp+0)->a==temp[0] ...

嵌入式,还没学过
呼叫大神 @无符号整形
程序透过结构体指针改变结构体内容,但是代码 24 - 46 对结构体扩充
我的回答: 5 楼

点评

ok  发表于 2018-8-23 11:09
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-23 11:09:23 | 显示全部楼层
本帖最后由 无符号整形 于 2018-8-23 11:21 编辑

见9楼
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-23 11:21:02 | 显示全部楼层    本楼为最佳答案   
claws0n 发表于 2018-8-23 10:53
嵌入式,还没学过
呼叫大神 @无符号整形
程序透过结构体指针改变结构体内容,但 ...

总算明白你要问什么了。
temp[0]就相当于*(temp+0),相当于temp
temp[1]就相当于*(temp+1),相当与temp的下一个地址
以此类推

点评

有句话:C语言根本没有实际上的数组,只有实际上的指针。 数组即指针  发表于 2018-8-23 11:21
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-23 11:29:55 | 显示全部楼层
无符号整形 发表于 2018-8-23 11:21
总算明白你要问什么了。
temp[0]就相当于*(temp+0),相当于temp
temp[1]就相当于*(temp+1),相当与temp ...

对这个线性扩充我知道,所以
第二个情况没有遇过,不过这样写是很危险的。结构体本身就可大可小,也许是因为这样,所以编译器让你自由扩充结构体的空间。

但是没有相对应的结构/变量,很危险,算野指针?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-23 11:33:43 | 显示全部楼层
claws0n 发表于 2018-8-23 11:29
对这个线性扩充我知道,所以

但是没有相对应的结构/变量,很危险,算野指针?

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-23 11:36:50 | 显示全部楼层
claws0n 发表于 2018-8-23 11:29
对这个线性扩充我知道,所以

但是没有相对应的结构/变量,很危险,算野指针?

那个地方如果是栈的话可能会超过栈顶,有可能超过栈底。假如是内存的话可能会访问到别的进程的地址空间,甚至有可能访问到系统内核保留空间(0x70000000~0xFFFFFFFF),这样会引发0xC000005错误,就是访问违规,会导致程序“停止工作”。(其实你可以通过try来捕获这些异常但是扯太远了)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-23 11:42:29 | 显示全部楼层
无符号整形 发表于 2018-8-23 11:36
那个地方如果是栈的话可能会超过栈顶,有可能超过栈底。假如是内存的话可能会访问到别的进程的地址空间, ...

甚至有可能访问到系统内核保留空间(0x70000000~0xFFFFFFFF),这样会引发0xC000005错误,就是访问违规,会导致程序“停止工作”。可以理解,数字认不得~
(其实你可以通过try来捕获这些异常但是扯太远了)
初学者
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-23 11:48:37 | 显示全部楼层
啦啦啦啦啦啦

评分

参与人数 1荣誉 -2 鱼币 -2 收起 理由
claws0n -2 -2 请不要无意义灌水!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-8-23 13:08:54 | 显示全部楼层
无符号整形 发表于 2018-8-23 11:21
总算明白你要问什么了。
temp[0]就相当于*(temp+0),相当于temp
temp[1]就相当于*(temp+1),相当与temp ...

1.当传入的是一个结构体地址的时候可以用temp->a访问  也能用temp[0].a访问,但是超出后可能会发生一些严重的错误。
2.当传入的是一个结构体数组的地址,在这个数组元素个数范围内都可以用temp[i].a来访问


这样理解对么?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-23 14:14:49 | 显示全部楼层
我是大甲鱼 发表于 2018-8-23 13:08
1.当传入的是一个结构体地址的时候可以用temp->a访问  也能用temp[0].a访问,但是超出后可能会发生一些严 ...

对的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-23 14:19:48 | 显示全部楼层
本帖最后由 无符号整形 于 2018-8-23 14:21 编辑
claws0n 发表于 2018-8-23 11:42
甚至有可能访问到系统内核保留空间(0x70000000~0xFFFFFFFF),这样会引发0xC000005错误,就是访问违规, ...

try//尝试执行的语句部分
{
        ...
}
catch(xxx xx)//假如出现了异常,系统会抛出一个异常结构,这个结构是不确定的,你需要根据上面的可能会出现的错误来决定
{
        ...
}
PS:什么?你是初学者??我不信~别那么谦虚嘛~

点评

是的,我是初学者,私聊~  发表于 2018-8-23 14:34
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-30 07:45

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表