Learn C Programming

lesson ৩ / ৮ · C-র সঙ্গে পরিচয়: প্রথম program, চিহ্ন ধরে ধরে

Module ১ · C-র সঙ্গে পরিচয়: প্রথম program, চিহ্ন ধরে ধরে

চিহ্নের অভিধান: C-র প্রতিটা সাইন কী বলে

Freeপড়া

এই lesson-এ যা শিখবে

  • C যে চিহ্নগুলো ব্যবহার করে, প্রতিটার আসল নাম আর একটা কাজ বলতে পারবে।
  • চার রকম bracket দেখেই চিনতে পারবে, আর কোনটা কী কাজ করে বলতে পারবে।
  • দেখতে একরকম ছয়টা জোড়া আলাদা করতে পারবে, শুরুটা single quote আর double quote দিয়ে।

Bob পর্দায় আঙুল রেখে Maria-কে জিজ্ঞেস করল, ওই আঁকাবাঁকা জিনিসটা কী করে। Maria জিজ্ঞেস করল, কোন আঁকাবাঁকা জিনিসটা। ওই লাইনে তিনটা আছে।

দুইজনের কেউই ওটা খুঁজে বের করতে পারছে না, কারণ কেউই জানে না ওটার নাম কী। এই lesson-টাই সেই অভিধান। এটা "ওই ছোট টুপির মতো জিনিসটা কী করে"-কে বানিয়ে দেয় "C-তে caret operator কী করে", যার উত্তর এক খোঁজেই মেলে।

Track-র বাকিটা করার সময় এই lesson খোলা রাখো। এটা দেখে নেওয়ার page, মুখস্থ করার chapter না।

Bracket আর brace: চারটা জোড়া, চারটা কাজ

C চার রকম bracket ব্যবহার করে, আর একটার জায়গায় আরেকটা বসে না। ভুল জোড়াটা ব্যবহার করা মানে সবচেয়ে দ্রুত একটা গোলমেলে message-এ পৌঁছানো।

চিহ্নআসল নামএকে আরও বলা হয়C-তে কাজপ্রথম দেখা
( )Parenthesesround bracket, parenFunction call, parameter-র তালিকা, condition, দল বাঁধা, castM1 lesson 1
{ }Bracescurly bracket, curly braceBlock, function-র body, initialiser-র তালিকাM1 lesson 1
[ ]Bracketssquare bracketArray ঘোষণা আর index করাM9
< >Angle bracketschevronSystem header include, আর ছোট-বড় মেলানোM1 lesson 1

তাই parentheses call করে আর দল বাঁধে, brace block ধরে, bracket array-তে index করে, আর angle bracket সম্পর্কহীন দুইটা কাজ করে।

Arithmetic আর assignment

চিহ্নআসল নামএকে আরও বলা হয়C-তে মানেপ্রথম দেখা
+Plus signplusযোগ, আর একক plusM1 lesson 2
-Minus signhyphen, dashবিয়োগ, আর ঋণাত্মক করাM1 lesson 4
*Asteriskstar, timesগুণ; pointer ঘোষণা আর pointer ধরে যাওয়াওM1 lesson 2
/Forward slashslash, solidusভাগ; // আর /* comment-ও শুরু করেM1 lesson 2
%Percent signpercent, modভাগশেষ; printf-র placeholder-ও শুরু করেM4
=Equals signequals, getsAssignment, কখনোই comparison নাM1 lesson 2
++Double plusincrementএক যোগ করাM4
--Double minusdecrementএক বিয়োগ করাM4
+=Plus equalsযোগ করে বসানোx += 3 মানে x = x + 3M4

=-কে মুখে পড়ো "পায়" বলে, "সমান" বলে না। ওই একটা অভ্যাসই গত lesson-র ফাঁদটা আটকে দেয়।

Comparison আর logic

চিহ্নআসল নামএকে আরও বলা হয়C-তে মানেপ্রথম দেখা
==Double equalsequal toসমান কি না; 1 বা 0 দেয়M1 lesson 2
!=Exclamation equalsnot equalসমান না কি নাM1 lesson 3
< >Less-than, greater-thanangle bracketমেলানোM1 lesson 3
<= >=Less-or-equal, greater-or-equalমেলানোM1 lesson 3
&&Double ampersandlogical ANDদুই দিকই সত্যি হলেই সত্যিM5
||Double vertical barlogical ORযেকোনো এক দিক সত্যি হলেই সত্যিM5
!Exclamation markbang, logical NOTসত্যিকে মিথ্যা আর মিথ্যাকে সত্যি করেM5

এই table-র প্রতিটা চিহ্ন তোমাকে একটা সংখ্যা দেয়: সত্যির জন্য 1, মিথ্যার জন্য 0। নিচের Example 2 ছয়টা comparison-ই ছাপে।

Punctuation আর গঠনের চিহ্ন

চিহ্নআসল নামএকে আরও বলা হয়C-তে কাজপ্রথম দেখা
;SemicolonStatement শেষ করেM1 lesson 1
,CommaArgument, declaration আর তালিকার জিনিস আলাদা করেM1 lesson 1
.Full stopperiod, dotদশমিক বিন্দু, আর struct-র একটা member-এ পৌঁছানোM12
:ColonLabel, case, ?-র দ্বিতীয় অর্ধেকM5
?Question markternaryConditional operator, :-র সঙ্গে জোড়ায়M5
'Single quoteapostropheএকটা character: 'A'M1 lesson 4
"Double quotequotation markএকটা string: "Hello"M1 lesson 1
\Backslashreverse slash\n-র মতো escape sequence শুরু করেM1 lesson 1
#Hashnumber sign, poundPreprocessor-র directiveM1 lesson 1
&Ampersandand signAddress-of, আর bitwise ANDM1 lesson 1
|Vertical barpipeBitwise ORM4
^Carethat, circumflexBitwise XORM4
~TildesquiggleBitwise NOTM4
_Underscorelow lineনামের ভেতরে চলে, আর শব্দ আলাদা করার চেনা উপায়M1 lesson 5
->ArrowPointer ধরে struct-র একটা memberM12

Punctuation-র পুরো সেটটা এই। C-তে এমন আর কোনো চিহ্ন নেই যেটার সঙ্গে তোমার এখন পরিচয় হলো না।

দেখতে একরকম, এমন ছয়টা জোড়া

এই জোড়াগুলোই beginner-দের ঘণ্টার পর ঘণ্টা খায়। প্রতিটা সারিতে দুইটা চিহ্ন, যারা keyboard-এ পাশাপাশি বসে আর সম্পর্কহীন জিনিস বোঝায়।

জোড়াপ্রথমটাদ্বিতীয়টাআলাদা রাখার উপায়
'A' আর "A"একটা character, 1 byteএকটা string, 2 byte: অক্ষরটা আর শেষের চিহ্নটাSingle quote-এ ঠিক একটা character থাকে
= আর ==একটা মান বসায়দুইটা মান মেলায়একটাকে বলো "পায়", আরেকটাকে "সমান কি না"
& আর &&Address-of, বা bitwise ANDLogical ANDদুইটা চিহ্ন মানে হ্যাঁ-না প্রশ্ন
/ আর \ভাগ, আর comment-র শুরুEscape sequenceযেটা সামনে হেলে আছে সেটা ভাগ করে
*-র দুই কাজa * b গুণ করেint *p একটা pointer ঘোষণা করেবাঁয়ে একটা type থাকলে ওটা pointer
<stdio.h> আর a < bInclude করার একটা headerএকটা comparisonপ্রথমটা কেবল #include লাইনেই বসে

নিচের অনুশীলন 2-তে এমন একটা program আছে, যেটা এই ছয়টার চারটা পরপর ব্যবহার করে, আর তোমাকে আগেই বলতে বলে সেটা কী ছাপবে।

Escape sequence: আকারহীন character-গুলো

String-র ভেতরে একটা backslash একটা escape sequence শুরু করে। নিজের কোনো দেখার মতো আকার নেই এমন character, বা যেটা থাকলে string-টাই শেষ হয়ে যেত, সেটা লেখার উপায় এটাই।

Escapeনামযা করে
\nNewlineপরের লাইনের শুরুতে যায়
\tHorizontal tabপরের tab-র ঘরে লাফ দেয়
\\Backslashএকটা আসল backslash ছাপে
\"Double quoteString শেষ না করে একটা quote ছাপে
\'Single quoteএকটা আসল apostrophe ছাপে
\0Null characterএকটা C string-র শেষ চিহ্নিত করে
\rCarriage returnচলতি লাইনের শুরুতে ফেরে
\aAlertTerminal-র ঘণ্টা বাজায়
\bBackspaceএক character পেছনে যায়
%%Percent, দুইবারEscape না: printf এভাবেই একটা % ছাপে

তুমি যতগুলোই লেখো, প্রতিটা escape output-এ একটা character। ওটা ঠিকঠাক গোনাই শেষের মাথা খাটানোর প্রশ্ন।

Example 1: চার রকম bracket-ই, নাম দেওয়া

ছোট একটা program, যেটা C-র প্রতিটা bracket ব্যবহার করে, আর প্রতিটা কাজের নাম comment-এ বলা আছে।

#include <stdio.h>        /* angle brackets: a system header */

int main(void)             /* parentheses: the parameter list */
{                          /* braces: the body of main */
    int marks[3] = {90, 85, 77};   /* brackets declare, braces initialise */

    printf("%d\n", marks[0]);      /* parentheses call, brackets index */
    return 0;
}
90

Array আসছে Module 9-এ, তাই marks[3] নিয়ে এখন ভাবতে হবে না। শুধু খেয়াল করো, চারটা আলাদা bracket এসেছে, আর এদের যেকোনো জোড়া অদলবদল করলেই program ভাঙে।

Compiler-এ চালাও
Example 2: প্রতিটা comparison, ছেপে দেখা

Comparison কোনো জাদু না। প্রতিটাই একটা expression, যার মান 1 বা 0, আর printf ওটাকে অন্য যেকোনো সংখ্যার মতোই ছাপতে পারে।

#include <stdio.h>

int main(void)
{
    int a = 7;
    int b = 4;

    printf("a == b gives %d\n", a == b);
    printf("a != b gives %d\n", a != b);
    printf("a > b  gives %d\n", a > b);
    printf("a < b  gives %d\n", a < b);
    printf("a >= b gives %d\n", a >= b);
    printf("a <= b gives %d\n", a <= b);
    return 0;
}
a == b gives 0
a != b gives 1
a > b  gives 1
a < b  gives 0
a >= b gives 1
a <= b gives 0

b-কে 7 করে আবার চালাও। ছয়টার চারটা উত্তর উল্টে যায়, আর যে দুইটা যায় না, ওদের নাম তোমার বলতে পারা উচিত।

Compiler-এ চালাও
Example 3: escape-গুলো, একসঙ্গে

এই program-টা রেখে দাও। এটা tab দিয়ে আলাদা করা একটা table, quote-র ভেতরে একটা কথা, একটা Windows path আর একটা শতকরা ছাপে, আর তাতেই এই মাসে লাগবে এমন প্রতিটা escape চলে আসে।

#include <stdio.h>

int main(void)
{
    printf("Name\tMarks\n");
    printf("Zara\t92\n");
    printf("Kenji\t87\n");
    printf("She said \"well done\"\n");
    printf("Path: C:\\progsity\\bin\n");
    printf("Discount: 15%%\n");
    return 0;
}
Name	Marks
Zara	92
Kenji	87
She said "well done"
Path: C:\progsity\bin
Discount: 15%

Source-র শেষ দুইটা লাইন দেখো। দুইটা backslash একটা ছাপে, আর দুইটা percent চিহ্ন একটা ছাপে। আর সব জায়গায় জোড়ার প্রথমটাই নির্দেশ।

Compiler-এ চালাও

এটা কোথায় কাজে লাগছে

  • Compiler-র message পড়া। expected '=', ',', ';', 'asm' or '__attribute__' before '-' token পড়া যায় না, যতক্ষণ তুমি বলতে না পারো "minus চিহ্নের আগে"। Message চিহ্নের নাম বলে, তাই তোমাকেও নামগুলো জানতে হয়।
  • সাহায্য চাওয়া। কোনো forum বা search engine "C-তে caret operator কী করে"-র উত্তর দেয়, আর "ওই ছোট টুপির মতো জিনিসটা কী করে"-র উত্তর দিতে পারে না। হুবহু শব্দ একটা debugging-র হাতিয়ার।
  • Documentation পড়া। C standard library-র page-গুলো printf বোঝায় percent চিহ্ন দিয়ে শুরু হওয়া conversion specification দিয়ে। এই lesson-র নামগুলোই ওই page-গুলোর নাম।
  • কাজে code review. "তোমার এখানে double ampersand দরকার, তুমি ampersand বসিয়েছ" এমন একটা বাক্য reviewer মুখেই বলে। এতে পাঠককে লাইনটা আবার পড়তে হয় না।

যে ভুলগুলো সবাই করে

১. Single quote দিয়ে একটা string লেখা।

printf('Hello\n');

GCC 12 দেয় warning: multi-character character constant, আর তারপর pointer-র জায়গায় integer পাঠানোর একটা warning। এটা build হয়, আর সাধারণত crash করে। Single quote-এ ঠিক একটা character থাকে; লেখার জন্য double quote লাগে।

২. একটা character-কে double quote-এ বসানো।

char grade = "A";

GCC 12-তে এটা warning: initialization of 'char' from 'char *' makes integer from pointer without a cast, আর GCC 14-তে error। তুমি এক byte-র বাক্সে একটা address রেখে দিলে। তুমি চেয়েছিলে 'A'।

৩. আসল backslash বোঝাতে একটা backslash লেখা।

printf("Path: C:\progsity\bin\n");

এখানে ভরসা করার মতো কোনো message নেই। \p হলো undefined behaviour, যেটা GCC চুপচাপ p হিসেবে ছাপে, আর \b একটা সত্যিকারের escape, backspace, যেটা তার আগের character খেয়ে ফেলে। Output দেখতে প্রায় ঠিক লাগে, আর ঠিক না। আসল backslash সব সময় দুইবার লেখো।

৪. নামের ভেতরে hyphen।

int total-marks = 90;

Message হলো error: expected '=', ',', ';', 'asm' or '__attribute__' before '-' token। C hyphen-টাকে বিয়োগ ধরে নিয়েছে, তারপর বিয়োগ করার মতো কিছু পায়নি। নামে underscore বসে, আর সেজন্যই পরের lesson ওটাকে total_marks বলে।

মাথা খাটাও

Amara এই এক লাইন লিখে বলছে string-টায় ছয়টা character আছে। Bob গুনে পায় নয়টা, কারণ source-এ সে ওটাই দেখতে পাচ্ছে।

printf("a\\b\"c\n");

তিনটা প্রশ্নের উত্তর দাও। পর্দায় হুবহু কী আসে? ছাপা লেখাটায় কয়টা character? আর "a\\b\"c" string-টা memory-তে কয় byte নেবে, যদি ওতে \n না থাকে?

প্রতিটা escape জোড়াকে একটা character হিসেবে গোনো। তারপর মনে রাখো, প্রতিটা string-র শেষে C একটা অদৃশ্য character বসায়, escape-র table-এ শূন্য মানের ওইটা।

অনুশীলন ১সহজ

Zara হাতে নোট নিচ্ছিল, আর চিহ্নের বদলে চিহ্নগুলোর নাম লিখে ফেলেছে। আসল চিহ্নগুলো ফিরিয়ে দাও, যাতে program-টা expression আর তার মান ছাপে।

Input. এক লাইনে দুইটা integer a b।

Output. ঠিক এক লাইন: (a + b) * 2 = X, দুইটা সংখ্যা আর উত্তরটা বসানো অবস্থায়।

Constraints. 0 <= a, b <= 1000।

Sample. Input 7 4 দিলে আসে (7 + 4) * 2 = 22। Parentheses আর asterisk character হিসেবে ছাপা হয়, আর দ্বিগুণ করাটা সত্যিকারের হিসাব।

#include <stdio.h>

int main(void)
{
    int a, b;
    scanf("%d %d", &a, &b);

    /* Print: open-paren, a, space, plus, space, b, close-paren,
       space, asterisk, space, 2, space, equals, space, the value. */
    printf("%d\n", 0);

    return 0;
}

Hidden test সহ grading হয় এই module-র Problems lesson-এ, restore-symbols নামে।

Compiler-এ চালাও
অনুশীলন ২সহজ

এই program চার লাইন কী ছাপবে, চালানোর আগে কাগজে লিখে ফেলো। তারপর চালিয়ে মিলিয়ে দেখো।

#include <stdio.h>

int main(void)
{
    int a = 6;
    int b = 3;
    char grade = 'A';

    printf("%d\n", a & b);
    printf("%d\n", a && b);
    printf("%c\n", grade);
    printf("%d\n", a / b);
    return 0;
}

কী খেয়াল করবে। 1 আর 2 নম্বর লাইনের তফাত একটা character, আর উত্তর আলাদা। Bitwise AND আসছে Module 4-এ, তাই এখন শুধু দেখো যে দুইটা চিহ্ন এক চিহ্ন না।

নিজে যাচাই করো। দেখার আগে চার লাইনের প্রতিটার নাম লিখে ফেলো: bitwise AND, logical AND, একটা character, integer-র ভাগ। চারটার নামই বলতে পারলে এই lesson-র কাজ হয়ে গেছে।

Compiler-এ চালাও

যে প্রশ্নগুলো সবার মনে আসে

  • এই সবগুলো মুখস্থ করতে হবে?

    না। চারটা bracket-র নাম আর দেখতে একরকম ছয়টা জোড়া তোমার দরকার। বাকিটা ফিরে এসে দেখে নেওয়ার page, আর সেজন্যই শেষ column-টা বলে দেয় প্রতিটা চিহ্ন প্রথম কোথায় আসে।

  • C-তে এত punctuation কেন?

    কারণ 1972 সালের একটা ধীর terminal-র জন্য এটা বানানো, যেখানে ছোট একটা চিহ্ন লম্বা একটা শব্দকে হারিয়ে দিত। Python কিছু কাজে শব্দ বেছেছে, যেটা পড়তে সহজ আর লিখতে বেশি।

  • "একে আরও বলা হয়" নামগুলো কি ভুল?

    ওগুলো অনানুষ্ঠানিক, আর সবাই ব্যবহার করে। ইচ্ছা হলে curly bracket বলো, আর জেনে রাখো standard আর প্রতিটা error message ওদের brace বলে।

  • নামে কোন চিহ্নগুলো ব্যবহার করতে পারি?

    অক্ষর, অঙ্ক আর underscore, আর নাম অঙ্ক দিয়ে শুরু হতে পারে না। এই table-র বাকি সবই operator বা punctuation, তাই ওগুলো নামটা শেষ করে দেয়।

  • অন্যের code-এ <<-র মতো যা দেখি, সেগুলো?

    ওগুলো এখানকার চিহ্নগুলোরই জোড়া। << হলো দুইটা less-than চিহ্ন, আর মানে bit shift, আসছে Module 4-এ। টুকরোগুলোর নাম বলতে পারলে জোড়াটাও খুঁজে নিতে পারবে।

মূল কথা

  • চার রকম bracket, চারটা কাজ: parentheses call করে, brace block বানায়, bracket index করে, angle bracket include করে বা মেলায়।
  • প্রতিটা চিহ্নের একটা আসল নাম আছে, আর error message সেটাই ব্যবহার করে।
  • Single quote-এ একটা character থাকে; double quote-এ একটা string।
  • & আর &&, = আর ==, / আর \: দেখতে এক, মানে সম্পর্কহীন তিনটা জোড়া।
  • তুমি যতগুলোই লেখো, একটা escape sequence output-এ একটা character।
  • দুইটা backslash একটা ছাপে, আর দুইটা percent চিহ্ন একটা ছাপে।

পরের lesson-এ দেখবে একটা character আসলে কেন ছোট একটা সংখ্যা, আর কোন character-র সংখ্যা কত, সেই পুরো table।

lesson ৩ শেষ

শেষ হলে চিহ্ন দিন, অগ্রগতি আপনার সাথে থাকবে।

পরেরটা: পুরো ASCII টেবিল, ১২৮টা সারিই