بازدید نسخه کامل شده : سوالات و اشکالات من در برنامه نویسی سی
Electronics Art
03-30-2007, 11:13 AM
سلام دوستان
از اونجایی که تو این انجمن برنامه نویس حرفه ای و آماتور و تجاری و ... کم نیست و اکثرشونم
همیشه به اینجا سر می زنند این تاپیک رو باز کردم تا سوالات و اشکلات خودم رو پیرامون
برنامه نویسی در زبان سی اینجا مطرح کنم تا اگه دوستان وقت داشتند منو راهنمایی کنند تا
اشکالات من هم رفع بشه
پیشاپیش از همکاری و مساعدت همه برنامه نویسان عزیز کمال تشکر و قدردانی رو دارم
بابا برقی بیمس :bad_smile:
Electronics Art
03-30-2007, 11:19 AM
خوب به عنوان اولین سوال میخواستم بپرسم معادل دستورات GOSUB --- RETURN که در زبان
بیسیک هستش در زبان سی چیه ؟
یا ما چگونه میتونیم تو زبان سی زیر روالی رو فراخوانی کنیم و بعد از اجرای زیرروال برگردیم به
نقطه ای که عمل فراخوانی انجام گرفته ؟
به این سمپل توجه کنید :
GOTO Start ' Jump over the subroutines
SubA:
{ subroutine A code
……
……
}
RETURN
SubB:
{ subroutine B code
……
……
}
RETURN
' Actual start of the main program
Start: GOSUB SubA
GOSUB SubB
STOP حالا معادل این کدها در زبان سی چی میشه ؟ همون دستور GOTO اینکار رو برای ما انجام میده ؟
اگه میشه کد رو کامل بنویسید
ممنون
Mercury
03-30-2007, 12:47 PM
براي چه نوع كامپايلري ؟! اخه بعضي هاشون يچندتا چيز متفاوت دارن . اما ازونجايي كه حدث ميزنم براي چي ميخواهي ، از اين استفاده كن :
section1:
// do something
if(1){
goto section1;
}
و حتما هم بايد section1 قبل از استفاده تعريف شده باشه .
مثلا اگر section1 در خط 10 بود شما نميتوني از خط 5 به اونجا جامپ كني مگراينكه ادرس حافظه رو داشته باشي . section1 حتما بايد قبل از خط 5 باشه . كه اونم باز راه داره .
Electronics Art
03-30-2007, 01:50 PM
ممنون ابراهیم جان
بله درست حدس میزنی برای برنامه نویسی میکروکنترلرها خصوصاً PIC میخوام
اینو تست کنم نتیجه رو بهت اطلاع میدم
Electronics Art
03-30-2007, 02:31 PM
ببین ابراهیم جان بذار دقیق تر برات بگم
این برنامه زیر رو میبینی :
Main:
if PortB.0 = 1 then
Portb.1 = 1
Gosub Timedelay
Portb.1 0
Gosub Timedelay
endif
goto Main
Timedelay:
Delayms 500
returnاین تو کامپایلر Proton هستش برای میکروکنترلرهای PIC و زبانش هم بیسیکه میاد پایه B.0
رو چک میکنه اگه این پایه یک بود ( مثلاً یوزر یه کلید رو فشار داده ) بعد میره پایه B.1 رو که یه
LED بهش وصله تو پریود 500 میلی ثانیه خاموش و روش میکنه این تاخیر 500 میلی ثانیه تو یه
زیر روال قرار داده شده
حالا ما چطور میتونیم عین این برنامه رو تو سی پیاده کنیم ؟
Mercury
03-30-2007, 03:19 PM
ببین ابراهیم جان بذار دقیق تر برات بگم
این برنامه زیر رو میبینی :
Main:
if PortB.0 = 1 then
Portb.1 = 1
Gosub Timedelay
Portb.1 0
Gosub Timedelay
endif
goto Main
Timedelay:
Delayms 500
returnاین تو کامپایلر Proton هستش برای میکروکنترلرهای PIC و زبانش هم بیسیکه میاد پایه B.0
رو چک میکنه اگه این پایه یک بود ( مثلاً یوزر یه کلید رو فشار داده ) بعد میره پایه B.1 رو که یه
LED بهش وصله تو پریود 500 میلی ثانیه خاموش و روش میکنه این تاخیر 500 میلی ثانیه تو یه
زیر روال قرار داده شده
حالا ما چطور میتونیم عین این برنامه رو تو سی پیاده کنیم ؟
من زياد با pic اشنا نيستم و رجيستر هاشو نميدونم ، ولي اگه avr ش بدردت ميخوره بگو برات تحت avrgcc يا cavr بنويسم .
Mercury
03-30-2007, 03:30 PM
avrgcc يا همون winavr خودمون
#include <avr/io.h>
#include <util/delay.h>
int main(){
DDRB = 0x7F; // set portb.0 = input and each others as output
while(1){
if(bit_is_set(PINB,0)){
PORTB |= _BV(1);
_delay_ms(500);
PORTB &=~ _BV(1);
}
}
}
Electronics Art
03-30-2007, 04:47 PM
ممنون ابراهیم جان
ولی منظور من این نبود که شما برنامه ای در سی بنویسی که کار همون برنامه من در بیسیک رو انجام بده
منظورم این بود که چطور دستورات GOSUB --- RETURN که در بیسیک هستش در سی هم پیاده سازی کنیم ( عین بیسیک )
Electronics Art
03-30-2007, 08:08 PM
ببین این دو برنامه کارشون یکی هستش اول در زبان بیسیک و کامپایلر Proton و دومی در زبان سی و کامپایلر PIC C
زبان بیسیک
device = 16f877
xtal = 4
TRISB = %10000000
Main:
if PortB.0 = 0 then
PortB.1 = 1
Gosub Timedelay
PortB.1 = 0
Gosub Timedelay
endif
goto Main
Timedelay:
Delayms 500
return
زبان سی
#include <16F877.h>
#include <stdio.h>
#use delay (clock=4000000)
void main()
{
while (true)
if (input(pin_b0))
{
blink:
output_bit(pin_b1, 1);
delay_ms(500);
output_bit(pin_b1,0);
delay_ms(500);
goto blink;
}
}
کار هر دو برنامه یکی هستش ولی تو زبان بیسیک ما اون تاخیر رو تو زیر روال Timedelay ایجاد کردیم و هر وقت که نیاز به تاخیر بود این زیر روال رو فراخوانی کردیم و دوباره برگشتیم به برنامه اصلی ولی تو زبان سی مستقیماً از دستور ایجاد تاخیر استفاده کردیم البته تو زبان بیسیک هم می تونیم از دستور مستقیم ایجاد تاخیر استفاده کنیم ولی مساله ما ایجاد تاخیر نیستش بلکه هدف فراخوانی یه ساب روتین و اجرای اون و بازگشت یا return به برنامه اصلی در زبان سی هستش
Electronics Art
03-30-2007, 08:13 PM
البته دو برنامه فوق یه تفاوت کوچیکی دارند که ربطی به مساله ما نداره
برنامه بیسیک صفر بود B.0 رو چک میکنه ولی برنامه سی یک بودن B.0 رو چک میکنه
Electronics Art
03-31-2007, 02:21 AM
خوب ابراهیم جان شما اول گفتی که این جوری حلش کنم درسته ؟
#include <16F877.h>
#include <stdio.h>
#use delay (clock=4000000)
void timedelay() // your delay subroutine
{
delay_ms(1000);
}
void main() // your main routine
{
while (true)
if (input(pin_b0))
{
blink:
output_bit(pin_b1, 1);
timedelay();
output_bit(pin_b1, 0);
timedelay();
goto blink;
}
}
خوب این برای یه ساب روتین که حجمش کمه و کارش ایجاد تاخیره خوب و مشکلی پیش نمیاره ولی اگه ساب روتین ما یه چیزه دیگه بود و کدهاش هم طولانی بود با توجه به اینکه قبل از تابع main تعریف شده اول اون ساب روتین اجرا میشه و بعدش تابع main درسته یا من اشتباه میکنم ؟
اگه اینجوریه چطور میشه این مشکل رو حلش کرد ؟
مثلاً اول برنامه یه goto بزاریم تا بپره به تابع main و اون ساب روتین رو دور بزنه ؟ چطوره ؟ چون من اینکار رو کردم ولی اون مشکل تعریف نشدن قبل از پرش رخ داد :beat_brick:
#include <16F877.h>
#include <stdio.h>
#use delay (clock=4000000)
void first()
{
goto first_loop;
}
void timedelay() // your delay subroutine
{
delay_ms(1000);
}
first_loop:
void main() // your main routine
{
while (true)
if (input(pin_b0))
{
blink:
output_bit(pin_b1, 1);
timedelay();
output_bit(pin_b1, 0);
timedelay();
goto blink;
}
}
amironline
03-31-2007, 06:19 AM
براي چه نوع كامپايلري ؟! اخه بعضي هاشون يچندتا چيز متفاوت دارن . اما ازونجايي كه حدث ميزنم براي چي ميخواهي ، از اين استفاده كن :
section1:
// do something
if(1){
goto section1;
}
و حتما هم بايد section1 قبل از استفاده تعريف شده باشه .
مثلا اگر section1 در خط 10 بود شما نميتوني از خط 5 به اونجا جامپ كني مگراينكه ادرس حافظه رو داشته باشي . section1 حتما بايد قبل از خط 5 باشه . كه اونم باز راه داره .
چرا از توابع و حلقه ها استفاده نمیکنین؟
معمولا تو برنامه نویسی از goto خیلی کم استفاده میشه
Mercury
03-31-2007, 11:46 AM
چرا از توابع و حلقه ها استفاده نمیکنین؟
معمولا تو برنامه نویسی از goto خیلی کم استفاده میشه
با مني يا با بابا برقي ؟!
---
ببين بابا برقي جان (اسمتو نميدونم :big_smile:) به نظر من استفاده بيش از اندازه از goto يكم برنامه رو شلوغ ميكنه . د صورتي كه ميشه همون برنامه رو با يك حلقه پياده كرد . تشخيص اينكه چه وقت ، كي و كجا بايد از حلقه ها و .. استفاده بشه ديگر بر ميگرده به خلاقيت شما و الگوريتمي كه استفاده ميكني.
والا من منظور دو پست اخر شما رو متوجه نشدم . ببين ،شما بجاي پرش به ادرس delay ميايي براش يك تابع تعريف ميكني . از ويژگي هاي خوب زبان هاي سط بالاتر همين چيز هاست وگرنه اگر بخوايي همش پرش كني كه ميشه اسمبلي !
وقتي شما يك تابع رو در يك تابع ديگه صدا ميزني ، متغير هاي و موقعيت كرسر در يك بسته ذخير ميشه و پردازنده ميره توي اون تابعي كه صدا زديش ، و اون رو اجرا ميكنه و در نتيجه اگر خروجي داشت ( return ) خروجي رو در جاي مناسب كه تعريف شده استفاده ميكنه . اين يه تعريف ساده بود .
ولي شما ميخواهي به جاي اينكه تابع رو صدا بزني ، مستقيما بهش پرش كني ! با اينكار فقط كدت رو شلوغ و ناخونا ميكني.
Electronics Art
03-31-2007, 06:07 PM
با مني يا با بابا برقي ؟!
---
ببين بابا برقي جان (اسمتو نميدونم :big_smile:) به نظر من استفاده بيش از اندازه از goto يكم برنامه رو شلوغ ميكنه . د صورتي كه ميشه همون برنامه رو با يك حلقه پياده كرد . تشخيص اينكه چه وقت ، كي و كجا بايد از حلقه ها و .. استفاده بشه ديگر بر ميگرده به خلاقيت شما و الگوريتمي كه استفاده ميكني.
والا من منظور دو پست اخر شما رو متوجه نشدم . ببين ،شما بجاي پرش به ادرس delay ميايي براش يك تابع تعريف ميكني . از ويژگي هاي خوب زبان هاي سط بالاتر همين چيز هاست وگرنه اگر بخوايي همش پرش كني كه ميشه اسمبلي !
وقتي شما يك تابع رو در يك تابع ديگه صدا ميزني ، متغير هاي و موقعيت كرسر در يك بسته ذخير ميشه و پردازنده ميره توي اون تابعي كه صدا زديش ، و اون رو اجرا ميكنه و در نتيجه اگر خروجي داشت ( return ) خروجي رو در جاي مناسب كه تعريف شده استفاده ميكنه . اين يه تعريف ساده بود .
ولي شما ميخواهي به جاي اينكه تابع رو صدا بزني ، مستقيما بهش پرش كني ! با اينكار فقط كدت رو شلوغ و ناخونا ميكني.
مخلص شما ، صابر هستم http://qsmile.com/qsimages/305.gif
ممنون
من بیشتر من باب مقایسه گفتم
چون همون طور که خودت میدونی کد نویسی تو بیسیک خیلی راحت ، سریع و آسون هستش
در حالی که تو سی قضیه یه خورده فرق میکنه منم که بیشتر از بیسیک استفاده میکنم و حالا
میخوام به سی سوئیچ کنم اگه فراخوانی تابع در سی همون کار gosub در بیسیک رو انجام میده
پس من هم باید از همون فراخوانی تابع استفاده کنم و راه دیگه ای نداره
amironline
04-01-2007, 06:59 AM
با مني يا با بابا برقي ؟!
---
ببين بابا برقي جان (اسمتو نميدونم :big_smile:) به نظر من استفاده بيش از اندازه از goto يكم برنامه رو شلوغ ميكنه . د صورتي كه ميشه همون برنامه رو با يك حلقه پياده كرد . تشخيص اينكه چه وقت ، كي و كجا بايد از حلقه ها و .. استفاده بشه ديگر بر ميگرده به خلاقيت شما و الگوريتمي كه استفاده ميكني.
والا من منظور دو پست اخر شما رو متوجه نشدم . ببين ،شما بجاي پرش به ادرس delay ميايي براش يك تابع تعريف ميكني . از ويژگي هاي خوب زبان هاي سط بالاتر همين چيز هاست وگرنه اگر بخوايي همش پرش كني كه ميشه اسمبلي !
وقتي شما يك تابع رو در يك تابع ديگه صدا ميزني ، متغير هاي و موقعيت كرسر در يك بسته ذخير ميشه و پردازنده ميره توي اون تابعي كه صدا زديش ، و اون رو اجرا ميكنه و در نتيجه اگر خروجي داشت ( return ) خروجي رو در جاي مناسب كه تعريف شده استفاده ميكنه . اين يه تعريف ساده بود .
ولي شما ميخواهي به جاي اينكه تابع رو صدا بزني ، مستقيما بهش پرش كني ! با اينكار فقط كدت رو شلوغ و ناخونا ميكني.
البت در اسمبلی هم میشه تابع و حلقه داشت
وی بولتین نسخه 3.8.0 Release Candidate 1, تمام حقوق محفوظ می باشد ©
2000-2009, نرم افزار تجاری شرکت Jelsoft