比如说Link是链表结构体,
那Link n; &n
与Link *n, n=malloc(sizeof(Link))有无区别?
请各位再看一下问题补充,不需要回答什么堆或者栈的详细内部实现,只需要说对于初级程序员来说,假如只需要做一般的链表创建、插入、删除操作,两者的运行效果上有无区别,如果有,有何区别?
根据对追问的回答来采纳!
直接声明的变量储存的区域叫做 栈(stack),使用malloc获得的区域叫堆(heap)。
栈是连续高速而小的(1M,2M的都有,一般不超过2M),堆是不连续低速但容量极大的。追问
对初学者来说,如果只看很基本的插入、删除等操作,程序运行结果上有无区别?
追答如果是链表的操作的话,那么没有任何区别,因为一个节点里面有指向下一个节点的地址,只要有这个地址,就能确定一个内存区域。
struct linklist
{
...//数据
struct linklist *pNext;//这个用于指向下一个结构体,不需要数组一样的连续内存区域
}
Link
{
Link *next;//指向下个节点
Elem e;//元素
}
Link n;就是创建一个Link的结构体,这个变量叫做n。&n表示Link结构体n的首地址。
但是因为Link是链表,里面有个成员是指向一个结构体的指针。所以要用malloc分配空间,而malloc(sizeof(Link));就是为这个地址分配一个可用的堆空间。
你可以开始定义一个 Link L;但是L.next是指针,还是要用malloc为其分配空间。
因为这样是不行。这样定的话会是一个死递归,是非法的。
Link
{
Link next;
Elem e;//元素
}追问
我试过不需要再分配都可以用next。
追答那是一个地址,但是没有空间。如果不用malloc你试试:
Link l;
l.next->e根本放不进去东西的,程序会退出的。l.next是在Link l;时就分配好的指针变量,地址还没确定呢。
可以放的,就用你上面的代码。
追答vc6.0反正是不行。有图有真相。
可是我说的是当前这个节点,你再声明一个Link nextL,刚刚那个s.next=L,再L.p="hello"不就行了?
追答行啊,但是这样做你就是要创建很多结构体变量了,而且各个还是独立的。如果你这个nextL.next还要放呢,你是不是还要搞个nextnextL的变量?这就不灵活了。
追问node *tail;
tail=(node*)malloc(sizeof(node));
tail->v=20000;
tail->next=NULL;
q->next=tail;
node tail;
tail.v=20000;
tail.next=NULL;
q->next=&tail;
功能是在末尾追加一个节点,下面的报错,你说是为什么?
都行的啊。你的q有没malloc?
追问编译是没错,但是在遍历输出的时候,使用下面的情况下,输出完最后一个似乎还有个next,然后就报错了。
追答有问题还是贴代码吧,应该没有什么疑问了吧?
追问贴不下,你上面实际上并没有说出这两者的区别,不过如果你解释了上面我的代码为什么报错就采纳你。代码已经贴了,q就是尾节点,输出是标准的输出函数。
追答你的代码都不完全。出错的原因不好解释。区别就是malloc灵活,无用定义无数个变量。你的这种方式可以,但是要定义多个变量,然后连到一起。
追问那你就定义一个标准的结构体,初始化一下,然后用我上面两种方式添加个尾节点再遍历输出试试。
追答#include "stdio.h"#include "stdlib.h"
struct Link
{
char *p;
struct Link *next;
};
struct Link2
{
short p;
struct Link2 *next;
};
int main()
{
//你的做法
struct Link l,a,b,c;
l.next=&a;
a.next=&b;
b.next=&c;
l.p="hello ";
a.p="world ";
b.p="HI ";
c.p="C ";
printf("%s%s%s%s\n",l.p,a.p,b.p,c.p);
//标准的做法
int i=0;
struct Link2 head,*t;
t=(struct Link2 *)malloc(sizeof(struct Link2));
t=&head;
while (i<10)
{
t->p=i;
t->next=(struct Link2*)malloc(sizeof(struct Link2));
t=t->next;
i++;
}
t->next=NULL;
printf("created\n");
t=&head;
i=0;
while(t->next!=NULL)
{
printf("%d\n",t->p);
t=t->next;
}
return 0;
}本回答被提问者采纳
C程序中编译后的程序在加载后,栈中分配局部变量空间,堆区是向上增长的用于分配程序员申请的内存空间。如果你在一个函数中一下子分配一个很大的数据,就可能导致栈溢出。
另外malloc用于分配大小不固定的链表,使用变量静态分配的不够灵活。追问
对初学者来说,如果只看很基本的插入、删除等操作,程序运行结果上有无区别?
追答在结果上无区别。只是写代码的时候一个用“->”访问结构体内成员,一个用"."访问结构体内成员。除非对直接声明变量获取的指针再复制给一个指针变量。
追问在对@爱问西瓜爱答树的答案的追问中,我的代码有个奇怪的报错,你认为是什么原因?
追答没看到你的完整代码,也不清楚报错信息是什么,不好判定原因。
比如 int a[n],*p;p=a;是不合法的。而int *p;p=(int *)malloc(n*sizeof(int))却可以实现创建这样一个长度为n的数组
Link n; 申明结构体实体
&n 结构体地址
Link *n; 申明结构体指针
n=malloc(sizeof(Link)); 让结构体指针指向申请的内存空间,需要free释放
后者需要释放并且申请大小灵活
希望对你有帮助追问
要用malloc,多个函数反而还更灵活了?是更复杂了吧!
追答是分配的时候更灵活了,当然可以理解为使用更复杂