بایگانی برچسب: s

نوشتن Makefile برای تسریع فرایند ساخت

احتمال خیلی زیاد، همه ما یک بار توی عمرمون این صحنه رو دیدیم :

کد   
make
make install
make clean

خب ما وقتی یه سورس کدی رو دریافت میکنیم معمولا همراهشم یه Makefile داریم، سازنده اون برنامه، یا همون دوست عزیزی که سورس کد رو برامون نوشته، میتونست بگه کسی که دانلود کرد دیگه خودش بشینه یکی یکی کد ها رو کامپایل کنه و آخرش لینک کنه و این حرفا. ولی خب چون همه توانایی، وقت یا دانش لازم رو ندارن، معمولا یه Makefile نوشته میشه که این کارها درونش صورت بگیره! توی این پست، قراره ما یاد بگیریم که چطور Makefile بنویسیم. اول ببینیم make چیه؟ همونطور که میدونید make به معنای ساختنه. و نرم افزار make هم ساخته شده که بسازه. طبق تعریفی که توی ویکیپدیا و صفحه رسمیش هست، میگن که «نرم افزاریه که فایل های قابل اجرا از یک سری سورس تولید میکنه». البته کارهای دیگری هم میشه باهاش کرد! مثلا همون سورس ها و … رو باهاش منتقل کنیم به جایی که میخوایم و از این قبیل کارا. خب برای نوشتن یک Makefile نیاز به یک ادیتور متنی، نرم افزار make (دقت کنید این نرم افزار جزئی از استاندارد POSIX به حساب میاد و معمولا روی همه یونیکس-لایک ها نصبه)، یک محیط یونیکس لایک (اگر ویندوزی هستید Cygwin یا یک یونیکس لایک مجازی) نیاز داریم. همین؟ درسته همین. حالا با make قراره چی کار کنیم؟ اول بیایم یه Makefile ساده بنویسیم.

سناریوی کلی ما استفاده از نرم افزار echo هست که اونم در یونیکس لایک ها موجوده. ما میخوایم با استفاده از make و echo پیام معروف Hello, World رو نشون بدیم :

کد   
all:
	echo "Hello, World"

خب اینجا دو تا توضیح داریم :

یکی این که all چیه؟ این all یه سوییچ عمومی هست که توی همه Makefile ها موجوده. وقتی که شما صرفا تایپ کنید make هرچی که به این سوییچ گفته شده اجرا میشه، حالا میتونه روی فایل خاصی تغییر اعمال کنه یا نه، مثل ما صرفا یکی از برنامه ها رو فراخوانی کنه. و این که اون فاصله زیاد برای چیه؟ هر وقت نوشتید all (یا هر سوییچ دیگه ای) ، کافیه بیاید خط بعدی و Tab رو بزنید (دقت کنید مطلقا از Space استفاده نکنید چون با هم فرق دارن!) و دستور مورد نظرتون رو وارد کنید!. الان میتونید این تکه کد رو در یک فایل به اسم Makefile ذخیره کنید و بعدش تایپ کنید make و نتیجه رو ببینید! خواهید دید اول دستوری که بهش دادیم و سپس نتیجش رو نشون میده.

بسیار خوب! بیایم یک سناریوی دیگه پیاده کنیم. فرض کنیم شما اومدید :

یک برنامه به زبان C نوشتید، و الان میخواید اون رو کامپایل کنید، در یک دایرکتوری خاص به اسم path (که زیرشاخه دایرکتوری Root هست) قرار بدید، و سپس با یک دستور فایل باینری رو از دایرکتوری سورس حذف کنید. 

قطعا به صورت دستی هم میشه انجام داد، ولی خب منطقی ترش اینه که بیایم و از Makefile استفاده کنیم! فرض میکنیم اسم سورس شما src.c هست و در دایرکتوری ای قرار داره! خب میک فایل ما به این شکل میشه :

کد   
all: src.c
	gcc -o src src.c
 
install: src
	cp -v src /path
 
clean: src
	rm -v src

خب برای این که اینجا، ما سوییچ های all و install و clean رو روی فایلهای مورد نظرمون اعمال کنیم، اسم فایل های مورد نظر رو جلوی سوییچ ها قرار دادیم. توی all میاد از src.c یک فایل باینری به اسم src میسازه! توی install هم اون باینری رو کپی میکنه توی path (البته چون path زیرشاخه دایرکتوری ریشه ماست، باید make رو با sudo اجرا کنید و فکر کنم ترکیب sudo و make و install شدیدا براتون آشناس 😀 )، توی clean هم اومدیم اون فایل باینری رو پاک کردیم! به همین سادگی!

توی این پست سعی کردم تا حد امکان، ساده توضیح بدم چرا که واقعا ساده تر از این نمیشد make رو توضیح داد. البته میشه Makefile های بسیار پیچیده تری هم نوشت که همه می بینیم هستن! مثلا Makefile های FreeBSD هر کدوم غولی به حساب میان. ولی برای پروژه های ساده، خوندن و دونستن همین پست هم کافیه.

امیدوارم که این پست به دردتون خورده باشه، موفق باشید 🙂

Share

نوشتن یک سیستم عامل ساده – قسمت دوم

در مقاله قبلی، در مورد نمایش یک حرف روی مانیتور صحبت شد. اما یک حرف کافی نیست. حتی نمیشه به صورت حرف به حرف کلمات و جملات رو نشون داد چون واقعا کار سختیه. ما میخوایم یک پیغام (مثل Hello World) رو موقع بوت شدن سیستم عاملمون شاهد باشیم. پس باید چه کنیم؟ یک راه حل اینه که از یک ویژگی ای در زبان مورد نظر (اینجا اسمبلی) استفاده کنیم که بتونه یک رشته رو چاپ کنه. طبیعتا اسمبلی به طور پیشفرض دستوری مثل cout نداره و ما مجبوریم که خودمون اون رو به cout بیاریم. در این قسمت از مقالات «نوشتن یک سیستم عامل ساده» به این میپردازیم که چطور سیستم عامل ۱۶ بیتی ما، یک یا چند جمله رو نشونمون بده! در این قسمت علاوه بر رجیستر AX از سایر رجیستر ها هم استفاده خواهیم کرد. ممکنه بپرسید چرا؟ جواب سوالتون رو توی متن میگیرید!

خب فایل my16bitos.asm رو باز کنید. کل محتواش رو پاک کنید و این رو جایگزینش کنید :

کد   
org 0x7c00
bits 16
 
mov ax, 0
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7c00
 
mov si, welcome 
call print_string 
 
mov si, about
call print_string
 
welcome db  'Welcome to my OS', 0x0d, 0x0a, 0
about db  'Written in 16-bit real mode', 0x0d, 0x0a, 0
 
print_string:
 lodsb
 or al, al
 jz .done 
 
 mov ah, 0x0e
 int 0x10
 
  jmp print_string
 
 
 .done:
   ret
 
times 510-($-$$) db 0
dw 0xaa55

دیدید ؟ کد خیلی طولانی تر شده نسبت به قبل. طبیعیه چون که ما یه تابع تعریف کردیم و از یه سری چیزای جدید هم استفاده کردیم. خب آماده اید؟ میریم که بخش به بخش سیستم عامل کوچولوی خودمون رو بررسی کنیم!

کد   
org 0x7c00
bits 16

این قسمت، برای اینه که اولا ، اسمبلر آدرس ها رو بفهمه، ثانیا بفهمه که کد چند بیتیه. در آینده کد ما ۳۲ بیت خواهد شد و این بخش هم تغییر خواهد کرد. ولی فعلا تا آموزشهای بعدی همین برنامه رو داریم.

کد   
mov ax, 0
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7c00

این قسمت از کدمون هم مقدار صفر رو توی رجیستر AX میذاره و سپس اون رو به Data Segment, Extra Segment و Stack Segment منتقل میکنه (توجه کنید مستقیما نمیتونیم مقداری رو درون این رجیستر ها بذاریم. پس اول مقدار رو میذاریم توی AX سپس با MOV یکی یکی منتقل میکنیم). در آخر هم مقدار 7C00 هگزا دسیمال رو توی Stack Pointer قرار میدیم (استک از این آدرس شروع میکنه و میاد پایین).  این بخش داره مقدمات اجرای سیستم عامل ما رو فراهم میکنه.

بعد از اونا میرسیم به این بخش :

کد   
mov si, welcome 
call print_string 
 
mov si, about
call print_string
 
welcome db  'Welcome to my OS', 0x0d, 0x0a, 0
about db  'Written in 16-bit real mode', 0x0d, 0x0a, 0

این قسمت تقریبا ساده ترین قسمت برنامست. اومدیم welcome و about که دو رشته هستند رو ریختیم توی Source Index و سپس تابع print_string که کارش چاپ رشته هست هم صدا زدیم. با دستور db هم گفتیم که چه رشته هایی رو مد نظر داریم که چاپ شن. اون اعداد هگزاسیمال بعد از متغیر ها هم معادل New Line هستند (مثلا مقدار n در دستورات بک اسلش در C ).

بعد از این جنگولک بازیا ( 😀 ) میرسیم به کار اصلیمون یعنی نوشتن تابع print_string . این تابع نسبتا سادس ولی خب نیاز به توضیح داره چون دستوراتی رو استفاده کردیم که توی مطلب قبلی نبودن :

کد   
print_string:
 lodsb
 or al, al
 jz .done 
 
 mov ah, 0x0e
 int 0x10
 
  jmp print_string
 
 
 .done:
   ret

خب اول اومدیم اسم تابع رو گذاشتیم print_string (شما میتونید هرچیزی دلتون میخواد بذارید، مثلا دوستی ممکنه بذاره cout که براش ملموس تره و …). بیایم ببینیم خط به خط تابع چه میکنه؟

اون lodsb یک بایت رو از SI میخونه ، بعد رجیستر AL با خودش از نظر منطقی OR میشه. در نهایت اگر نتیجه صفر شد میره به done که done هم همونطور که می بینید داره return میکنه و از تابع خارج میشه. اگر جواب صفر نشه، مقدار 0e هگزا دسیمال وارد AH میشه و سپس وقفه 10 هگزادسیمال که یکی از وقفه های بایوس هست اجرا میشه. در واقع 0e یکی از تابع های وقفه مورد نظر ماست. بعد از اون پرش رخ میده به print_string. در واقع ما یک حلقه نوشتیم که به تعداد کرکتر های رشتمون، تکرار میشه و رشته رو تکرار میکنه.

در نهایت هم باید به اسمبلر بفهمونیم که برناممون یک Boot Sector عه پس طبیعتا از این قطعه کد استفاده میکنیم که در مطلب قبلی توضیحش دادم :

کد   
times 510-($-$$) db 0
dw 0xaa55

خب الان یک سیستم عاملی داریم که میتونه یک رشته چاپ کنه. ولی هنوز نمیتونه چیزی رو از کاربر بگیره و بخونه. این مورد میره برای آموزش های بعدی. فعلا بیاید این کد رو توی ویرچوال باکس اجرا کنیم! برای اجرای این سیستم عامل کد های زیر رو به ترتیب توی ترمینال اجرا کنید :

کد   
nasm -f bin -o my16bitos.bin my16bitos.asm
dd if=my16bitos.bin of=my16bitos.img

بعد یک ماشین مجازی توی ویرچوال باکس ایجاد کنید، یک Floppy Controller بسازید و اولویت بوت رو بهش بدید. سپس img رو بدید به فلاپی کنترلر و سپس ماشین رو روشن کنید. باید چنین صحنه ای رو مشاهده کنید :

 

os

تبریک! شما تقریبا نصف بیشتر راه رو رفتید! در ادامه هم میرسیم به باقی ماجرا و نوشتن prompt و این چیزا!

موفق باشید 🙂

Share

پیاده سازی لیست پیوندی در روبی

لیست پیوندی، یکی از ساختمان داده هایی هست که معمولا توی درس ساختمان داده درس داده میشه (البته در مورد کاربردش در زندگی واقعی چیزی نمیدونم، ممنون میشم بهم بگید) و خب معمولا سر کلاس، توی زبانهایی مثل C یا ++C درس میدنش. اما من داشتم توی نت میگشتم و به این مقاله رسیدم. که این مقاله، توضیح داده چطور میشه توی روبی این ساختمان داده رو پیاده کرد. خب به صورت ساده میریم سراغ پیاده سازی و کم کم پیچیدش میکنیم.

کد   
class Node
 attr_accessor :node, :next
 
 def initialize(node)
  @node = node
 end
end

خب تا اینجا، عملکرد ساده لیست پیوندی رو داریم. همون node و next که next معمولا از جنس اشاره گره. خب ما قاعدتا یک متد دیگری هم نیاز داریم. متدی که نیاز داریم، متدیه که بهمون بگه چیا توی لیستمون ذخیره کردیم. اصولا یکی از مهم ترین متد هاییه که میتونیم توی این کلاس، اضافه کنیم. متد رو به این شکل مینویسیم :

کد   
def self.node_list(node, msg = nil)
    msg ||= ""
    return msg[0..-4] if node.nil?
    node_list(node.next, msg << "#{node.node} -> ")
  end

بسیار خوب! حالا یک متدی مینویسیم که این لیست رو برای ما، برعکس کنه. گرچه چنین متدی نیاز نیست، اما چون توی روبی از این متد برای هش ها و لیست ها (آرایه ها) استفاده شده، بهتره ما هم به لینک لیستمون اضافش کنیم. خب یک متد هم به اسم Reverse ایجاد میکنیم به این شکل:

کد   
def self.reverse(node)
    return node if node.next.nil?
 
    head, swap, node.next = node.next, node, nil
    link = head.next
 
    while link != nil
      head.next = swap
      swap = head
      head = link
      link = link.next
    end
 
    head.next = swap
    head
  end

حالا میتونیم با استفاده از این کلاس، از لیست های پیوندی استفاده کنیم. البته دقت کنید که ما در اینجا در مورد حذف و اضافه کردن Node ها حرفی نزدیم. بلکه صرفا نمایش و معکوس کردن لیست رو بررسی کردیم. امیدوارم کد به کمکتون اومده باشه :).

Share

رویای کریستالی برنامه نویسانه

خب، اول از همه بگم که نمیدونستم چه عنوانی رو باید انتخاب میکردم، و طبق فرمول «احمقانه ترین ایده ممکن» این عنوان رو روی پست گذاشتم. بگذریم، توی این پست میخوام یه پدیده جدید و خیلی خوب رو معرفی کنم. میدونید که من مدت زیادی هست که روبی کار شدم ( و حتی پایگاهی برای توسعه دهندگان روبی ایجاد کردم)  روبی زبان خیلی خوبیه ولی خب قاعدتا نمیشه به نیتیو کد تبدیلش کرد. همونطور که پایتون و … نمیشه نیتیو کد کامپایل کرد. اما با یه چیزی رو به رو شدم که دقیقا خود روبی بود، ولی نیتیو کد میشد. من که بهش سلام کردم، شما هم بهش سلام کنید. زبان برنامه نویسی کریستال یک زبان ruby – inspired هست که کاملا کامپایلری عمل میکنه. سینتکس کاملا سینتکس روبی هست و از این بابت خیالتون راحت باشه که اگر روبی بلدید، یاد گیری این زبان براتون چند دقیقه بیشتر زمان نخواهد برد. اجازه بدید چند مثال رو بررسی کنیم.

برنامه Hello World

کد   
puts "Hello, World"

 

چقدر فرق با روبی حس کردید؟ درسته! هیچ فرقی با روبی نداره. مثالهای بعدی هم هیچ فرقی ندارند.

برنامه شرطی (چک کردن سن قانونی)

کد   
if age >= 18
 puts "Legal"
else 
 puts "Not Legal"
end

 

استفاده از حلقه (برنامه چاپ اعداد ۰ تا ۱۰)

کد   
n = 0
while n <= 10
 puts n
 n += 1
end

 

برنامه شیء گرا (نوشتن کلاس Greeter )

کد   
class Greeter
 def initialize(name)
  @name = name
 end
 
 def say_hi
  puts "Hello, I am #{@name}"
 end
end

 

کد ها رو دیدید؟ خیلی خوب! اگر دوست دارید که این ها رو به نیتیو کد تبدیل کنید همین الان به وبسایت کریستال (که ابتدای پست لینک دادم) مراجعه کنید و شروع به خوندن داکیومنت هاش کنید. مطمئنا کوچکترین تفاوتی در ظاهر با روبی نداره و از این جهت، روبیست ها میتونن به سادگی یادش بگیرند.

Share

نوشتن یک Data Parser ساده

چندین پست قبل، در مورد نوشتن یک زبان برنامه سازی ، مطلبی نوشته بودم. در این مطلب قصد داریم یکی از بخشهای مهم هر زبان یعنی Parser رو بررسی کنیم. اگر یک جست و جوی ساده در اینترنت انجام دهید، حتما خواهید دید که اکثر آموزشهای ساخت زبان برنامه سازی، عملیات parse کردن داده رو با parser generator های موجود مثل bison و … انجام دادن. اما چرا اون رو خودمون ننویسیم؟

برای نوشتن یک Parser ساده تنها نیاز داریم به این که از Regex ها استفاده کنیم. البته، چیزی که در این مطلب نوشته میشه به هیچ وجه شما رو برنامه نویس نمی‌کنه، فقط ممکنه راه رو برای برنامه نویس شدن شما باز کنه.

خب، بریم سر اصل مطلب. میشه گفت تقریبا همه با زبان Lisp و Scheme و سینتکسشون آشنا میشن. این زبان ها سینتکس های جالبی دارن و از همه مهم تر این سینتکس ها نسبتا راحته، و در همان نتایج جست و جو، شما هزاران آموزش پیاده سازی Lisp و Scheme خواهید دید. یک عملیات ساده در Lisp و Scheme به این شکله :

کد   
(+ 1 2)

خب ساختار پرانتز مبنا، باعث میشه کار ما برای بازسازی عملیات های ساده در این زبان ها، بسیار بسیار ساده تر بشه. بیایم اول ببینیم که دیتا پارسر ما باید چه کنه؟

  1. باید این خط از برنامه بهش داده بشه
  2. باید اون رو تجزیه تحلیل کنه و انواع داده ای رو جدا کنه
  3. عملگر رو تشخیص بده
  4. عملیات رو انجام بده و خروجی مناسب رو بگردونه

خب، ما میخوایم نوع داده ایمون عدد باشه، حرف باشه، و بعد از اولین پرانتز، عملگر تعریف شه.

برای این کار، ابتدا دستورات زیر رو در نظر میگیریم :

کد   
( + 1 2 )
( display 'Hello')

خب، الان باید یه تابع کوچولو بنویسیم که نوع داده ای رو بهمون نشون بده. این تابع رو من توی روبی مینویسم و به این شکل در میاد :

کد   
def parse(str)
 str = str.split(' ')
 str[1] = str[1].to_sym
 for i in str
  if /[a-zA-Z]/ === i
   puts "#{i} is STRING"
  elsif /[0-9]/ === i
   puts "#{i} is NUMBER"
  elsif /[:a-z\+\-]/ === i
   puts "#{i} is OPERATOR"
  else
   puts "#{i} is not defined}
  end
end
end

ابتدا، تمام اعضای یک رشته که با فاصله از هم قرار گرفته اند را جدا کردیم (در واقع فاصله ای که در قطعه کد Scheme قرار داده شده، برای Parser ما مهم است) ، سپس با یک دستور شرطی نوع آن را بررسی کردیم. عضو شماره ۱ هر آرایه هم به یک Symbol تبدیل شده است (بعدها سمبل ها را بعنوان اوپراتور ها استفاده خواهیم نمود). بیاید این تابع را اجرا کنیم. آن هم با دو دستور داده شده.

نتیجه به این شکل خواهد بود :

Screenshot from 2015-08-21 19:16:40

همانگونه که شاهدید، پرانتز هارا نمیشناسد، display را هم به عنوان اوپراتور قبول ندارد، حال باید چه کرد؟ برای پرانتز ها باید دو شرط دیگر اضافه کنیم. پس برنامه ما به این شکل خواهد بود :

کد   
def parse(str)
 str = str.split(' ')
 str[1] = str[1].to_sym
 for i in str
  if /[a-zA-Z]/ === i
   puts "#{i} is STRING"
  elsif /[0-9]/ === i
   puts "#{i} is NUMBER"
  elsif /:[a-z\+\-]/ === i
   puts "#{i} is OPERATOR"
  elsif /\(/ === i
   puts "#{i} is LPAREN"
  elsif /\)/ === i 
   puts "#{i} is RPAREN"
  else
   puts "#{i} is not defined
  end
end
end

خب، کد جدید را تست میکنیم وبا تست کد جدید، شما شاهد نتیجه درست خواهید بود.

در این مطلب قصد آن بود که شما ببینید چگونه میتوان فهمید که زبان Lisp ، بررسی میکند که یک داده از چه نوعی است. برای پردازش دستورات درون یک repl هم کافیست تا با یک حلقه بی نهایت، دستوری مشابه دستور زیر بنویسید :

کد   
while true
 print "Lisp > "
 cmd = gets.chomp
 parse(cmd)
end

تبریک، شما یک دیتا پارسر نوشته اید. در مراحل بعدی، سعی میکنم تا توضیح دهم چگونه یک Lisp یا Scheme کوچک درست کنیم.

 

Share

به بهانه سه سالگی!

امروز وقتی داشتم هاست و دامنه رو تمدید میکردم، به تاریخ اولین فاکتور نگاه کردم، مرداد ماه ۹۱ اولین فاکتور بود و چهارمین فاکتور رو در چهارمین سال فعالیتم در وبلاگ نویسی، پرداخت کردم. با خودم گفتم چقدر سریع گذشت! حالا نمیخوام وارد ناله ها و بحث های فلسفی و خسته کنندگی همیشگی بشم. بیاید به وبلاگ، یه طور دیگه تبریک بگیم! تاحالا فکر کردید چرا اولین رشته ای که در یادگیری برنامه نویسی چاپ میکنید Happy Birthday نیست؟ خب بیاید این رو امروز چاپ کنیم! چندین زبان متفاوت از زبان هایی که قبلا در موردش بحث کردیم، امروز سوژه پستمونن. زبان هایی که مدت زیادی سراغشون نرفته بودم، یا تازه باهاشون آشنا شدم. این هم میتونه بهانه خوبی باشه برای کمی کد زدن 🙂

۱. Lua

کد   
print('Happy Birthday!')

۲. Scheme

کد   
(display "Happy Birthday!")

۳. Erlang

کد   
io:fwrite("Happy Birthday").

۴. Javascript

کد   
alert("Happy Birthday");

۵. bash

کد   
echo "Happy Birthday"

بله و این هم زبان های جا افتاده و یا زبانهایی که برام نا آشنا بودن و تازه باهاشون آشنا شدم (البته فقط Scheme چنین حالتی رو برام داشت). توی این سه سال کلی بحث و مطلب و … از این بلاگ اومد بیرون، در کنارش، مدت نسبتا زیادی که به لطف مبین نت دوست داشتنی، نت درست و حسابی نداشتم، وبلاگ رول توییتر من رو هم داشت 😀 . حالا همه چیز رو به جای خود دارم استفاده میکنم، وبلاگ و توییتر و فیسبوک و … . یه سری کارها هم بود که قرار بود بعد از «کنکور» انجام بدم، خب الانم بعد کنکوره (تا زمانی که دوباره بخوام کنکور بدم برای ارشد 😀 ) و خب وقت زیاده برای انجامشون. چیزایی مثل پادکست و ویدئو کست و … . و در آخر هم تشکر میکنم از همه کسایی که این وبلاگ رو توی این ۳ سال، دنبال کردن و خوندن 🙂

 

Share

مقدمه ای بر پرل

در پست قبلی سعی کردم تا حدودی با پرل، آشناتون کنم. در این پست هم قصد دارم تا حدودی بیسیک های پرل رو بررسی کنم. همونطور که در پست قبلی اشاره کردم، پرل شباهت بسیار زیادی به C داره، البته این شباهت به php بیشتره تا C ، ولی خب معمولا بیان میشه که پرل سینتکس مشابه C داره. شما چه C بدونید و چه php ، کد زدن با پرل براتون بسیار راحت میشه. خب، بذارید از اول اول شروع کنیم، یعنی نصب و راه اندازی پرل روی یه سیستم لینوکسی، باید بگم که پرل معمولا روی توزیع های آماده (مثل اوبونتو) نصب شده، چرا که بخش عظیمی از کانفیگ فایلها، توسط اسکریپت های پرل انجام میشه. ولی روی توزیع هایی که آماده نیستند (مثل آرچ، جنتو و …) معمولا نصب نیست (ولی با نصب X نصب میشه و خیالتون از این بابت راحت باشه). حالا که خیالتون راحت شد که پرل رو دارید ( 😀 ) ، بیاید مثل دو پست قبلی، به دنیا سلام کنید. برای این کار، یه فایل به اسم hello.pl ایجاد کنید و داخلش بنویسید :

کد   
print "Hello, World!\n";

خب حالا بخوایم این کد رو آنالیز کنیم، print که مشخصه کارش چیه، یک رشته متنی رو چاپ میکنه که روبروش هم ما از ” استفاده کردیم، و یک متن نوشتیم. اون کرکتر بک اسلش هم یک خط جدید برامون ایجاد میکنه. اما میشه این رو طور دیگه هم نوشت. در واقع میتونید متن Hello, World رو درون یک متغیر بریزید و متغیر رو چاپ کنید!

کد   
$hello = "Hello, World";
 
print "$hello\n";

خب، از این کد میشه به شباهت زیاد پرل با php هم پی برد، پرل هرچیزی که با $ شروع بشه رو خودکار متغیر در نظر میگیره. خب انواع متغیر در پرل مثل سایر زبان ها، به عدد صحیح و ممیز شناور و … تقسیم میشه . در واقع در کد زیر مشخص میشه که این کد ها چی هستند :

کد   
$int = 1;
$float = 3.14;
$char = 'a';
$string = 'Hello, World';

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

Share

قطعه کد «سلام دنیا» در زبان های مورد علاقه من

خیلی وقت بود چنین قصدی رو داشتم، تا این که ابتکار علیرضا رو توی نوشتن پست اول وبلاگ دیدم. البته علیرضا اشاره ای نکرده که آیا این زبان ها، زبان مورد علاقش هستند، یا نه. ولی بهرحال ابتکار جالبی پشت این قضیه بود و من تصمیم گرفتم تا «سلام دنیا» رو در زبان های مورد علاقه خودم، و البته به سبک مورد علاقه خودم بنویسم.

۱. C .

میشه گفت، کیه که C رو نشناسه؟ در واقع یکی از زبانهایی که لازمه هرکسی تا حدودی بدوندش و باهاش کد بزنه. و این زبان بخاطر ذاتش، که سازندگی هست (تقریبا ۹۰٪ سیستم عاملهای موجود با C نوشته شدند).

کد   
#include <stdio.h>
 
int main(){
 puts("Hello, World!");
 return 0;
}

۲. ++C

خب اگر دقیقا از کتابخانه stdio استفاده کنید، هیچ فرقی با C نخواهد داشت. بنابراین از این کد می گذریم 🙂

۳. Java

جاوا، یک زبان شی گرا، همه منظوره و همه فن حریف به حساب میاد. کمتر کسی هست که این زبان رو نشناسه و حداقل گذرش یک بار به دباغ خونه جاوا نیفتاده باشه. آندروید، و برنامه هاش تحت این زبان توسعه داده میشن.

کد   
system.out.println("Hello, World!");

۴. Go

خب این زبان هم که یک زبان جدید و توسعه یافته توسط گوگل هست، شباهت بسیاری به C داره. اگر کمی وارد این زبان بشید، متوجه منظورم خواهید شد!

کد   
package main
import "fmt"
 
func main(){
 fmt.Println("Hello, World!")
 }

۵. Lisp

خب لیسپ هم یک زبان جالب و در نوع خودش باحاله! ممکنه کسی از این زبان استفاده نکنه، ولی دونستنش بد نیست. بخصوص این که خیلی از کورس های پیاده سازی زبان برنامه سازی در اینترنت، پیاده سازی لیسپ به یک زبان مطرح هست.

کد   
(print "Hello, World")

۶. Haskell

این زبان هم مدتها یکی از زبان های مورد علاقم بود. گرچه یه سری ایرادات نسبتا بزرگی داره، ولی خب برای درک الگوریتم یکی از بهترین هاست.

کد   
putStrLn("Hello, World!")

۷. Coffee Script

خب، در زمونه ای که حتی با جاوااسکریپت کامپایلر C می نویسن، بد نیست خودش یا یکی از فک و فامیلاش رو بلد باشیم! Coffee Script هم یکی دیگر از زبان های مورد علاقه من هست که یادش گرفتم و ازش استفاده میکنم.

کد   
console.log "Hello, World!"

۸. Ruby

خب حتما همه میدونید که این زبان، زبانی هست که خیلی کارها توش/براش کردم. از نوشتن کتاب راهنما گرفته تا نوشتن بات تلگرام ! به نظرم که اگر برنامه نویس با زبانش کنار بیاد، مشکلی نخواهد داشت در فان ساختن با زبان 🙂

کد   
puts "Hello, World!"

۹. Perl

این زبان، یکی از اولین تلاش هام برای اسکریپت نویس شدن بود. هنوزم که هنوزه دوستش دارم و گهگاهی اسکریپت های کوچیک و جمع و جور باهاش مینویسم.

کد   
print "Hello,World!\n";

۱۰. php

زبان مورد علاقه من در زمینه وب!

کد   
<?php
 echo "Hello, World!\n";
?>

۱۱ . Python

این زبان، تا حدودی مورد علاقم هست البته نسخه ۲ش. قدرتش هم تقریبا در همه زمینه ها، به اثبات رسیده

کد   
print 'Hello, World!'

 

خب، امیدوارم از این پستم خوشتون اومده باشه 🙂

Share

مقدمه ای بر شی گرایی در ++C

پس از مدتها دوباره تصمبم گرفتم دست به نوشتن در این وبلاگ ببرم، و گفتم چه بهتر که مطالب آموزشی و مفید بنویسم. الان مدتیه خودم هم با شی گرایی درگیرم، و گفتم چه بهتر که در مورد شی گرایی در ++C بنویسم. اول از همه، بگم که ++C واقعا زبان خوبیه و بهتره اگر میخواید شی گرایی رو از پایه یاد بگیرید، وارد این زبان بشید و بعدش سراغ جاوا یا هر زبان دیگری برید.

خب، در این مطلب صرفا ساخت کلاس و ایجاد یک شیء توسط کلاس رو بررسی خواهم کرد. باقی مفاهیم شیء گرایی رو هم خرد خرد در ادامه، در وبلاگ قرار خواهم داد.

ساخت کلاس

ساخت کلاس، به غایت ساده است. در واقع ساخت یک کلاس جدید به این شکل صورت میگیره :

کد   
class CLASSNAME {
 	....
 };

درون بدنه کلاس، میتونیم متغیرهای مربوط به کلاس، و متدها رو تعریف کنیم. که اونها هم سه نوع public و private و protected دارن. نوع public نوعیه که همه بهش دسترسی دارن. نوع private نوعی هست که فقط خود کلاس (و دوستانش! که بعدا مفهومشون رو توضیح خواهم داد) بهش دسترسی داره و نوع protected هم نوعیه که فقط و فقط خود کلاسمون بهشون دسترسی داره. هرچیزی که توی کلاس تعریف کنیم، پیشفرض private در نظر گرفته میشه. و خودمون میتونیم مشخص کنیم که private یا public یا protected باشن.

خب، فرض کنید الان میخوایم کلاسی بسازیم به اسم student و نیازه که اسم، فامیل و شمار دانشجویی واردش بشه. خیلی ساده کدش رو مینویسیم :

کد   
class Student {
	public:
	int number;
	string name;
	string lastname;
};

این کلاس، یک کلاس کامل به شمار میره. تنها چیزی که الان نیاز داریم، یک متد هست که این اطلاعات رو چاپ کنه! پس باید یک تابع درون کلاسمون تعریف کنیم تا این کار رو برامون انجام بده!

یعنی کلاس ما و متدش به این شکل تعریف میشن :

کد   
class Student {
	public:
	int number;
	string name;
	string lastname;
	void PrintInfo();
};
 
void Student::PrintInfo() {
	cout<<"Name: "<<student.name<<endl;
	cout<<"Last name: "<<student.lastname<<endl;
	cout<<"Number: "<<student.number<<endl;
}

گرچه میتوانیم متد را، درون خود کلاس هم تعریف کنیم. اما ترجیح با این است که متد بیرون از کلاس تعریف گردد. اکنون که یک کلاس کامل ساختیم، چطور است یک شیء نیز بسازیم و برنامه خود را تست کنیم؟

ساخت یک شیء

یادتان نرود که با تعریف کلاس ها، در واقع یک variable type جدید ساختید. پس تعریف یک شیء بسیار آسان است! چرا که صرفا کافیست اسم کلاس + اسم متغیر را نوشته و بعد برنامه را اجرا کنیم!

برنامه ما به این شکل در میاد آخر سر :

کد   
#include <iostream>
#include <string.h>
using namespace std;
class Student {
public:
int number;
string name;
string lastname;
void PrintInfo(void);
};
void Student::PrintInfo(void) {
cout<<"Name: "<<name<<endl;
cout<<"Last name: "<<lastname<<endl;
cout<<"Number: "<<number<<endl;
}
int main(){
Student s1;
s1.name = "Muhammadreza";
s1.lastname = "Haghiri";
s1.number = 12;
s1.PrintInfo();
return 0;
}

 

همونطور که می بینید، شیء s1 بلافاصله بعد از کلاس مربوطه، تولید شده. و بعد هم ویژگی های مربوطه اضافه شدند و بعدش هم متد مربوطه رو فراخوانی کردیم.

به همین سادگی!

تا آموزش بعدی، بدرود!

Share

لقمه را دور سر نچرخانیم – برعکس کردن یک رشته در سی شارپ

با سلام و عرض ادب خدمت خوانندگان وبلاگ. در این پست قصد دارم یکم سی شارپ رو بررسی کنم. سی شارپ، یکی از دلایل محبوب شدنش، اینه که سینتکس نسبتا ساده ای داره، ولی همین رو هم میشه پیچوند 🙂 .

مثلا این سوال رو در نظر بگیرید :

برنامه ای بنویسید که یک رشته کاراکتری از ورودی دریافت کرده و سپس آن را برعکس در خروجی قرار دهد. 

اگر فقط بخواهیم از System استفاده کنیم و یک تابع ساده بنویسیم، کد ما میشه این :

کد   
using System;
 
namespace ReverseName
{
	class MainClass
	{
		public static void NameReverse(string name){
			for (int i = name.Length; i > 0; i--){
				Console.Write(name.Substring(i-1, 1));
			}
		}
		public static void Main (string[] args)
		{
			//Challenge Accepted!
			Console.Write ("Enter a name: ");
			string n = Console.ReadLine ();
			NameReverse (n);
		}
	}
}

(اون Challenge Accepted داستانی داره که بعدا تعریف خواهم کرد 😀 ).

خب با یکم بررسی می بینید که این کد، خروجی به صورت رشته ای نداره (دستور Console.Write) و نمیشه ازش جاهایی که لازمه، استفاده کنیم. پس بهتره به جای System از System.Linq استفاده کنیم و کد رو خلاصه کنیم :

کد   
using System;
using System.Linq; 
namespace ForEach
{
	class MainClass
	{
		public static void Main (string[] args)
		{
			Console.Write ("Enter your name: "); 
			string name = Console.ReadLine (); 
			foreach (char c in name.Reverse()) {
				Console.Write (c);
			}
 
		}
	}
}

و اگر دقت کنید به جای اون for ، از foreach استفاده کردم که بسیار کار رو راحت تر کرده.

امیدوارم هر وقت خواستید کد بزنید، به این شکل و به خلاصه ترین شکل ممکن کدتون رو بنویسید.

موفق باشید 🙂

Share