مشکل این تابع من چیه؟؟

sozan2009

New Member
این تابع قراره یه لیست پیوندی خطی رو معکوس کنه ولی نمی دونم چرا در آخر آدرس متغیر "l " را اشتباهی میده
بعد از اینکه لیست رو معکوس کرد وقتی از درون ای تابه لیست معکوس شده رو چاپ می کنم درست نشون میده .اما وقتی می خوام از درون تابع اصلی فراخانی کنم بعد از عملیات لیست را برابر صفر می گیره !!!


PHP:
 void main_list::invert(list*l)
{
  list*temp,*s,*p;
  p=l;
  temp=l->next;
  p->next=0;
  while(temp!=0)
  {
    s=temp->next;
    temp->next=l;
    l=temp;
    temp=s;
  }
  p->next=0;
  print(l);
}


ممنون میشم بهم کمک کنین:rose:
 

the_king

مدیرکل انجمن
همانطوری که خودتان هم تست کرده بودید، کد داخل تابع ()Invert ای که نوشته اید درسته، شما صرفا یک نکته ظریف
را در نظر نگرفته بودید، آنهم این نکته بود که شما مقدار l را به تابع ()Invert ارسال کرده اید و تابع ()Invert به
خود l دسترسی ندارد.

شما شروع لیست را با یک اشاره گر به نام l نشان داده اید که مقدار آنرا به عنوان پارامتر ورودی به تابع ()Invert ارسال
می کنید.
آنچیزی که شما به تابع ()Invert ارسال کردید، یک اشاره گر به لیست است، یعنی در حقیقت آدرس مکانی از حافظه که
اولین عنصر لیست در آن قرار دارد. کد های داخل تابع هم ترتیب عناصر لیست را معکوس می نماید، اما تابع آدرس خود
متغیر l را نمی داند و نمی تواند مقدار داخل l ای که در بیرون از تابع تعریف شده را تغییر دهد. برای همین l همچنان
به همان موقعیت اولین عنصر لیست اشاره خواهد کرد که پیش از اجرای تابع ()Invert وجود داشت.

کاری که باید انجام دهید این است که بجای ارسال مقدار l، آدرس متغیر l را ارسال کنید. در واقع اشاره گری که به اشاره گر
اشاره می کند. به همین خاطر من در تعریف پارامتر ورودی تابع ()Invert از دو ستاره (**) بجای یک ستاره (*) استفاده کردم.

با اعمال کردن این تغییر کوچک، تغییر موقعیت l در داخل تابع ()Invert به درستی انجام می شود :

کد:
void main_list::invert(list **l)
{
	list *temp,*s,*p;
	p=*l;
	temp=p->next;
	p->next=0;
	while(temp!=0)
	{
		s=temp->next;
		temp->next=*l;
		*l=temp;
		temp=s;
	}
	p->next=0;
	print(*l);
}

کد شما پس از تغییر بصورت یک برنامه ساده بازنویسی کردم که سه تابع اضافه دارد :
تابع ()add برای اضافه کردن آیتم به لیست
تابع ()clear برای پاک کردن کلیه عناصر لیست
تابع ()print برای چاپ کردن لیست

در روتین اصلی ()main ابتدا عناصر لیست تهی چاپ می شود.
سپس پنج عنصر با مقدار های 1 الی 5 به لیست اضافه می گردد.
سپس عناصر لیست مجددا چاپ می شود.
سپس لیست معکوس می گردد.
سپس عناصر لیست مجددا چاپ می شود.
سپس عناصر لیست پاک می شوند.
سپس عناصر لیست مجددا چاپ می شود.

کد:
#include <stdio.h>
#include <conio.h>

struct list
{
	int value;
	list *next;
};

void invert(list **l)
{
	list *temp,*s,*p;
	p=*l;
	temp=p->next;
	p->next=0;
	while(temp!=0)
	{
		s=temp->next;
		temp->next=*l;
		*l=temp;
		temp=s;
	}
	p->next=0;
}

void add(list **l,int value)
{
	list *p;
	if (*l==0)
	{
		*l=new list;
		(*l)->value=value;
		(*l)->next=0;
	}
	else
	{
		p=*l;
		while (p->next!=0)
			p=p->next;
		p->next=new list;
		p=p->next;
		p->value=value;
		p->next=0;
	}
}

void clear(list **l)
{
	list *p=*l;
	while (p!=0)
	{
		delete p;
		p=p->next;
	}
	*l=0;
}

void print(list *l)
{
	list *p;
	p=l;
	while (p!=0)
	{
		printf("%d > ",p->value);
		p=p->next;
	}
	printf("null\n");
}

void main()
{
	clrscr();
	list *l=0;
	print(l);
	add(&l,1);
	add(&l,2);
	add(&l,3);
	add(&l,4);
	add(&l,5);
	print(l);
	invert(&l);
	print(l);
	clear(&l);
	print(l);
   getch();
}
 

جدیدترین ارسال ها

بالا