· زبان های برنامه نویسی

آموزش متغیرها، انواع داده و عملگرها در زبان C با مثال مهندسی

مقدمه

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

در زبان C، متغیرها (Variables)، انواع داده (Data Types) و عملگرها (Operators) از پایه‌ای‌ترین مفاهیم برنامه‌نویسی هستند. تسلط بر این مفاهیم برای نوشتن برنامه‌های مهندسی، محاسبات عددی و در ادامه توسعه UDF در نرم‌افزار ANSYS Fluent ضروری است.

در این مقاله از مجموعه آموزش برنامه‌نویسی Simucore، با مثال‌های ساده و مهندسی این مفاهیم را یاد می‌گیریم.

۱. متغیر در زبان C چیست؟

متغیر (Variable) نامی است که برای نگهداری یک مقدار در حافظه برنامه استفاده می‌شود. مقدار یک متغیر می‌تواند در طول اجرای برنامه تغییر کند.

برای مثال، می‌توانیم سرعت سیال را در متغیری به نام velocity ذخیره کنیم:

double velocity = 2.5;

در این دستور:

  • double نوع داده متغیر است.
  • velocity نام متغیر است.
  • 2.5 مقدار اولیه آن است.
  • علامت = مقدار سمت راست را به متغیر سمت چپ اختصاص می‌دهد.

قواعد نام‌گذاری متغیرها

نام متغیر در زبان C باید از قواعد مشخصی پیروی کند:

  • می‌تواند شامل حروف انگلیسی، اعداد و زیرخط _ باشد.
  • نباید با عدد شروع شود.
  • نباید کلمه رزروشده زبان C باشد؛ مانند int یا return.
  • حروف بزرگ و کوچک متفاوت هستند؛ بنابراین velocity و Velocity دو نام متفاوت‌اند.
  • بهتر است نام متغیر، مفهوم فیزیکی آن را مشخص کند.

نمونه نام‌های مناسب:

double temperature;
double pressure;
double velocity;
double density;
double viscosity;

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

۲. انواع داده در زبان C

نوع داده (Data Type) مشخص می‌کند که یک متغیر چه نوع مقداری را نگهداری می‌کند و چگونه در محاسبات استفاده می‌شود.

مهم‌ترین انواع داده پایه عبارت‌اند از:

نوع دادهکاربردمثال
intاعداد صحیحint count = 10;
floatاعداد اعشاری با دقت معمولیfloat velocity = 2.5f;
doubleاعداد اعشاری با دقت بیشتر از float در پیاده‌سازی‌های متداولdouble temperature = 350.25;
charنگهداری یک کاراکترchar grade = 'A';

نکته: اندازه دقیق انواع داده به پیاده‌سازی و محیط کامپایل بستگی دارد. در بسیاری از محیط‌های رایج، int چهار بایت، float چهار بایت و double هشت بایت است؛ اما نباید این اندازه‌ها را برای همه سیستم‌ها قطعی فرض کرد.

۲.۱. نوع داده int

از int برای نگهداری اعداد صحیح استفاده می‌کنیم:

int numberOfCells = 5000;
int iteration = 100;

این نوع برای شمارنده حلقه‌ها، تعداد سلول‌های شبکه و شماره تکرارهای محاسباتی مناسب است.

اگر به اعداد صحیح بدون علامت نیاز داشته باشیم، نوع unsigned int نیز وجود دارد؛ بااین‌حال انتخاب آن باید متناسب با دامنه مقادیر موردنیاز باشد.

۲.۲. نوع داده float

نوع float برای نگهداری اعداد اعشاری با دقت معمولی به کار می‌رود:

float velocity = 2.5f;
float diameter = 0.04f;

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

۲.۳. نوع داده double

نوع double برای بسیاری از محاسبات مهندسی مناسب است، زیرا در پیاده‌سازی‌های متداول نسبت به float دقت بیشتری دارد.

double density = 1.225;
double viscosity = 1.81e-5;
double temperature = 300.0;

در محاسبات انتقال حرارت، مکانیک سیالات و روش‌های عددی، انتخاب دقت مناسب اهمیت دارد. البته استفاده از double به‌تنهایی تضمین نمی‌کند که تمام محاسبات بدون خطای عددی باشند.

۲.۴. نوع داده char

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

char materialCode = 'S';

کاراکتر باید داخل علامت نقل‌قول تکی قرار گیرد؛ مانند 'S'. در مقابل، رشته متنی مانند "Steel" داخل علامت نقل‌قول دوتایی نوشته می‌شود.

۳. چگونه نوع داده مناسب انتخاب کنیم؟

فرض کنید در حال نوشتن برنامه‌ای برای تحلیل جریان در یک لوله هستیم. متغیرهای زیر را در نظر بگیرید:

int numberOfCells = 10000;
double velocity = 2.5;
double diameter = 0.04;
double density = 1.225;
double viscosity = 1.81e-5;

در این مثال، تعداد سلول‌ها یک عدد صحیح است؛ اما سرعت، قطر، چگالی و ویسکوزیته مقادیر اعشاری‌اند.

در برنامه‌های مهندسی، نوع داده را باید با توجه به ماهیت فیزیکی کمیت، دامنه مقادیر، دقت لازم و نیاز محاسباتی انتخاب کرد.

۴. نمایش مقدار متغیرها با printf

تابع printf از کتابخانه استاندارد ورودی و خروجی C برای نمایش متن و مقادیر در خروجی استفاده می‌شود. برای استفاده از آن، باید سرآیند stdio.h را وارد کنیم:

#include <stdio.h>

int main(void)
{
    double velocity = 2.5;
    int iteration = 100;

    printf("Velocity = %f m/s\n", velocity);
    printf("Iteration = %d\n", iteration);

    return 0;
}

خروجی:

Velocity = 2.500000 m/s
Iteration = 100

در این مثال:

  • %d برای نمایش مقدار int استفاده شده است.
  • %f برای نمایش مقدار double در printf به کار می‌رود.
  • \n باعث رفتن به خط بعد می‌شود.

برای تعیین تعداد ارقام اعشاری می‌توان از قالب‌هایی مانند %.2f استفاده کرد:

printf("Velocity = %.2f m/s\n", velocity);

خروجی:

Velocity = 2.50 m/s

توجه کنید که قالب نمایش در printf با برخی قالب‌های ورودی، مانند قالب‌های scanf، تفاوت دارد.

۵. عملگرهای ریاضی در زبان C

عملگرها (Operators) عملیات مختلفی را روی مقادیر و متغیرها انجام می‌دهند.

عملگرعملکردمثال
+جمعa + b
-تفریقa - b
*ضربa * b
/تقسیمa / b
%باقی‌مانده تقسیم صحیحa % b

مثال:

#include <stdio.h>

int main(void)
{
    double a = 10.0;
    double b = 4.0;

    printf("Addition = %.2f\n", a + b);
    printf("Subtraction = %.2f\n", a - b);
    printf("Multiplication = %.2f\n", a * b);
    printf("Division = %.2f\n", a / b);

    return 0;
}

خروجی:

Addition = 14.00
Subtraction = 6.00
Multiplication = 40.00
Division = 2.50

نکته مهم درباره تقسیم اعداد صحیح

به این مثال توجه کنید:

int a = 5;
int b = 2;

printf("%d\n", a / b);

خروجی 2 است؛ زیرا تقسیم دو عدد صحیح در C بخش اعشاری را حذف می‌کند.

اگر نتیجه اعشاری بخواهیم، باید دست‌کم یکی از عملوندها اعشاری باشد:

printf("%.2f\n", (double)a / b);

خروجی:

2.50

این موضوع در محاسبات مهندسی اهمیت زیادی دارد؛ زیرا تقسیم ناخواسته صحیح می‌تواند نتیجه محاسبات را تغییر دهد.

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

۶. عملگرهای مقایسه‌ای و منطقی

عملگرهای مقایسه‌ای دو مقدار را با یکدیگر مقایسه می‌کنند:

عملگرمفهوم
==برابر بودن
!=نابرابر بودن
>بزرگ‌تر بودن
<کوچک‌تر بودن
>=بزرگ‌تر یا مساوی بودن
<=کوچک‌تر یا مساوی بودن

برای نمونه:

double temperature = 350.0;

if (temperature > 300.0)
{
    printf("Temperature is above 300 K.\n");
}

در این مثال، شرط بررسی می‌کند که دما از ۳۰۰ کلوین بیشتر است یا خیر.

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

  • && : عملگر AND
  • || : عملگر OR
  • ! : عملگر NOT

مثال:

if (velocity > 0.0 && diameter > 0.0)
{
    printf("Input values are positive.\n");
}

در این برنامه، پیام فقط زمانی نمایش داده می‌شود که هر دو مقدار مثبت باشند.

نکته مهم: = برای انتساب مقدار و == برای مقایسه برابری است. اشتباه گرفتن این دو می‌تواند باعث خطاهای منطقی شود.

۷. عملگرهای انتساب و افزایش مقدار

عملگر انتساب ساده = مقدار را به متغیر اختصاص می‌دهد:

double velocity = 2.0;
velocity = 3.5;

پس از دستور دوم، مقدار velocity برابر با ۳٫۵ است.

عملگرهای ترکیبی نیز وجود دارند:

velocity += 1.0;  /* velocity = velocity + 1.0 */
velocity -= 0.5;  /* velocity = velocity - 0.5 */
velocity *= 2.0;  /* velocity = velocity * 2.0 */
velocity /= 2.0;  /* velocity = velocity / 2.0 */

برای متغیرهای شمارنده صحیح، می‌توان از ++ و -- استفاده کرد:

int iteration = 0;

iteration++;

در این مثال، مقدار iteration یک واحد افزایش پیدا می‌کند. این عملگرها در حلقه‌های محاسباتی بسیار رایج‌اند.

۸. ثابت‌ها و پارامترهای قابل تغییر

گاهی لازم است مقدار یک کمیت در طول اجرای برنامه تغییر نکند. برای این منظور می‌توان از const استفاده کرد:

const double gravity = 9.81;

در این حالت، برنامه نباید به‌طور مستقیم مقدار gravity را تغییر دهد.

روش دیگری برای تعریف ثابت‌های نمادین، استفاده از دستور پیش‌پردازنده #define است:

#define PI 3.141592653589793

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

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

۹. مثال مهندسی: محاسبه عدد رینولدز

عدد رینولدز (Reynolds Number) یک کمیت بی‌بُعد است که برای بررسی رژیم جریان استفاده می‌شود. برای جریان در لوله، در صورت استفاده از سرعت متوسط و قطر داخلی لوله، رابطه آن به صورت زیر است:

[
Re = \frac{\rho V D}{\mu}
]

که در آن:

  • (\rho): چگالی سیال، بر حسب (\mathrm{kg/m^3})
  • (V): سرعت متوسط سیال، بر حسب (\mathrm{m/s})
  • (D): قطر داخلی لوله، بر حسب (\mathrm{m})
  • (\mu): ویسکوزیته دینامیکی، بر حسب (\mathrm{Pa \cdot s})

کد کامل برنامه

#include <stdio.h>

int main(void)
{
    /* Fluid properties and pipe dimensions */
    double density = 998.0;       /* kg/m^3 */
    double velocity = 0.5;        /* m/s */
    double diameter = 0.02;       /* m */
    double viscosity = 1.0e-3;    /* Pa.s */

    /* Validate the required input values */
    if (density <= 0.0 ||
        velocity < 0.0 ||
        diameter <= 0.0 ||
        viscosity <= 0.0)
    {
        printf("Error: Invalid input values.\n");
        return 1;
    }

    /* Calculate Reynolds number */
    double reynolds = density * velocity * diameter / viscosity;

    printf("Density   = %.2f kg/m^3\n", density);
    printf("Velocity  = %.3f m/s\n", velocity);
    printf("Diameter  = %.3f m\n", diameter);
    printf("Viscosity = %.6f Pa.s\n", viscosity);
    printf("Reynolds number = %.2f\n", reynolds);

    return 0;
}

خروجی برنامه

Density   = 998.00 kg/m^3
Velocity  = 0.500 m/s
Diameter  = 0.020 m
Viscosity = 0.001000 Pa.s
Reynolds number = 9980.00

تحلیل برنامه

در این مثال، چهار متغیر اصلی برای ذخیره خواص سیال و ابعاد لوله تعریف شده‌اند. از double استفاده کرده‌ایم تا محاسبات اعشاری با دقت متداول این نوع داده انجام شوند.

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

در پایان، عدد رینولدز محاسبه و همراه با مقادیر ورودی نمایش داده می‌شود.

این کد یک برنامه مستقل C است؛ هنوز UDF نیست. بااین‌حال، مهارت تعریف پارامترها، انجام محاسبات و کنترل ورودی‌ها در توسعه کدهای مهندسی و UDF نیز کاربرد دارد.

۱۰. ترتیب اجرای عملگرها

مانند ریاضیات، در زبان C نیز ترتیب اجرای عملگرها مهم است.

برای مثال:

double result = 2.0 + 3.0 * 4.0;

نتیجه برابر با 14.0 است؛ زیرا ضرب پیش از جمع انجام می‌شود.

اگر بخواهیم ابتدا جمع را انجام دهیم، باید از پرانتز استفاده کنیم:

double result = (2.0 + 3.0) * 4.0;

نتیجه این بار برابر با 20.0 است.

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

۱۱. خطاهای رایج در کار با متغیرها و عملگرها

۱. استفاده از متغیر بدون مقداردهی اولیه

double velocity;
printf("%f\n", velocity);

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

۲. تقسیم صحیح به‌جای تقسیم اعشاری

int a = 5;
int b = 2;
double result = a / b;

مقدار result برابر ۲ است، نه ۲٫۵؛ زیرا تقسیم ابتدا با نوع صحیح انجام شده است. برای نتیجه اعشاری بنویسید:

double result = (double)a / b;

۳. انتخاب قالب نامناسب در printf

برای نمایش int از %d و برای نمایش double در printf از %f استفاده کنید. قالب نامتناسب می‌تواند به رفتار نامعین منجر شود.

۴. اشتباه گرفتن انتساب و مقایسه

= مقدار را اختصاص می‌دهد؛ == برابری را بررسی می‌کند.

۵. نادیده گرفتن واحدها

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

۶. فرض کردن دقت نامحدود برای double

نوع double نیز محدودیت دقت دارد و همه اعداد حقیقی را نمی‌تواند دقیقاً نمایش دهد. در محاسبات حساس، خطای گردکردن و پایداری عددی باید جداگانه بررسی شوند.

۱۲. تمرین‌های آموزشی

برای تثبیت مفاهیم، تمرین‌های زیر را انجام دهید:

تمرین اول: محاسبه مساحت دایره

برنامه‌ای بنویسید که شعاع را در یک متغیر double ذخیره کند و مساحت دایره را محاسبه کند:

[
A = \pi r^2
]

مساحت را با دو رقم اعشار نمایش دهید.

تمرین دوم: تبدیل دما

برنامه‌ای بنویسید که دمای سلسیوس را دریافت کند و دمای کلوین را محاسبه کند:

[
T_K = T_C + 273.15
]

متغیرها باید نوع داده مناسب داشته باشند و واحد خروجی نیز نمایش داده شود.

تمرین سوم: بررسی سرعت جریان

برنامه‌ای بنویسید که سرعت و قطر را تعریف کند. اگر هر دو مقدار مثبت باشند، پیام مناسب نمایش داده شود؛ در غیر این صورت، پیام خطا نشان داده شود.

تمرین چهارم: تغییر پارامترهای عدد رینولدز

کد مثال مهندسی را تغییر دهید و برای چند سرعت مختلف، عدد رینولدز را محاسبه کنید. بررسی کنید که با ثابت بودن سایر پارامترها، عدد رینولدز چگونه به سرعت وابسته است.

۱۳. ارتباط این مفاهیم با UDF در ANSYS Fluent

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

برای نمونه، یک UDF ممکن است رابطه‌ای برای محاسبه شار حرارتی روی دیواره داشته باشد. در چنین حالتی، درک نوع داده، واحدها، ترتیب عملیات و اعتبار مقادیر ورودی ضروری است.

بااین‌حال، UDF صرفاً یک برنامه مستقل C نیست. UDF باید از ساختارهای API و ماکروهای تعریف‌شده در Fluent استفاده کند و مطابق نسخه نرم‌افزار، شرایط مدل و روش کامپایل آماده شود.

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

جمع‌بندی

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

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

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

دیدگاه خود را بنویسید

نشانی ایمیل شما منتشر نخواهد شد.