رفتن به مطلب
جامعه‌ی برنامه‌نویسان مُدرن ایران

جستجو در تالارهای گفتگو

در حال نمایش نتایج برای برچسب های 'c'.



تنظیمات بیشتر جستجو

  • جستجو بر اساس برچسب

    برچسب ها را با , از یکدیگر جدا نمایید.
  • جستجو بر اساس نویسنده

نوع محتوا


وبلاگ‌ها

چیزی برای نمایش وجود ندارد

چیزی برای نمایش وجود ندارد

تالارهای گفتگو

  • انجمن‌های آی او استریم
    • اخبار و اعلامیه‌های سایت
    • اسناد و قوانین مرجع
    • رویداد‌ها و جلسات
    • معرفی محصولات نوشته شده‌ بومی
  • استارتاپی و کسب‌و‌کار
    • استارتاپ‌ها
    • سرمایه گذاری
    • شتاب دهنده‌ها
    • پارک‌های علم و فناوری و مراکز رشد
    • مصاحبه با استارت‌آپ‌ها
    • قوانین حقوقی
    • داستان‌های موفقیت
    • کارآفرینان و متخصصین
    • مشاوره اجرای کسب‌وکار
    • اخبار حوزه‌ی استارتا‌پی
    • آگهی‌های استخدامی
  • زبان‌های برنامه نویسی
    • برنامه نویسی در C و ‏++C
    • برنامه نویسی با Java
    • برنامه نویسی با JavaScript
    • برنامه نویسی با Go
    • برنامه نویسی با Python
    • برنامه نویسی با Delphi
    • برنامه نویسی با Ruby
    • برنامه نویسی با VB6
  • طراحی و توسعه وب
    • برنامه نویسی در PHP
    • برنامه نویسی در Asp.Net
    • برنامه نویسی با Node.JS
  • طراحی و توسعه وب اپلیکیشن‌ها
    • طراحی و توسعه در Angular
    • طراحی و توسعه در React.JS
    • طراحی و توسعه در Vue.JS
  • طراحی و توسعه موبایل و اِمبِد‌ها و تلوزیون‌ها
    • برنامه نویسی تحت محصولات اپل
    • برنامه نویسی تحت محصولات گوگل
    • طراحی و توسعه تحت محصولات دیگر
  • برنامه‌نویسی سطح پایین و سیستم عامل‌ها
    • سیستم عامل‌های آزاد
    • سیستم عامل‌های تجاری
  • بانک‌های اطلاعاتی
    • پایگاه داده MySQL
    • پایگاه داده PostgreSQL
    • پایگاه داده SQLite
    • پایگاه داده MongoDB
    • پایگاه داده SQL Server
    • دیگر پایگاه‌های داده
  • برنامه نویسی تحت محصولات اپل
    • محیط توسعه Xcode
    • برنامه نویسی با Objective-C
    • برنامه نویسی با Swift
  • برنامه نویسی تحت محصولات مایکروسافت
    • محیط توسعه Visual Studio
    • برنامه نویسی با #C
    • برنامه نویسی با Visual Basic.Net
    • طراحی و توسعه تحت Wpf
    • طراحی و توسعه تحت Universal و Fluent
  • طراحی و توسعه تجربه کاربری (UX) و رابط کاربری (UI)
    • طراحی رابط کاربری (UI)
    • طراحی تجربه کاربری (UX)
  • درخواست انجام پروژه (ویژه)
    • پروژه‌های منبع‌باز
  • سوالات و مباحث عامیانه
    • سوالات دانشجویی
    • فناوری و سخت افزار
    • سوالات مشاوره‌ای
  • سطل آشغال
    • سطل آشغال

Product Groups

  • کتاب‌ها و مقالات آموزشی

دسته ها

  • علمی
  • استارتاپی
  • برنامه‌نویسی
    • زبان‌های برنامه نویسی
    • معماری‌ها
  • کامپایلر و مفسر
  • محیط‌های توسعه
  • پلتفرم‌های توسعه
  • کدنویسی ایمن
  • فناوری‌ها
    • پردازش تصویر
    • اینترنت اشیاء
    • پردازش ابری (Cloud Computing)
    • چند سکویی (Cross-Platform)
    • بیگ دیتا (Big Data)
    • هوش مصنوعی (AI)
    • سخت افزار
    • نرم‌افزار و اپلیکیشن
    • اینترنت و شبکه
    • رمزنگاری
    • امبد‌ها (Embedded)
  • طراحی
    • تجربه کاربری
    • رابط کاربری

دسته ها

  • عمومی
  • گرافیکی
  • شبکه و ارتباطات

دسته ها

  • کامپایلر‌ها
  • محیط‌های توسعه
  • کتابخانه‌ها
  • ماژول‌ها و پلاگین‌ها
  • محصولات بومی
  • کتاب‌ها و مقالات
  • زبان‌ها و ابزار‌ها
  • طراحی و گرافیک

جستجو در ...

نمایش نتایجی که شامل ...


تاریخ ایجاد

  • شروع

    پایان


آخرین بروزرسانی

  • شروع

    پایان


فیلتر بر اساس تعداد ...

تاریخ عضویت

  • شروع

    پایان


گروه


شناسه گیت‌هاب


شناسه لینکدین


شهر

5 نتیجه پیدا شد

  1. با سلام و خسته نباشید چطوری میتوان دیتابیس موجود در شبکه اینترنت را خواند ودر کلاینت نشان داد دوستان اگه کسی اطلاعاتی در این مورد داره راهنمایی کنه
  2. با سلام ! دو قطعه برنامه ی زیر یکی آرایه ۱۰۰۰۰۰ تایی در حافظه Stack ساخته و به صورت Random مقداردهی شده و Sort میشود. کد اول به زبان ++C و با استاندارد 11 نوشته شده است که حدود ۷ دقیقه و کد دوم به زبان C نوشته شده است که حدود 1 دقیقه زمان میبرد ! CPU : Intel i7 M 620 (4) @ 2.667GHz آیا راهی برای بهینه سازی سرعت اجرای برنامه ی نوشته شده به زبان ++C هست ؟ کد نوشته به زبان ++C : #include <iostream> #include <functional> #include <utility> #include <array> #include <random> #include <chrono> const unsigned int MAX_LENGTH = 100000; bool Compare(unsigned int FirstVariable,unsigned int SecondVariable){ if(FirstVariable < SecondVariable) return true; return false; } void SortArray(std::array<unsigned int,MAX_LENGTH> &MyArray,std::function<bool(unsigned int,unsigned int)> function){ for(unsigned int index=0;index < MAX_LENGTH;++index) for(unsigned int AnotherIndex=0;AnotherIndex<MAX_LENGTH;++AnotherIndex) if(function(MyArray[index],MyArray[AnotherIndex])) std::swap(MyArray[index],MyArray[AnotherIndex]); } void PrintArrayElements(const std::array<unsigned int,MAX_LENGTH> &MyArray){ for(const auto &item : MyArray) std::cout << item << std::endl; } void RandomizeArray(std::array<unsigned int,MAX_LENGTH> &MyArray){ std::mt19937_64 Random(static_cast<int>(std::chrono::high_resolution_clock::now().time_since_epoch().count())); std::uniform_int_distribution<> RandomGenerator(0,1000); for(unsigned int index=0;index<MAX_LENGTH;++index) MyArray[index] = static_cast<unsigned int>(RandomGenerator(Random)); } int main(){ std::array<unsigned int,MAX_LENGTH> MyOrginalArray; RandomizeArray(MyOrginalArray); SortArray(MyOrginalArray,Compare); PrintArrayElements(MyOrginalArray); return 0x0000; } کد نوشته شده به زبان C : #include <stdio.h> #include <stdlib.h> #include <time.h> #include <stdbool.h> #define MAX_LENGTH 100000 bool Compare(unsigned int FirstVariable,unsigned int SecondVariable){ if(FirstVariable < SecondVariable) return true; return false; } void SortArray(unsigned int *MyArray,bool (*compare)(unsigned int,unsigned int)){ unsigned int tmp=0; for(unsigned int index=0;index < MAX_LENGTH;++index){ for(unsigned int AnotherIndex=0;AnotherIndex<MAX_LENGTH;++AnotherIndex){ if(compare(MyArray[index],MyArray[AnotherIndex])){ tmp = MyArray[index]; MyArray[index] = MyArray[AnotherIndex]; MyArray[AnotherIndex] = tmp; } } } } void RandomizeArray(unsigned int *MyArray){ srand(time(NULL)); for(unsigned int index=0;index < MAX_LENGTH ;++index) MyArray[index] = rand() % 1000; } void PrintArrayElements(unsigned int *MyArray){ for(unsigned int index=0;index<MAX_LENGTH;++index) fprintf(stdout,"%d\n",MyArray[index]); } int main(){ unsigned int Array[MAX_LENGTH]; RandomizeArray(Array); SortArray(Array,Compare); PrintArrayElements(Array); return 0x0000; }
  3. ادامه آموزش توابع کاربردی برای برنامه نویسی سوکت... تابع bind : int bind( SOCKET s, const struct sockaddr FAR *name, int namelen ); این تابع وظیفه پیوند دادن اطلاعات ارتباطی (مانند آدرس) را به سوکت تعریف شده دارد ودر برنامه سرور به کار می رود. آرگومان های این تابع به ترتیب زیر خواهد بود... آرگومان اول که متغیر نوع سوکت تعریف شده در برنامه است که با مقدار برگشتی تابع socket مقدار دهی شده است. آرگومان دوم آدرس محلی از حافظه است که متغیر ساختمان sockaddr_in در آنجا تعریف شده است (شرح این ساختمان در ادامه درج شده است.) آرگومان سوم هم اندازه متغیر ساختمان sockaddr_in است که می توانید با عملگر sizeof اندازه آن را بدست آورید. این تابع در صورت موفقیت مقدار صفر را بر می گرداند و در صورت عدم موفقیت SOCKET_ERROR را بر می گرداند. ساختمان داده ای sockAddr_in یک structure تعریف شده در هدر winsock.h است که محل نگه داری شماره پورت ارتباط و همچنین آدرس IP و دیگر اطلاعات است. struct sockaddr_in{ short sin_family, unsigned short sin_port, struct in_addr sin_addr, char sin_zero[8] }; عضوی به نام sin_family برای نگه داری نوع آدرس ارتباطی است که برای کاربرد های اینترنتی برابر ثابت AF_INET است. عضو sin_port مشخص کننده شماره پورت ارتباطی است. تابع تبدیل کننده htons(int portNumer) برای تبدیل عدد به نوع قابل فهم (BE1 to LE2) توسط ساختمان از تابع فوق استفاده می شود. و عضو sin_addr که خود یک ساختمان می باشد برای نگه داری آدرس IP که به صورت یک رشته کاراکتر مشخص می شود می باشد تابع تبدیل کننده inet_addr(char *ipaddress) برای تبدیل رشته کاراکتری که معرف آدرس IP است به نوع قابل فهم برای ساختمان داده از تابع فوق استفاده می کنیم. مثال کاربردی : sockaddr_in recSinIP; recSinIP.sin_family = AF_INET ;//set address family recSinIP.sin_port = htons(1362);//set port number recSinIP.sin_addr.S_un.s_addr = inet_addr("192.168.0.1"); نکته فنی : توجه داشته باشید که طبق تعاریف شبکه مقدار حداکثری تعریف پورت می تواند 65555 می باشد. که از این مقدار 1024 پورت اول توسط لایه های شبکه رزرو شده اند بنابراین شما نمی توانید از آنها استفاده نمایید. مانند پورت 80 که مختص به پروتکل HTTP می باشد. تابع listen : int listen( SOCKET s, int backlog ); تابع listen وظیفه گوش دادن به خط را در برنامه سرور به عهده دارد توجه داشته باشید که این تابع فقط در برنامه سرور کاربرد دارد. شرح آرگومان ها: آرگومان اول S که متغیر سوکت تعریف شده در برنامه می باشد. آرگومان دوم backlog هم تعداد صف های درخواستی است که به سیستم در یک زمان درخواست ارتباط داده اند و سیستم می تواند آنها را به حالت معلق نگه دارد این آرگومان می تواند برابر ثابت SOMAXCONN باشد. این تابع در صورت موفقیت صفر و درصورت بروز خطا ثابتی برابر با SOCKET_ERROR را برمی گرداند. تابع accept : SOCKET accept( SOCKET s, struct sockaddr FAR *addr, int FAR *addrlen ); این تابع برای قبول درخواست اتصال بعد از تابع listen استفاده می شود. آرگومان های این تابع مانند تابع bind می باشد با این تفاوت که در آرگومان addr مشخصات ماشین متصل شده به سرور قرار می گیرد. آرگومان addrlen اندازه ساختمانی که این اطلاعات را نگهداری می کنند را مشخص می کند. این تابع در صورت موفقیت مقدار برگشتیش توصیفات مربوط به سوکت ماشین راه دور مورد نظر ماست و در صورت بروز خطا ثابتی به نام INVALID_SOCKET را بر می گرداند. تابع connect : int connect( SOCKET s, const struct sockaddr FAR *name, int namelen ); تابع connect وظیفه برقراری ارتباط را با برنامه سرور بر عهده دارد و آرگومان های آن به شرح زیر می باشد: آرگومان اول s که از نوع سوکت می باشد وهمان مقدار برگشتی تابع socket می باشد. آرگومان دوم هم که از نوع sockAddr_in می باشد. و آرگومان آخر تابع connect یعنی namelen اندازه ساختمان داده sockaddr_in است که می توان به جا مقدار آن نوشت : sizeof(sockaddr_in) این تابع در صورت موفقیت مقدار صفر و در صورت بروز خطا ثابتی برابر با SOCKET_ERROR را بر می گرداند. نکته فنی : همانطور که میدانید در کامپیوتر های امروزی کلمات در حافظه به صورت (LE(Little Endian ذخیره می شوند، یعنی بایت کم ارزش تر در خانه با شماره کوچکتر ذخیره می شود و بایت با ارزشتر در خانه با شماره بزرگتر ذخیره می شود. مثلا برای عدد هگز 3578H بایت کم ارزشتر برابر 78 وبایت پرارزشتر برابر عدد 35 است وترتیب قرار گرفتن آنها در حافظه به صورت زیر می باشد: خانه 89:35 خانه 89:34 خانه 89:33 خانه 89:32 همانطور که مشاهده میکنید بایت کم ارزشتر در آدرس 89:33 ذخیره شده و بایت با ارزشتر در خانه 89:34 ذخیره شده است کامپیوترهای معمول بدین صورت کلمات را در حافظه ذخیره میکنند اما در پشته TCP/IP به صورت عکس عمل می شوند یعنی از نوع (BE(Big Endian پشتیبانی می شود به بیان دقیق تر باید ترتیب بایت ها در حافظه درست باشد یعنی بایت با ارزشتر در آدرس کوچکتر و بایت کم ارزشتر در آدرس بزرگترذخیره شود مثلا برای عدد 3578H مانند شکل زیر عمل می شود: خانه 89:32 خانه 89:33 خانه 89:34 خانه 89:35 البته باید توجه داشته باشید که فقط ما باید ورودی های هدر TCP/IP را به نوع (BE(Big Endian تبدیل کنیم یعنی آدرس IP و شماره پورت وکلا اطلاعاتی که تحت شبکه ارسال می شوند. دیگر ثوابت به طور خودکار در تمامی کامپیوترها به صورت صحیح قرار دارند و دیگری نیازی به تنظیم ما ندارند. //برمی گرداند BE این تابع آرگومان خود را که یک عدد دوبایتی است به حالت u_short htons( u_short hostshort ); //برمی گرداند BE این تابع آرگومان خود را که یک عدد چهار بایتی است را به حالت u_long htonl( u_long hostlong ); //برمی گرداند LE این تابع آرگومان خود را که یک عدد دوبایتی است به حالت u_short ntohs( u_short netshort ); //برمی گرداند LE این تابع آرگومان خود را که یک عدد چهار بایتی است را به حالت u_long ntohl( u_long netlong ); //که معرف آدرس آی پی است را دریافت میکند ویک عدد چهار بایتی (a.b.c.d)این تابع یک رشته کاراکتر //بر می گرداند در صورتی که آدرس آی پی نامعتبر باشد یا تابع عملیات خود را با موقیت انجام BE از نوع //توسط تابع برگردانده می شود INADDR_NONE ندهد ثابت unsigned long int inet_addr( const char FAR *cp ) همچنان ادامه خواهد داشت...
  4. با سلام هدف من از تهیه این آموزش شناخت کلی درباره (Socket Programming) که بسیار وسیع هست، والبته برای خیلی از برنامه نویسها هم همیشه جذاب بوده که بتوانند برنامه های تحت شبکه بنویسند بوده است. و از آنجاییکه با فراگیری برنامه نویسی سوکت در زبان C قادر خواهید بود، برنامه هایی در زمینه های بسیار تخصصی مانند (Intrusion Detect system) سیستم های تست نفوذ، ابزارهای (sniff) تحت نظرقرار دادن پکت ها، تا برنامه های ساده ای مانند چت و نمایش فیلم های آنلاین و خرید های مجازی و ... را انجام دهید. البته ما دراین آموزش سعی بر آن خواهیم داشت که بیشتر به نکات کاربردی درباره سوکت، که اغلب خود من از آنها در پروژه هایم استفاده کرده ام اشاره داشته باشیم. سوکت (Socket) چیست؟ با یک بیان ساده می توان گفت که سوکت به ترتیب یک آدرس ماشین IP ویک شماره درگاه Port گفته می شود. در برقراری ارتباط بین کامپیوترها در یک شبکه دوچیز بسیار مهم است. 1- آدرس ماشینی که می خواهیم اطلاعاتی از آن بگیریم ویا به آن ارسال کنیم. 2- برنامه ای از آن ماشین که در خواست اطلاعات کرده یا اینکه می خواهیم اطلاعاتی از آن برنامه کسب کنیم این دو یعنی آدرس ماشین وشماره برنامه به وسیله سوکت در شبکه مشخص می شوند. WinSock چیست؟ Winsock یا Windows Socket یک رویه (Interface) برنامه نویسی است که در غالب یک DLL در سیستم عامل ویندوز برای برنامه نویسی شبکه و ساخت برنامه هایی که بتوانند با شبکه محاوره داشته باشند معرفی شده است. ارتباط مابین دوکامپیوتر می تواند به یکی از دوصورت زیر باشد: - اتصال گرا (Connection Oriented) - غیر اتصال گرا (Connection Less) در سیستم اتصال گرا ابتدا درخواست اتصال ارسال شده و درصورت موافقت طرف مقابل ارتباط برقرار می شود.به این تکنیک Data Stream نیز گفته می شود. اما در سیستم غیر اتصال گرا بدون نیاز به موافقت طرف مقابل بسته ها ارسال می شوند به این تکنیک Data Gram نیز می گویند. TCP/UDP : در پشته پروتکلی TCP/IP دونوع ارتباط می توان با کامپیوتر دور ایجاد کرد: - اتصال به کامپیوتر راه دور به وسیله سوکت Data Stream. - اتصال به کامپیوتر راه دور به وسیله سوکت Data Gram. به طورخلاصه به نوع ارتباط اول (اتصال گرا) ارتباط از نوع TCP گفته می شود. واگر نوع برقراری ارتباط به حالت (غیر اتصال گرا ) باشد به آن UDP گفته می شود. دوستان بهتره هست قبلا حتما مدل مرجع OSI برای شناخت بهتر لایه های شبکه را مطالعه نمایید. به علت مباحث تکنیکی و کمی هم پیچیده مدل OSI ما در این آموزش وارد جزئیات نخواهیم شد. تحقیق درباره آن را به خودتون واگذار میکنم. معرفی توابع مهم مورد استفاده در برنامه نویسی TCPIP با زبان C کتابخانه کار با سوکت های در زبان C می تواند از سیستم عاملی به سیستم عاملی دیگر متفاوت باشد. همینطور از سخت افزاری به سخت افزاری دیگر به عنوان مثال برای برنامه نویسی شبکه در سیستم عامل ویندوز ما از هدر فایل winsock2.h استفاده می کنیم که خود نگارشهای مختلفی دارد وبرای برنامه نویسی شبکه در سیستم عامل های خانواده NIX* از هدر فایل sys/socket.h , sys/type.h و هدرهای دیگر استفاده می کنیم که البته می توان با اقدامی هوشمندانه توسط راهنمای کامپایلر نوع سیستم عامل را تشخیص داد وبعد هدر های مربوط به هر سیستم عامل را مورد استفاده قرارداد. البته باید عرض کنم که توابع مورد استفاده در همه انواع هدرها یکسان می باشند، مگر در معدود مواردی که هر کجا احساس نیاز شود ذکر خواهند شد. شرح توابع مهم موجود در هدر فایل winsock2.h int WSAStartup( WORD wVersionRequested , LPWSADATA lpWSAData ); این تابع برای آماده سازی و بار گذاری اولیه سیستم عامل برای اجرای برنامه تحت شبکه می باشد. آرگومان های آن عبارتند از : wVersionRequested شماره نگارش هدر winsock.h است که برای تبدیل این شماره به نوع WORD می توان از ماکرو makeword استفاده کرد. نکته فنی : به هر 4 بیت یک NIBBLE گفته می شود. وبه هر 8 بیت یک BYTE گفته می شود. وبه هر 16 بیت یا دو بایت یک WORD گفته می شود. به عنوان مثال : WORD wVersionRequested=makeword(2,0); winsock1.1.h و برای نگارش WORD wVersionRequested=makeword(2,1); و آرگومان دوم یک متغیر از نوع ساختمان داده ای WSADATA می باشد که در هدر winsock تعریف شده است. اعضای این ساختمان و نحوه تعریف آن به این صورت است: typedef struct WSAData{ WORD wVersion; WORD wHighVersion; char szDescription[WSADESCRIPTION_LEN+1]; char szSystemStatus[WSASYS_STATUS_LEN+1]; unsigned short iMaxSockets; unsigned short iMaxUdpDg; char FAR* lpVendorInfo; } WSADATA , *LPWSADATA; مثال کاربرد : WSADATA wsaData; WORD wVersionRequested=makeword(2,0); WSAStatrtup(wVersionRequested,wsaData); این تابع در صورت موفقیت مقدار صفر را بر می گرداند و در صورت شکست کد خطای رخ داده را بر می گرداند. int WSACleanup(void); از این تابع برای اتمام بارگذاری مربوط به شکست سیستم عامل استفاده می شود. این تابع در صورت موفقیت مقدار صفر و در صورت بروز خطا ثابتی برابر با SOCKET_ERROR را برمی گرداند. تابع socket : SOCKET socket( int af, int type, int protocol ); از تابع فوق برای تعریف وایجاد یک پورت استفاده می کنیم .و مقدار برگشتی آن توصیف کننده پورت مورد نظر است آرگومانهای تابع به ترتیب از این قرار هستند: af - مشخص کننده نوع آدرس است که برای کاربری اینترنت برابر ثابت AF_INET است برای کنترل سوکت ها در یونیکس برابر ثابت AF_UNIX است و مقادیر دیگر... type - مشخص کننده نوع ارتباطها می باشد که برای ارتباط TCP ثابت SOCK_STREAM و برای یک ارتباط UDP برابر SOCK_DGRAM است. protocol - هم نماینگر نوع پروتکل انتخابی ماست برای یک ارتباط TCP برابر با ثابت IPPROTO_TCP یا مقدار عددی 0 وبرای UDP مقدار عددی 1 یا ثابت IPPROTO_UDP می باشد. این تابع در صورت موفقیت مقدار برگشتی اش توصیفات مربوط به سوکت مورد نظر ماست و در صورت بروز خطا ثابتی به نام INVALID_SOCKET را بر می گرداند. ادامه دارد...
  5. کامبیز اسدزاده

    حافظه اِستَک (Stack) و هیپ (Heap)

    در این مقاله من قصد دارم در رابطه با تفاوت‌های اختصاص دادن حافظه در اِستک و هیپ توضیحاتی دهم که بسیاری از علاقه‌مندان راجب آن‌ها سوال کرده اند. با توجه به اینکه، از اوایل سیستم‌های کامپیوتری این تمایز در این وجود داشته است که برنامه های اصلی در حافظه فقط خواندنی مانند ROM ٬ PROM و یا EEPROM نگه داری می‌شوند. به عنوان دیگر از زمانی که سیستم ها پیچیده تر شدند برنامه ها از حافظه های دیگری مانند RAM به جای اجرا در حافظه ROM استفاده کردند. این ایده به خاطر این بود که تعدادی از قسمت های حافظه مربوط به برنامه نباید تغییر یابند و در این حالت باید حفظ شوند. در این میان دو بخش .text و .rodata بخشی‌هایی از برنامه هستند که می‌تواند به بخش های دیگر برای وظایف خاص تقسیم شوند که در ادامه به آن‌ها اشاره شده است. بخش کد، به عنوان یک بخش متنی (.text) و یا به طور ساده به عنوان متن شناخته می‌شود. جایی است که بخشی از یک فایل شیء یا بخش مربوطه از فضای آدرس مجازی برنامه که حاوی دستورالعمل های اجرایی است و به طور کلی فقط خواندنی بوده و اندازه ثابتی دارد می‌باشد. بخش .bss که به عنوانی بخشی ویژه (محل نگه داری اطلاعات تخصیص داده نشده (مقدار دهی نشده)) محلی که متغیر‌های سراسری و ثابت با مقدار صفر شروع می‌شوند. بخش داده (.data) حاوی هر گونه متغیر سراسری و یا استاتیک که دارای یک مقدار از پیش تعریف شده هستند و می‌توانند اصلاح شوند. تصویر زیر طرح معمولی از یک حافظه برنامه ساده کامپیوتری را با متن٬ داده های مختلف٬ و بخش‌های استک و هیپ و bss را نشان می‌دهد. برای مثال در کد C به صورت زیر خواهد بود: int val = 3; char string[] = "Hello World"; مقادیر برای این نوع متغیر‌ها در ابتدا در حافظه فقط خواندنی ذخیره می‌شوند. (معمولا در داخل .text) و در زمان اجرای برنامه که به صورت روتین خواهد بود در بخش .data کپی می‌شوند. بخش BSS یا همان .BSS در برنامه نویسی کامپیوتری، نام .bss یا bss توسط بسیاری از کامپایلرها و لینکرها برای بخشی از دیتا سِگمنت (Data Segment) استفاده می‌شود که حاوی متغیر های استاتیک اختصاصی که تنها از بیت هایی با ارزش صفر شروع شده است می‌باشد. این بخش به عنوان BSS Section و یا BSS Segment شناخته می‌شود. به طور معمول فقط طول بخش bss نه data در فایل آبجکت ذخیره می‌شود. برای نمونه، یک متغیر به عنوان استاتیک تعریف شده است static int i; این در بخش BSS خواهد بود. حافظه هیپ (Heap) ناحیه هیپ (Heap) به طور رایج در ابتدای بخش‌های .bss و .data قرار گرفته است و به اندازه‌های آدرس بزرگتر قابل رشد است. ناحیه هیپ توسط توابع malloc, calloc, realloc و free مدیریت می‌شود که ممکن است توسط سیستم‌های brk و sbrk جهت تنظیم اندازه مورد استفاده قرار گیرد. ناحیه هیپ توسط تمامی نخ‌ها٬ کتابخانه‌های مشترک و ماژول‌های بارگذاری شده در یک فرآیند به اشتراک گذاشته می‌شود. به طور کلی حافطه Heap بخشی از حافظه کامپیوتر شما است که به صورت خودکار برای شما مدیریت نمی‌شود، و به صورت محکم و مطمئن توسط پردازنده مرکزی مدیریت نمی‌شود. آن بیشتر به عنوان یک ناحیه شناور بسیار بزرگی از حافظه است. برای اختصاص دادن حافظه در ناحیه هیپ شما باید از توابع malloc(), calloc() که توابعی از C هستند استفاده کنید. یکبار که شما حافظه ای را در ناحیه هیپ اختصاص دهید، جهت آزاد سازی آن باید خود مسئول باشید و با استفاده از تابع free() این کار را به صورت دستی جهت آزاد سازی حافظه اختصاص یافته شده انجام دهید. اگر شما در این کار موفق نباشید، برنامه شما در وضعیت نَشت حافظه (Memory Leak) قرار خواهد گرفت. این بدین معنی است که حافظه اختصاص یافته شده در هیپ هنوز خارح از دسترس قرار گرفته و مورد استفاده قرار نخواهد گرفت. این وضعیت همانند گرفتگی رَگ در بدن انسان است و حافظه نشت شده جهت عملیات در دسترس نخواهد بود. خوشبختانه ابزار‌هایی برای کمک کردن به شما در این زمینه موجود هستند که یکی از آن‌ها Valgrind نام دارد و شما می‌توانید در زمان اشکال زدائی از آن جهت تشخیص نواحی نشت دهنده حافظه استفاده کنید. بر خلاف حافظه اِستک (Stack) حافظه هیپ محدودیتی در اندازه متغیر‌ها ندارد (جدا از محدودیت آشکار فیزیکی در کامپیوتر شما). حافظه هیپ در خواندن کمی کُند تر از نوشتن نسبت به حافظه اِستک است، زیرا جهت دسترسی به آن‌ها در حافظه هیپ باید از اشاره گر استفاده شود. بر خلاف حافظه اِستک، متغیر‌هایی که در حافظه هیپ ساخته می‌شوند توسط هر تابعی در هر بخشی از برنامه شما در دسترس بوده و اساسا متغیر‌های تعریف شده در هیپ در دامنه سراسری قرار دارند. حافظه اِستک (Stack) ناحیه اِستک (Stack) شامل برنامه اِستک٬ با ساختار LIFO کوتاه‌ شده عبارت Last In First Out (آخرین ورودی از همه زودتر خارج می‌شود) به طور رایج در بالاترین بخش از حافظه قرار می‌گیرد. یک (اشاره گر پشته) در بالاترین قسمت اِستک قرار می‌گیرد. زمانی که تابعی فراخوانی می‌شود این تابع به همراه تمامی متغیرهای محلی خودش در داخل حافظه اِستک قرار می‌گیرد و با فراخوانی یک تابع جدید تابع جاری بر روی تابع قبلی قرار می‌گیرد و کار به همین صورت درباره دیگر توابع ادامه پیدا می‌کند. مزیت استفاده از حافظه اِستک در ذخیره متغیرها است، چرا که حافظه به صورت خودکار برای شما مدیریت می‌شود. شما نیازی برای اختصاص دادن حافظه به صورت دستی ندارید، یا نیازی به آزاد سازی حافظه ندارید. به طور کلی دلیل آن نیز این است که حافظه اِستک به اندازه کافی توسط پردازنده مرکزی بهینه و سازماندهی می‌شود. بنابراین خواندن و نوشتن در حافظه اِستک بسیار سریع است. کلید درک حافظه اِستک در این است که زمانی که تابع خارج می‌شود، تمامی متغیر‌های موجود در آن همراه با آن خارج و به پایان زندگی خود میرسند. بنابراین متغیر‌های موجود در حافظه اِستک به طور طبیعی به صورت محلی هستند. این مرتبط با مفهوم دامنه متغیر‌ها است که قبلا از آن یاد شده است، یا همان متغیر‌های محلی در مقابل متغیر‌های سراسری. یک اشکال رایج در برنامه نویسی C تلاش برای دسترسی به یک متغیر که در حافظه اِستک برای یک تابع درونی ساخته شده است می‌باشد. یعنی از یک مکان در برنامه شما به خارج از تابع (یعنی زمانی که آن تابع خارج شده باشد) رجوع می‌کند. یکی دیگر از ویژگی‌های حافظه اِستک که بهتر است به یاد داشته باشید این است که٬ محدودیت اندازه (نسبت به نوع سیستم عامل متفاوت) است. این مورد در حافظه هیپ صدق نمی‌کند. خلاصه ای از حافظه اِستک (Stack) حافظه اِستک متناسب با ورود و خروج توابع و متغیر‌های درونی آن‌ها افزایش و کاهش می‌یابد نیازی برای مدیریت دستی حافظه برای شما وجود ندارد٬ حافظه به طور خودکار برای متغیر‌ها اختصاص و در زمان نیاز به صورت خودکر آزاد می‌شود در اِستک اندازه محدود است متغیر‌های اِستک تنها در زمان اجرای تابع ساخته می‌شوند مزایا و معایب حافظه اِستک و هیپ حافظه اِستک (Stack) دسترسی بسیار سریع به متغیر‌ها نیازی برای باز پس گیری حافظه اختصاص یافته شده ندارید فضا در زمان مورد نیاز به اندازه کافی توسط پردازنده مرکزی مدیریت می‌شود، حافظه ای نشت نخواهد کرد متغیر‌ها فقط محلی هستند محدودیت در حافظه اِستک بسته به نوع سیستم عامل متفاوت است متغیر‌ها نمی‌توانند تغییر اندازه دهند حافظه هیپ (Heap) متغیر‌ها به صورت سراسری قابل دسترس هستند محدودیتی در اندازه حافظه وجود ندارد تضمینی برای حافظه مصرفی وجود ندارد، ممکن است حافظه در زمان‌های خاص از برنامه نشت کرده و حافظه اختصاص یافته شده برای استفاده در عملیات دیگر آزاد نخواهد شد شما باید حافظه را مدیریت کنید٬ شما باید مسئولیت آزاد سازی حافظه های اختصاص یافته شده به متغیر‌ها را بر عهده بگیرید اندازه متغیر‌ها می‌تواند توسط تابع realloc() تغییر یابد در اینجا یک برنامه کوتاه وجود دارد که در آن متغیرها در یک حافظه اِستک ایجاد شده اند. #include <stdio.h> double multiplyByTwo (double input) { double twice = input * 2.0; return twice; } int main (int argc, char *argv[]) { int age = 30; double salary = 12345.67; double myList[3] = {1.2, 2.3, 3.4}; printf("double your salary is %.3f\n", multiplyByTwo(salary)); return 0; } ما متغیر‌هایی را اعلان کرده ایم که یک int ، یک double و یک آرایه که سه نوع double دارد هستند. این متغیر‌ها داخل اِستک وارد و به زودی توسط تابع main در زمان اجرا حافظه مورد نیاز خود را دریافت خواهند کرد. زمانی که تابع main خارج می‌شود (برنامه متوقف می‌شود) این متغیر‌ها همگی از داخل حافظه اِستک خارج خواهند شد. به طور مشابه٬ در تابع multiplByTwo() متغیر twice که از نوع double است، داخل اِستک وارد شده و در زمان اجرای تابع multiplyByTwo() حافظه به آن اختصاص می‌یابد. زمانی که تابع فوق خارج شود یعنی به نقطه پایان اجرایی خود برسد، حافظه اختصاص یافته شده به متغیر‌های داخلی آن نیز آزاد خواهند شد. به طور خلاصه توجه داشته باشید که تمامی متغیر‌های محلی در این نوع تعریف تنها در طول زمان اجرایی زمانی تابع زنده هستند. به عنوان یک یادداشت جانبی، روشی برای نگه داری متغیر‌ها در حافظه اِستک وجود دارد، حتی در زمانی که تابع خارج می‌شود. آن روش توسط کلمه کلیدی static ممکن خواهد شد که در زمان اعلان متغیر استفاده می‌شود. متغیری که توسط کلمه کلیدی static تعریف می‌شود، بنابراین چیزی مانند متغیر از نوع سراسری خواهد بود، اما تنها در داخل تابعی که داخل آن ایجاد شده است قابل مشاهده خواهد بود. این یک ساختار عجیب و غریب است، که احتمالا به جز شرایط بسیار خاص نیازی به آن نباشد. نسخه دیگری از برنامه فوق در قالب حافظه هیپ به صورت زیر است: #include <stdio.h> #include <stdlib.h> double *multiplyByTwo (double *input) { double *twice = malloc(sizeof(double)); *twice = *input * 2.0; return twice; } int main (int argc, char *argv[]) { int *age = malloc(sizeof(int)); *age = 30; double *salary = malloc(sizeof(double)); *salary = 12345.67; double *myList = malloc(3 * sizeof(double)); myList[0] = 1.2; myList[1] = 2.3; myList[2] = 3.4; double *twiceSalary = multiplyByTwo(salary); printf("double your salary is %.3f\n", *twiceSalary); free(age); free(salary); free(myList); free(twiceSalary); return 0; } همانطور که می‌بینید، استفاده از malloc() برای تخصیص حافظه در حافظه Heap و استفاده از free() جهت آزاد سازی حافظه تخصیص یافته می‌باشد. این مواجه شدن چیز بسیار بزرگی محسوب نمی‌شود اما کمی مبهم است. چیز دیگری که باید به آن توجه داشته باشید علامت ستاره (*) است که در همه جای کد‌ها دیده می‌شود. اینها چه چیز‌هایی هستند؟ پاسخ این سوال این است : اینها اشاره گر هستند! توابع malloc() و calloc() و free() با اشاره‌گر‌هایی مواجه می‌شوند که مقادیرشان واقعی نیست. اشاره گر‌ها نوع داده ای خاصی در C هستند که آدرس حافظه مربوطه را بر می‌گردانند. در خط ۵ متغیر twice یک متغیر از نوع double نیست، اما اشاره به یک double دارد. آن آدرس حافظه ای است که نوع double در آن بلوک از حافظه ذخیره شده است. در ++C توسط کلمه کلیدی new که خود آن نیز یک اپراتور محسوب می‌شود می‌توان حافظه ای را در Heap اختصاص داد. به عنوان مثال: int* myInt = new int(256); آدرس‌های موجود در حافظه توسط اپراتور new به اشاره‌گر مربوطه پاس داده می‌شود. به مثال زیر توجه کنید٬ متغیر تعریف شده در حافظه اِستک قرار گرفته است: int variable = 256; سوالی که ممکن است افراد کنجکاو از خود بپرسند این است که چه زمانی از Stack و چه زمانی از Heap باید استفاده کنیم؟! خب پاسخ این سوال اینگونه خواهد بود٬ زمانی که شما نیاز به یک بلوک بسیار بزرگی از حافظه دارید٬ که در آن یک ساختار بزرگ یا یک ارایه بزرگی را ذخیره کنید و نیاز داشته باشید که متغیر‌های شما به مدت طولانی در سرتاسر برنامه شما در دسترس باشند در این صورت از حافظه Heap استفاده کنید. در صورتی که شما نیاز به متغیر‌های کوچکی دارید که تنها نیاز است در زمان اجرای تابع در دسترس باشند و قابلیت خواندن و نوشتن سریعتری داشته باشند از نوع حافظه Stack استفاده کنید. فقط فراموش نکنید که حافظه Heap تحت توابع molloc(), realloc(), calloc() و free() مدیریت می‌شوند. هرچند اشاره‌گر های هوشمند نیز در ++C وجود دارند اما در بسیاری از مواقع که نیاز است بسیار جزئی و حساس بر روی کد‌های خود کار کنید از مدیریت حافظه به صورت دستی استفاده کنید.
×