PDA

View Full Version : سوال درمورد معني چند دستور از اساتيد زبان c



dr-data
چهارشنبه 16 فروردین 1391, 20:17 عصر
با سلام خدمت دوستان و اساتيد
من برنامه نويس حرفه اي نيستم ولي در حد متوسط هستم و كتاب جعفر نژادو خوندم ولي توي جزئيات و ريزه كاريا مسلط نيستم. رشتمم كامپيوتر نيست.
توي چند تا برنامه بدجوري گير كردم كه معني اين عبارات چيه؟ :

بعضي دستورا و رهنمودا يسري underline داره جلوشون مثلاً:

struct __FILE { int handle;} ;
يا مثلا:

#ifndef __ASSEMBLY__

بعد مگه تابع هم مثل متغيرها استاتيك و رجيستر و .. داره؟ مثلاً اينجا تابع استاتيك يعني چي؟!! :

static void IS_Tc0(void)

يجاهم ديدم كه جلوي دستور
#define‌ به جاي 2 عبارت 3 عبارت بود!! معنيش چيه؟


ممنون و عذرخواهي اگه ابتدائيه سوالا ولي بدجور درگيرم كرده اين ريزكاريا:افسرده:

shahmohammadi
چهارشنبه 16 فروردین 1391, 21:18 عصر
سلام.

بعضي دستورا و رهنمودا يسري underline داره جلوشون مثلاً:
در نام گذاري متغير ها و توابع مي شه از _ هم در ابتدا و انتها و وسط اسم استفاده كرد.
مثلا برنامه زير در كامپايلر من ارور نميده:
int main()
{
int _a;
int __;
return 0;
}

بعد مگه تابع هم مثل متغيرها استاتيك و رجيستر و .. داره؟ مثلاً اينجا تابع استاتيك يعني چي؟!!
در داخل كلاس ها بله.

يجاهم ديدم كه جلوي دستور 1
#define



‌ به جاي 2 عبارت 3 عبارت بود!! معنيش چيه؟
من هم تا حالا define رو به روش هاي مختلفي ديدم كه ازش استفاده شده و در كتاب هاي سي نديدم. اگر يه مثال بزنيد شايد بتونيم كمكي بكنيم.

Ananas
چهارشنبه 16 فروردین 1391, 22:23 عصر
سلام.
اگه منظورت همچین چیزیه :
#define SinDegree(ANGLE) sin(ANGLE * 3.14159265 / 180.0)
یا همچین چیزی :
#define GETSTD #include <stdio.h>
اینا هم دو قسمتی هستن ولی یک قسمت خوش دو قسمت داره مثلا #include <stdio.h> یک قسمته و GETSTD هم یک قسمته یا مثلا SinDegree(ANGLE) یک قسمت sin(ANGLE * 3.14159265 / 180.0) و این هم یک قسمت.

dr-data
پنج شنبه 17 فروردین 1391, 10:14 صبح
سلام و ممنون از پاسخهاتون.

shahmohammadi : آخه برنامه C هستش كلاس نداريم تو C تا اونجا كه من ميدونم! داريم مگه؟!
مثلا،‌اين يكي ديگه:

static void ME_Ad(void)

فقط تابع هستن اينا، داخل هيچ كلاسي نيستن.

بعد شما كامپيوتريها ها اذييت ميكنيدااا، اين همه حرف حالا بايد از UNDERLINE استفاده كنيد مارو گيج كنيد؟:بامزه:

ANANAS در مورد دستور DEFINE كه 3 قسمتي بود هم عرض كنم كه چون اين برنامه من خيلي تو در توه الان هرچي ميگردم پيداش نميكنم ولي همينو بگم كه دقيقاً مثل دستور DEFINE خودمون بود ولي به جاي 2 تا عبارت جلوش 3 تا بود!!! SPACE داشت اينو مطمئنم 3 عبارتي بود. گفتم شايد معني داشته باشه و من بي خبرم!

يه سوال ديگه كه دارم اينه كه مگه PREPROCESSOR DIRECTIVE ها كه همون
#DEFINE يكيشه، ميتونن داخل تابع MAIN هم بيان؟ مگه نبايد اول برنامه اين رهنمود ها رو بياريم؟

با تشكر

shahmohammadi
پنج شنبه 17 فروردین 1391, 11:52 صبح
بله توي گوگل چند تا فايل c پيدا كردم كه توابعش با ststic تعريف شده بودند.
بنا به اين سايت (http://www.lix.polytechnique.fr/%7Eliberti/public/computing/prog/c/C/SYNTAX/static.htm):

static functions are functions that are only visable to other functions in the same file. Consider the following code. توابع استاتيك توابعي هستند كه فقط توسط ساير توابع فايلي .c كه در آن قرار دارند ديده مي شوند.
همونطور كه مي دونيد بعضي از برنامه ها شامل چند تا فايل سي هستند. به نظرم توي كتاب جعفر نژاد هم يه چنين چيزي بود.

Ananas
پنج شنبه 17 فروردین 1391, 13:15 عصر
در مورد دستور DEFINE كه 3 قسمتي بود هم عرض كنم كه چون اين برنامه من خيلي تو در توه الان هرچي ميگردم پيداش نميكنم ولي همينو بگم كه دقيقاً مثل دستور DEFINE خودمون بود ولي به جاي 2 تا عبارت جلوش 3 تا بود!!! SPACE داشت اينو مطمئنم 3 عبارتي بود. گفتم شايد معني داشته باشه و من بي خبرم!
دقت کنی مثال دوم من هم سه تا هست. اگه پیدا کردی بگذار ببینیم. تا اونجا که میدونم مطلب همونی هست که عرض کردم یعنی همیشه دو تا عبارت هست که هر عبارتی ممکنه خودش از دو یا چند عبارت تشکیل بشه.

ميتونن داخل تابع MAIN هم بيان؟ مگه نبايد اول برنامه اين رهنمود ها رو بياريم؟هر جای برنامه که بخوای میتونه استفاده بشه حتی قبل از همه کدها و یا بعد از همه ی کد ها و لابه لای دستور ها و توابع . در واقع پا به پای کد میان تا به کامپایلر منظور برنامه نویس رو برسونن و از اسمشم پیداست که کامپایلر رو مدیریت و هدایت میکنه به سمتی که برنامه نویس میخواد. برای اینکه بیشتر آشنا بشی فایل های سرآیند همراه کامپایلرتون رو یک نگاهی بندازید.

dr-data
جمعه 18 فروردین 1391, 11:52 صبح
بله توي گوگل چند تا فايل c پيدا كردم كه توابعش با ststic تعريف شده بودند.
بنا به اين سايت (http://www.lix.polytechnique.fr/%7Eliberti/public/computing/prog/c/C/SYNTAX/static.htm):
توابع استاتيك توابعي هستند كه فقط توسط ساير توابع فايلي .c كه در آن قرار دارند ديده مي شوند.
همونطور كه مي دونيد بعضي از برنامه ها شامل چند تا فايل سي هستند. به نظرم توي كتاب جعفر نژاد هم يه چنين چيزي بود.

shahmohammadi جان خيلييي ممنون، حق با شماست تست كردم اين توابع استاتيك فقط در فايل برنامه خودش قابل اجرا هستن:چشمک:

dr-data
جمعه 18 فروردین 1391, 11:56 صبح
دقت کنی مثال دوم من هم سه تا هست. اگه پیدا کردی بگذار ببینیم. تا اونجا که میدونم مطلب همونی هست که عرض کردم یعنی همیشه دو تا عبارت هست که هر عبارتی ممکنه خودش از دو یا چند عبارت تشکیل بشه.
هر جای برنامه که بخوای میتونه استفاده بشه حتی قبل از همه کدها و یا بعد از همه ی کد ها و لابه لای دستور ها و توابع . در واقع پا به پای کد میان تا به کامپایلر منظور برنامه نویس رو برسونن و از اسمشم پیداست که کامپایلر رو مدیریت و هدایت میکنه به سمتی که برنامه نویس میخواد. برای اینکه بیشتر آشنا بشی فایل های سرآیند همراه کامپایلرتون رو یک نگاهی بندازید.

ananas چشم حتماً قرار ميدم مثال رو.

ولي من كه سر درنياوردم چرا بعضي برنامه نويسا برنامه هاشونو زياد شكيل نمينويسن!!


ممنون از همه دوستاي عزيز بابت راهنماييهاشون:قلب:

dr-data
جمعه 18 فروردین 1391, 23:36 عصر
سلام دوستان

1سوال ديگه برام پيش اومده بنظر سادس ولي من جوابي تو كتابا براش نديدم!!

توي دستور scanf براي چي كنار متغيري كه مقدار ميگيره & ميذاريم؟!! ما كه كاري با Pointer نداريم! مشكلي با دستور ندارم ولي ميخام بدونم چرا فرمت دستور اينطورية؟ً

shahmohammadi
شنبه 19 فروردین 1391, 00:34 صبح
با اين كار آدرسشو ميديم. اگر خودشو بديم يعني تابع بايد از مقدارش استفاده كنه. در صورتي كه ما مي خواهيم تابع مقدار متغير رو تغيير بده. پس آدرسشو مي ديم تا خونه اي با اون آدرس رو تغيير بده.

Ananas
شنبه 19 فروردین 1391, 04:49 صبح
ولي من كه سر درنياوردم چرا بعضي برنامه نويسا برنامه هاشونو زياد شكيل نمينويسن!!
تو برناامه نویسی شکیل بودن نوشته ها فقط به برنامه نویسا کمک میکنه و در خروجی مثلا فایل exe تاثیری نداره. ببینید برای نامگذاری ها بعضی وقتها یک عباراتی بر حسب قرارداد به شکل خاصی نوشته میشن که نشون دهنده ی مطلب خاصی باشن و شما با دیدن اسم چیزی، بتونی از نامگذاریش اطلاعاتی راجب جنسش و کاربردش بدست بیاری. مثلا ثوابت رو با حروف بزرگ مینویسن! چه فرقی داره؟ فرقش اینه که شما با دیدن حروف بزرگ بلافاصله متوجه ثابت بودن اون مقدار میشید و اون رو مثلا با متغیر یا تابع اشتباه نمیگیرید. این یک مطلب، مطلب دیگه اینکه یک شرکت خاص یا یک مجموعه توابع و برنامه های خاص پارامتر ها و توابعشون رو با حروفی خاص شروع میکنن و معمولا حروف اختصاری اون محصول یا موضوع هست و یکی از کاربرداش اینه که از برخورد اسم های مشابه در جاهای مختلف جلوگیری میشه و دوم اینکه هر کجا این پارامتر یا تابع دیده بشه بلافاصله متوجه میشید که تابع برای چه مجموعه ای از برنامه ها و توابع هست و دلیل خیلی مهمتر برای این کار اینه که مجموعه ای از اسامی مشابه در هنگام جستجو در کنار هم نمایش داده میشن یعنی همون ctrl+space ای که استفاده میکنیم. مثلا من مینویسم d3dx همه ی اسامی پارامترها و توابعی که مربوط به D3DX هستن برام لیست میشن و خیلی راحت میتونم با تایپ چند حرف دیگه جستجو رو محدود تر کنم به مثلا سه یا 10 پارامتر و خیلی راحت گزینه مورد نظرم رو از لیست اننخاب کنم.
یه زمانی من فکر میکردم که مثلا تابع D3DXVec3Length که یکی از توابع DirectX در فایل D3DX هست و کارش محاسبه ی طول یک بردار سه بعدی هست چرا اینقدر اسمش طولانیه؟ خوب اگه بخوام یک کیلومتر اسم تابع رو بنویسم بعد پارامتر ورودی اسم یک بردار رو بهش بدم خوب میام خود تابع رو به شکل اینلاین مینویسم دیگه چرا اینقدر خودمو اذیت کنم اسمای طولانی یاد بگیرم و تایپ کنم؟ اگه اینو :
l := Sqrt(x*x+y*y+z*z);
بنویسم که راحت ترم!
بعد دقت کردم که سرعت اجرای یک تابع ربطی به اسم اون نداره و طولانی و کوتاه بودن اسم فقط برای برنامه نویس میتونه فرق کنه و از دید کاربر نرم افزار ایجاد شده مخفی هست و هیچ فرقی نداره و توابع D3DX استاندارد هستن و کار با اونها باعث میشه که برنامه یک روند یکنواختی رو برای محاسبات ریاضی سه بعدی طی کنه. پس اینجا طولانی بودن اسم میتونه یک امتیاز باشه.
احتمالا دیدید که تو توابع برای ورودی از عباراتی استفاده میکنن که با مثلا حروف dw شروع میشه مثل dwSize ، خوب اینجا اسم این پارامتر size داره به ما میگه که باید از نوع DWORD باشه. یا مثلا pOut داره به ما میگه خروجی از جنس اشاره گر هست و موارد مشابه.
در مورد under-line هم حتما همچین دلیل هایی وجود داره البته من نمیدونم این مورد در کجا استفاده میشه یعنی مورد قراردادش رو نمی دونم که منظورشون چیز خاصی هست یا نه.

dr-data
شنبه 19 فروردین 1391, 12:09 عصر
با اين كار آدرسشو ميديم. اگر خودشو بديم يعني تابع بايد از مقدارش استفاده كنه. در صورتي كه ما مي خواهيم تابع مقدار متغير رو تغيير بده. پس آدرسشو مي ديم تا خونه اي با اون آدرس رو تغيير بده.

shahmohammadi فرمايش شما كاملا درسته كه ما ميخوايم مقدار رو تغيير بديم، ولي براي اينكار مگه لازم نيست كه اول يك اشاره گر تعريف كنيم ؟ يعني موقع تعريف تابع scanf‌ آرگومان ورودي كه همون متغير ماست رو با استفاده از اشاره گر مينويسه؟

shahmohammadi
شنبه 19 فروردین 1391, 20:21 عصر
اين اضافه كاري مي شه. چون &a يعني آدرس a و نيازي نيست كه اشاره گر تعريف كنيم. اگر اشاره گر تعريف كنيم هم همون معني رو مي داد:
#include <stdio.h>
#include <conio.h>

int main()
{
int a,*p;
p=&a;
scanf("%d",p);
printf("%d",a);
getch();
return 0;
}
در كتاب جعفرنژاد مثالي بود كه يك تابع دو متغير رو مي گرفت و مقاديرشون رو عوض مي كرد. از همين روش استفاده مي كرد. الان كتاب رو در اختيار ندارم كه بگم كجاشه.

dr-data
چهارشنبه 23 فروردین 1391, 10:43 صبح
سلام به دوستاي عزيز و ممنون بايت تمام راهنماييهاشون.

يه سوال ديگه در مورد پياده سازي يه تابعي با c دارم كه نخاستم تاپيك جديد باز كنم، اگه اساتيد لطف كنن راهنمايي كنن ممنون ميشم.

من مي خوام يه تابع واس پياده سازي تابع تكه اي خطي به صورت زير رو كدشو بنويسم به c :
85569

تا حدودي ميتونم بنويسم ولي تو يه جاهاييش گير كردم، من اينطور به نظرم ميرسه كه از if استفاده كنم و مثلا بگم :

if(x>=2&&x<+5)
y=x;
els if (x>5&&x<=10)
y=...
...

ولي مشكلم تو نوشتن معادله خطوطه:افسرده: كسي ميتونه كد لازم واس پياده سازي اين تابع رو قرار بده؟ (اساتيد shahmohamadi و ananas يه راهنمايي كنيد لطفا)...

Ananas
چهارشنبه 23 فروردین 1391, 20:21 عصر
(اساتيد shahmohamadi و ananas يه راهنمايي كنيد لطفا)لطف دارید من شاگرد هم نیستم چه برسه به استاد.
ببینید اگه بخواید فقط نمودار رو رسم کنید فقط کافیه نقاط ابتدا و انتهای هر خط رو داشته باشید یعنی همون x , y نقطه ابتدا و انتها. اما اگه یه تابع ریاضی ای می خواید که منم فکر میکنم همینو میخواید از همون روشی که فرمودید استفاده کنید یعنی if ولی چند تا نکته تو استفاده از if :
نمودار شما یعنی این تصویری که من می بینم سه قسمت هست (از نظر تابع ریاضی ای) که هر قسمت یکی دو تا شکستگی داره برای هر شکستگی به شکل جدا بررسی میکنیم.
دقت کنید که یک if تو هر مرحله کافیه و if ها رو به ترتیب کوچک به بزرگ تنطیم کنید و فقط بنویسید اگر x کوچک تر از فلان... لازم نیست از && استفاده بشه.
تابع نمودار اول :

float GetLine_01(const float x)
{
if (x < 28) {
return 1.0;
}
else
{
return ((x - 28.0) * (0.0 - 1.0) / (32.0 - 28.0) + 1.0);
}
}

تابع نمودار دوم :

float GetLine_02(const float x)
{
if (x < 29.0) {
return 0.0;
}
else if (x < 32.0) {
return ((x - 29.0) * (1.0 - 0.0) / (32.0 - 29.0));
}
else if (x < 34.0)
{
return 1.0;
}
else
{
return ((x - 34.0) * (0.0 - 1.0) / (38.0 - 34.0) + 1.0);
}
}

تابع نمودار سوم :

float GetLine_03(const float x)
{
if (x < 36.0) {
return 0.0;
}
else if (x < 38.0) {
return ((x - 36.0) * (1.0 - 0.0) / (38.0 - 36.0));
}
else
{
return 1.0;
}
}

برای خط های افقی که مقدار برابر عدد ثابت در اینجا یا 0 یا 1 هست.
اما برای خط های شیب دار باید شیب خط از فرمول

(y2 - y1) / (x2 - x1)

محاسبه بشه که میبینید هر جا لازم بوده نوشتم.
اما یک مقدار اولیه و به اصطلاح Offset هم برای x و هم برای y ممکنه وجود داشته باشه که با عمل تفریق برای x و جمع برای y به نتیجه مطلوب میرسیم.
در واقع شما ابتدا فرمول هر خط رو از نقطه 0 و 0 یعنی مبدا با استفاده از ضرب x در شیب خط بدست میارید بعد offset ها رو برای x و y حساب میکنید.
مثلا این :
return (x * (0.0 - 1.0) / (32.0 - 28.0));
همراه با منهای 28 برای x و به علاوه ی 1.0 برای y یعنی خروجی، تبدیل میشه به :
return ((x - 28.0) * (0.0 - 1.0) / (32.0 - 28.0) + 1.0);

dr-data
چهارشنبه 23 فروردین 1391, 23:17 عصر
سلام

ananas جان مرسيي بابت وقتي كه گذاشتيدو كدرو نوشتيد:تشویق:

كامل فهميدم روش كار رو...
فقط يه سوالي دارم اينه كه چرا Y‌رو هميشه با 1 جمع كرديد؟ تا اونجا كه من ميبينم عرض از مبداً‌اين خطوط 1 بنظر نميرسه درست نيست؟ اگه ميشه يكم در مورد اين قسمتم بگيد ممنون ميشم..

Ananas
پنج شنبه 24 فروردین 1391, 10:03 صبح
فقط يه سوالي دارم اينه كه چرا Y‌رو هميشه با 1 جمع كرديد؟ تا اونجا كه من ميبينم عرض از مبداً‌اين خطوط 1 بنظر نميرسه درست نيست؟ اگه ميشه يكم در مورد اين قسمتم بگيد ممنون ميشم.. y های تصویر شما رو من بین 0 تا 1 میبینم شاید اشتباه کردم ولی منظورم همون y ها بودن که در اینجا 0 و یا 1 هستند
ببینید اگه فرمول کلی این خطوط رو بخوایم بنویسیم به این شکله:
برای اینکه نقطه ی [x, y] رو خط [x1, y1] و [x2, y2] باشه باید شرط زیر برقرار باشه.
چون شیب خط از نقطه اول تا x,y برابر شیب خط از نقطه اول تا نقطه دوم هست.

(y - y1) / (x - x1) = (y2 - y1) / (x2 - x1)

نتیجه میگیریم :

(y - y1) = (x - x1) * (y2 - y1) / (x2 - x1)

نتیجه میگیریم :

y = (x - x1) * (y2 - y1) / (x2 - x1) + y1

یعنی فرمول کلی به این شکله که x1, y1 , x2 , y2 رو باید نسبت به هر خط خاص تو فرمول جاگذاری کنید.

dr-data
پنج شنبه 24 فروردین 1391, 10:23 صبح
مرسيييي حل شد كامل مشكلم، سوتي رياضي در حد راهنمايي دادم:افسرده:

خيلي ممنون دوست عزيز از راهنماييهاتون.

dr-data
پنج شنبه 24 فروردین 1391, 22:45 عصر
سلام
بازم سوال پيش اومد برام شرمنده:عصبانی++: و اميد دارم به كمك شما دوستان.

الگوريتمي ميشناسيد كه يك بردار ستوني يعني يك ماتريس با 4 سطر و يك ستون رو روي قطر اصلي يك ماتريس با درايه اي تمام صفر جاگذاري كنه؟
مثلاً تو شكل زير من بردار ستوني I رو دارم و مي خوام با ضرب و جمع و تفريق يه سري عبارات در اين بردار I ام اونو تبديل كنم به ماتريس B ، بنظرتون اون عبارتي كه بايد ضرب بشه چيه؟ اصلاً وجود داره؟

85649 من كه كلييي فكر كردم ولي چيزي پيدا نكردم:عصبانی++::گریه:

Ananas
جمعه 25 فروردین 1391, 11:59 صبح
فرمول خواصی نیاز نداره درایه ها رو دستی جاگذاری کن. مشکل شما با تعریف نوع داده بردار و ماتریس هست یا کد جاگذاری؟
از نظر ریاضی که بردار به ماتریس تبدیل نمیشه حالا با ضرب یا جمع یا هرچی. ضرب ماتریس در ماتریس تعریف شده که نتیجه اش یک ماتریسه و ضرب بردار در ماتیس که نتیجه اش یک برداره. پس اگه میخوای از برداری که در اختیار داری ماتریسی با خصوصیاتی که گفتی بسازی باید درایه ها رو دستی وارد کنی. شاید با یک حلقه هم بشه ولی خیلی فرقی نمیکنه فقط شاید با حلقه سرعت اجرای تابع کمتر بشه.