PDA

View Full Version : سوال: مشكل كجاست؟



بانوی ایران
چهارشنبه 09 دی 1388, 15:08 عصر
سلام دوستان و اساتيد گرامي من اين برنامه رو نوشتم ولي ايراد داره نميدونم مشكلازallocateكردن منه يا جاي ديگس

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
void input_array(int * array, int row, int column)
{
array=(int *)malloc(row*column*sizeof(int));
int i, j;
for (i=0;i<row;i++)
{
for(j=0;j<column;j++)
{
printf ("enter array[%d][%d]\n", i, j);
scanf ("%d", array);
array++;
}
}
}
void multiply (int *result, int *first,int *second, int rowA, int columnA, int columnB)
{
result=(int*)malloc(rowA*columnB*sizeof(int));
int i,j,k,x;
for (i=0;i<rowA;i++)
{
for (k=0;k<columnB;k++)
{
for (j=0;j<columnA;j++)
{
x=first[i][j]* second[j][k];//اينجا مشكل داره
result[i][k]+=x
}
}
}
}
void print_array(int *array,int row, int column)
{
int i, j;
for (i=0;i<row;i++)
{
for(j=0;j<column;j++)
{
printf("%4d ", *array);
array++;
}
printf("\n");
}
}
int main()
{
int n, m, y,*list_A,*list_B,*new_list;
printf("enter n,m,y\n");
scanf ("%d%d%d", &n, &m, &y);
input_array (list_A, n, m);
input_array(list_B,m,y);
multiply (new_list,list_A,list_B,n,m,y);
print_array(new_list,n,y);
getch();
return 0;
}


اينم ارورش
invalid types `int[int]' for array subscript

clover
چهارشنبه 09 دی 1388, 17:21 عصر
result, first و second همگی آرایه های یک بعدی هستند (آرایه های دو بعدی واقعی نیستند) بنابراین با دو اندیس قابل استفاده نیستند.

دستورات داخل حلقه را به این شکل تغییر بدید:

x=first[i * columnA + j]* second[j * columnB + k];//اينجا مشكل داره
result[i * rowA+ k]+=x;

البته برنامه شما چند تا خطای اساسی هم داره، اگر یادتون بیاد در تاپیک قبلی گفتم که در صورتی که نمی خواهید اشاره گر آرایه را return کنید باید تخصیص حافظه به آرایه را در تابع main انجام بدید و اشاره گر را به تابع بفرستید.

برنامه اصلاح شده :

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>

int **makeMat(int m, int n)
{
int **iMat = (int **)malloc(m * sizeof(int *));
for (int i = 0; i < m; i++)
iMat[i] = (int *)malloc(n * sizeof(int));
return iMat;
}
void input_array(int **array, int row, int column)
{
int i, j;
for (i=0;i<row;i++)
{
for(j=0;j<column;j++)
{
printf ("enter array[%d][%d]\n", i, j);
scanf ("%d", &array[i][j]);
}
}
}
void multiply (int **result, int **first,int **second, int rowA, int columnA, int columnB)
{
int i,j,k,x;
for (i=0;i<rowA;i++)
{
for (k=0;k<columnB;k++)
{
result[i][k] = 0; // اصلاح شد
for (j=0;j<columnA;j++)
{
x=first[i][j]* second[j][k]; // اصلاح شد
result[i][k]+=x;
}
}
}
}
void print_array(int **array,int row, int column)
{
int i, j;
for (i=0;i<row;i++)
{
for(j=0;j<column;j++)
{
printf("%4d ", array[i][j]);
}
printf("\n");
}
}
int main()
{
int n, m, y,**list_A,**list_B,**new_list;


printf("enter n,m,y\n");
scanf ("%d%d%d", &n, &m, &y);
list_A = makeMat(n, m);
list_B = makeMat(m, y);
new_list = makeMat(n, y);
input_array (list_A, n, m);
input_array(list_B,m,y);
multiply (new_list,list_A,list_B,n,m,y);
print_array(new_list,n,y);
getch();
return 0;
}
موفق باشید

بانوی ایران
چهارشنبه 09 دی 1388, 18:33 عصر
خيلي ممنون دوست عزيز:چشمک:
پس اگر بخوام اين ها رو به صورت اراريه دو بعدي(واقعي ) با mallocتعريف كنم چجوري ميشه؟
راجع به توضيحي هم كه در تاپيك قبل داديد حق با شماست يادمم بود كه اونجوريه ولي اين تابع رو من قبلا int*تعريف كرده بودم خيلي با عجله تغييرش دادم (اگر توي خود تابع تعريفش كنيم mallocرو مشكل اينه كه فضايي كه بهش ميديم توي حافظه نامعلومه؟)
راه حلي هم كه داديد رو روش فكر ميكنم

clover
چهارشنبه 09 دی 1388, 20:06 عصر
پس اگر بخوام اين ها رو به صورت اراريه دو بعدي(واقعي ) با mallocتعريف كنم چجوري ميشه؟
به این صورت:

int **iMat = (int **)malloc(m * sizeof(int *));
for (int i = 0; i < m; i++)
iMat[i] = (int *)malloc(n * sizeof(int));

راه حلي هم كه داديد رو روش فكر ميكنم
منظورتون کدوم راه حل هست ؟
کد بالا کامل بود. البته تغییرات جدید را هم روی اون کد اعمال کردم(برای استفاده از آرایه دوبعدی).

بانوی ایران
چهارشنبه 09 دی 1388, 22:55 عصر
سلام مرسي
ميگمmakemat,imatتعاريف كتابخونه اي هستن؟ اگه نه چرا اينجوريه؟
كدتون كه بله كامله منظورم از فكر اينه كه ببينم ميفهممش يا نه:چشمک:
دوست عزيز ممنون از اينكه وقت ميزاريد

clover
چهارشنبه 09 دی 1388, 23:06 عصر
ميگمmakemat,imatتعاريف كتابخونه اي هستن؟ اگه نه چرا اينجوريه؟
نه، آرایه دو در دو را ماتریس دوبعدی هم میگن. i برای int بودنشه و Mat هم مخفف ماتریس، نوعش هم اشاره گر به اشاره گر (آرایه) هست، به دلیل اینکه قرار هست به یک ماتریس دو بعدی اشاره می کنه.
makeMat هم به همین صورت، به فهم بهتر کد (حتی برای خود نویسنده کد!) کمک می کنه.
توابع تا حد ممکن باید کوچک باشند و اختصاصا یک وظیفه را انجام بدن. حالا من برای ساخت یک آرایه (ماتریس) دو بعدی به صورت پویا، یک تابع نوشتم به اسم makeMat که اشاره گر ماتریس ایجاد شده را به ما بر میگردونه.


دوست عزيز ممنون از اينكه وقت ميزاريد
خواهش می کنم. نیازی به تشکر نیست، بیشتر یه وظیفه هست تا کمک.

بانوی ایران
پنج شنبه 10 دی 1388, 01:31 صبح
به این صورت:

int **iMat = (int **)malloc(m * sizeof(int *));
for (int i = 0; i < m; i++)
iMat[i] = (int *)malloc(n * sizeof(int));



ميشه يكم توضيحش بديد
توي يه بعدي وقتي ميگيم
list_A=(int *)malloc(n*m*sizeof(int));
يعني فضايي به اندازه mدرnبه اين ارايه تخصيص بده و ادرس اولين خونشو ميزاريم توي liat_A
اگر درست بگم!؟
ولي توي اين چيزي كه نوشتيد داريم چي كار ميكنيم:متفکر:

clover
پنج شنبه 10 دی 1388, 17:58 عصر
وقتی میگیم ماتریس دوبعدی 8x4 یعنی یک آرایه که 8 تا خونه داره و توی هر خونه ای یک آرایه با 4 خونه وجود داره.
خب ما این را به این شکل پیاده سازی می کنیم:

آرایه ای با 8 عنصر از نوع آرایه:

int **iMat = (int **)malloc(8 * sizeof(int *));
هر خانه یک آرایه هست با 4 عنصر از نوع عددی:

for (int i = 0; i < 8; i++)
iMat[i] = (int *)malloc(4 * sizeof(int));

همیشه این را مد نظر داشته باشید که اسم آرایه اشاره گری به اولین خانه آرایه هست، عکس این مطلب هم صادق هست.
وقتی می نویسیم [3][2]iMat کامپایلر ابتدا به دنبال [2]iMat می گرده و مقدار اون را که یک اشاره گر هست به یک آرایه به صورت ضمنی (یعنی اون را به عنوان یک متغیر مثلا با نام temp در نظر می گیره) با اندیس دوم به کار می بره ([3]temp) که حاصل مقدار [3][2]iMat هست.