易码技术论坛

 找回密码
 加入易码
搜索
查看: 2003|回复: 30

[求助]六个关于在yan编译器中如何使用“引用”的问题

[复制链接]
发表于 2008-1-18 16:43:28 | 显示全部楼层 |阅读模式
你是Lava菜鸟吗?看了下面几个问题后 关于使用引用这个话题,还有其他想问的吗?跟帖问吧

如果不是,可以回帖传道解惑吗?
你对那些还是菜鸟的有什么期待吗?可以说说你是如何学习,成为Lava编程大师的。对于学习中产生的问题(比如第一次屡败屡改的 原代码[NUMofCODE] )如何处理的呢?有把它们——像 错题集 那样收集起来吗?.......
最重要是回帖答疑

感觉最近很长时间Lava新手作品较少,我打算在寒假期间编个 时间管理工具LAV文件,成为一名Lava新手,为星迷们做出一点贡献。但对如何在函数间传递参数始终搞不明白,尤其是引用特别是结构体引用的使用一直没学会,故此发表此贴,寻求各位编程大师的帮助

示范程序代码         编译器Y2.19最终版(包含编译器工程包,浮点数库,12.10更新)
//关于引用(取自http://www.emsky.net/bbs/viewthread.php?tid=19874&extra=&page=1

[01]#include <stdio.y>
[02]#include <malloc.y>
[03]struct student
[04]{char name[20];
[05]int score;
[06]struct student &next;
[07]};
[08]void main()
[09]{  int i,n;
[10]  struct student& p,q,head=0;
[11]  settop(0x3fff);
[12]  SetScreen(0);
[13]  scanf("Input member:","%2d",&n);
[14]  for(i=0;i<n;i++)
[15]    {if(malloc(sizeof(struct student),&(&p))){printf("内存分配失败!\n");getchar();return;}
[16]      scanf("name:","%20s",p.name);
[17]      scanf("score:","%2d",&p.score);
[18]      if(!(&head))&head=&p;else &q.next=&p;//建立链表
[19]      &q=&p;?&p.next=NULL;
[20]    }
[21]   &p=&head;
[22]   while(&p!=NULL)
[23]    {  printf("name:%s score:%d\n",p.name,p.score);getchar();
[24]        &q=&p;&p=p.next;
[25]        free(&q);//释放空间
[26]     }
[27]}

[ 本帖最后由 only 于 2008-1-18 19:11 编辑 ]
 楼主| 发表于 2008-1-18 16:51:18 | 显示全部楼层

问题1

问题1:[10]行代码(简写为[10],下同)的变量声明,p,q,head到底是什么类型的变量呢?变量初始化在yan编译器(wqx)上不是只有全局变量才能用吗?ps:不同函数的局部变量不能重名,这是bug吗?
head=0是指head=NULL吗?

[ 本帖最后由 only 于 2008-1-18 17:13 编辑 ]
 楼主| 发表于 2008-1-18 16:54:27 | 显示全部楼层

问题2

问题2:[11]行的settop(0x3fff) 是不是只有用了0x3fff,才可通用全部lava1.0机型呢?

[ 本帖最后由 only 于 2008-1-18 17:16 编辑 ]
 楼主| 发表于 2008-1-18 16:59:20 | 显示全部楼层

问题3

问题3:[15]用“引用”就必须在开头载入#include<malloc.y>吗?哪些情况可以导致“内存分配失败”??
发表于 2008-1-18 17:02:51 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
 楼主| 发表于 2008-1-18 17:08:05 | 显示全部楼层

问题4

问题4:[16]     为什么用p.name表示地址,而不是&p.name或(&p).name?p不是引用吗?
            [17]     这里为什么又用&p.score呢?可以理解为&(p.score)吗?根据测试(&p).score 和(&p).name都是错的,为什么?

[ 本帖最后由 only 于 2008-1-18 17:14 编辑 ]
 楼主| 发表于 2008-1-18 17:10:39 | 显示全部楼层
原帖由 红色激情 于 2008-1-18 17:02 发表
你不能一气问完吗?

因为问题有点多,现在发现整理了六个,可以详细回答这几个问题吗?
谢谢

[ 本帖最后由 only 于 2008-1-18 18:06 编辑 ]
 楼主| 发表于 2008-1-18 17:19:50 | 显示全部楼层

问题5

问题5:
符号&在yan编译器里有哪些用法?
[18],[19],[21]及至[25] 的&符号各自是什么意思?
 楼主| 发表于 2008-1-18 17:23:22 | 显示全部楼层

问题6

问题6:[25]free(&q)???
             [15]    {if(malloc(sizeof(struct student),&(&p))){...

根据函数说明,malloc 与free是成对的,那么free(&p)怎么没有呢?? free(&q)是与[15]的malloc对应吗?

[ 本帖最后由 only 于 2008-1-18 19:17 编辑 ]
发表于 2008-1-18 23:25:20 | 显示全部楼层
1.p,q,head都是student&型变量,这和C里的是不同的,C里的“char* pa,pb”表示声明pa为char指针,而pb是char。
变量的初始化可以用在局部变量(只能用常量初始化)。
不同函数的局部变量可以重名,YAN的编译器没有这个问题吧?
NULL只是一个宏,它在预处理时被替换成0,但人们习惯用NULL表示“不存在”,这里可以用head=NULL代替。

2.是的。

3.不是。malloc.y提供动态内存分配函数(settop,malloc,free),引用是编译器支持的
一种语法。
当没有足够的连续内存时会失败(对此想要详细理解时可以继续提问)

4.p.name当然是地址:char name[20];name是地址,那么char name[20]作为struct的一个成员,又有什么区别呢?不管p是不是引用,都是这样啊?
&p.score就是&(p.score)

5.&可以取地址。另外,对引用赋值时一定要以&开头。例如:
  1. struct Noname
  2. {
  3.         char& cRef;
  4. };
  5. Noname n;
  6. char c;
  7. &n.cRef=&c;        //这里的第一个'&'不能省略
复制代码
6.从[22]到[26]不是把前面用的内存全部释放了吗?

最后,对引用作一个我的解释:引用实际上是记录了一个地址(它占2字节),从这一
点说,它相当于一个int,但是它有一个好处,就是它在为你保存了地址的同时提供了
一种寻址方式,用来对它所指向的内存寻址。
例:
  1. int a[10];
复制代码
现在你妄图用一个变量记录下它的首地址,并用这个地址来对a数组读写。你用一个int变量pt:
  1. int pt;
  2. pt=a;
复制代码
现在要做a[5]=1000这件事,怎么用pt做呢?你发现无能为力,*(pt+5)=1000是不行的。
现在用引用来做这件事呢?看看:
  1. int& pt[];        //它表示,我要用pt来记下一个地址,并且我希望对它指向的内存用int的方式来对待,并且我要用下标来对它所指向的内存寻址,就好象它是一个int数组一样。
  2. pt[5]=1000;
复制代码
可以看到,引用是很有用的,若是没有它,你也许要:
  1. *(pt+5*sizeof(int))=1000%256;
  2. *(pt+5*sizeof(int)+1)=1000/256;
复制代码
对待long时很需要4条语句,就是说你就要自己去寻址了。
用在struct上时很显威力。
对一块内存,你想把它当作什么对待,就用相应的引用“指向”它。

最后,说一下,
int& a;那么&a(注意,是“&a”)就是引用的本质,它是一个int(再说一遍,引用的本质是int,所以你可以看到&q=&p,就相当于把一个int赋给另一个int),而a=555就相当于把555用int的方式存在&a所指向的内存。
再看看引用struct:
struct Noname
{
        char cmem;
        int imem;
        long lmem;
};
struct Noname& nRef;也差不多,&nRef是它的本质(但对于结构,nRef和&nRef一
样,'&'可以省略)。&nRef.imem=555;就是说“我要把&nRef所指向的内存在偏移1处
的内存看作一个int,并把555赋给它”。

怎样?

[ 本帖最后由 Lumj 于 2008-1-18 23:37 编辑 ]
发表于 2008-1-18 23:28:03 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
发表于 2008-1-18 23:39:47 | 显示全部楼层
貌似牛人一看问题帖就发蒙
 楼主| 发表于 2008-1-19 12:48:57 | 显示全部楼层
原帖由 Lumj 于 2008-1-18 23:25 发表

.p,q,head都是student&型变量,这和C里的是不同的,C里的“char* pa,pb”表示声明pa为char指针,而pb是char。
变量的初始化可以用在局部变量(只能用常量初始化)。
不同函数的局部变量可以重名,YAN的编译器没有这个问题吧?
......
当没有足够的连续内存时会失败(对此想要详细理解时可以继续提问)
......
怎样?

[ 本帖最后由 Lumj 于 2008-1-18 23:37 编辑 ] ...


1.struct student口&p,q,head;[10]  struct student&口p,q,head=0;(口:空格以表示强调)是两种用法吗?它们实际表达的意思有区别吗?
YAN的编译器没有这个不同函数的局部变量可以重名的问题真的没问题吗?我以为是wqx硬件不行,让yan不得不这样设计呢
ps:各位走过路过的星迷们,确认一下“不同函数的局部变量可以重名的问题”有没有问题。回帖答复一下,把这个帖给顶起来,让更多的星迷们学会如何在自己的小星星上编程使用“引用”(还真拗口啊,为什么yan不叫它“指针”呢?还特意说什么“本质上是指针”多费劲啊,如果真有区别,容易让人误解,叫“wqx版指针”不更好`更形象吗?)

2.这个“内存”只是指RAM(临时动态内存)还是包括象电脑硬盘那样的wqx闪存呢?
“对此想要详细理解时可以继续提问”  当然多多益善啦
电量,或者说是电压不足是不是导致“内存分配失败”原因之一?有没有Lava函数检测wqx电量呢?
如果没有,哪为大师可以为大家编个“检测.y”——就像灰度函数那样。最好还有检测内存大小的,文件夹当前文件数的(据说wqx一个文件夹最多只能有31个文件,是不是啊?)

3.学习ing......

可以说说你是如何学好Lava(其他语言像C,Java...也行)的呢?对那些正在观望中的星迷们有什么指导的呢?极度期待对这两个问题的回答。红色激情 ,leesoft别在旁调侃啊,回帖答复一下这2个问题.....

离下午考试(万恶的考研啊......)还有 1小时,先写到这儿。

[ 本帖最后由 only 于 2008-1-19 18:29 编辑 ]
发表于 2008-1-19 13:01:32 | 显示全部楼层
1.引用不是指针。不能划等号,否则就不用增加一个名词了。
2.内存从来都是指能够被cpu直接按字节(或更大的单位)访问的的存储设备,包括RAM,ROM,NOR FLASH。有些无良电子词典商用nand flash冒充内存,这是对人民智慧的侮辱
 楼主| 发表于 2008-1-19 13:06:39 | 显示全部楼层
哇。
Lava创始人终于不调侃拉。。难得一见啊

我还以为被ggv炒鱿鱼(当然也许是炒了ggv)后,对Lava的发展壮大不关心了呢,一心扑在LVC上了呢

时间不多了,就写到这儿把(忙里偷闲跑到网吧里打的字...)......

[ 本帖最后由 only 于 2008-1-19 18:10 编辑 ]
发表于 2008-1-19 15:55:55 | 显示全部楼层
原帖由 only 于 2008-1-19 12:48 发表


1.[06]struct student口&next;[10]  struct student&口p,q,head=0;(口:空格以表示强调)是两种用法吗?它们实际表达的意思有区别吗?
YAN的编译器没有这个不同函数的局部变量可以重名的问题真的没问题吗?我以为是wqx硬件不 ...

1.Noname& a和Noname &a是一样的,完全一样.
如果一个编译器会把不同函数里的同名变量看作错误,那么如果一个函数里有for(i=0;i<n;i++)这种语句,那另一个函数里只能for(j=0;i<n;i++)?函数一多怎么办?你忙着取名字都来不及.这种编译器会有人用吗?你说呢?
2.此"内存"指RAM
电力不足不是导致内存分配失败的原因.LAVA里没有检测电量的函数.
不要以为动态内存分配你难以理解,实际上DMA(Dynamic Memory Allocation)你可以自己写一个(不过现在有现成的了,没有必要)我在附件里给出我写的DMA,你可以拿去看看,或许你不会再有"电压不足是不是导致“内存分配失败”原因之一?"这种疑问了(不过这代码不是用于星端的,是用于gameghost的GLGC编译器).
WQX的文件夹里可以放超过31个文件.

Sample.rar

599 Bytes, 下载次数: 501

DMA代码

 楼主| 发表于 2008-1-19 17:55:12 | 显示全部楼层
原帖由 Lumj 于 2008-1-19 15:55 发表

1.1.Noname& a和Noname &a是一样的,完全一样.
如果一个编译器会把不同函数里的同名变量看作错误,那么如果一个函数里有for(i=0;i<n;i++)这种语句,那另一个函数里只能for(j=0;i<n;i++)?函数一多怎么办?你忙着取名字都来不及.这种编译器会有人用吗?你说呢?



你举的例子中,只对i 进行一次变量声明,所以
当 编译器会把“在不同函数里“声明”的同名变量看作错误”时,或对此不很肯定时
for(i=0;i<n;i++){....;}这代码可以随意用,关键是只要在第一次使用变量i之前 ,对i 只声明一次之后不在一一去声明。

而我指的编译器错误是这种情况:
void  f(int n)
{
......
}

void   g(int  n)
{
  ......
}

void  main()
{
  int  n=4;
......
  f(n);
  g(n);
  ......
}

[ 本帖最后由 only 于 2008-1-19 18:21 编辑 ]
发表于 2008-1-19 18:13:47 | 显示全部楼层
云山雾罩
 楼主| 发表于 2008-1-19 18:20:59 | 显示全部楼层
原帖由 leesoft 于 2008-1-19 18:13 发表
云山雾罩


什么意思?....云山雾罩......
发表于 2008-1-19 18:22:57 | 显示全部楼层
云山雾罩就是云山雾罩
不懂可以查词典
您需要登录后才可以回帖 登录 | 加入易码

本版积分规则

Archiver|手机版|小黑屋|EMAX Studio

GMT+8, 2025-7-2 15:13 , Processed in 0.018377 second(s), 21 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

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