آموزش میکروبلیز قسمت پنجم : آموزش زبان برنامه‌نویسی C

0
96
آموزش زبان برنامه‌نویسی C
آموزش زبان برنامه‌نویسی C

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

کاراکتر در زبان برنامه‌نویسی‌C چیست؟

کاراکتر‌(char) یک نوع متغیر‌(Variable) در زبان برنامه‌نویسی‌C است که برای ذخیره تنها یک کاراکتر به‌کار می‌رود. منظور از کاراکتر در‌واقع، حروف الفبا، اعداد و علامت‌هایی است که در متن‌ها به‌کار می‌بریم. نکته‌ای که در استفاده‌از کاراکتر‌ها بسیار حائز اهمیت است، اندازه آن می‌باشد. که در قسمت “آموزش میکروبلیز قسمت سوم: آموزش زبان برنامه‌نویسی C” به این موضوع پرداختیم.

طرز‌صحیح استفاده‌از کاراکتر در زبان برنامه‌نویسی C به‌صورت‌زیر است:

char Character = 'B';

هشدار: در خط برنامه‌ای که نوشتیم فقط تنها کلمه‌ای که کلیدی است و باید باشد اسم char است و ما بقی همگی اسم‌هایی کاملا اختیاری هستند. هشدار: یک کاراکتر در بین دو علامت ‘ ‘ تعریف می‌شود(نباید علامت ” ” را به‌کار ببرید). هشدار: تلفظ صحیح کلمه Char به‌صورت کر است نه چر‌( لطفا درست تلفط کنید خودتونو مسخره می‌کنند خیرتونو می‌خوام اینجوری میگم).

آرایه در زبان برنامه‌نویسی C چیست؟

آرایه (Array)، تعدادی عنصر از یک نوع خاص هستند که با یک‌دیگر تعریف می‌شوند و بااستفاده‌از اندیس‌های‌(در ادامه توضیح می‌دهیم) متناظر آنها، می‌توانیم به آنها اشاره‌نماییم.

طرز صحیح تعریف آرایه در زبان برنامه‌نویسی C

نوع آرایه اسم آرایه [ اندازه آرایه];
double balance[10];

درصورتیکه بخواهیم آرایه را مقداردهی اولیه کنیم باید از علامت{} استفاده کنیم.

طرز صحیح مقدار دهی اولیه به متغیر در زبان برنامه‌نویسی C

روش اول:

double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};

در این روش اگر دقت‌کنید سایز آرایه که عدد۵ (تعداد اعضای آرایه) است مشخص‌شده‌است.

روش دوم:

double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0};

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

توصیه: ترجیحا اگر تعداد اعضای آرایه‌ای که تعریف می‌کنید زیاد بود نیازی نیست که حتما اندازه آن را بنوسید و دقیقا مانند روش دوم عمل‌کنید.

نحوه فراخوانی اعضای آرایه در زبان برنامه‌نویسی C

ابتدا نیاز است که با نحوه شماره‌گذاری‌(اندیس‌گذاری) آرایه‌ها آشنا شویم. برای درک این موضوع به تصویری که در ادامه قرار می‌دهیم دقت‌کنید.

آرایه در زبان C چیست؟
آرایه در زبان C چیست؟

 

اگر به تصویر دقت‌کنید دقیقا همان متغیری است که قبلا تعریف‌کرده‌ایم حال به شماره‌هایی‌(اندیس‌هایی) که در بالای هر خانه نوشته‌شده‌است دقت‌کنید می‌بینید که اولین خانه آرایه همیشه از صفر شروع می‌شود و بعد‌از آن شمارش به‌ترتیب انجام می‌گیرد. نتبجه مهم: در آرایه‌ها اولین عضو همیشه از عدد صفر شروع می‌شود. خب حالا باتوجه‌به اینکه با نحوه اندیس‌گذاری آرایه‌ها آشنا‌شدیم نوبت به استفاده‌از اعضای آرایه رسیده‌است که برای این‌کار کافی‌است به‌صورت دستور زیر عمل‌کنیم:

balance[4] = 50.0;

حال اگر به جدولی که در بالا قرار داده‌ایم دقت‌کنید می‌بینید که خانه چهارم متعلق به عدد ۵۰ است. دقت‌کنید که برای فراخوانی هر عضو از آرایه فقط کافی‌‌است که اندیس مربوطه آن‌را درون براکتی که آرایه را تعریف‌کرده‌ایم قرار دهیم.

تعریف آرایه چند‌بعدی در زبان برنامه‌نویسی C

تقریبا می‌توان گفت مثل آرایه تک‌بعدی است اما با این تفاوت که اعضای آن بسته به چندبعدی‌بودن آرایه متفاوت است. به فرمول‌زیر دقت‌کنید.

نوع اسم [اندازه آرایه شماره 1][اندازه آرایه شماره2]...[اندازه آرایه شماره n];

به‌طور‌مثال:

int threedim[5][10][4];

حال با تعریف‌بالا، می‌خواهیم آرایه دو‌بعدی را تعریف‌کنیم.

نوع آرایه اسم آرایه[ x ][ y ];

درواقع اگر به فرمول‌بالا نگاه‌کنیم می‌بینیم که دقیقا یک ماتریس تشکیل‌داده‌است. برای درک‌بهتر لطفا به تصویری که در ادامه قرار می‌دهیم دقت‌کنید.

تعریف آرایه‌ها در زبان برنامه‌نویسی C
تعریف آرایه‌ها در زبان برنامه‌نویسی C

 

اگر به جدول دقت‌کنید دقیقا متوجه خواهید شد که یک ماتریس تشکیل‌شده‌است که اگر با تعریف آرایه دوبعدی آنرا قیاس‌کنیم به این‌گونه است که مقدار X در واقع همان ROW و مقدار Y همان Column است. برای درک بهتر به مثال‌زیر توجه کنید.

int a[3][4] = { 
{0, 1, 2, 3} , /* initializers for row indexed by 0 */
{4, 5, 6, 7} , /* initializers for row indexed by 1 */
{8, 9, 10, 11} /* initializers for row indexed by 2 */
};

توصیه : نرم‌افزار متلب دارای ساختار ماتریسی است(دیگه متوجه داستان باشید که چقدر این مبحث مهمه)

دسترسی به اعضای آرایه دو بعدی در زبان برنامه‌نویسی C

int val = a[2][3];

تمرین: مقدار a چه عددی است؟ برای درک بهتر به مثال‌زیر توجه‌کنید.(تحلیلش با خودتون واقعا‌ساده است)

#include <stdio.h>

int main () {

/* an array with 5 rows and 2 columns*/
int a[5][2] = { {0,0}, {1,2}, {2,4}, {3,6},{4,8}};
int i, j;

/* output each array element's value */
for ( i = 0; i < 5; i++ ) {

for ( j = 0; j < 2; j++ ) {
printf("a[%d][%d] = %d\n", i,j, a[i][j] );
}
}

return 0;
}

قبل‌از اینکه به خروجی کد نگاه‌کنید توصیه می‌کنیم ابتدا خودتان خروجی را تحلیل‌کنید.

a[0][0]: 0
a[0][1]: 0
a[1][0]: 1
a[1][1]: 2
a[2][0]: 2
a[2][1]: 4
a[3][0]: 3
a[3][1]: 6
a[4][0]: 4
a[4][1]: 8

 

اشاره‌گر‌ها در آرایه‌ها

یکی‌از مباحثی که بسیار زیاد در برنامه‌نویسی از اهمیت زیادی برخوردار است بحث اشاره‌گر‌ها (Pointer) است که در بخش خودش به‌طور‌مفصل در این مورد صحبت‌خواهیم‌کرد ان‌شالله اما در این قسمت می‌خواهیم صرفا از اشاره‌گر‌ها برای ارتباط با آرایه‌ها صحبت‌کنیم.

نکته مهم این است که آرایه‌ها خود نوعی اشاره‌گر محسوب می‌شوند که ما از همین نکته می‌خواهیم در ادامه استفاده‌کنیم.

طرز‌استفاده‌از اشاره‌گر‌ها در آرایه‌ها

خب اگر به نکته‌ای که در بالا اشاره‌کردیم دقت‌کنیم می‌توانیم به‌صورت‌زیر عمل‌کنیم.

double *p;
double balance[10];

p = balance;

اجازه‌دهید این قسمت را با یک‌دیگر تحلیل‌کنیم. علامت * به معنی اشاره‌گر است که در اینجا اشاره‌گر P از نوع Double تعریف‌شده‌است. تعریف یک آرایه ۱۰عضوی با نام Balance که نکته جالب اینجا است که از نوع اشاره‌گر تعریف‌نشده‌است(معنیش اینکه خودش یک نوع اشاره‌گره وگرنه امکان نداشت بتونن اینجوری خوش‌و خرم کنار‌هم باشن)

نکته طلایی: باید و حتما نوع اشاره‌گر‌ها با یکدیگر یکی باشد به‌طور‌مثال نوع P و Balance هردو از نوع Double هستند.(درمورد تبدیل صریح و ضمنی هم در ادامه مقالات خواهیم گفت)

دسترسی به اعضای آرایه از‌طریق اشاره‌گر

اگر خاطرتان باشد در مورد اندیس‌های آرایه‌ها صحبت‌کردیم و به این نکته هم اشاره کردیم که اولین عضو آرایه از صفر شروع می‌شود. با این توضیحات به مثال‌زیر دقت‌کنید:

double balance[5] = {1000.0, 2.0, 3.4, 17.0, 50.0};
double *p;

تا این قسمت که چیز جدیدی را نگفته‌ایم و دقیقا یک آرایه ۵ عضوی و یک اشاره‌گر P تعریف کرده‌ایم. حالا برای دسترسی به هر عضو باید به‌صورت دستور زیر عمل‌کنیم:

*(p + 0) : 1000.0 
* (p + 1) : 2.0
* (p + 2) : 3.4
* (p + 3) : 17.0
* (p + 4) : 50.0

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

نوشتن توابع بر‌حسب آرایه‌ها

این بخش خود شامل ۳قسمت است که به‌صورت‌زیر تقسیم می‌شوند.(البته هنوز در‌مورد توابع صحبت نکرده‌ایم که در ادامه مقالات به‌طور‌مفصل به این مبحث خواهیم‌پرداخت نگران‌نباشید)

  • تابع اشاره‌گر با آرایه‌ها
  • تابع آرایه با اندازه محدود
  • تابع آرایه با اندازه نامحدود

تابع اشاره‌گر با آرایه‌ها

این تابع داری ورودی از نوع اشاره‌گر است که به‌صورت‌زیر تعریف می‌شود.

void myFunction(int *param) {
.
.
.
}

تابع آرایه با اندازه محدود

این تابع داری ورودی از نوع آرایه از نوع سایز محدود است که به‌صورت‌زیر تعریف می‌شود.

void myFunction(int param[10]) {
.
.
.
}

 

تابع آرایه با اندازه نامحدود

این تابع داری ورودی از نوع آرایه از نوع سایز نامحدود است که به‌صورت‌زیر تعریف می‌شود.

void myFunction(int param[]) {
.
.
.
}

خب حال می‌خواهیم با‌استفاده‌از دانشی که تاکنون نسبت به آرایه‌ها پیدا‌کردیم یک مثال کاربردی را انجام‌دهیم. مثال: تابعی بنوسید که اسم و سایز آرایه را به همراه تشخیص اعضای آرایه بدست آورد و درنهایت عمل میان‌گیری را انجام دهد.

double getAverage(int arr[], int size) {

int i;
double avg;
double sum = 0;

for (i = 0; i < size; ++i) {
sum += arr[i];
}

avg = sum / size;

return avg;
}

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

#include <stdio.h>

/* function declaration */
double getAverage(int arr[], int size);

int main () {

/* an int array with 5 elements */
int balance[5] = {1000, 2, 3, 17, 50};
double avg;

/* pass pointer to the array as an argument */
avg = getAverage( balance, 5 ) ;

/* output the returned value */
printf( "Average value is: %f ", avg );

return 0;
}

همانطورکه گفتیم اگر به کد دقت‌کنید ابتدا تابعی که نوشته‌بودیم را فراخوانی‌کردیم و درنهایت از آن در برنامه اصلی خود استفاده‌کردیم. در برنامه یک آرایه یک بعدی با نام Balance تعریف‌شده‌است که درنهایت توسط تابعی که فراخوانی‌کرده‌بودیم عمل میانگیری را انجام‌دادیم که درنهایت جواب به‌صورت‌زیر است:

Average value is: 214.400000

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

#include <stdio.h>

/* function to generate and return random numbers */
int * getRandom( ) {

static int r[10];
int i;

/* set the seed */
srand( (unsigned)time( NULL ) );

for ( i = 0; i < 10; ++i) {
r[i] = rand();
printf( "r[%d] = %d\n", i, r[i]);
}

return r;
}

/* main function to call above defined function */
int main () {

/* a pointer to an int */
int *p;
int i;

p = getRandom();

for ( i = 0; i < 10; i++ ) {
printf( "*(p + %d) : %d\n", i, *(p + i));
}

return 0;
}

خروجی کد هم به‌صورت‌زیر می‌باشد.

 r[0] = 313959809
r[1] = 1759055877
r[2] = 1113101911
r[3] = 2133832223
r[4] = 2073354073
r[5] = 167288147
r[6] = 1827471542
r[7] = 834791014
r[8] = 1901409888
r[9] = 1990469526
*( p + 0) : 313959809
*(p + 1) : 1759055877
*(p + 2) : 1113101911
*(p + 3) : 2133832223
*(p + 4) : 2073354073
*( p + 5) : 167288147
*(p + 6) : 1827471542
*( p + 7) : 834791014
*(p + 8) : 1901409888
*(p + 9) : 1990469526

 

رشته در زبان برنامه‌نویسی C چیست؟

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

char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};

اگر به برنامه بالا نگاه‌کنیم می‌بینیم که دقیقا آرایه‌ای از کاراکتر‌ها کنار یکدیگر قرارگرفته‌اند که درنهایت، این حروف می‌خواهند به کلمه Hello تبدیل‌شوند اما سوال اینجا است که کاراکتر آخر چیست؟

این کاراکتر نشان‌دهنده انتهای رشته از کاراکتر خاصی به‌نام(تهی= NULL) است که با ‘۰\ ‘ مشخص‌شده‌است. بنابراین آخرین کاراکتر در هر رشته برابر با ‘۰\ ‘ می باشد. لذا اگر رشته‌ای به طول n تعریف‌کنیم، فقط از n-۱ کاراکتر آن میتوانیم استفاده‌کنیم. زیرا کاراکتر آخر ‘۰\ ‘ است.

تعریف اصولی رشته در زبان برنامه‌نویسی C روش اول

در این روش می‌توان مقدار اندازه رشته را مشخص‌کرد که باید حتما به این نکته هم توجه‌کنید که خود کاراکتر تهی یا Null هم، خودش یک کاراکتر محسوب می‌شود.

برای درک بهتر به مثال‌زیر توجه‌کنید.

char greeting[6] = "Hello";

اگر دقت‌کنید کلمه Hello از ۵حرف تشکیل‌شده‌است که حرف ۶ آن همان کاراکتر تهی است. پس لطفا درصورتیکه از این روش استفاده می‌کنید حتما به نکته‌ای که گفته‌شد دقت‌کنید. اما سوال اینجا است که همیشه باید این مقداردهی را انجام‌دهیم اگر رشته خیلی بزرگ بود راه‌حل چیست؟ پاسخ این سوال در روش دوم گفته‌شده‌است. روش دوم در این روش دیگر نیازی نیست که حتما اندازه رشته را مشخص‌کنیم و یا به کاراکتر تهی دقت‌کنیم بلکه خود کامپایلر این کار را برای ما انجام می‌دهد البته به‌شرط اینکه به‌صورت ساختار زیر عمل‌کنیم:

char greeting[] = "Hello";

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

رشته‌ها در زبان C و کاربرد آنها
رشته‌ها در زبان C و کاربرد آنها

 

اگر به تصویر دقت‌کنید می‌بینید که خود کامپایلر به‌صورت‌خودکار کاراکتر تهی را قرارداده‌است و در بخش آدرس‌های حافظه نیز به‌صورت پشت‌سرهم قرار گرفته‌اند.

تعریف آرایه‌ای از رشته‌ها

اگر بخواهیم متغیری را تعریف‌کنیم که چندین رشته را در خود قرار دهد باید آرایه‌ای از رشته‌ها را تعریف‌کنیم. که باید به‌صورت‌زیر عمل‌کنیم:

آرایه از رشته ها در زبان C
آرایه از رشته ها در زبان C

 

تعریف اصولی آرایه‌ای از رشته‌ها

در زبان روش اول در این روش باید طول هر رشته و تعداد رشته را حتما مشخص‌کنیم. در طول رشته کاراکتر تهی را فراموش‌نکنید.

char names[3][7] = { "BLOOM", "Phonix", "Zeus", };

روش دوم

در این روش نیازی‌به تعیین طول رشته‌ها نیست البته دقت‌کنید که حتما باید تعداد آن‌ها ذکر شود.

char names[3][] = { "BLOOM", "Phonix", "Zeus", };

 

معرفی توابع کاربردی کتابخانه String.h

strcpy(s1, s2);

strcat(s1, s2);

strlen(s1);

strcmp(s1, s2);

strchr(s1, ch);

strstr(s1, s2);

تابع strcpy

strcpy(s1, s2);

این تابع کار کپی‌کردن مقادیر را انجام می‌دهد. به‌عبارت ساده‌تر مقدار S2 را جای S1 قرار می‌دهد. برای درک‌بهتر به‌همراه استفاده آن در برنامه‌نویسی به مثال‌زیر توجه‌کنید.

#include <stdio.h>
#include <string.h>

int main ()
{
char str1[]="Sample string";
char str2[40];
char str3[40];
strcpy (str2,str1);
strcpy (str3,"copy successful");
printf ("str1: %s\nstr2: %s\nstr3: %s\n",str1,str2,str3);
return 0;
}

خروجی برنامه به‌صورت‌زیر است:

str1: Sample string
str2: Sample string
str3: copy successful

تابع strcat

strcat(s1, s2);

این تابع کار الحاق رشته‌ها را به یکدیگر انجام می‌دهد برای درک‌بهتر به مثال‌زیر توجه‌کنید:

#include <stdio.h>
#include <string.h>

int main ()
{
char str[80];
strcpy (str,"these ");
strcat (str,"strings ");
strcat (str,"are ");
strcat (str,"concatenated.");
puts (str);
return 0;
}

خروجی برنامه به‌صورت‌زیر است:

these strings are concatenated.

تابع strlen

strlen(s1);

از این تابع برای بدست‌آوردن طول‌رشته استفاده می‌شود برای درک‌بهتر به مثال‌زیر توجه‌کنید:

#include <stdio.h>
#include <string.h>

int main ()
{
char szInput[256];
printf ("Enter a sentence: ");
gets (szInput);
printf ("The sentence entered is %u characters long.\n",(unsigned)strlen(szInput));
return 0;
}

توصیه: به‌نحوه برنامه‌نویسی دقت‌کنید چون علاوه‌بر اینکه کار با تابع موردنظر را یاد می‌گیرید طرز صحیح تعریف متغیر و استفاده‌از سایر دستورات را هم می‌آموزید که فکر نمی‌کنیم خالی از لطف باشد. خروجی برنامه به‌صورت‌زیر است:

Enter sentence: just testing
The sentence entered is 12 characters long.

تابع strcmp

strcmp(s1, s2);

این تابع کار مقایسه بین دو مقدار S1 و S2 را انجام می‌دهد که خروجی آن از ۳حالت‌زیر خارج نیست: حالت اول (0>): زمانیکه مقدار S1 کوچکتر از مقدار S2 باشد که در این حالت خروجی نادرست است. حالت دوم (0): زمانیکه مقدار S1 و S2 برابر باشند که در این حالت مقدار خروجی درست است. حالت سوم (0<): زمانیکه مقدار S1 بزرگتر از مقدار S2 باشد که در این حالت هم خروجی نادرست است. برای درک‌بهتر به مثال‌زیر دقت‌کنید: در این مثال یک رشته که نام آن apple انتخاب‌شده‌است در اول برنامه تعریف‌شده‌است و درنهایت برنامه‌ای نوشته‌شده‌است که درصورتیکه رشته‌ای برابر با apple وارد شود در خروجی عبارتی مبنی‌بر صحیح‌بودن جواب می‌بینیم در غیر اینصورت پاسخی مبنی‌بر صحیح‌بودن جواب دریافت نخواهیم‌کرد.

#include <stdio.h>
#include <string.h>

int main ()
{
char key[] = "apple";
char buffer[80];
do {
printf ("Guess my favorite fruit? ");
fflush (stdout);
scanf ("%79s",buffer);
} while (strcmp (key,buffer) != 0);
puts ("Correct answer!");
return 0;
}

خروجی برنامه به‌صورت‌زیر است:

Guess my favourite fruit? orange
Guess my favourite fruit? apple
Correct answer!

تابع strchr

strchr(s1, ch);

این تابع درواقع تعداد موجودبودن یا نبودن یک کاراکتر را در یک جمله تعیین می‌کند. برای درک بهتر به مثال‌زیر توجه‌کنید: برنامه چون واضح نوشته‌شده فکر نمی‌کنیم که نیاز به توضیح‌داشته‌باشد:

#include <stdio.h>
#include <string.h>

int main ()
{
char str[] = "This is a sample string";
char * pch;
printf ("Looking for the 's' character in \"%s\"...\n",str);
pch=strchr(str,'s');
while (pch!=NULL)
{
printf ("found at %d\n",pch-str+1);
pch=strchr(pch+1,'s');
}
return 0;
}

خروجی برنامه به‌صورت‌زیر است:

Looking for the 's' character in "This is a sample string"...
found at 4

تابع strstr

strstr(s1, s2);

این تابع درواقع به جستجو رشته موردنظر در یک عبارت می‌گردد. برای درک بهتر به مثال‌زیر دقت‌کنید:

#include <stdio.h>
#include <string.h>

int main ()
{
char str[] ="This is a simple string";
char * pch;
pch = strstr (str,"simple");
strncpy (pch,"sample",6);
puts (str);
return 0;
}

خروجی برنامه به‌صورت‌زیر است:

This is a sample string

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

 

منبع: سیسوگ

برای این مقاله نظر بگذارید:

لطفا دیدگاه خود را بنویسید
لطفا نام خود را وارد کنید