Category Archives: প্রাথমিক সি প্রোগ্রামিং । C Programming Basics

প্রাথমিক সি প্রোগ্রামিং । C Programming Basics

সি প্রোগ্রামিঙে টাইপ কাস্টিং

সি প্রোগ্রামিঙে টাইপ কাস্টিংঃ
রিদওয়ান বিন শামীম

টাইপ কাস্টিং একটি পদ্ধতি যেখানে কোন চলককে এক ডাটা টাইপ থেকে অন্য ডাটা টাইপে পরিবর্তিত করা যায়। যেমন, একটি লম্বা মানকে যদি সাধারণ একটি পূর্ণ সংখ্যায় প্রকাশ করতে চাই, তাহলে long থেকে int এ টাইপ কাস্ট করে তা করা যায়।এক টাইপ থেকে অন্য টাইপে রুপান্তরের ক্ষেত্রে নিচের মত করে কাস্ট অপারেটর ব্যবহার করে এটি করা হয়ঃ
(type_name) expression

কাস্ট অপারেটর কীভাবে floating-point operation হিসাবে দুটি পূর্ণসংখ্যা চলক বিভাজন তৈরি করে আলাদা করে তা নিচের উদাহরণ থেকে আমরা বুঝতে পারি।

#include <stdio.h>

main()
{
int sum = 17, count = 5;
double mean;

mean = (double) sum / count;
printf("Value of mean : %f\n", mean );

}
উপরের কোড ঠিকভাবে কাজ করলে তা যে ফলাফল দেখাবে তা হল,
Value of mean : 3.400000
এখানে বলা উচিৎ যে, কাস্ট অপারেটর ডিভিশনের চেয়ে বেশি অগ্রাধিকার পায় তাই অঙ্কের মান type double দ্বারা রূপান্তরিত হয়, তারপর দ্বৈত মান প্রদর্শন করে। টাইপ কনভার্সন অন্তর্নিহিতও হতে পারে যা কম্পাইলারের মাধ্যমে স্বয়ংক্রিয়ভাবে হতে পারে বা কাস্ট অপারেটরের মাধ্যমে সরাসরিও হয়। তবে টাইপ কনভার্সন কাস্ট অপারেটরের মাধ্যমে করাই ভাল।
পূর্ণসংখ্যার মানোন্নয়নঃ পূর্ণসংখ্যার মানোন্নয়ন একটি প্রক্রিয়া যেটি int বা unsigned int এরচে ছোট মানের পূর্ণসংখ্যার মানকে int বা unsigned int এর মানে আনতে ব্যবহার করা হয়।কোন int এ ক্যারেকটার যোগ করার ক্ষেত্রে আমরা যা করতে পারি তা হল,
#include <stdio.h>

main()
{
int i = 17;
char c = 'c'; /* ascii value is 99 */
int sum;

sum = i + c;
printf("Value of sum : %d\n", sum );

}
উপরের কোড ঠিকভাবে কাজ করলে তা যে ফলাফল দেখাবে তা হল,

Value of sum : 116
এখানে মান ১১৬ আসছে কারণ কম্পাইলার পূর্ণসংখ্যার মানোন্নয়ন করে সি ('c' )এর মান ascii তে রুপান্তর করে নিচ্ছে মূল কাজের আগে।
সাধারণ এরিথমেটিক রুপান্তরঃ সাধারণ এরিথমেটিক রুপান্তরের ক্ষেত্রে অন্তর্হিত ভাবে সব মানকে একটি নির্দিষ্টভাবে সাজানো হয়। কম্পাইলার প্রথমে পূর্ণসংখ্যার মানোন্নয়ন করে, এর পরও টাইপ সমান না হলে নিচের ক্রমানুসারে সংখ্যার প্রাপ্যতার অগ্রাধিকার ভিত্তিতে রুপান্তর করা হয়।

সাধারণ এরিথমেটিক রুপান্তর assignment operators বা logical operators ইত্যাদির জন্য ব্যবহার করা হয় না। নিচের উদাহরণ থেকে আমরা ব্যপারটা বুঝবঃ
#include <stdio.h>

main()
{
int i = 17;
char c = 'c'; /* ascii value is 99 */
float sum;

sum = i + c;
printf("Value of sum : %f\n", sum );

}
উপরের কোড ঠিকভাবে কাজ করলে তা যে ফলাফল দেখাবে তা হল,

Value of sum : 116.000000
এখানে c প্রথমে পূর্ণসংখ্যায় রূপান্তরিত হয়েছে কিন্তু মূল মান দ্বিগুণ হওয়ায় সাধারণ এরিথমেটিক রুপান্তর ব্যবহার করে এবং কম্পাইলার i ও c কে floatএ রূপান্তরিত করে সেভাবেই ফলাফল দিয়েছে।

সি প্রোগ্রামিঙে প্রিপ্রসেসর

সি প্রোগ্রামিঙে প্রিপ্রসেসরঃ
রিদওয়ান বিন শামীম

সি প্রোগ্রামিঙে প্রিপ্রসেসর কম্পাইলারের অংশ নয় কিন্তু কিন্তু কম্পাইলেসন প্রক্রিয়ার একটি পৃথক অংশ। সহজ কথায় বলতে গেলে, সি প্রিপ্রসেসর একটি টেক্সট সাবস্টিটিউশন অনুষঙ্গ এবং কম্পাইলারকে মূল কম্পাইলেসনের আগে প্রয়োজনীয় প্রিপ্রসেসিং সম্পন্ন করার নির্দেশ দিয়ে থাকে। আমরা এ প্রবন্ধে সি প্রিপ্রসেসরকে সিপিপি বলব।
সমস্ত প্রিপ্রসেসর কমান্ড একটি পাউন্ড প্রতীক (#) দ্বারা শুরু হয়। এটি প্রথম অশূন্য মাত্রা, এবং পঠনযোগ্যতার জন্য এটি প্রথম কলামে শুরু করা হয়। কিছু গুরুত্বপূর্ণ প্রিপ্রসেসিং ডিরেক্টিভ নিচের তালিকায় দেয়া হল।
Directive Description
#define প্রিপ্রসেসর ম্যাক্রো অন্তর্ভুক্ত/অদলবদল করে।
#include অন্য ফাইল থেকে নির্দিষ্ট হিডার(header) অন্তর্ভুক্ত করে।
#undef প্রিপ্রসেসরের ম্যাক্রোকে আনডেফাইন করে।
#ifdef ম্যাক্রো ডিফাইনড হলে সত্য নির্দেশ করে।
#ifndef ম্যাক্রো আনডিফাইনড হলে সত্য নির্দেশ করে।
#if কম্পাইলেসনের সময় ঠিক হলে টা টেস্ট করে।
#else #if এর অলটারনেটিভ।
#elif #else এবং #if যদি এক বিবৃতিতে থাকে।
#endif শর্ত সাপেক্ষে প্রিপ্রসেসরের সমাপ্তি করে।
#error Stderr এ এরর ম্যাসেজ নির্দেশ করে।
#pragma বিশেষ প্রক্রিয়া ব্যবহার করে কম্পাইলারে বিশেষ কমান্ড নির্দেশ করে।

বিভিন্ন ডিরেক্টিভ বুঝার জন্য নিচের উদাহরণ দেয়া হল,
#define MAX_ARRAY_LENGTH 20
এই ডিরেক্টিভ MAX_ARRAY_LENGTH কে 20 দিয়ে পালটানোর জন্য সিপিপিকে নির্দেশ দেয় এবং #define ব্যবহার করে ধ্রুবকের পঠনযোগ্যতা বাড়াতে।
#include <stdio.h>
#include "myheader.h"
এই ডিরেক্টিভ সিস্টেম লাইব্রেরি থেকে stdio.h নেয়ার জন্য সিপিপিকে নির্দেশ দেয়, এবং বর্তমান সোর্স ফাইলে টেক্সট যোগ করে। পরবর্তী লাইন সিপিপিকে লোকাল ডিরেক্টরি থেকে myheader.h নিতে ও বর্তমান সোর্স ফাইলে কন্টেন্ট যোগ করতে নির্দেশ দেয়।
#undef FILE_SIZE
#define FILE_SIZE 42
এটি সিপিপিকে FILE_SIZE কে 42 হিসেবে প্রদর্শন করতে নির্দেশ করে।
#ifndef MESSAGE
#define MESSAGE "You wish!"
#endif
এটি সিপিপিকে কোন ম্যাসেজ যদি ডিফাইন না করা হয়ে থাকে তাকে ডিফাইন করতে নির্দেশ দেয়।
#ifdef DEBUG
/* Your debugging statements here */
#endif
এটি সিপিপিকে কোন বিবৃতি সম্পন্ন করতে বলে যদি DEBUG ডিফাইন করা থাকে। কম্পাইলেসনের সময় -DDEBUG flag সম্পন্ন থাকলে এটি দরকার হয়, জিসিসি কম্পাইলারের ক্ষেত্রে। এটি DEBUGকে ডিফাইন করবে তাই কম্পাইলেসনের সময় debugging on বা off করা যাবে।
ANSI C কয়েক রকম ম্যাক্রো ডিফাইন করে। প্রোগ্রামিঙে এর সবগুলোই ব্যবহার করা যাবে কিন্তু পূর্বনির্ধারিত ম্যাক্রোগুলো সরসরি পরিবর্তন করা যায় না।
Macro Description
__DATE__ character literalএ বর্তমান তারিখ "MMM DD YYYY" ফরমেটে
__TIME__ character literal এ বর্তমান সময়"HH:MM:SS" ফরমেটে
__FILE__ string literalএ বর্তমান ফাইল নেম।
__LINE__ দশমিক ধ্রুবকে বর্তমান লাইন নাম্বার।
__STDC__ কম্পাইলার ANSI standardএ কম্পাইল করলে 1 দ্বারা নির্ণীত।

নিচের উদাহরণগুলো দেখা যাক;
#include <stdio.h>

main()
{
printf("File :%s\n", __FILE__ );
printf("Date :%s\n", __DATE__ );
printf("Time :%s\n", __TIME__ );
printf("Line :%d\n", __LINE__ );
printf("ANSI :%d\n", __STDC__ );

}
test.c ফাইলে কোডগুলো সম্পন্ন হলে যে ফলাফল হবেঃ
File :test.c
Date :Jun 2 2012
Time :03:36:24
Line :8
ANSI :1

প্রিপ্রসেসরের অপারেটরঃ ম্যাক্রো তৈরি করতে সি প্রিপ্রসেসর যে অপারেটর সুবিধা দেয় টা হল, ম্যাক্রো চালু রাখাঃ ম্যাক্রো সাধারণত এক লাইনে হয়, এক লাইনের অনেক লম্বা কোন ম্যাক্রো চালু রাখতে এই অপারেটর ব্যবহার করা হয়। যেমন,
#define message_for(a, b) \
printf(#a " and " #b ": We love you!\n")
স্ট্রিংজাইজঃ ('#') দ্বারা প্রকাশ করা হয়। ম্যাক্রো ডেফিনেশনের মধ্যে ম্যাক্রো প্যারামিটারকে স্ট্রিং ধ্রুবকে পরিনত করে। নির্দিষ্ট প্যারামিটার লিস্ট বা আর্গুমেন্টের ক্ষেত্রেই কেবল এই অপারেটর ব্যবহার করা হয়।
#include <stdio.h>

#define message_for(a, b) \
printf(#a " and " #b ": We love you!\n")

int main(void)
{
message_for(Carole, Debra);
return 0;
}
কোড ঠিকভাবে লেখা হলে তা এই ফলাফল দেখাবে,
Carole and Debra: We love you!
টোকেন পেস্টিং অপারেটরঃ একে (##) দ্বারা প্রকাশ করা হয়, ম্যাক্রো ডেফিনেশনের দুটি তকেঙ্কে একীভূত করতে ব্যবহার করা হয়,
#include <stdio.h>

#define tokenpaster(n) printf ("token" #n " = %d", token##n)

int main(void)
{
int token34 = 40;

tokenpaster(34);
return 0;
}
কোড ঠিকভাবে লেখা হলে তা এই ফলাফল দেখাবে
token34 = 40
এটি কীভাবে দেখানো হল যেখানে
printf ("token34 = %d", token34);
token##n কে token34 এ রূপান্তরের ক্ষেত্রে stringize এবং token-pasting দুটিই ব্যবহৃত হয়েছে।
ডিফাইনড অপারেটরঃ কোন আইডেন্টিফায়ার #define ব্যবহার করে ধ্রুবক প্রকাশ করলে এটি ব্যবহার হয়, আইডেন্টিফায়ার ডিফাইনড হলে ভ্যলু ট্রু অর্থাৎ নন-জিরো আর আন ডিফাইনড হলে ফলস বা জিরো।
#include <stdio.h>

#if !defined (MESSAGE)
#define MESSAGE "You wish!"
#endif

int main(void)
{
printf("Here is the message: %s\n", MESSAGE);
return 0;
}
কোড ঠিকভাবে লেখা হলে তা এই ফলাফল দেখাবে
Here is the message: You wish!

প্যারামিটারাইজড ম্যাক্রোঃ সিপিপির একটি গুরুত্বপূর্ণ সুবিধা হল এইটি প্যারামিটারাইজড ম্যাক্রো ব্যবহার করে কাজকে এগিয়ে নেয়।
int square(int x) {
return x * x;
}
ম্যাক্রো ব্যবহার করে পুনরায় লিখতে পারি,
#define square(x) ((x) * (x))
আর্গুমেন্ট সহ ম্যাক্রোকে #define directive দ্বারা লিখতে হয়, আর্গুমেন্ট লিস্ট নির্দিষ্ট এবং ম্যাক্রোর নাম মেনে চলতে হয়, macro name ও open parenthesis এর মধ্যে কোন ফাঁকা জায়গা রাখা যাবে না।
#include <stdio.h>

#define MAX(x,y) ((x) > (y) ? (x) : (y))

int main(void)
{
printf("Max between 20 and 10 is %d\n", MAX(10, 20));
return 0;
}
কোড ঠিকভাবে লেখা হলে তা এই ফলাফল দেখাবে
Max between 20 and 10 is 20

সি প্রোগ্রামিং এর একটি গুরুত্বপূর্ণ টপিক Union

আপনাদের সবাইকে স্বাগতম আমাদের সাইটে। আজ আমরা এখানে সি প্রোগ্রামিং এর একটি গুরুত্বপূর্ণ চ্যাপ্টার আলোচনা করব, তার নাম হলো Union। আপনাদের আগেই বলেছি সি প্রোগ্রামিং শিখতে হলে আপনাকে কিছুটা হলেও ইংরেজী শিখতে হবে।
একটি ইউনিয়ন এর সাহায্যে আপনি একই মেমরির স্থানে বিভিন্ন ধরনের তথ্য সংরক্ষণ করতে সক্ষম হবেন যা সি তে পাওয়া যায় একটি বিশেষ ডাটা টাইপ হিসেবে। আপনি অনেক সদস্যদের সঙ্গে একটি ইউনিয়ন নির্ধারণ করতে পারবেন, কিন্তু শুধুমাত্র এক সদস্য যে কোনো সময় একটি মান থাকতে পারে. ইউনিয়ন মাল্টি উদ্দেশ্যর জন্য একই মেমরি অবস্থান ব্যবহার করে একটি কার্যকর উপায় প্রদান।
Defining a Union
এখানে Union এর সঙ্গা প্রদান করা হচ্ছেঃ
কাঠামো নির্ধারণ করার সময় হিসাবে আপনি কি একটি ইউনিয়ন নির্ধারণ করার জন্য, আপনি খুব অনুরূপ ইউনিয়ন বিবৃতি ব্যবহার করা আবশ্যক ছিল। ইউনিয়ন বিবৃতিতে আপনার প্রোগ্রামের জন্য একাধিক সদস্য, একটি নতুন ডাটা টাইপ সংজ্ঞায়িত করে। নিম্নরূপ ইউনিয়ন বিবৃতি বিন্যাস হল:
union [union tag]
{
member definition;
member definition;
...
member definition;
} [one or more union variables];

ইউনিয়ন ট্যাগ ঐচ্ছিক এবং প্রতিটি সদস্য সংজ্ঞা যেমন আমি কোন int হিসাবে একটি স্বাভাবিক পরিবর্তনশীল সংজ্ঞা, হয়; অথবা চ ভাসমান; বা অন্য কোন বৈধ পরিবর্তনশীল সংজ্ঞা. ইউনিয়ন এর সংজ্ঞা শেষে, চূড়ান্ত সেমিকোলন আগে, আপনি এক বা একাধিক ইউনিয়ন ভেরিয়েবল উল্লেখ করতে পারেন কিন্তু এটা ঐচ্ছিক. এখানে আপনি তিন সদস্য হয়েছে, যা ডেটা নামে একটি ইউনিয়ন টাইপ সংজ্ঞায়িত করবে উপায় i, f, and str:
union Data
{
int i;
float f;
char str[20];
} data;

এখন, ডাটা টাইপ একটি পরিবর্তনশীল একটি পূর্ণসংখ্যা, একটি ফ্লোটিং পয়েন্ট নম্বর, বা অক্ষরের একটি স্ট্রিং সঞ্চয় করতে পারেন. এই একটি পরিবর্তনশীল অর্থাৎ এর মানে হল যে। একই মেমরি অবস্থান তথ্য একাধিক ধরনের সংরক্ষণ করা যেতে পারে. আপনি আপনার প্রয়োজন উপর ভিত্তি করে একটি ইউনিয়ন ভিতরে কোনো বিল্ট ইন বা ব্যবহারকারী নির্ধারিত ধরনের তথ্য ব্যবহার করতে পারেন।

একটি ইউনিয়ন দ্বারা দখল মেমরি ইউনিয়নের বৃহত্তম সদস্য রাখা যথেষ্ট বড় হতে হবে. এই পংক্তি দ্বারা দখল করা যায়, যা সর্বোচ্চ স্থান, কারণ উদাহরণস্বরূপ, উপরোক্ত উদাহরণ তথ্য টাইপ মেমরি স্পেস 20 বাইট ব্যাপৃত হবে. নিম্নলিখিত উপরে ইউনিয়ন দখল করে মোট মেমরির মাপ প্রদর্শন করা হবে যা উদাহরণ:

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

union Data
{
int i;
float f;
char str[20];
};

int main( )
{
union Data data;

printf( "Memory size occupied by data : %d\n", sizeof(data));

return 0;
}

উপরের কোড কম্পাইল এবং মৃত্যুদন্ড কার্যকর করা হয়, এটি নিম্নলিখিত ফলাফল সৃষ্টি করে:
Memory size occupied by data : 20
Accessing Union Members
একটি ইউনিয়নের কোন সদস্য অ্যাক্সেস করার জন্য, আমরা সদস্য এক্সেস অপারেটর ব্যবহার (.). সদস্য এক্সেস অপারেটর ইউনিয়ন পরিবর্তনশীল নাম এবং আমরা অ্যাক্সেস করতে চান যে ইউনিয়ন সদস্য মধ্যে একটি নির্দিষ্ট সময়ের হিসাবে কোডেড হয়. আপনি ইউনিয়ন ধরনের ভেরিয়েবল সংজ্ঞায়িত করতে ইউনিয়ন শব্দ ব্যবহার করতে হবে. ইউনিয়নের ব্যবহার ব্যাখ্যা উদাহরণ অনুসরণ করা হয়:
#include <stdio.h>
#include <string.h>

union Data
{
int i;
float f;
char str[20];
};

int main( )
{
union Data data;

data.i = 10;
data.f = 220.5;
strcpy( data.str, "C Programming");

printf( "data.i : %d\n", data.i);
printf( "data.f : %f\n", data.f);
printf( "data.str : %s\n", data.str);

return 0;
}

উপরের কোড কম্পাইল এবং মৃত্যুদন্ড কার্যকর করা হয়, এটি নিম্নলিখিত ফলাফল সৃষ্টি করে:
data.i : 1917853763
data.f : 4122360580327794860452759994368.000000
data.str : C Programming
এখানে, আমরা পরিবর্তনশীল নির্ধারিত চূড়ান্ত মান মেমোরি দখল করেছে, কারণ আমি ও ইউনিয়ন চ সদস্যদের মান ক্ষতিগ্রস্ত হবে যে দেখতে পারেন এবং এই মান Str সদস্য খুব ভাল মুদ্রিত হচ্ছে যে যদি কারণ। এখন আমরা হচ্ছে ইউনিয়নের প্রধান উদ্দেশ্য, যা একটি সময়ে এক পরিবর্তনশীল ব্যবহার করতে হবে যেখানে এর আবার একই উদাহরণ দেখব:
#include <stdio.h>
#include <string.h>

union Data
{
int i;
float f;
char str[20];
};

int main( )
{
union Data data;

data.i = 10;
printf( "data.i : %d\n", data.i);

data.f = 220.5;
printf( "data.f : %f\n", data.f);

strcpy( data.str, "C Programming");
printf( "data.str : %s\n", data.str);

return 0;
}

উপরের কোড কম্পাইল এবং মৃত্যুদন্ড কার্যকর করা হয়, এটি নিম্নলিখিত ফলাফল সৃষ্টি করে:
data.i : 10
data.f : 220.500000
data.str : C Programming

এখানে, সব সদস্যদের খুব ভাল এক সদস্য একটি সময়ে ব্যবহার করা হচ্ছে, কারণ মুদ্রিত হচ্ছে।

সি প্রোগ্রামিং এ মেমোরি ব্যবস্থাপনাঃ Memory Management in C Programming

সি প্রোগ্রামিং এ মেমোরি ব্যবস্থাপনা

রিদওয়ান বিন শামীম

এই অধ্যায়ে সি প্রোগ্রামিং এ ডাইনামিক মেমোরি ম্যনেজমেন্ট নিয়ে আলোচনা করা হবে। সি প্রোগ্রামিং ল্যাঙ্গুয়েজে মেমোরি বণ্টন ও ব্যবস্থাপনার জন্য কয়েক ধরনের ব্যবস্থা আছে, তাদেরকে হিডার ফাইলে রাখা হয়। এধরনের ফাংশন গুলোকে এভাবে দেখানো যায়ঃ

S.N. Function and Description

1 void *calloc(int num, int size);
Num ইলিমেন্টের এর জন্য array বরাদ্দ দেয় এই ফাংশন, যেগুলোর আকার বাইটে সীমাবদ্ধ।

2 void free(void *address);
এই ফাংশন এড্রেস দ্বারা নির্ধারিত মেমোরি ব্লক প্রকাশ করে।

3 void *malloc(int num);
এই ফাংশন num bytes এর array বরাদ্ধ করে,এবং তাদের শুরু করায়।

4 void *realloc(void *address, int newsize);
এই ফাংশন মেমোরিকে পুনরায় সংগঠিত করে ও নতুন আকারে গড়ে তুলে।

প্রোগ্রামিং এ কাজ করার সময় যদি অ্যারির আকার সম্পর্কে জানা থাকে তাহলে অ্যারি সনাক্ত করা সহজ হবে। উদাহরণস্বরূপ, কারো নাম সংরক্ষণ করতে গেলে, নাম লিখতে ম্যাক্সিমাম ১০০ অক্ষর লাগতে পারে, যা আমরা এভাবে লিখতে পারি,
char name[100];

কিন্তু যদি এমন হয় যেখানে আমাদের যে তথ্য লিখতে হবে তার আকার সম্পর্কে কোন ধারণা নেই, যেমন কোন বিষয়ে বিবৃতি, সেক্ষেত্রে আমাদের একটি পয়েন্টার ব্যবহার করতে হবে অনির্ধারিত মেমোরি সাইজ উল্লেখ করে, যা পরবর্তীতে এভাবে দেখানো যায়,
#include
#include
#include

int main()
{
char name[100];
char *description;

strcpy(name, "Zara Ali");

/* allocate memory dynamically */
description = malloc( 200 * sizeof(char) );
if( description == NULL )
{
fprintf(stderr, "Error - unable to allocate required memory\n");
}
else
{
strcpy( description, "Zara ali a DPS student in class 10th");
}
printf("Name = %s\n", name );
printf("Description: %s\n", description );
}

উপরের কোডগুলো ঠিকভাবে লিখা হলে তা এরুপ ফলাফল দেখাবে,
Name = Zara Ali
Description: Zara ali a DPS student in class 10th

একই ধরনের প্রোগ্রাম লিখা যাবে malloc কে calloc দ্বারা রিপ্লেস করে,
calloc(200, sizeof(char));

অপারেটিং সিস্টেম নিজেই প্রোগ্রামের বরাদ্দ করা মেমোরি রিলিজ করবে, কিন্তু আমরা নিজেরাই প্রয়োজন শেষ হলে free() ফাংশন দ্বারা মেমোরি রিলিজ করে দিতে পারি। এছাড়াও realloc() ফাংশন ব্যবহার করে বরাদ্দকৃত মেমোরি ব্লকের আকার ছোটবড়ও করা যায়। realloc() এবং free() ফাংশন ব্যবহার করে দেখা যাক।

#include
#include
#include

int main()
{
char name[100];
char *description;

strcpy(name, "Zara Ali");

/* allocate memory dynamically */
description = malloc( 30 * sizeof(char) );
if( description == NULL )
{
fprintf(stderr, "Error - unable to allocate required memory\n");
}
else
{
strcpy( description, "Zara ali a DPS student.");
}
/* suppose you want to store bigger description */
description = realloc( description, 100 * sizeof(char) );
if( description == NULL )
{
fprintf(stderr, "Error - unable to allocate required memory\n");
}
else
{
strcat( description, "She is in class 10th");
}

printf("Name = %s\n", name );
printf("Description: %s\n", description );

/* release memory using free() function */
free(description);
}

উপরের কোড ঠিকভাবে লিখা হলে তা যে ফলাফল দেখাবে তা হল,
Name = Zara Ali
Description: Zara ali a DPS student.She is in class 10th
বাড়তি মেমোরি ব্লক বরাদ্দ না করে আমরা উপরের ফাংশন লিখে দেখতে পারি, মেমোরিতে সীমাবদ্ধতা থাকলে strcat() ফাংশন প্রদর্শিত হবে।

সি প্রোগ্রামিং : চলক আর্গুমেন্ট । C – Variable Arguments

সি প্রোগ্রামিং : চলক আর্গুমেন্ট।

রিদওয়ান বিন শামীম

অনেক সময় প্রোগ্রামিঙে এমন পরিস্থিতি আসে যখন অনুমিত প্যারামিটারের সংখ্যার স্থলে আর্গুমেন্টের চলক নাম্বার নেবে এমন ফাংশন খুঁজতে হয়। সি প্রোগ্রামিং এজাতীয় ক্ষেত্রের জন্য একটি ব্যবস্থা রেখেছে যাতে করে আমরা এমন একটি ফাংশন ব্যবহার করতে পারি যা আমাদের চাহিদামত প্যারামিটারের চলক নাম্বার গ্রহন করে থাকে। নিচের উদাহরণ তেমন একটি ফাংশনঃ

int func(int, ... )
{
.
.
.
}

int main()
{
func(1, 2, 3);
func(1, 2, 3, 4);
}

এখানে func() এক্লিপ্সের মত তিন ডটের(...) শেষ আর্গুমেন্ট নির্দেশ করে, এক্লিপ্সের সামনেরটি int যা গৃহীত আর্গুমেন্টের মোট চলক নাম্বার প্রকাশ করে। এটিকে ঠিকভাবে কাজ করানোর জন্য stdarg.h হিডার ফাইল ব্যবহার করতে হয় যা চলক আর্গুমেন্টের ফাংশন ও ম্যাক্রো সঠিকভাবে প্রয়োগের জন্য দরকার হয়। এক্ষেত্রে নিচের ধারাগুলো মেনে চলা হয়।

# শেষ প্যারামিটার এক্লিপ্স ধরে ফাংশন ঠিক করা হয়, এক্লিপ্সের আগের ফাংশন int যা আর্গুমেন্টের সংখ্যা প্রকাশ করে।
# ফাংশন ডেফিনেশনে va_list টাইপের চলক রাখতে হয়, যা stdarg.h হিডার ফাইলে বিবৃত হয়।
# int প্যারামিটার ও va_start ম্যাক্রো ব্যবহার করতে হয় আর্গুমেন্ট লিস্টে va_list চলক চালু করতে। va_start ম্যাক্রো stdarg.h হিডার ফাইলে বিবৃত হয়।
# আর্গুমেন্ট লিস্টে কাজ করতে va_arg ম্যাক্রো ও va_list চলক ব্যবহার করা হয়।
# va_list চলকের বিবৃত মেমোরি পরিষ্কার করতে va_end ম্যাক্রো ব্যবহার করা হয়।
উপরের পদ্ধতি ব্যবহার করে প্যারামিটারের চলক নাম্বার একটি ফাংশনে আমরা লিখতে পারি,

#include <stdio.h>
#include <stdarg.h>

double average(int num,...)
{

va_list valist;
double sum = 0.0;
int i;

/* initialize valist for num number of arguments */
va_start(valist, num);

/* access all the arguments assigned to valist */
for (i = 0; i < num; i++)
{
sum += va_arg(valist, int);
}
/* clean memory reserved for valist */
va_end(valist);

return sum/num;
}

int main()
{
printf("Average of 2, 3, 4, 5 = %f\n", average(4, 2,3,4,5));
printf("Average of 5, 10, 15 = %f\n", average(3, 5,10,15));
}

উপরের কোড সঠিকভাবে লিখলে যে ফলাফল হয় তা নিচে দেয়া হল, বলে নেয়া ভাল, দুবার average() ফাংশন ব্যবহার করা হয়েছে প্রথমবার প্রথম আর্গুমেন্ট চলক আর্গুমেন্টের সংখ্যা প্রকাশ করেছে, আর্গুমেন্টের চলক সংখ্যা ছাড়ে কেবল এক্লিপ্স ব্যবহার করা হয়।
Average of 2, 3, 4, 5 = 3.500000
Average of 5, 10, 15 = 10.000000

সি –রিকারসিং (C – Recursion)

সি –রিকারসিং (C – Recursion)

Md. Amirul Islam (ARIF)

Bogra

 

 

রিকারসিং ( Recursion) হল আইটেম রিপিটিং করার একটি স্বয়ংসম্পূর্ণ প্রক্রিয়া। প্রোগ্রামিং ল্যাঙ্গুয়েজে একই প্রয়োগ পাশাপাশি  যদি একটি প্রোগ্রাম আপনাকে অনুমতি দেয় একই ফাংশনের ভিতরে একই /the same ফাংশন কল করতে তাহলে এটাকে রিকারসিং বলা হয় ।

এভাবে ফাংশন কল করা হয়ঃ

 

void recursion(){   recursion(); /* function calls itself */} int main(){   recursion();}  

সি প্রোগ্রামিং ল্যাঙ্গুয়েজ রিকারসিং সমর্থিত অর্থাৎ একটি ফাংশন নিজেকেই কল করতে পারে । কিন্তু যখন রিকারসিং ব্যাবহার করা হয় তখন প্রোগ্রামারের প্রয়োজন হয় ফাংশনটি থেকে সতর্কতার সাথে একটি এক্সিট কন্ডিশন সংজ্ঞায়িত করা, অন্যথায় এটি ইনফিনিটি লুপে চলে যাবে ।

 

রিকার্সিভ ফাংশনগুলো খুবই গুরুত্বপূর্ণ অনেক গাণিতিক সমস্যা সমাধান করতে।  যেমন একটি নাম্বারের গৌণিক নিরূপণ (calculate factorial), জেনারেটিং Fibonacci সিরিজ ইত্যাদি।

 

সংখ্যা গুণিতক (Number Factorial)

নিচের উদাহরনটি অনুসরন করুন। যা একটি রিকার্সিভ ফাংশন ব্যবহার করে একটি প্রদত্ত সংখ্যার জন্য গৌণিক হিসাব: সংখ্যা গুণিতক

 

#include <stdio.h> int factorial(unsigned int i){   if(i <= 1)   {      return 1;   }   return i * factorial(i - 1);}int  main(){    int i = 15;    printf("Factorial of %d is %d\n", i, factorial(i));    return 0;}

 

 

 

যখন উপরের কোড গুলো প্রণীত ও অনুষ্ঠিত (compiled and executed) হয় তখন নিম্নলিখিত ফলাফল সৃষ্টি করে:

Factorial of 15 is 2004310016 Fibonacci সিরিজ (Fibonacci Series) আরেকটি উধাহরন অনুসরন করুন, যা একটি রিকার্সিভ ফাংশন ব্যবহার করে একটি প্রদত্ত সংখ্যার জন্য Fibonacci সিরিজ তৈরি করে: #include <stdio.h> int fibonaci(int i){   if(i == 0)   {      return 0;   }   if(i == 1)   {      return 1;   }   return fibonaci(i-1) + fibonaci(i-2);} int  main(){    int i;    for (i = 0; i < 10; i++)    {       printf("%d\t%n", fibonaci(i));    }    return 0;}

যখন উপরের কোড গুলো প্রণীত ও অনুষ্ঠিত (compiled and executed) হয় তখন নিম্নলিখিত ফলাফল সৃষ্টি করে:

 0       1       1       2       3       5       8       13      21      34     

 

সি প্রোগ্রামিঙে এরর হ্যান্ডেলিং . Error Handling in C Programming

সি প্রোগ্রামিঙে এরর হ্যান্ডেলিং
রিদওয়ান বিন শামীম

যেহেতু সি প্রোগ্রামিঙে সরাসরি ভুল সংশোধনের সুযোগ নেই কিন্তু সিস্টেম প্রোগ্রামিং ল্যাঙ্গুয়েজ হওয়ার কারণে কিছু নিম্ন মানের পরিবর্তনের সুযোগ দিয়ে থাকে। বেশিরভাগ সি এমনকি ইউনিক্স ফাংশনও -1 বা NULL রিটার্ন দেখায়, এবং errno নামক এরর কোড প্রদর্শন করে যা একটি গ্লোবাল কোড, যা নির্দেশ করে ভুলটি কোন ফাংশন কলের সময় হয়েছিল। হিডার ফাইলে বিভিন্ন এরর কোড পাওয়া যায়। তাই সি প্রোগ্রামিং রিটার্ন ভ্যলু চেক করে ও সেই মোতাবেক ব্যবস্থা নেয়। প্রোগ্রাম শুরুর সময় errno কে ০ নির্ধারণ করে নেয়া ভাল, এর মানে হচ্ছে প্রোগ্রামে কোন ভুল নেই।
errno, perror()এবং strerror()
perror() এবং strerror(),errnoএর অধীনে টেক্সট মেসেজ প্রদর্শনে ব্যবহার করা হয়। perror() ফাংশন এর কাছে সরবরাহকৃত string প্রদর্শন করে কোলন, স্পেসের
মাধ্যমে, তারপর লিখিত বার্তা আকারে errno value প্রদর্শন করে। strerror()ফাংশন লিখিত বার্তার একটি পয়েন্টার ফেরত দেয়, বর্তমান errno value সহ। একটি এরর কন্ডিশন তৈরি করে এমন একটি ফাইল খোলার চেষ্টা করা যাক যার অস্তিত্বই নেই। এখানে যদিও দুটি ফাংশন ব্যবহার করা হবে, একটি বা বেশি ফাংশনও ব্যবহার করা যায়। আরেকটি ব্যপার হল, stderr file stream ব্যবহার করা ভাল এররের আউটপুট পাওয়ার জন্য।
#include <stdio.h>
#include <errno.h>
#include <string.h>

extern int errno ;

int main ()
{
FILE * pf;
int errnum;
pf = fopen ("unexist.txt", "rb");
if (pf == NULL)
{
errnum = errno;
fprintf(stderr, "Value of errno: %d\n", errno);
perror("Error printed by perror");
fprintf(stderr, "Error opening file: %s\n", strerror( errnum ));
}
else
{
fclose (pf);
}
return 0;
}
উপরোক্ত কোড লেখার পর যে ফলাফল আসবে তা হল,
Value of errno: 2
Error printed by perror: No such file or directory
Error opening file: No such file or directory

শূন্য এরর দিয়ে ডিভাইড করাঃ অনেক ডেভলপার এটি করেন না, যার ফলে রানটাইম এরর হয়ে প্রোগ্রামটি অচল হয়ে যায়। শূন্য এরর দিয়ে ডিভাইড করতে নিচের কোড লিখতে হবে,
#include <stdio.h>
#include <stdlib.h>

main()
{
int dividend = 20;
int divisor = 0;
int quotient;

if( divisor == 0){
fprintf(stderr, "Division by zero! Exiting...\n");
exit(-1);
}
quotient = dividend / divisor;
fprintf(stderr, "Value of quotient : %d\n", quotient );

exit(0);
}
ঠিকভাবে লিখলে যা ফলাফল হবে তা হল,
Division by zero! Exiting...
প্রোগ্রামের Exit Status ঃ প্রোগ্রামিঙে কোন সফল কোডিঙের পরে EXIT_SUCCESS কোড পাওয়া যায় যা মূলত একটি ম্যাক্রো, এর মান ০, কোন প্রোগ্রামে এরর কন্ডিশন থাকলে এবং সেভাবেই বের হয়ে আসার চেষ্টা করলে এই কোডটি দেখাবে, EXIT_FAILURE। যেটিকে -1 দ্বারা প্রকাশ করা হয়, তাই এক্ষেত্রে এই কোড লেখা হয়,
#include <stdio.h>
#include <stdlib.h>

main()
{
int dividend = 20;
int divisor = 5;
int quotient;

if( divisor == 0){
fprintf(stderr, "Division by zero! Exiting...\n");
exit(EXIT_FAILURE);
}
quotient = dividend / divisor;
fprintf(stderr, "Value of quotient : %d\n", quotient );

exit(EXIT_SUCCESS);
}
ঠিকভাবে লিখা হলে যে ফলাফল আসবে তা হল,
Value of quotient : 4

এরচেয়ে কম ওয়ার্ডে হল না। বোনাস (1.20 => 350 words article) আশা করছি।

সি ফাইল অপারেশন্স . C File I/O

শেখ আবুল হাশিম

খুলনা খানজাহান আলী কলেজ

বাগেরহাট, খুলনা।

 

১. ফাইল খোলা
২. ফাইল থেকে কোন কিছু পড়া বা ফাইলে কিছু লেখা
৩. ফাইল বন্ধ করা

ফাইল ব্যবহারের জন্য আমাদের একটা ফাইল handle দরকার। এটার মাধ্যমে আমরা একটা ফাইরকে চিহ্নিত করি। এটা FILE টাইপের একটা পয়েন্টার যেটাকে এভাবে ডিক্লেয়ার করতে হয়ঃ

FILE *fp;

fopen দিয়ে একটা ফাইল খুললে আমরা এটা রিটার্ন পাই।

 

File open:

fp = fopen(filename, mode);

একটা ফাইল খোলার জন্য এই ফাংশনটা ব্যবহার কারা হয়। এই ফাংশনের দুইটি প্যারামিটার আছে। প্রথমটা ফাইলের নাম এবং দ্বিতীয়টা ফাইল খোলার পর কিভাবে ব্যবহার করা হবে সেটা প্রথমেই বলে দিতে হবে।

r – read মোডে ফাইল খোলা হবে। ফাইল আগে থেকে না থাকলে এভাবে ব্যবহার করলে FILE পয়েন্টার রিটার্ন করবে না।
w – read মোডে ফাইল খোলা হবে। ফাইল না থাকলে নতুন একটা ফাইল তৈরি হবে। ফাইল আগে থেকে থাকলে ফাইলের সব ডাটা মুছে যাবে এবং ফাইলের প্রথম থেকে লেখে হবে।
a – append- আগে থেকে আছে এরকম ফাইলের শেষে থেকে লেখা শুরু করার জন্য এই মোড ব্যবহার করা হয়। ফাইল না থাকলে নতুন একটা ফাইল তৈরি হবে।

+ ব্যবহার করে একই সাথে read এবং write করা যায়। এরপর ব্যবহার করে কিভাবে বা হবে সেটা ঠিক করা যায়।

r+ – একই সাথে লেখা এবং পড়ার দরকার হলে এবং ফাইলের শুরু থেকে পড়া শুরু করার জন্য এই মোড ব্যবহার করা হয়।
w+ – একই সাথে লেখা এবং পড়ার দরকার হলে এবং ফাইলের শুরু থেকে লেখা শুরু করার জন্য এই মোড ব্যবহার করা হয়। ফাইল না থাকলে নতুন একটা ফাইল তৈরি হবে।
a+ – একই সাথে লেখা এবং পড়ার দরকার হলে এবং ফাইলের শেষে লেখা শুরু করার জন্য এই মোড ব্যবহার করা হয়। ফাইল না থাকলে নতুন একটা ফাইল তৈরি হবে।

নীচে কয়েকটি উদাহরণ দেখি।

একটা ফাইল খুলে কোন কিছু লেখার জন্য এভাবে ফাইল ওপেন করা যায়ঃ

fp = fopen(“myfile.txt”, “w”);

তাহলে myfile.txt নামে একটি ফাইল তৈরি হবে যেটার মধ্যে আমরা লিখতে পারব।

read মোডে ফাইল খোলার জন্য এভাবে লিখতে হবেঃ

fp = fopen("names.txt", "r");

এখানে names.txt ফাইলটি থাকতে হবে। তাহলে আমরা এখন এই ফাইল থেকে পড়তে পারব।

 

File print:

এই ফাংশনটি printf এর মত তবে এটা ফাইলে লেখার জন্য ব্যবহার করা হয়।

যেমন আমরা যদি এভাবে লিখি

printf("Hello, World!");

তাহলে কনসোলে Hello, World! লেখা হবে।

fprintf এর ক্ষেত্রেও তাই- শুধু ফাইল handle টা দিয়ে দিতে হবে।

fprintf(fp, "Hello, World!");

তাহলে ফাইলে Hello, World! লেখা হবে।

 

File scan:

এই ফাংশনটি scanf এর মত তবে এটা ফাইল থেকে পড়ার জন্য ব্যবহার করা হয়।

যেমন আমরা যদি এভাবে লিখি

int num;
scanf(“%d”, &num);

তাহলে কিবোর্ড থেকে একটা পুর্ণসংখ্যা ইনপুট নিয়ে num ভেরিয়েবলে রাখা হবে।

fscanf এর ক্ষেত্রেও তাই- শুধু ফাইল handle টা দিয়ে দিতে হবে।

int num;
fscanf(fp, “%d”, &num);

তাহলে ফাইল থেকে একটা পুর্ণসংখ্যা পড়ে নিয়ে num ভেরিয়েবলে রাখা হবে।

 

File close:

ফাইল ব্যবহার শেষে ফাইলটি বন্ধ করার জন্য এই ফাংশন ব্যবহার করতে হবে।

এভাবে লিখলে ফাইল বন্ধ হবেঃ

fclose(fp);

একটা সম্পুর্ণ উদাহরণ দেখিঃ

#include "stdio.h"

 

int main()

{

FILE *fp;

 

fp = fopen("myfile.txt", "w");

 

fprintf(fp, "Hello, World!n");

 

fclose(fp);

 

return 0;

}

এটা রান করলে একটা ফাইল তৈরি হবে এবং তাতে Hello, World! লেখা হবে। আপনারা ফাইলটি খুলে দেখতে পারেন ঠিকমত লেখা হল কিনা।

আরও কয়েকটি ফাংশনের নাম জেনে রাখুন যেগুলো দিয়ে ফাইল থেকে পড়া বা ফাইলে লেখা যায়।
fputc
fgetc
fread
fwrite
ftell
fseek
fflush

সি প্রোগ্রামিঙে typedef এর ব্যবহার

সি প্রোগ্রামিঙে typedef এর ব্যবহারঃ
রিদওয়ান বিন শামীম

সি প্রোগ্রামিং ল্যাঙ্গুয়েজ typedef নামের একটি কি-ওয়ার্ড ব্যবহার করতে দেয়, যা নতুন নাম টাইপ করতে দেয়, নিচের উদাহরণে BYTE টার্ম বিবৃত করা হয়েছে।
typedef unsigned char BYTE;
বিবৃত করার পর unsigned char এর ব্যাখ্যা হিসাবে BYTE identifier রূপে কাজ করে। যেমন,
BYTE b1, b2;
বড় হাতের অক্ষর দ্বারা নিশ্চিত করা হয় যে এটি symbolic abbreviation কিন্তু ছোট হাতের অক্ষরও ব্যবহার করা যায় যেমন,
typedef unsigned char byte;
ব্যবহারকারী নির্ধারিত ডাটা বিবৃতির জন্য typedef ব্যবহার করা যায়, যেমন নতুন ডাটা টাইপের জন্য typedef ব্যবহার করা যায়, এরপর কাঠামোগত চলক প্রকাশের জন্য সরাসরি নিচের কোড ব্যবহার করা যায়।
#include
#include

typedef struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
} Book;

int main( )
{
Book book;

strcpy( book.title, "C Programming");
strcpy( book.author, "Nuha Ali");
strcpy( book.subject, "C Programming Tutorial");
book.book_id = 6495407;

printf( "Book title : %s\n", book.title);
printf( "Book author : %s\n", book.author);
printf( "Book subject : %s\n", book.subject);
printf( "Book book_id : %d\n", book.book_id);

return 0;
}
কোডগুলো ঠিকমত লিখা হলে তা যে ফলাফল দেখাবে তা হল,
Book title : C Programming
Book author : Nuha Ali
Book subject : C Programming Tutorial
Book book_id : 6495407
typedef vs #define
#define হল এক প্রকার C-directive যা যা বিভিন্ন ডাটা টাইপের aliases বোঝাতে ব্যবহার হয়। যা মূলত typedef এর মতই কিন্তু কিছু পার্থক্য আছে, typedef সিম্বোলিক নাম দেয়ার ক্ষেত্রে সীমাবদ্ধ কিন্তু #define সাধারণত alias এর ভ্যলু বোঝাতে পারে, typedef এর প্রভাব কম্পাইলার থেকে প্রকাশ পায় কিন্তু #define বিবৃতি প্রিপ্রসেসর থেকে প্রকাশ করা হয়। #define এর সবচে সহজ ব্যবহার নিচে দেখানো হল।
#include

#define TRUE 1
#define FALSE 0

int main( )
{
printf( "Value of TRUE : %d\n", TRUE);
printf( "Value of FALSE : %d\n", FALSE);

return 0;
}
উপরের কোড সঠিকভাবে লিখা হলে তা যে ফলাফল দেবে তা হল,
Value of TRUE : 1
Value of FALSE : 0

সি – বিট ক্ষেত্র (C – Bit Fields)

সি - বিট ক্ষেত্র (C - Bit Fields)
Md. Amirul Islam (ARIF)
Bogra

ধরুন আপনার সি প্রোগ্রামে একটি স্ট্রাচার নামক কয়েকটি TRUE/FALSE ভেরিয়াবল গ্রুপ ।
নিম্নরূপ:

struct
{
unsigned int widthValidated;
unsigned int heightValidated;
} status;

এই স্ট্রাচারের লাগে ৮ বাইট মেমোরি স্পেস কিন্তু আমরা প্রত্যেক ভেরিয়াবলে সংরক্ষণ করতে যাচ্ছি 0 অথবা 1 । সি প্রোগ্রামিং ল্যাঙ্গুয়েজ স্বল্প মেমোরি স্পেস ব্যবহার করতে একটি ভাল সুবিধা করে দিয়েছে । যদি আপনি এই ভেরিয়াবল ব্যাবহার করেন একটি স্ট্রাকচারের ভিতরে তারপর আপনি সংজ্ঞায়িত করতে পারবেন একটি ভেরিয়াবল এর প্রস্থ যা সি কম্পিলার বলে যে আপনি সুধুমাত্র সেই বাইট সংখ্যা ব্যাবহার করতে যাচ্ছেন ।
নিম্নে উদাহরণস্বরূপ, উপরোক্ত গঠন পুনরায় লেখা যেতে পারে:

struct
{
unsigned int widthValidated : 1;
unsigned int heightValidated : 1;
} status;

এখন, উপরোক্ত গঠনে 4 বাইট মেমোরি স্পেস স্ট্যাটাস ভেরিয়াবল এর জন্য লাগবে কিন্তু শুধুমাত্র 2 বিট ব্যাবহার হবে ভেলু গুলো জমা রাখতে । যদি আপনি প্রত্যেকটি একটি 1 বিটের প্রস্থে 32 ভেরিয়াবল ব্যাবহার করতে চান, তারপরেও স্ট্যাটাস স্ট্রাকচারে 4 বাইট হবে । কিন্তু যখনি আপনার ৩৩ ভেরিয়াবল থাকবে তখন এটি মেমোরির পরবর্তী স্লটে বরাদ্দ হবে । এবং এটাতে ৮ বাইট ব্যাবহার হবে।
আমাদের ধারণা বুঝতে নিম্নলিখিত উদাহরণে পরীক্ষা করা যাক:
#include
#include

/* define simple structure */
struct
{
unsigned int widthValidated;
unsigned int heightValidated;
} status1;

/* define a structure with bit fields */
struct
{
unsigned int widthValidated : 1;
unsigned int heightValidated : 1;
} status2;

int main( )
{
printf( "Memory size occupied by status1 : %d\n", sizeof(status1));
printf( "Memory size occupied by status2 : %d\n", sizeof(status2));

return 0;
}

যখন উপরের কোড গুলো প্রণীত ও অনুষ্ঠিত (compiled and executed) হয় তখন নিম্নলিখিত ফলাফল সৃষ্টি করে:
Memory size occupied by status1 : 8
Memory size occupied by status2 : 4

বিট ফিল্ড ঘোষণা (Bit Field Declaration)
একটি স্ট্রাকচারের ভিতর বিট ফিল্ডের ফর্ম ঘোষণা করা হয়ঃ

struct
{
type [member_name] : width ;
};

নিচে বিট ফিল্ডের ভেরিয়াবল উপাদানের বর্ণনা দেওয়া হলঃ

উপাদান বর্ণনা
type একটি ইন্টেগ্রা টাইপ (integer type) যেটা নির্ধারণ করে কিভাবে বিট ফিল্ডের এর মান ব্যাখ্যা করা হয়। টাইপ হতে পারেঃ int, signed int, unsigned int.
member_name বিট ফিল্ডের নাম।
width একটি বিট ফিল্ডের বিটের সংখ্যা। প্রস্থ (width) কে অবশ্যই নির্দিষ্ট প্রকারের বিট প্রস্থ এর সমান অথবা ছোট হতে হবে ।

একটি পূর্বনির্ধারিত প্রস্থ সঙ্গে সংজ্ঞায়িত ভেরিয়েবলকে বিট ফিল্ড বলা হয়। একটি বিট ক্ষেত্র একটি একক বিটের চেয়ে বেশি রাখা যাবে। উদাহরণস্বরূপ, যদি আপনার প্রয়োজন হয় একটি ভেরিয়াবল শুধুমাত্র ০ থেকে ৭ ভেলু জমা করতে তখন আপনি একটি বিট ফিল্ড সংজ্ঞায়িত করতে পারেন একটি ৩ বিটের প্রস্থের সাথে।
এরুপঃ

struct
{
unsigned int age : 3;
} Age;

উপরের গঠন সংজ্ঞা C কম্পাইলার নির্দেশ করে যে ভেলু জমা করতে এজ ভেরিয়াবল ব্যাবহার করছে শুধু ৩ বিট, যদি আপনি তিনের বেশি বিট ব্যাবহার করতে চেষ্টা করেন তখন এটা আপনাকে আনুমতি দেবে না ।
চলুন নিচের উধাহরন চেষ্টা করা যাকঃ

#include
#include

struct
{
unsigned int age : 3;
} Age;

int main( )
{
Age.age = 4;
printf( "Sizeof( Age ) : %d\n", sizeof(Age) );
printf( "Age.age : %d\n", Age.age );

Age.age = 7;
printf( "Age.age : %d\n", Age.age );

Age.age = 8;
printf( "Age.age : %d\n", Age.age );

return 0;
}

যখন উপরের কোড গুলো প্রণীত ও অনুষ্ঠিত (compiled and executed) হয় তখন নিম্নলিখিত ফলাফল সৃষ্টি করে:

Sizeof( Age ) : 4
Age.age : 4
Age.age : 7
Age.age : 0

The above structure definition instructs C compiler. that age variable is going to use only 3 bits to store the value, if you will try to use more than 3 bits then it will not allow you to do so. Let us try the following example:

সি প্রোগ্রামিং – স্ট্রাকচার

শেখ আবুল হাশিম
খুলনা খানজাহান আলী কলেজ
বাগেরহাট, খুলনা।

লেকচার ৯ – সি প্রোগ্রামিং – স্ট্রাকচার

C ল্যাংগুয়েজে একাধিক ভেরিয়েবল নিয়ে গ্রুপ ভেরিয়েবল ডিক্লেয়ার করা যায়। এই গুপটিকে বলা হয় স্ট্রাকচার। আমরা যদি কোন এক ব্যাক্তির নাম, বয়স এবং তার বেতন নিয়ে কাজ করতে চাই তাহলে সেগুলো একসাথে রাখা সুবিধাজনক।
সেজন্য আমরা এভাবে স্ট্রাকচার তৈরি করিঃ
struct [struct_name]
{
[structure fields]
};
যেমনঃ
struct Person
{
char name[20];
int age;
int salary;
};
এখানে স্ট্রাকচারে তিনটি ফিল্ড রয়েছে- name, age এবং salary । এই ফিল্ড তিনটিকে কোন আলাদা ভেরিয়েবল ধরার দরকার নেই। এগুলো সবসময় একসাথে থাকবে। তবে আলাদে ভাবে এদের মান দেখা বা পরিবর্তন করা যাবে।
এখন এই স্ট্রাকচারটিকে আমরা সাধারন একটা প্রাথমিক (primitive type) টাইপের ভেরিয়েবলের মত ব্যবহার করতে পারব।
যেমন এভাবে ভেরিয়েবল ডিক্লেয়ার করা হয়ঃ
Person p1;
[বিঃদ্রঃ আমরা বেশিরভাগ সময় C++ কম্পাইলার ব্যবহার করি। সেকারনে একেবারে শুদ্ধ C ল্যাংগুয়েজ ব্যবহার করার চেষ্টা করছি না এই লেকচারে।]

Initializing a Structure
ভেরিয়েবল ডিক্লেয়ার করার সময়ই অন্য টাইপের ভেরিয়েবলের যেমন প্রাথমিক মান ঠিক করে দেয়া যায় সেরকম স্ট্রাকচারের ক্ষেত্রেও করা যায়ঃ
Person p1 = {“”Kalam””, 38, 60000};
এক্ষেত্রে স্টাকচারের ফিল্ডগুলোর ক্রম ঠিক রাখতে হবে।
ক্রম উলটাপাল্টা করতে চাইলে ফিল্ডগুলোর নামসহ এভাবে লেখা যায়ঃ
Person p1 = { .age = 38, .name = “”Kalam””, .salary= 60000};
ফিল্ডের নামের আগে ডট (.) দিতে হবে। এক্ষেত্রে ইচ্ছা করলে এক বা একাধিক ফিল্ডের মান না দিলেও অসুবিধা নেই।
স্ট্রাকচারের ফিল্ডগুলো নিয়ে আলাদা ভাবে কাজ করতে চাইলে ডট (.) ব্যবহার করে করা যায়ঃ
int current_age;
Person p1;

p1.name = “"Kalam";
p1.age = 38;
p1.salary = 60000;

current_age = p1.age
Assignment
Person p1 = {“"Kalam"”, 38, 60000};

Person p2;

p2 = p1; /* copies the member values from p1 into p2. */
এখানে মনে রাখতে হবে এভাবে একটা ভেরিয়েবল থেকে আরেকটাতে মান কপি করলে দুইটা আলাদা ভেরিয়েবল হিসাবে কাজ করবে। একটাতে মান পরিবর্তন করলে আরেকটাতে কোন পরিবর্তন হবে না।
যেমন p2.age=56; লিখলে p1.age এর মানের কোন পরিবর্তন হবে না।
Functions and Structures
ফাংশনের প্যারামিটার বা রিটার্ন ভ্যালু হিসাবে অন্য যেকোন টাইপের ভেরিয়েবলের মতই স্ট্রাকচার ব্যবহার করা যায়।
নীচের প্রোগ্রামটি লক্ষ করুণঃ
#include "stdio.h"

void print_person(Person p)
{
printf("Name: %sn", p.name);
printf("Age: %dn", p.age);
printf("Salary: %dn", p.salary);
}

void main()
{
Person p1 = {“"Kalam"”, 38, 60000};
print_person(p1);
}
এখানে ভ্যালু হিসাবে পাঠানো হচ্ছে স্ট্রাকচার। ফাংশনের মধ্যে কোন ফিল্ডের মান পরিবর্তন করলে সেটা ফাংশনের বাইরে কোন প্রভাব ফেলবে না বা মান পরিবর্তন হবে না।
রেফারেন্স হিসাবেও স্ট্রাকচার ভেরিয়েবল ব্যবহার করা যায় এভাবে (অন্য টাইপের ভেরিয়েবলের মতই ভরিয়েবলের নামের পূর্বে & ব্যবহার করে)
#include "stdio.h"

void test_person(Person &p)
{
if(p.age == 0)
{
p.age=18;
}
}

void main()
{
Person p1 = {“"Kalam"”, 0, 60000};
test_person(p1);

printf("Age: %d", p1.age);
}
এখনে Age: 18 এভাবে আউটপুট পাব।
Arrays of Structure
অন্য টাইপের মতই স্ট্রাকচারের Array তৈরি ও ব্যবহার করা যায়ঃ
ডিক্লেয়ার করার জন্য এভাবে লিখতে হবেঃ
Person pn[10];
এখন অন্য টাইপের ভেরিয়েবলের মতই ইনডেক্স ব্যবহার করা যাবে এভাবেঃ
pn[0].age = 30;

pn[9].salary=50000;
Structure within a Structure (nested structure)
আমরা যদি্ ব্যক্তির ঠিকানাও রাখতে চাই একসাথে তাহলে আমরা nested structure ব্যবহার করে সেটা করতে পারিঃ
struct Person
{
char name[20];
int age;
int salary;
struct address
{
int house_no;
char street[30];
char post[30];
char district[30];
};
};
এক্ষেত্রে যেভাবে ব্যবহার করতে হবেঃ
Person p1;

p1.age = 34;
p1.address.house_no = 2543;

C – Operators . সি অপারেটর গুলো

আপনাকে স্বাগতম আমাদের টিটোরিয়াল সাইটে আসার জন্য। আজ আমরা আপনাকে শেখাবো অপারেটর কি।

প্রোগ্রামিং শিখতে হলে আপনাকে ইংরেজীও শিখতে হবে কারণ আপনাকে কম্পিউটারকে ইংরেজীর মাধ্যমে ইনপুট দিতে হবে তাই আমার এই টিউটোরিয়ালে আমি বাংলার পাশাপাশি দরকারি কিছু যায়গায় ইংরেজী শব্দ ব্যভার করেছি।

অপারেটর হলো একটি গাণিতিক লজিক যা আপনার প্রোগ্রামকে বিভিন্ন দিক নির্দেশ দেবে। এটি সি প্রোগ্রামে সীমাবদ্ধ থাকে। নিচের নাম গুলো আপনাকে ইংরেজীতেই জানতে হবে। অপারেটর বিভিন্ন রকমের হয়ে থাকে তা হলোঃ

  1. Arithmetic Operators
  2. Relational Operators
  3. Logical Operators
  4. Bitwise Operators
  5. Assignment Operators
  6. Misc Operators

এই টিউটোরিয়ালট এ পাটিগণিত, রিলেশনাল, লজিক্যাল, নিয়োগ এবং অন্যান্য অপারেটরদের একের পর এক ব্যাখ্যা করবে।

Arithmetic Operators

নিচের টেবিলের সব Arithmetic Operators সি প্রোগ্রামকে সমর্থন করে। মনে করুন পরিবর্তনশীল A 10  পরিবর্তনশীল B 20:

Operator Description Example
== Checks if the values of two operands are equal or not, if yes then condition becomes true. (A == B) is not true.
!= Checks if the values of two operands are equal or not, if values are not equal then condition becomes true. (A != B) is true.
> Checks if the value of left operand is greater than the value of right operand, if yes then condition becomes true. (A > B) is not true.
< Checks if the value of left operand is less than the value of right operand, if yes then condition becomes true. (A < B) is true.
>= Checks if the value of left operand is greater than or equal to the value of right operand, if yes then condition becomes true. (A >= B) is not true.
<= Checks if the value of left operand is less than or equal to the value of right operand, if yes then condition becomes true. (A <= B) is true.

 

 

Relational Operators

নিচের টেবিলের সব Relational Operators সি প্রোগ্রামকে সমর্থন করে। মনে করুন পরিবর্তনশীল A 10  পরিবর্তনশীল B 20:

Operator Description Example
== Checks if the values of two operands are equal or not, if yes then condition becomes true. (A == B) is not true.
!= Checks if the values of two operands are equal or not, if values are not equal then condition becomes true. (A != B) is true.
> Checks if the value of left operand is greater than the value of right operand, if yes then condition becomes true. (A > B) is not true.
< Checks if the value of left operand is less than the value of right operand, if yes then condition becomes true. (A < B) is true.
>= Checks if the value of left operand is greater than or equal to the value of right operand, if yes then condition becomes true. (A >= B) is not true.
<= Checks if the value of left operand is less than or equal to the value of right operand, if yes then condition becomes true. (A <= B) is true.

Logical Operators

নিচের টেবিলের সব Logical Operators সি প্রোগ্রামকে সমর্থন করে। মনে করুন পরিবর্তনশীল A 10  পরিবর্তনশীল B 20:

Operator Description Example
&& Called Logical AND operator. If both the operands are non-zero, then condition becomes true. (A && B) is false.
|| Called Logical OR Operator. If any of the two operands is non-zero, then condition becomes true. (A || B) is true.
! Called Logical NOT Operator. Use to reverses the logical state of its operand. If a condition is true then Logical NOT operator will make false. !(A && B) is true.

Bitwise Operators

Bitwise অপারেটর বিট উপর কাজ করে এবং বিট-দ্বারা-বিট অপারেশন সম্পাদন করে:

p Q p & q p | q p ^ q
0 0 0 0 0
0 1 0 1 1
1 1 1 1 0
1 0 0 1 1

 

অনুমান কর যদি A = 60; এবং B = 13; নিম্নরূপ এখন বাইনারি বিন্যাসে তারা হবে:

A = 0011 1100

B = 0000 1101

-----------------

A&B = 0000 1100

A|B = 0011 1101

A^B = 0011 0001

~A  = 1100 0011

 

সি ভাষা দ্বারা সমর্থিত Bitwise অপারেটরদের নিম্নলিখিত টেবিলে তালিকাভুক্ত করা হয়. পরিবর্তনশীল একটি 60 ঝুলিতে এবং পরিবর্তনশীল বি, তারপর 13 ঝুলিতে অনুমান:

 

Operator Description Example
& Binary AND Operator copies a bit to the result if it exists in both operands. (A & B) will give 12, which is 0000 1100
| Binary OR Operator copies a bit if it exists in either operand. (A | B) will give 61, which is 0011 1101
^ Binary XOR Operator copies the bit if it is set in one operand but not both. (A ^ B) will give 49, which is 0011 0001
~ Binary Ones Complement Operator is unary and has the effect of 'flipping' bits. (~A ) will give -61, which is 1100 0011 in 2's complement form.
<< Binary Left Shift Operator. The left operands value is moved left by the number of bits specified by the right operand. A << 2 will give 240 which is 1111 0000
>> Binary Right Shift Operator. The left operands value is moved right by the number of bits specified by the right operand. A >> 2 will give 15 which is 0000

 

Assignment Operators

 

সি ভাষা দ্বারা সমর্থিত নিম্নলিখিত Assignment অপারেটর আছে:

Operator Description Example
= Simple assignment operator, Assigns values from right side operands to left side operand C = A + B will assign value of A + B into C
+= Add AND assignment operator, It adds right operand to the left operand and assign the result to left operand C += A is equivalent to C = C + A
-= Subtract AND assignment operator, It subtracts right operand from the left operand and assign the result to left operand C -= A is equivalent to C = C - A
*= Multiply AND assignment operator, It multiplies right operand with the left operand and assign the result to left operand C *= A is equivalent to C = C * A
/= Divide AND assignment operator, It divides left operand with the right operand and assign the result to left operand C /= A is equivalent to C = C / A
%= Modulus AND assignment operator, It takes modulus using two operands and assign the result to left operand C %= A is equivalent to C = C % A
<<= Left shift AND assignment operator C <<= 2 is same as C = C << 2
>>= Right shift AND assignment operator C >>= 2 is same as C = C >> 2
&= Bitwise AND assignment operator C &= 2 is same as C = C & 2
^= bitwise exclusive OR and assignment operator C ^= 2 is same as C = C ^ 2
|= bitwise inclusive OR and assignment operator C |= 2 is same as C = C | 2

Misc Operators ↦ sizeof & ternary

Sizeof  এবং সহ কয়েক অন্যান্য গুরুত্বপূর্ণ অপারেটর আছে  যা  সি ভাষা দ্বারা সমর্থিত.

Operator Description Example
sizeof() Returns the size of an variable. sizeof(a), where a is integer, will return 4.
& Returns the address of an variable. &a; will give actual address of the variable.
* Pointer to a variable. *a; will pointer to a variable.
? : Conditional Expression If Condition is true ? Then value X : Otherwise value Y

Operators Precedence in C

অপারেটর প্রাধান্য একটি অভিব্যক্তি পদ গ্রুপ নির্ধারণ করে. এই একটি অভিব্যক্তি মূল্যায়ন করা হয় কিভাবে প্রভাবিত করে. নির্দিষ্ট অপারেটরের অন্যদের তুলনায় বেশি প্রাধান্য আছে; উদাহরণস্বরূপ, গুণ অপারেটর ছাড়াও অপারেটর বেশী প্রাধান্য আছে.

 

উদাহরণস্বরূপ X = 7 + + 3 * 2; এখানে, এক্স, 13 নির্ধারিত হয় না 20 অপারেটর * + + চেয়ে বেশী প্রাধান্য আছে, তাই এটা প্রথম 3 * 2 দিয়ে গুন করা হয় এবং তারপর 7 মধ্যে যোগ করা হয়.

 

এখানে, সর্বোচ্চ প্রাধান্য দিয়ে অপারেটরদের টেবিলের শীর্ষে প্রদর্শিত হবে, সর্বনিম্ন সঙ্গে যারা নীচের অংশে প্রদর্শিত হবে. একটি অভিব্যক্তি মধ্যে বেশি প্রাধান্য, অপারেটর প্রথম মূল্যায়ন করা হবে.

Category  Operator  Associativity 
Postfix () [] -> . ++ - - Left to right
Unary + - ! ~ ++ - - (type)* & sizeof Right to left
Multiplicative * / % Left to right
Additive + - Left to right
Shift << >> Left to right
Relational < <= > >= Left to right
Equality == != Left to right
Bitwise AND & Left to right
Bitwise XOR ^ Left to right
Bitwise OR | Left to right
Logical AND && Left to right
Logical OR || Left to right
Conditional ?: Right to left
Assignment = += -= *= /= %=>>= <<= &= ^= |= Right to left
Comma , Left to right

C – Strings . সি প্রোগ্রামিং এ স্ট্রিং

C - Strings
মোঃ আব্দুল্লাহ
সি প্রোগ্রামিং এ স্ট্রিং হল মুলত এক ডাইমেনশনের array যা কিনা শেষ হয় '\0' বা null character দিয়ে ।
নিম্নের বিবৃতি এবং উদ্ধৃতিটি এমন একটি স্ট্রিং তৈরী করে যা "Hello" স্ট্রিংটি ধারণ করে। array র শেষে null character কে ধারণ করার জন্য array র ধারণক্রিত পদের স্ট্রিং একের মত বড় যেন তা "Hello." স্ট্রিংটি ধারণ করতে পারে।
char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};

তুমি যদি array শুরু করার নিয়ম অনুসরণ করতে চাও তবে তুমি উপরের বিবৃতিটি নিম্নরুপে লিখতে পার।
char greeting[] = "Hello";
উপরের স্ট্রিংটি মেমোরিরে কিভাবে থাকবে তার জন্য নীচের ছবিটি দেখতে পারোঃ

বস্তুত তুমি স্ট্রিং কন্সটান্টের শেষে null characte টিকে স্থাপন কর না। সি কম্পাইলর নিজে থেকে '\0' কে স্ট্রিং এর শেষে স্থাপন করে যখন এটি array initialize করে। চলো উপরের স্ট্রিং কে প্রিন্ট করিঃ
#include <stdio.h>
int main ()
{
char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
printf("Greeting message: %s\n", greeting );
return 0;
}

যখন উপরের কোডটি কম্পাইল করে রান করা হয় তখন এটি নিম্নোক্ত ফলাফল দেয়ঃ
Greeting message: Hello

সি স্ট্রিং এর জন্য অনেক ফাংসন এর অবলম্বন করে থাকে । নিম্নে তার একটি তালিকা দেওয়া হলঃ
S.N. Function & Purpose
1 strcpy(s1, s2);
স্ট্রিং s2 কে s1 এ কপি করে।
2 strcat(s1, s2);
স্ট্রিং s1 এর শেষে স্ট্রিং s2 কে যুক্ত করে।
3 strlen(s1);
স্ট্রিং s1 এর দৈর্ঘ্য ফেরত পাঠায় ।
4 strcmp(s1, s2);
যদি s1 এবং s2 সমান হয় তবে 0; যদি s1s2 হলে 0 থেকে বেশি ফেরত দেয়।
5 strchr(s1, ch);
ch এর পয়েন্টার ফেরত পাঠায় যখন ch প্রথম স্ট্রিং s1 এ দেখা যায় ।
6 strstr(s1, s2);
স্ট্রিং s1 এর মধ্যে স্ট্রিং s2 প্রথম দেখা যায় তার পয়েন্টেরকে ফেরত দেয়।
নিম্নের উদাহরণটি উপরে দেখানো কিছু ফাংসনের ব্যবহার দেখায়ঃ
#include <stdio.h>
#include <string.h>

int main ()
{
char str1[12] = "Hello";
char str2[12] = "World";
char str3[12];
int len ;

/* copy str1 into str3 */
strcpy(str3, str1);
printf("strcpy( str3, str1) : %s\n", str3 );

/* concatenates str1 and str2 */
strcat( str1, str2);
printf("strcat( str1, str2): %s\n", str1 );

/* total lenghth of str1 after concatenation */
len = strlen(str1);
printf("strlen(str1) : %d\n", len );
return 0;
}

যখন উপরের কোডটি কম্পাইল করে এবং রান করা হয়, এটি নিম্নোক্ত ফলাফল দেয়ঃ
strcpy( str3, str1) : Hello
strcat( str1, str2): HelloWorld
strlen(str1) : 10

C – Loops

C - Loops
মোঃ আব্দুল্লাহ

কখনো কখনো এমন পরিস্থিতি হতে পারে যে একটি কোড ব্লককে একাধিকবার পরিচালনা করতে হতে পারে। সাধারনত, বিবৃতিগুলি একের পর এক পরিচালিত হয়। একটি ফাংশনের প্রথম বিবৃতিটি প্রথমে পরিচালিত হবে, এরপর দ্বিতীয়টি, তারপর বাকিগুলি।
প্রোগ্রামিং এর ভাষাগুলি বিভিন্ন ধরনের পরিচালনা চক্র অনুসরন করে যা আরো জটিল পরিচালনার পথে পরিচালিত হতে পারে।
লুপ বিবৃতি একটি বিবৃতি বা এক গুচ্ছ বিবৃতিকে একাধিক বার পরিচালনার অনুমুতি দেয় সাধারন উপায়ে সব ধরনের প্রগ্রামিং ভাষায়।

সি প্রোগ্রামিং ভাষা লুপিং চাহিদা পরিপূরণের জন্য নিম্নের ধরনের লুপ দিয়ে থাকে। নিম্নের লিংকগুলি ক্লিক করে এর সম্পর্কে বিস্তারিত জানো।
Loop Type Description
while loop
হওয়াইল লুপ যখন প্রদত্ত যুক্তিটি সত্য তখন এটি একটি বিবৃতি বা এক গুচ্ছ বিবৃতিকে পুনরাবৃত্তি করে। এটি লুপটিকে পরিচালনার আগে বিবৃতিকে পরীক্ষা করে।
for loop
ফর লুপ বিবৃতির ধারা্টিকে একাধিকবার পরিচালনা করে এবং কোডটিকে সংক্ষেপে প্রকাশ করে যা লুপ চলকের ব্যবস্থাপনা করে।
do...while loop
ডু... হওয়াইল লুপ এটি হওয়াইল বিবৃতির মত, শুধু এটি লুপের শেষে যুক্তি পরীক্ষা করে।
nested loops
ডু... হওয়াইল লুপের জন্য তুমি এক বা একাধিক লুপকে যেকোন হওয়াইল লুপের ভিতরে ব্যবহার করতে পার।

Loop Control Statements:

লুপ নিয়ন্ত্রন বিবৃতি সাধারন ধারা থেকে পরিবর্তিত হয়ে পরিচালিত হতে পারে। যখন পরিচালনা একটি সুযোগ রেখে দেয় তখন সব বস্তু যা ওই সুযোগে নিজে থেকে সৃষ্টি হয়েছিল তা ধ্বংস হয়ে যায়।
সি নিম্নোক্ত নিয়ন্ত্রন বিবৃতিকে সমর্থন করে। নিম্নের লিঙ্কটিকে ক্লিক করে এর সম্পর্কে বিস্তারিত জানো।
Control Statement Description
break statement
ব্রেক বিবৃতি এটি লুপকে শেষ বা বিবৃতিকে পরিবর্তন করে । লুপ বা সুইচকে অনুসরণ করে বিবৃতিকে সঙ্গে সঙ্গে পরিচালনা করে।
continue statement
কনটিনিউ বিবৃতি এটি লুপকে এর অবশিষ্ট অংশকে টপকে এবং সঙ্গে সঙ্গে এর আগের যুক্তিতে ফেরত যেতে সাহায্য করে।
goto statement
গো টু বিবৃতি লেবেলেড বিবৃতিতে পরিবর্তনকে নিয়ন্ত্রণ করে। যদিও গো টু বিবৃতিতে প্রোগ্রামটিকে পরিবর্তন করার উপদেশ দেওয়া হয় না।

The Infinite Loop:
যদি কোন যুক্তি কখনও মিথ্যা না হয় তবে লুপটি ইনফিনিট লুপ হয়। এর জন্য ফর লুপটি ব্যবহৃত হয়। যদিও এই তিনটি এক্সপ্রেশনের একটিও ফর লুপের জন্য প্রয়োজন হয় না, তবুও তুমি একটি স্থায়ী লুপ বানাতে পার নির্ভরশীল এক্সপ্রেশনকে খালি রেখে।
#include <stdio.h>
int main ()
{
for( ; ; )
{
printf("This loop will run forever.\n");
}
return 0;
}

যখন নির্ভরশীল এক্সপ্রেসন অনুপস্থিত থাকে, তখন একে সত্যি ধরে নেয়া হয়। তোমার একটি প্রস্তুতিমূলক বা ক্রমবৃদ্ধি এক্সপ্রেশন থাকতে পারে , কিন্তু সি প্রোগ্রাম বেশিরভাগ ক্ষেত্রে ফর (;;) বানানোর জন্য ইনফিনিট লুপকে প্রকাশ করে।

C – Command Line Arguments (কমান্ড লাইন আর্গুমেন্ট)

C - Command Line Arguments

মোঃ আব্দুল্লাহ

একটি সি প্রোগ্রাম রান করার সময় কমান্ড লাইন থেকে কিছু ভেল্যু বা মান পাস করা সম্ভব । এই ভেল্যু বা মান গুলোকে কমান্ড লাইন আর্গুমেন্ট বলা হয় । অনেক সময় এই কমান্ড লাইন আর্গুমেন্ট অনেক গুরুত্বপূর্ণ এবং প্রয়োজনীয় হয়ে উঠে কারন এই কমান্ড লাইন আর্গুমেন্ট দিয়ে একটি সি প্রোগ্রামকে বাহির থেকে নিয়ন্ত্রণ করা যায় যা কিনা প্রোগ্রামের ভিতরের হার্ড কোডেড ভেল্যু বা মান তুলনায় বেশী কার্যকরী।
কমান্ড লাইন আর্গুমেন্ট এর আর্গুমেন্ট গুলি main( int argc, char *argv[]) ফাংশন এর আর্গুমেন্ট হিসেবে ব্যবহৃত হয়ে থাকে, যেখানে argc উল্লেখ করে কতগুলি আর্গুমেন্ট পাঠানো হয়েছে এবং argv[] হল pointer array যা কিনা যেই আর্গুমেন্ট গুলি পাঠানো হয়েছে তার দিকে point করে থাকে । নিম্নে একটি সহজ উদাহরণ তুলে ধরা হল যার দ্বারা পরীক্ষা করা যাবে যে প্রোগ্রামে কোন আর্গুমেন্ট পাঠানো হয়েছে কিনা এবং যদি পাঠানো হয়ে থাকে তাহলে ঐ অনুযায়ী কাজ করাঃ

#include <stdio.h>

int main( int argc, char *argv[] )
{
printf("Program name %s\n", argv[0]);

if( argc == 2 )
{
printf("The argument supplied is %s\n", argv[1]);
}
else if( argc > 2 )
{
printf("Too many arguments supplied.\n");
}
else
{
printf("One argument expected.\n");
}
}

 

উপরের প্রোগ্রামটি কম্পাইল করে যখন একটি কমান্ড লাইন আর্গুমেন্ট দিয়ে যখন রান করা হবে, তখন নিম্নোক্ত আউটপুট দেখাবেঃ
$./a.out testing
The argument supplied is testing

যখন দুইটি কমান্ড লাইন আর্গুমেন্ট দিয়ে যখন রান করা হবে, তখন নিম্নোক্ত আউটপুট দেখাবেঃ
$./a.out testing1 testing2
Too many arguments supplied.

যখন কোন আর্গুমেন্ট না দিয়ে যখন রান করা হবে, তখন নিম্নোক্ত আউটপুট দেখাবেঃ
$./a.out
One argument expected

এইখানে উল্লেখ্য যে, argv[0] তে যেই প্রোগ্রামটি কম্পাইল করে রান করা হবে তার নাম সংরক্ষিত হয়ে থাকবে এবং argv[1] হল pointer যা কিনা প্রথম আর্গুমেন্টকে point করে থাকবে এবং *argv[n] সর্বশেষ আর্গুমেন্টকে point করে থাকবে । যদি কোন আর্গুমেন্ট না পাঠানো হয় তাহলে argc এর মান হবে ১ এবং যদি একটি আর্গুমেন্ট হয় তাহলে argc এর মান হবে ২ ।
কমান্ড লাইন আর্গুমেন্ট এর প্রত্যেকটি আর্গুমেন্ট একটি স্পেস দিয়ে আলাদা করে পাঠানো হয়ে থাকে অথবা যদি কোন আর্গুমেন্টেই স্পেস থাকে তাহলে ডাবল কোটেশন ("") বা সিংগেল কোটেশন ('') দিয়ে পাঠাতে হয় ।
নিম্নের প্রোগ্রামটির মাধ্যমে আমরা প্রোগ্রামটির নাম এবং স্পেসসহ কোন আর্গুমেন্ট যদি দিতে চাই তা কিভাবে দিবো তা দেখবঃ
#include <stdio.h>

int main( int argc, char *argv[] )
{
printf("Program name %s\n", argv[0]);

if( argc == 2 )
{
printf("The argument supplied is %s\n", argv[1]);
}
else if( argc > 2 )
{
printf("Too many arguments supplied.\n");
}
else
{
printf("One argument expected.\n");
}
}

উপরের প্রোগ্রামটি কম্পাইল করে যখন একটি কমান্ড লাইন আর্গুমেন্ট দিয়ে যখন রান করা হবে, তখন নিম্নোক্ত আউটপুট দেখাবেঃ
$./a.out "testing1 testing2"

Progranm name ./a.out
The argument supplied is testing1 testing2

উল্লেখ যে, এইখানে একটি আর্গুমেন্টই স্পেসসহ পাঠানো হয়েছে ।

সি প্রোগ্রামিং ল্যাংগুয়েজ পরিচিতি (C – Language Overview)

সি প্রোগ্রামিং ল্যাঙ্গুয়েজ
নাফিরুল ইসলাম

সি প্রোগ্রামিং ল্যাঙ্গুয়েজ প্রথম উদ্ভাবিত হয়েছিল ডেনিশ এম রিচসি এর মাধ্যমে যার প্রধান লক্ষই ছিল উনিক্স অপারেটিং সিস্টেম ব্যবহার উন্নত পর্যায়ে নিয়ে যাওয়া। DEC PDP-11 কম্পিউটারে ১৯৭২ এই সি প্রোগ্রামিং ল্যাঙ্গুয়েজ এর ব্যবহার প্রথম লক্ষ্য করা যায়।

১৯৭২ সালে ব্রায়ান কারনিঘান এবং ডেনিশ রিচসি দুজনে মিলে সি প্রোগ্রামিং ল্যাঙ্গুয়েজ প্রথম বিবরণ বের করেন যা এখন K&R Standard নামে পরিচিত।

উনিক্স অপারেটিং সিস্টেম, সি কম্পাইলার এবং উনিক্স অপারেটিং সিস্টেম এর সব গুরুত্বপূর্ণ প্রোগ্রামগুলো সি প্রোগ্রামিং ল্যাঙ্গুয়েজ এ রচিত। এখন তা বিভিন্ন কারনে টেকনোলজি বিশ্বে জনপ্রিয়তা অর্জন করেছে। এগুলোর মধ্যে উল্লেখযোগ্য কিছু কারন হল,
১. এটা সহজেয় শেখা যায়।
২. এটা একটা সুগঠিত প্রোগ্রামিং ভাষা।
৩. এটা সাবলীল প্রোগ্রাম তৈরিতে ব্যবহার করা হয়।
৪. এটা ল-লেভেল কাজ গুলো রক্ষা করতেও ব্যবহার করা হয়।
৫. এটা কম্পিউটার এর বিভিন্ন প্লাটফর্মে প্রয়োগ করা যাবে।

সি ল্যাঙ্গুয়েজ সম্পর্কে যা কিছু সত্যি

১. এটা প্রধানত উনিক্স অপারেটিং সিস্টেম তৈরিতে প্রথম উদ্ভাবন করা হয়েছিল।
২. ১৯৭০ সালের বি ল্যাঙ্গুয়েজ এর উত্তরসরি হল সি ল্যাঙ্গুয়েজ।
৩. এটা ১৯৮৮ সালে American National Standard Institute এর দ্বারা প্রাতিষ্ঠানিক রূপ দেয়া হয়েছিল।
৪. ১৯৭৩ সালে উনিক্স অপারেটিং সিস্টেম এর পুরোটাই সি ল্যাঙ্গুয়েজ এ তৈরি করা হয়েছিল।
৫. আজকের অতীব জনপ্রিয় অপারেটিং সিস্টেম লিনাক্স এর অপারেটিং সিস্টেম এবং RBDMS মাইএসকিউএল সি ল্যাঙ্গুয়েজ এ রচিত হয়েছে।