❖ 1. Introduction to C
1.1 What is C?
C គឺជាភាសាសរសេរកម្មវិធីទូទៅ (General-Purpose Programming Language) ដែលត្រូវបានបង្កើតឡើងដោយ Dennis Ritchie នៅឆ្នាំ 1972 នៅក្នុងក្រុមហ៊ុន Bell Labs។ C ជាភាសាដែលប្រើ procedural programming paradigm គឺជាភាសានៃការបង្ហាត់ programming មូលដ្ឋានដ៏ល្អបំផុត។
C ត្រូវបានគេប្រើប្រាស់យ៉ាងទូលំទូលាយក្នុងការអភិវឌ្ឍន៍ដូចជា៖
- Operating Systems (ដូចជា UNIX, Linux kernel)
- Embedded Systems (microcontrollers, IoT devices)
- System Software (compilers, assemblers)
- Device Drivers (កម្មវិធីបញ្ជាឧបករណ៍)
- Network Protocols (TCP/IP stack)
- Database Systems (MySQL core)
1.2 Features and Benefits of C
1. Procedural Language (ភាសា Procedural)
C ប្រើ procedural programming ដែលកម្មវិធីត្រូវបានរៀបចំជា functions/procedures។ ការប្រតិបត្តិ statements ធ្វើតាមលំដាប់ស្ដង់ដារ។
2. Low-Level Access (ចូលប្រើកម្រិតទាប)
C អនុញ្ញាតឱ្យចូលប្រើ hardware ដោយផ្ទាល់តាមរយៈ pointers និង memory addresses ធ្វើឱ្យវាល្អសម្រាប់ system programming។
3. Fast and Efficient (លឿន និងមានប្រសិទ្ធភាព)
C ត្រូវបាន compile ទៅជា machine code ដោយផ្ទាល់ ធ្វើឱ្យវាមានល្បឿនលឿនខ្លាំង។ Programs មានទំហំតូច និងប្រើ memory បានប្រសិទ្ធភាព។
4. Portability (ភាពអាចប្តូរ platform)
កូដ C ដែលសរសេរនៅ platform មួយ អាចដំណើរការលើ platforms ផ្សេងៗ ដោយ recompile ម្ដងទៀតប៉ុណ្ណោះ។
5. Rich Library (Library សម្បូរ)
C Standard Library (libc) ផ្ដល់ functions ជាច្រើន ដូចជា I/O, string manipulation, math operations, memory management, etc.
6. Middle-Level Language
C ស្ថិតនៅចន្លោះ low-level languages (Assembly) និង high-level languages (Python, Java)។ វាអាចធ្វើ low-level operations ដូច assembly ប៉ុន្តែក៏ងាយ program ដូច high-level languages ផងដែរ។
1.3 History of C
Dennis Ritchie បានបង្កើត C នៅ Bell Labs ក្នុងអំឡុងពេល 1969-1973 ក្នុងបំណងសរសេរ UNIX operating system។
- 1969-1972: ចាប់ផ្ដើម develop C ដោយ Dennis Ritchie
- 1972: C ចាប់ផ្ដើម official
- 1978: "The C Programming Language" ដោយ Kernighan & Ritchie (K&R C)
- 1989: ANSI C (C89) - ស្ដង់ដារ ANSI ដំបូង
- 1990: ISO C (C90) - ទទួលស្គាល់ដោយ ISO
- 1999: C99 - ភ្ជាប់ features ថ្មីៗ
- 2011: C11 - ភ្ជាប់ multithreading support
- 2018: C17/C18 - bug fixes and clarifications
- 2023: C23 - version ចុងក្រោយ
1.4 Structure of a C Program
មុនពេលចូលសិក្សាលម្អិត សូមមើលកម្មវិធី C ដំបូង (Hello World):
#include <stdio.h>
int main() {
printf("Hello, World!\n");
return 0;
}
ពន្យល់ផ្នែកនីមួយៗ៖
1.4.1 #include <stdio.h>
#include គឺជា preprocessor directive ដែលប្រាប់ compiler ឱ្យ include header file មួយ។ stdio.h (Standard Input/Output) ផ្ដល់ functions ដូចជា printf() និង scanf()។
Header files ដែលប្រើជាញឹកញាប់ក្នុង C:
#include <stdio.h> // printf, scanf, file operations
#include <stdlib.h> // malloc, free, exit, rand
#include <string.h> // strlen, strcpy, strcmp
#include <math.h> // sqrt, pow, sin, cos
#include <ctype.h> // isdigit, isalpha, toupper
#include <time.h> // time, clock
<stdio.h> ចំណែក C++ ប្រើ <iostream>។ ក្នុង C គ្មាន cout ឬ cin ទេ គឺប្រើ printf() និង scanf() ជំនួស។
1.4.2 Header Files ក្នុង C
Header files មាន 2 ប្រភេទ:
- Standard Library Headers: ប្រើ
< >ដូចជា<stdio.h> - User-defined Headers: ប្រើ
" "ដូចជា"myheader.h"
1.4.3 main() Function
int main() ជា entry point (ចំណុចចូល) នៃរាល់កម្មវិធី C ទាំងអស់។ Execution ចាប់ផ្ដើមពី function នេះ។
int- return type (main return integer ទៅ OS)main- ឈ្មោះ function (ត្រូវតែជា main){ }- function body (ខ្លួន function)
1.4.4 printf() Function
printf() (print formatted) ប្រើសម្រាប់បង្ហាញ output លើ screen។ ខុសពី C++ ដែលប្រើ cout។
printf("Hello, World!\n"); // \n = newline character
1.4.5 return 0;
return 0; ប្រាប់ OS ថាកម្មវិធីបានបញ្ចប់ដោយជោគជ័យ។
return 0;- ជោគជ័យ (Success)return 1;ឬ number ផ្សេង - មានបញ្ហា (Error)
1.5 Basic Syntax Rules
1.5.1 Semicolon (;)
រាល់ statement ក្នុង C ត្រូវបញ្ចប់ដោយ semicolon (;)។
int x = 10; // ត្រឹមត្រូវ
printf("Hello"); // ត្រឹមត្រូវ
int y = 20 // ERROR - ខ្វះ semicolon
1.5.2 Case Sensitivity
C មានលក្ខណៈ case-sensitive ។ Main, main, MAIN ខុសគ្នាទាំងស្រុង។
int Number = 10; // Variable ឈ្មោះ Number
int number = 20; // Variable ឈ្មោះ number (ខុសពី Number)
int NUMBER = 30; // Variable ឈ្មោះ NUMBER
1.5.3 Comments
Comments គឺជាអត្ថបទដែល compiler មិនប្រតិបត្តិ ប្រើសម្រាប់ពន្យល់កូដ:
// Single-line comment (C99 and later)
/* Multi-line comment
C ប្រើ comment ប្រភេទនេះ
ពី version ដំបូង */
int x = 10; /* comment ក្នុងបន្ទាត់ */
/* */ ប៉ុណ្ណោះ។ // ត្រូវបានបន្ថែមក្នុង C99។ ក្នុង compiler ចាស់ // អាចបង្ករបញ្ហា។
1.5.4 Curly Braces { }
Curly braces ប្រើដើម្បីកំណត់ block នៃកូដ ដូចជា function body, if block, loop block:
int main() {
// Code block សម្រាប់ main function
if (1 == 1) {
// Code block សម្រាប់ if statement
printf("True!");
}
return 0;
}
1.6 Compilation Process
ដំណើរការ compile កូដ C មាន 4 ជំហាន:
ជំហានទី 1: Preprocessing
Preprocessor ដំណើរការ #include, #define។ វារួម include header files ហើយ expand macros។
ជំហានទី 2: Compilation
Compiler បម្លែង C code ទៅជា Assembly code ហើយពិនិត្យ syntax errors។
ជំហានទី 3: Assembly
Assembler បម្លែង Assembly code ទៅជា machine code (object files .o)។
ជំហានទី 4: Linking
Linker បញ្ចូល object files និង library files ដើម្បីបង្កើត executable file។
Compilation Flow:
Source (.c) → Preprocessor → Compiler → Assembler → Linker → Executable
Commands ដើម្បី Compile:
/* Linux / Mac */
gcc myprogram.c -o myprogram
./myprogram
/* Windows (MinGW) */
gcc myprogram.c -o myprogram.exe
myprogram.exe
/* Compile ជាមួយ math library */
gcc myprogram.c -o myprogram -lm
-Wall ដើម្បីឱ្យ compiler បង្ហាញ warnings ទាំងអស់: gcc -Wall myprogram.c -o myprogram
1.7 Variables & Data Types
1.7.1 Variables (អថេរ)
Variable ជាទីតាំងក្នុង memory ប្រើរក្សាទុកទិន្នន័យ។ ក្នុង C ត្រូវប្រកាស variable មុន ហើយទើបប្រើ។
Declaration (ប្រកាស):
int age; /* ប្រកាស variable ប្រភេទ int */
float salary; /* ប្រកាស variable ប្រភេទ float */
char grade; /* ប្រកាស variable ប្រភេទ char */
Initialization (ប្រកាស + ផ្ដល់តម្លៃ):
int age = 25;
float salary = 1500.50;
char grade = 'A';
ប្រកាស variables ច្រើននៅក្នុងមួយបន្ទាត់:
int x = 10, y = 20, z = 30;
float a, b, c = 3.14f;
1.7.2 Data Types ក្នុង C
1. Integer Types (ប្រភេទចំនួនគត់)
| Type | Size | Range | Example |
|---|---|---|---|
| int | 4 bytes | -2,147,483,648 to 2,147,483,647 | int age = 25; |
| short | 2 bytes | -32,768 to 32,767 | short count = 100; |
| long | 4/8 bytes | varies by platform | long pop = 15000000; |
| long long | 8 bytes | -9.2×10¹⁸ to 9.2×10¹⁸ | long long big = 9876543210; |
| unsigned int | 4 bytes | 0 to 4,294,967,295 | unsigned int u = 100; |
2. Floating-Point Types (ប្រភេទទសភាគ)
| Type | Size | Precision | Example |
|---|---|---|---|
| float | 4 bytes | ~7 digits | float price = 19.99f; |
| double | 8 bytes | ~15 digits | double pi = 3.14159265359; |
| long double | 12-16 bytes | ~19 digits | long double x = 3.14L; |
3. Character Type
| Type | Size | Range | Example |
|---|---|---|---|
| char | 1 byte | -128 to 127 | char letter = 'A'; |
| unsigned char | 1 byte | 0 to 255 | unsigned char c = 200; |
bool type (true/false) ក្នុង C89 ទេ។ C99 បន្ថែម <stdbool.h> ដែលផ្ដល់ bool, true, false។ ក្នុង C89 គេប្រើ int ជំនួស (0 = false, non-zero = true)។
1.7.3 Format Specifiers ក្នុង printf/scanf
C ប្រើ format specifiers ដើម្បីកំណត់ប្រភេទទិន្នន័យដែលបង្ហាញ ឬ input:
| Specifier | Type | Example |
|---|---|---|
| %d | int (decimal) | printf("%d", 42); |
| %i | int (integer) | printf("%i", 42); |
| %f | float/double | printf("%f", 3.14); |
| %lf | double (scanf) | scanf("%lf", &x); |
| %c | char | printf("%c", 'A'); |
| %s | string (char array) | printf("%s", name); |
| %ld | long | printf("%ld", 100L); |
| %lld | long long | printf("%lld", 100LL); |
| %u | unsigned int | printf("%u", 100u); |
| %o | octal | printf("%o", 8); |
| %x | hexadecimal | printf("%x", 255); |
| %p | pointer address | printf("%p", ptr); |
| %% | percent sign | printf("100%%"); |
1.8 Input / Output (printf / scanf)
1.8.1 Output with printf()
printf() (print formatted) ប្រើបង្ហាញ output ។
Syntax:
printf("format string", variable1, variable2, ...);
ឧទាហរណ៍:
#include <stdio.h>
int main() {
int age = 20;
float score = 95.5;
char grade = 'A';
printf("Hello, World!\n");
printf("Age: %d\n", age);
printf("Score: %.2f\n", score); /* .2 = 2 decimal places */
printf("Grade: %c\n", grade);
printf("Age: %d, Score: %.2f, Grade: %c\n", age, score, grade);
return 0;
}
Escape Sequences (តួអក្សរពិសេស):
| Sequence | Description |
|---|---|
| \n | Newline (ចុះបន្ទាត់) |
| \t | Tab (ចន្លោះ Tab) |
| \r | Carriage Return |
| \\ | Backslash |
| \" | Double Quote |
| \' | Single Quote |
| \0 | Null character |
1.8.2 Input with scanf()
scanf() (scan formatted) ប្រើទទួល input ពីអ្នកប្រើប្រាស់។
Syntax:
scanf("format string", &variable1, &variable2, ...);
scanf() ត្រូវដាក់ & (address-of operator) មុន variable name ។ ដូចជា scanf("%d", &age); មិនមែន scanf("%d", age);
ឧទាហរណ៍:
#include <stdio.h>
int main() {
int age;
float height;
char initial;
printf("Enter your age: ");
scanf("%d", &age);
printf("Enter your height (m): ");
scanf("%f", &height);
printf("Enter your initial: ");
scanf(" %c", &initial); /* space before %c ដើម្បីរំលង whitespace */
printf("\n--- Your Information ---\n");
printf("Age: %d years\n", age);
printf("Height: %.2f m\n", height);
printf("Initial: %c\n", initial);
return 0;
}
Input ច្រើន variables ក្នុងមួយ scanf:
#include <stdio.h>
int main() {
int day, month, year;
printf("Enter date (day month year): ");
scanf("%d %d %d", &day, &month, &year);
printf("Date: %02d/%02d/%d\n", day, month, year);
/* %02d = បង្ហាញ 2 ខ្ទង់ ប្រសិនបើ 1 ខ្ទង់ ដាក់ 0 ទៅមុខ */
return 0;
}
1.8.3 Naming Rules for Variables
- ត្រូវចាប់ផ្ដើមដោយអក្សរ (a-z, A-Z) ឬ underscore (_)
- អាចមានអក្សរ, លេខ (0-9), underscore ប៉ុណ្ណោះ
- មិនអាចប្រើ keywords (int, if, for, while, return...)
- Case-sensitive (myVar ≠ MyVar ≠ MYVAR)
/* ឈ្មោះត្រឹមត្រូវ */
int studentAge;
float _price;
int count123;
/* ឈ្មោះមិនត្រឹមត្រូវ */
int 123count; /* ERROR - ចាប់ផ្ដើមដោយលេខ */
float my-price; /* ERROR - មាន hyphen */
int for; /* ERROR - keyword */
ឧទាហរណ៍ពេញលេញ - Student Information:
#include <stdio.h>
int main() {
/* ប្រកាស variables */
char name[50];
int age;
float score;
char grade;
/* Input */
printf("===== Student Information =====\n");
printf("Enter student name: ");
scanf("%s", name);
printf("Enter student age: ");
scanf("%d", &age);
printf("Enter student score: ");
scanf("%f", &score);
printf("Enter student grade (A/B/C/D/F): ");
scanf(" %c", &grade);
/* Output */
printf("\n===== Student Report =====\n");
printf("Name : %s\n", name);
printf("Age : %d years old\n", age);
printf("Score : %.2f\n", score);
printf("Grade : %c\n", grade);
return 0;
}
លំហាត់ប្រចាំមេរៀនទី 1 - Introduction to C (printf, scanf, data types)
- សរសេរកម្មវិធីបង្ហាញពាក្យ "Hello, C Programming!" នៅលើអេក្រង់។
- សរសេរកម្មវិធីប្រកាសអថេរប្រភេទ
int,float, និងcharរួចកំណត់តម្លៃ និងបង្ហាញវាមកវិញ។ - សរសេរកម្មវិធីទទួលយកអាយុ (ជាចំនួនគត់) ពីក្តារចុចដោយប្រើ
scanfហើយបង្ហាញអាយុនោះមកវិញ។ - សរសេរកម្មវិធីទទួលយកចំនួនគត់ពីរពីអ្នកប្រើប្រាស់ រួចគណនា និងបង្ហាញផលបូករបស់វា។
- សរសេរកម្មវិធីគណនាផ្ទៃក្រឡាចតុកោណកែង (ដោយឲ្យអ្នកប្រើប្រាស់បញ្ចូលបណ្តោយ និងទទឹងជាប្រភេទ
float)។ - សរសេរកម្មវិធីទទួលយកតួអក្សរមួយ (
char) ពីអ្នកប្រើប្រាស់ ហើយបង្ហាញតួអក្សរនោះ។ - សរសេរកម្មវិធីប្តូរតម្លៃពីឯកតាម៉ែត្រ ទៅជាសង់ទីម៉ែត្រ។
- សរសេរកម្មវិធីគណនាមធ្យមភាគនៃពិន្ទុមុខវិជ្ជាចំនួន៣ (ជាប្រភេទ
float)។ - សរសេរកម្មវិធីប្រើប្រាស់
sizeof()ដើម្បីរកទំហំ (Bytes) របស់ប្រភេទint,float,double, និងchar។ - សរសេរកម្មវិធីទទួលយកឈ្មោះមួយម៉ាត់ (string ដោយប្រើ
%sក្នុងscanf) រួចបង្ហាញពាក្យស្វាគមន៍ទៅកាន់ឈ្មោះនោះ។
❖ 2. Operators & Expressions in C
2.1 What are Operators?
Operators គឺជានិមិត្តសញ្ញាពិសេស ដែលប្រាប់ compiler ឱ្យធ្វើប្រមាណវិធីលើ operands។ Expression គឺជាបន្សំ variables, values, operators ដែលផ្ដល់លទ្ធផល (value) មួយ។
int result = 10 + 5;
/* + = operator
10 និង 5 = operands
10 + 5 = expression
result = variable ដែលទទួល value */
2.2 #define - Constants
ក្នុង C គេប្រើ #define (preprocessor macro) ដើម្បីកំណត់ constants ។ C99 ក៏អនុញ្ញាតឱ្យប្រើ const ក្នុង C++ style ផងដែរ។
Syntax:
#define NAME value
ឧទាហរណ៍:
#include <stdio.h>
#define PI 3.14159
#define MAX_SIZE 100
#define SCHOOL "ABC High School"
#define DAYS_IN_WEEK 7
int main() {
printf("PI = %f\n", PI);
printf("Max Size = %d\n", MAX_SIZE);
printf("School: %s\n", SCHOOL);
printf("Days in week: %d\n", DAYS_IN_WEEK);
/* PI = 3.14; // ERROR - cannot modify #define */
/* C99 style - const */
const double gravity = 9.81;
printf("Gravity: %.2f m/s2\n", gravity);
return 0;
}
#define- preprocessor macro, replacement ពីមុន compile, គ្មាន type checkingconst- variable ពិតប្រាកដ, មាន type, type-safe, debuggable- C89/C90 ប្រើ
#defineជាញឹកញាប់ ព្រោះconstក្នុង C89 មិនស្មើ compile-time constant
2.3 Arithmetic Operators (សញ្ញាគណិត)
| Operator | Name | Example | Result |
|---|---|---|---|
| + | Addition (ផលបូក) | 10 + 5 | 15 |
| - | Subtraction (ផលដក) | 10 - 5 | 5 |
| * | Multiplication (ផលគុណ) | 10 * 5 | 50 |
| / | Division (ផលចែក) | 10 / 5 | 2 |
| % | Modulus (នៃសល់) | 10 % 3 | 1 |
#include <stdio.h>
int main() {
int a = 20, b = 6;
printf("a + b = %d\n", a + b); /* 26 */
printf("a - b = %d\n", a - b); /* 14 */
printf("a * b = %d\n", a * b); /* 120 */
printf("a / b = %d\n", a / b); /* 3 (integer division!) */
printf("a %% b = %d\n", a % b); /* 2 (remainder) */
/* Division ជាមួយ floating-point */
float x = 20.0, y = 6.0;
printf("x / y = %.4f\n", x / y); /* 3.3333 */
return 0;
}
7 / 2 = 3 មិនមែន 3.5 ។ ប្រើ (float)7 / 2 (type casting) ដើម្បីទទួល 3.5។
2.4 Assignment Operators
| Operator | Example | Equivalent |
|---|---|---|
| = | x = 5 | x = 5 |
| += | x += 3 | x = x + 3 |
| -= | x -= 3 | x = x - 3 |
| *= | x *= 3 | x = x * 3 |
| /= | x /= 3 | x = x / 3 |
| %= | x %= 3 | x = x % 3 |
#include <stdio.h>
int main() {
int x = 10;
printf("Initial: x = %d\n", x);
x += 5;
printf("After x += 5: x = %d\n", x); /* 15 */
x -= 3;
printf("After x -= 3: x = %d\n", x); /* 12 */
x *= 2;
printf("After x *= 2: x = %d\n", x); /* 24 */
x /= 4;
printf("After x /= 4: x = %d\n", x); /* 6 */
x %= 4;
printf("After x %%= 4: x = %d\n", x); /* 2 */
return 0;
}
2.5 Comparison Operators
Comparison operators ប្រើប្រៀបធៀប 2 តម្លៃ ហើយ return 1 (true) ឬ 0 (false)។
| Operator | Meaning | Example | Result |
|---|---|---|---|
| == | Equal to | 5 == 5 | 1 (true) |
| != | Not equal to | 5 != 3 | 1 (true) |
| > | Greater than | 5 > 3 | 1 (true) |
| < | Less than | 5 < 3 | 0 (false) |
| >= | Greater or equal | 5 >= 5 | 1 (true) |
| <= | Less or equal | 5 <= 3 | 0 (false) |
#include <stdio.h>
int main() {
int a = 10, b = 20;
printf("a = %d, b = %d\n", a, b);
printf("a == b : %d\n", a == b); /* 0 */
printf("a != b : %d\n", a != b); /* 1 */
printf("a > b : %d\n", a > b); /* 0 */
printf("a < b : %d\n", a < b); /* 1 */
printf("a >= b : %d\n", a >= b); /* 0 */
printf("a <= b : %d\n", a <= b); /* 1 */
return 0;
}
== (ប្រៀបធៀប) ≠ = (ផ្ដល់តម្លៃ)។ if (x = 5) គឺ bug ព្រោះ assign 5 ទៅ x ហើយ always true!
2.6 Logical Operators
| Operator | Name | Description | Example | Result |
|---|---|---|---|---|
| && | AND | ពិត ប្រសិនបើទាំងពីរពិត | 1 && 0 | 0 |
| || | OR | ពិត ប្រសិនបើមួយណាពិត | 1 || 0 | 1 |
| ! | NOT | បញ្ច្រាស់តម្លៃ | !1 | 0 |
#include <stdio.h>
int main() {
int age = 20;
int hasID = 1; /* 1 = true, 0 = false ក្នុង C */
/* AND - ទាំងពីរត្រូវ true */
if (age >= 18 && hasID) {
printf("You can enter!\n");
}
/* OR - មួយណាពិត */
int isWeekend = 0;
int isHoliday = 1;
if (isWeekend || isHoliday) {
printf("Day off!\n");
}
/* NOT */
int isRaining = 0;
if (!isRaining) {
printf("Go outside!\n");
}
/* Short-circuit evaluation */
int x = 0;
if (x != 0 && 10/x > 2) { /* 10/x មិន evaluate ប្រសិនបើ x==0 */
printf("Safe!\n");
}
return 0;
}
2.7 Increment & Decrement Operators
| Operator | Name | Description |
|---|---|---|
| ++x | Pre-increment | បន្ថែមមុន ហើយប្រើ |
| x++ | Post-increment | ប្រើមុន ហើយបន្ថែម |
| --x | Pre-decrement | ដកមុន ហើយប្រើ |
| x-- | Post-decrement | ប្រើមុន ហើយដក |
#include <stdio.h>
int main() {
int a = 5, b = 5;
/* Pre-increment: increment before use */
printf("++a = %d\n", ++a); /* print 6, a = 6 */
printf("a = %d\n", a); /* a = 6 */
/* Post-increment: use then increment */
printf("b++ = %d\n", b++); /* print 5, b = 6 */
printf("b = %d\n", b); /* b = 6 */
int x = 5;
int y = ++x; /* x = 6, y = 6 */
int p = 5;
int q = p++; /* p = 6, q = 5 */
printf("x=%d, y=%d\n", x, y);
printf("p=%d, q=%d\n", p, q);
return 0;
}
2.8 Bitwise Operators (ប្រមាណ Bit)
C ប្រើ bitwise operators ដែលធ្វើការលើ bits ដោយផ្ទាល់ ។ នេះជាលក្ខណៈពិសេសរបស់ C ដែល high-level languages ជាច្រើនពុំមាន:
| Operator | Name | Example (a=5, b=3) | Result |
|---|---|---|---|
| & | Bitwise AND | 5 & 3 (0101 & 0011) | 1 (0001) |
| | | Bitwise OR | 5 | 3 (0101 | 0011) | 7 (0111) |
| ^ | Bitwise XOR | 5 ^ 3 (0101 ^ 0011) | 6 (0110) |
| ~ | Bitwise NOT | ~5 | -6 |
| << | Left Shift | 5 << 1 | 10 |
| >> | Right Shift | 5 >> 1 | 2 |
#include <stdio.h>
int main() {
int a = 5; /* binary: 00000101 */
int b = 3; /* binary: 00000011 */
printf("a & b = %d\n", a & b); /* 1 (00000001) */
printf("a | b = %d\n", a | b); /* 7 (00000111) */
printf("a ^ b = %d\n", a ^ b); /* 6 (00000110) */
printf("~a = %d\n", ~a); /* -6 */
printf("a << 1 = %d\n", a << 1); /* 10 (គុណ 2) */
printf("a >> 1 = %d\n", a >> 1); /* 2 (ចែក 2) */
return 0;
}
2.9 Type Casting (បម្លែងប្រភេទ)
Type casting ជាការបម្លែង variable ពីប្រភេទមួយទៅប្រភេទផ្សេង:
Implicit Casting (ស្វ័យប្រវត្ត):
int x = 10;
float y = x; /* int → float ស្វ័យប្រវត្ត */
printf("%f\n", y); /* 10.000000 */
Explicit Casting (ដោយប្រើ cast operator):
#include <stdio.h>
int main() {
int a = 7, b = 2;
/* Without cast - integer division */
printf("7 / 2 = %d\n", a / b); /* 3 */
/* With cast - float division */
printf("7 / 2 = %.2f\n", (float)a / b); /* 3.50 */
printf("7 / 2 = %.2f\n", (double)a / b); /* 3.50 */
/* Cast float to int - cut decimal */
float pi = 3.14159;
int whole = (int)pi;
printf("(int)3.14159 = %d\n", whole); /* 3 */
return 0;
}
លំហាត់ប្រចាំមេរៀនទី 2 - Operators & Expressions (#define, bitwise, cast)
- ប្រើប្រាស់
#defineដើម្បីកំណត់តម្លៃអថេរថេរPI = 3.14159ហើយគណនាបរិមាត្ររង្វង់។ - សរសេរកម្មវិធីរកសំណល់នៃការចែក (Modulus
%) នៃចំនួនគត់ពីរ។ - សរសេរកម្មវិធីបង្ហាញពីការប្រើប្រាស់ Bitwise AND (
&) លើចំនួនគត់ពីរ។ - សរសេរកម្មវិធីបង្ហាញពីការប្រើប្រាស់ Bitwise OR (
|) និង XOR (^) លើចំនួនគត់ពីរ។ - សរសេរកម្មវិធីប្រើ Left Shift (
<<) និង Right Shift (>>) ដើម្បីគុណ និងចែកចំនួនមួយនឹង ២ តាមប្រព័ន្ធគោលពីរ។ - សរសេរកម្មវិធីប្រើ Type Casting ដើម្បីបំប្លែងតម្លៃ
floatទៅជាintបង្ហាញតែផ្នែកចំនួនគត់។ - សរសេរកម្មវិធីប្រៀបធៀបចំនួនពីរដោយប្រើ Relational Operators (>, <, ==, !=) រួចបង្ហាញលទ្ធផល 1 (ពិត) ឬ 0 (មិនពិត)។
- សរសេរកម្មវិធីប្រើ Logical AND (
&&) និង Logical OR (||) ដើម្បីពិនិត្យលក្ខខណ្ឌច្រើនក្នុងពេលតែមួយ។ - សរសេរកម្មវិធីបង្ហាញពីភាពខុសគ្នារវាង Pre-increment (
++x) និង Post-increment (x++)។ - សរសេរកម្មវិធីប្រើ Conditional (Ternary) Operator (
? :) ដើម្បីរកចំនួនធំជាងគេក្នុងចំណោមចំនួនពីរ។
❖ 3. Mathematical Functions in C
3.1 Header <math.h>
C ផ្ដល់ mathematical functions ក្នុង <math.h> header file ។ ខុសពី C++ ដែលប្រើ <cmath>។
#include <math.h>
gcc myprogram.c -o myprogram -lmWindows (MinGW) ជាធម្មតា link ដោយស្វ័យប្រវត្ត ប៉ុន្តែ Linux ត្រូវ explicit
-lm។
3.2 Basic Mathematical Functions
3.2.1 sqrt() - Square Root
ផ្ដល់ square root (ការ៉េ) នៃ number។
Syntax: double sqrt(double x)
#include <stdio.h>
#include <math.h>
int main() {
double numbers[] = {4, 9, 16, 25, 2};
int i;
for (i = 0; i < 5; i++) {
printf("sqrt(%.0f) = %.4f\n", numbers[i], sqrt(numbers[i]));
}
/* Output:
sqrt(4) = 2.0000
sqrt(9) = 3.0000
sqrt(16) = 4.0000
sqrt(25) = 5.0000
sqrt(2) = 1.4142 */
return 0;
}
3.2.2 pow() - Power (ស្វ័យគុណ)
គណនា xy (x raised to the power y)。
Syntax: double pow(double x, double y)
#include <stdio.h>
#include <math.h>
int main() {
printf("2^3 = %.0f\n", pow(2, 3)); /* 8 */
printf("5^2 = %.0f\n", pow(5, 2)); /* 25 */
printf("10^0 = %.0f\n", pow(10, 0)); /* 1 */
printf("4^0.5 = %.1f\n", pow(4, 0.5)); /* 2.0 (same as sqrt) */
printf("2^-1 = %.1f\n", pow(2, -1)); /* 0.5 */
return 0;
}
3.2.3 fabs() - Absolute Value (តម្លៃដាច់ខាត)
ផ្ដល់ absolute value (positive value) ។ ក្នុង C ប្រើ fabs() សម្រាប់ double, abs() ពី <stdlib.h> សម្រាប់ int។
Syntax: double fabs(double x)
#include <stdio.h>
#include <math.h>
#include <stdlib.h> /* for abs() */
int main() {
int a = -10;
double b = -15.5;
printf("abs(%d) = %d\n", a, abs(a)); /* 10 */
printf("fabs(%.1f) = %.1f\n", b, fabs(b)); /* 15.5 */
/* ចម្ងាយរវាង 2 ចំណុច */
int p1 = 5, p2 = -3;
printf("Distance: %d\n", abs(p1 - p2)); /* 8 */
return 0;
}
3.2.4 ceil() - Ceiling (បង្គត់ឡើង)
Syntax: double ceil(double x)
printf("ceil(4.2) = %.0f\n", ceil(4.2)); /* 5 */
printf("ceil(4.8) = %.0f\n", ceil(4.8)); /* 5 */
printf("ceil(-4.2) = %.0f\n", ceil(-4.2)); /* -4 */
printf("ceil(5.0) = %.0f\n", ceil(5.0)); /* 5 */
3.2.5 floor() - Floor (បង្គត់ចុះ)
Syntax: double floor(double x)
printf("floor(4.2) = %.0f\n", floor(4.2)); /* 4 */
printf("floor(4.8) = %.0f\n", floor(4.8)); /* 4 */
printf("floor(-4.2) = %.0f\n", floor(-4.2)); /* -5 */
printf("floor(5.0) = %.0f\n", floor(5.0)); /* 5 */
3.2.6 round() - Round (C99)
Syntax: double round(double x) (C99 លើ)
printf("round(4.2) = %.0f\n", round(4.2)); /* 4 */
printf("round(4.5) = %.0f\n", round(4.5)); /* 5 */
printf("round(4.8) = %.0f\n", round(4.8)); /* 5 */
printf("round(-4.5) = %.0f\n", round(-4.5)); /* -5 */
floor(x + 0.5) ជំនួសសម្រាប់ positive numbers ក្នុង C89។
ឧទាហរណ៍ - Math Functions Calculator:
#include <stdio.h>
#include <math.h>
int main() {
double num;
printf("Enter a number: ");
scanf("%lf", &num);
printf("\n===== Math Functions Results =====\n");
printf("Original : %.4f\n", num);
printf("sqrt : %.4f\n", sqrt(num));
printf("num^2 : %.4f\n", pow(num, 2));
printf("num^3 : %.4f\n", pow(num, 3));
printf("fabs : %.4f\n", fabs(num));
printf("ceil : %.0f\n", ceil(num));
printf("floor : %.0f\n", floor(num));
printf("round : %.0f\n", round(num));
return 0;
}
3.3 Trigonometric Functions
អនុគមន៍ Trigonometric ប្រើ radians (មិនមែន degrees)!
radians = degrees × π / 180
degrees = radians × 180 / π
sin(), cos(), tan():
#include <stdio.h>
#include <math.h>
#define PI 3.14159265359
int main() {
double degrees, radians;
printf("Enter angle in degrees: ");
scanf("%lf", °rees);
radians = degrees * PI / 180.0;
printf("\nAngle: %.2f degrees = %.4f radians\n", degrees, radians);
printf("sin(%.2f) = %.4f\n", degrees, sin(radians));
printf("cos(%.2f) = %.4f\n", degrees, cos(radians));
printf("tan(%.2f) = %.4f\n", degrees, tan(radians));
/* Inverse trig */
printf("\nasin(0.5) = %.2f degrees\n", asin(0.5) * 180.0 / PI);
printf("acos(0.5) = %.2f degrees\n", acos(0.5) * 180.0 / PI);
printf("atan(1.0) = %.2f degrees\n", atan(1.0) * 180.0 / PI);
return 0;
}
3.4 Exponential & Logarithmic Functions
#include <stdio.h>
#include <math.h>
int main() {
/* Exponential */
printf("exp(0) = %.5f\n", exp(0)); /* 1.00000 */
printf("exp(1) = %.5f\n", exp(1)); /* 2.71828 (e) */
printf("exp(2) = %.5f\n", exp(2)); /* 7.38906 */
/* Natural log */
printf("log(1) = %.5f\n", log(1)); /* 0 */
printf("log(M_E)= %.5f\n", log(exp(1))); /* 1 */
/* Log base 10 */
printf("log10(10) = %.1f\n", log10(10)); /* 1.0 */
printf("log10(100) = %.1f\n", log10(100)); /* 2.0 */
/* log base 2 (C99) */
printf("log2(8) = %.1f\n", log2(8)); /* 3.0 */
return 0;
}
Summary Table - Math Functions:
| Function | Header | Description | Example → Result |
|---|---|---|---|
| sqrt(x) | math.h | ការ៉េ | sqrt(16) → 4 |
| pow(x,y) | math.h | x^y | pow(2,3) → 8 |
| abs(x) | stdlib.h | |x| (int) | abs(-5) → 5 |
| fabs(x) | math.h | |x| (double) | fabs(-5.5) → 5.5 |
| ceil(x) | math.h | បង្គត់ឡើង | ceil(4.2) → 5 |
| floor(x) | math.h | បង្គត់ចុះ | floor(4.8) → 4 |
| round(x) | math.h | បង្គត់ជិត (C99) | round(4.5) → 5 |
| sin(x) | math.h | Sine (radians) | sin(0) → 0 |
| cos(x) | math.h | Cosine (radians) | cos(0) → 1 |
| tan(x) | math.h | Tangent (radians) | tan(0) → 0 |
| exp(x) | math.h | e^x | exp(1) → 2.71828 |
| log(x) | math.h | ln(x) | log(10) → 2.30259 |
| log10(x) | math.h | log₁₀(x) | log10(100) → 2 |
| log2(x) | math.h | log₂(x) (C99) | log2(8) → 3 |
លំហាត់ប្រចាំមេរៀនទី 3 - Mathematical Functions (math.h)
- សរសេរកម្មវិធីទទួលយកចំនួនពីរ (គោល និងនិទស្សន្ត) រួចគណនាស្វ័យគុណដោយប្រើអនុគមន៍
pow()។ - សរសេរកម្មវិធីរកឫសការ៉េ (Square Root) នៃចំនួនមួយដែលបញ្ចូលពីក្តារចុចដោយប្រើ
sqrt()។ - សរសេរកម្មវិធីរកតម្លៃដាច់ខាត (Absolute value) នៃចំនួនអវិជ្ជមានដោយប្រើ
abs()(សម្រាប់ int) ឬfabs()(សម្រាប់ float)។ - សរសេរកម្មវិធីធ្វើការបង្គត់ឡើង (Round up) នៃចំនួនទសភាគដោយប្រើអនុគមន៍
ceil()។ - សរសេរកម្មវិធីធ្វើការបង្គត់ចុះ (Round down) នៃចំនួនទសភាគដោយប្រើអនុគមន៍
floor()។ - សរសេរកម្មវិធីរកតម្លៃស៊ីនុស នៃមុំមួយ (គិតជារ៉ាដ្យង់) ដោយប្រើ
sin()។ - សរសេរកម្មវិធីរកតម្លៃកូស៊ីនុស នៃមុំមួយដោយប្រើ
cos()។ - សរសេរកម្មវិធីរកលោការីតធម្មជាតិ (Natural log base e) ដោយប្រើ
log()។ - សរសេរកម្មវិធីរកលោការីតគោល១០ ដោយប្រើអនុគមន៍
log10()។ - សរសេរកម្មវិធីប្រើអនុគមន៍
fmod()ក្នុង<math.h>ដើម្បីរកសំណល់នៃការចែកចំនួនទសភាគពីរ។
❖ 4. Control Structures in C
Control Structures គ្រប់គ្រង execution flow នៃ program។ ពួកវាមាន 3 ប្រភេទ: Sequence, Selection, Iteration។
4.1 Sequence Control Structure
Sequence Control Structure ប្រតិបត្តិ statements តាមលំដាប់ ពីលើទៅក្រោម ។ ចុះបន្ទាត់ស្ដាំ = statement ត្រូវបញ្ចប់ទើបទៅ statement ក្រោយ។
📌 ប្រតិបត្តិពីលើទៅក្រោម រហូតដល់ END
#include <stdio.h>
int main() {
/* ប្រតិបត្តិតាមលំដាប់ */
double price, tax, total;
printf("Enter price: $");
scanf("%lf", &price);
tax = price * 0.10; /* Statement 1 */
total = price + tax; /* Statement 2 */
printf("Price : $%.2f\n", price); /* Statement 3 */
printf("Tax : $%.2f\n", tax); /* Statement 4 */
printf("Total : $%.2f\n", total); /* Statement 5 */
return 0;
}
4.2 Selection Control Structure
Selection Control Structure (Decision/Conditional) ជ្រើសរើស execution path ផ្អែកលើ condition។
4.2.1 if Statement
Syntax:
if (condition) {
/* ប្រតិបត្តិ ប្រសិនបើ condition != 0 (true) */
}
#include <stdio.h>
int main() {
int age;
printf("Enter your age: ");
scanf("%d", &age);
if (age >= 18) {
printf("You are an adult.\n");
printf("You can vote!\n");
}
printf("Program ends.\n");
return 0;
}
4.2.2 if-else Statement
if (condition) {
/* true block */
} else {
/* false block */
}
#include <stdio.h>
int main() {
int num;
printf("Enter a number: ");
scanf("%d", &num);
if (num % 2 == 0) {
printf("%d is EVEN\n", num);
} else {
printf("%d is ODD\n", num);
}
return 0;
}
4.2.3 if-else if-else Statement
#include <stdio.h>
int main() {
int score;
printf("Enter your score (0-100): ");
scanf("%d", &score);
if (score >= 90) {
printf("Grade: A (Excellent!)\n");
} else if (score >= 80) {
printf("Grade: B (Very Good)\n");
} else if (score >= 70) {
printf("Grade: C (Good)\n");
} else if (score >= 60) {
printf("Grade: D (Pass)\n");
} else {
printf("Grade: F (Fail)\n");
}
return 0;
}
4.2.4 Ternary Operator (? :)
C មាន ternary operator ដែលជា shortcut សម្រាប់ if-else ។
Syntax: condition ? value_if_true : value_if_false
#include <stdio.h>
int main() {
int a = 10, b = 20;
int max;
max = (a > b) ? a : b; /* if(a>b) max=a; else max=b; */
printf("Max = %d\n", max); /* 20 */
int x = 5;
printf("%s\n", (x % 2 == 0) ? "Even" : "Odd"); /* Odd */
return 0;
}
4.2.5 switch Statement
switch ពិនិត្យតម្លៃ integer/char ជាក់លាក់ ។
#include <stdio.h>
int main() {
int choice;
double a, b;
printf("===== Calculator =====\n");
printf("1. Add\n2. Subtract\n3. Multiply\n4. Divide\n");
printf("Choice: ");
scanf("%d", &choice);
printf("Enter two numbers: ");
scanf("%lf %lf", &a, &b);
switch (choice) {
case 1:
printf("%.2f + %.2f = %.2f\n", a, b, a + b);
break;
case 2:
printf("%.2f - %.2f = %.2f\n", a, b, a - b);
break;
case 3:
printf("%.2f * %.2f = %.2f\n", a, b, a * b);
break;
case 4:
if (b != 0)
printf("%.2f / %.2f = %.2f\n", a, b, a / b);
else
printf("Error: Division by zero!\n");
break;
default:
printf("Invalid choice!\n");
}
return 0;
}
4.3 Iteration Control Structure (Loops)
4.3.1 for Loop
Syntax:
for (initialization; condition; increment/decrement) {
/* body */
}
#include <stdio.h>
int main() {
int i, n, sum = 0;
printf("Enter n: ");
scanf("%d", &n);
/* for loop - loop n times */
for (i = 1; i <= n; i++) {
sum += i;
printf("i=%d, sum=%d\n", i, sum);
}
printf("Total sum = %d\n", sum);
/* Multiplication table */
int num = 5;
printf("\nMultiplication table of %d:\n", num);
for (i = 1; i <= 10; i++) {
printf("%d x %d = %d\n", num, i, num * i);
}
return 0;
}
4.3.2 while Loop
Syntax:
while (condition) {
/* body */
}
📌 ពិនិត្យ Condition មុន → ប្រសិនបើ FALSE ពីដំបូង Loop Body មិនប្រតិបត្តិ (0 ដង)
#include <stdio.h>
int main() {
/* Guess the number game */
int secret = 7, guess;
printf("Guess the number (1-10): ");
scanf("%d", &guess);
while (guess != secret) {
if (guess < secret)
printf("Too low! Try again: ");
else
printf("Too high! Try again: ");
scanf("%d", &guess);
}
printf("Congratulations! Correct!\n");
return 0;
}
4.3.3 do-while Loop
Syntax:
do {
/* body - executes at least once */
} while (condition);
⚠️ Loop Body ប្រតិបត្តិមុន → ពិនិត្យ Condition ក្រោយ → យ៉ាងហោចណាស់ 1 ដង!
#include <stdio.h>
int main() {
int choice;
do {
printf("\n===== Menu =====\n");
printf("1. Say Hello\n");
printf("2. Show Date\n");
printf("3. Exit\n");
printf("Choice: ");
scanf("%d", &choice);
switch (choice) {
case 1: printf("Hello, User!\n"); break;
case 2: printf("Today is a great day!\n"); break;
case 3: printf("Goodbye!\n"); break;
default: printf("Invalid choice!\n");
}
} while (choice != 3);
return 0;
}
ប្រៀបធៀប Loops:
| Feature | for Loop | while Loop | do-while Loop |
|---|---|---|---|
| ចំនួនដង | ដឹងជាមុន | មិនដឹង | មិនដឹង, ≥1 |
| ពិនិត្យ condition | មុន execute | មុន execute | បន្ទាប់ execute |
| Minimum executions | 0 | 0 | 1 |
| ឧទាហរណ៍ | Loop arrays | Input validation | Menu system |
4.3.4 break និង continue
#include <stdio.h>
int main() {
int i;
/* break - ចេញពី loop */
for (i = 1; i <= 100; i++) {
if (i % 7 == 0) {
printf("First multiple of 7: %d\n", i);
break;
}
}
/* continue - រំលង iteration បច្ចុប្បន្ន */
printf("Odd numbers: ");
for (i = 1; i <= 10; i++) {
if (i % 2 == 0) continue; /* រំលងលេខគូ */
printf("%d ", i);
}
printf("\n"); /* Output: 1 3 5 7 9 */
return 0;
}
4.3.5 Nested Loops
#include <stdio.h>
int main() {
int i, j, n = 5;
/* Triangle pattern */
for (i = 1; i <= n; i++) {
for (j = 1; j <= i; j++) {
printf("* ");
}
printf("\n");
}
/* Output:
*
* *
* * *
* * * *
* * * * * */
return 0;
}
4.3.6 goto Statement (C-specific)
C មាន goto statement ដែលលោតទៅ label ណាមួយ ។ ជាធម្មតាមិន recommended ប៉ុន្តែ C ប្រើក្នុង error handling ខ្លះ:
#include <stdio.h>
int main() {
int i = 0;
start:
if (i < 5) {
printf("i = %d\n", i);
i++;
goto start; /* Jump back to label "start" */
}
printf("Done!\n");
return 0;
}
goto ក្នុងការ programming ធម្មតា ព្រោះវាធ្វើឱ្យកូដអានពិបាក (spaghetti code)។ ប្រើ loops ជំនួស។ goto ប្រើតែក្នុង error cleanup patterns ខ្លះ។
លំហាត់ប្រចាំមេរៀនទី 4 - Control Structures (if, switch, loops, goto)
- សរសេរកម្មវិធីពិនិត្យមើលថាចំនួនដែលបញ្ចូល ជាចំនួនគូ (Even) ឬចំនួនសេស (Odd) ដោយប្រើ
if-else។ - សរសេរកម្មវិធីរកចំនួនធំបំផុតក្នុងចំណោមចំនួន៣ ដោយប្រើ Nested
if-else។ - សរសេរកម្មវិធីពិនិត្យឆ្នាំពន្លត់ (Leap year) ដោយផ្អែកលើលក្ខខណ្ឌចែកដាច់នឹង ៤ និងមិនដាច់នឹង ១០០ ឬចែកដាច់នឹង ៤០០។
- សរសេរកម្មវិធីបំប្លែងពិន្ទុ (1-100) ទៅជានិទ្ទេស (A, B, C, D, F) ដោយប្រើ
if-else if។ - សរសេរកម្មវិធីម៉ាស៊ីនគិតលេខសាមញ្ញ (ទទួលយក +, -, *, /) ដោយប្រើ
switch-case។ - សរសេរកម្មវិធីបង្ហាញលេខពី 1 ដល់ n ដែលបញ្ចូលដោយអ្នកប្រើប្រាស់ ដោយប្រើរង្វិលជុំ
for។ - សរសេរកម្មវិធីគណនាផលបូកនៃលេខពី 1 ដល់ n ដោយប្រើរង្វិលជុំ
while។ - សរសេរកម្មវិធីបង្កើតតារាងមេគុណនៃលេខមួយ (ឧ. មេ៥ ពី 5x1 ដល់ 5x10) ដោយប្រើ
for។ - សរសេរកម្មវិធីទាមទារឱ្យអ្នកប្រើប្រាស់បញ្ចូលលេខសម្ងាត់រហូតទាល់តែត្រឹមត្រូវ ទើបអាចបន្តទៅមុខបាន ដោយប្រើ
do-while។ - សរសេរកម្មវិធីដែលប្រើ
breakដើម្បីបញ្ចប់ loop មុនកំណត់ និងប្រើgotoដើម្បីលោតទៅកាន់ label បង្ហាញសារបញ្ចប់កម្មវិធី។
❖ 5. Functions in C
5.1 Introduction to Functions
Function ជា block នៃ code ដែលរៀបចំឡើងដើម្បីធ្វើ task ជាក់លាក់ ហើយ អាចហៅ (call) ច្រើនដងក្នុង program។
ហេតុអ្វីប្រើ Functions:
- Code Reusability - សរសេរម្ដង ប្រើច្រើនកន្លែង
- Modularity - បែងចែក program ទៅជា modules តូចៗ
- Easy Debugging - ស្វែងរក bugs ងាយ
- Readability - អានកូដបានងាយ
5.2 Function Structure
returnType functionName(parameter1, parameter2, ...) {
/* Function body */
/* statements */
return value; /* optional */
}
ឧទាហរណ៍:
int add(int a, int b) {
int sum = a + b;
return sum;
}
/* int = return type
add = function name
int a, int b = parameters
return sum = return statement */
5.3 Function Declaration (Prototype)
Function prototype ជាការប្រកាស function signature មុនពេលប្រើ ។ ត្រូវ declare prototype ដែល compiler ដឹងអំពី function ដែល call ។
Syntax:
returnType functionName(parameterTypes);
#include <stdio.h>
/* Function Prototypes (declarations) */
int add(int, int);
void greet(void);
double circleArea(double);
int isEven(int);
int main() {
int result = add(5, 3);
printf("5 + 3 = %d\n", result);
greet();
double area = circleArea(5.0);
printf("Circle area (r=5): %.2f\n", area);
printf("Is 10 even? %s\n", isEven(10) ? "Yes" : "No");
return 0;
}
/* Function Definitions */
int add(int a, int b) {
return a + b;
}
void greet(void) {
printf("Hello from C!\n");
}
double circleArea(double radius) {
return 3.14159 * radius * radius;
}
int isEven(int n) {
return (n % 2 == 0); /* return 1 (true) or 0 (false) */
}
void ត្រូវ explicit ក្នុង parameter list ប្រសិនបើ function មិនទទួល argument: void greet(void); មិនមែន void greet(); (ក្នុង C89 greet() មានន័យថា accept any parameters!)
5.4 Types of Functions
5.4.1 No Parameter, No Return
#include <stdio.h>
void displayWelcome(void) {
printf("========================================\n");
printf(" Welcome to C Programming! \n");
printf("========================================\n");
}
int main() {
displayWelcome();
return 0;
}
5.4.2 With Parameters, No Return
#include <stdio.h>
void printSquare(int num) {
printf("Square of %d = %d\n", num, num * num);
}
void greetUser(char name[]) {
printf("Hello, %s!\n", name);
}
int main() {
printSquare(5);
printSquare(10);
greetUser("Sokha");
return 0;
}
5.4.3 No Parameter, With Return
#include <stdio.h>
double getPi(void) {
return 3.14159265359;
}
int getMaxInt(void) {
return 2147483647;
}
int main() {
printf("PI = %.10f\n", getPi());
printf("Max int = %d\n", getMaxInt());
return 0;
}
5.4.4 With Parameters, With Return (ប្រើច្រើនបំផុត)
#include <stdio.h>
#include <math.h>
int findMax(int a, int b) {
return (a > b) ? a : b;
}
double power(double base, double exp) {
return pow(base, exp);
}
int isPrime(int n) {
int i;
if (n <= 1) return 0;
if (n == 2) return 1;
for (i = 2; i <= (int)sqrt(n); i++) {
if (n % i == 0) return 0;
}
return 1;
}
int main() {
printf("Max(10, 25) = %d\n", findMax(10, 25));
printf("2^8 = %.0f\n", power(2, 8));
printf("Is 17 prime? %s\n", isPrime(17) ? "Yes" : "No");
return 0;
}
5.5 Pass by Value
ក្នុង C by default, arguments ត្រូវបាន pass by value គឺ function ទទួល copy ។ ផ្លាស់ប្ដូរ parameter ក្នុង function មិនប៉ះពាល់ original variable ។
#include <stdio.h>
void modifyValue(int x) {
x = x * 2;
printf("Inside function: x = %d\n", x);
}
int main() {
int num = 10;
printf("Before: num = %d\n", num);
modifyValue(num);
printf("After : num = %d\n", num); /* នៅតែ 10! */
return 0;
}
/* Output:
Before: num = 10
Inside function: x = 20
After : num = 10 ← មិនផ្លាស់ប្ដូរ */
5.6 Pass by Pointer (Pass by Reference in C)
ក្នុង C គ្មាន pass by reference ដូច C++ ទេ ។ ជំនួស ប្រើ pointers ដើម្បីផ្លាស់ប្ដូរ original variable ។
#include <stdio.h>
void modifyValue(int *x) { /* ទទួល pointer */
*x = *x * 2; /* dereference pointer */
printf("Inside function: *x = %d\n", *x);
}
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
int main() {
int num = 10;
printf("Before: num = %d\n", num);
modifyValue(&num); /* pass address of num */
printf("After : num = %d\n", num); /* ផ្លាស់ប្ដូរ! 20 */
int x = 5, y = 10;
printf("\nBefore swap: x=%d, y=%d\n", x, y);
swap(&x, &y);
printf("After swap : x=%d, y=%d\n", x, y);
return 0;
}
/* Output:
Before: num = 10
Inside function: *x = 20
After : num = 20 ← ផ្លាស់ប្ដូរ!
Before swap: x=5, y=10
After swap : x=10, y=5 */
5.7 Recursive Functions (អនុគមន៍ Recursive)
Recursive function ជា function ដែលហៅខ្លួនឯង ។ ត្រូវតែមាន base case ដើម្បីបញ្ចប់ recursion ។
#include <stdio.h>
/* Factorial: n! = n * (n-1) * ... * 1 */
long long factorial(int n) {
if (n == 0 || n == 1) /* Base case */
return 1;
return n * factorial(n - 1); /* Recursive case */
}
/* Fibonacci: fib(n) = fib(n-1) + fib(n-2) */
int fibonacci(int n) {
if (n == 0) return 0; /* Base case */
if (n == 1) return 1; /* Base case */
return fibonacci(n-1) + fibonacci(n-2); /* Recursive */
}
/* Sum: 1 + 2 + ... + n */
int sumN(int n) {
if (n == 0) return 0;
return n + sumN(n - 1);
}
int main() {
int i;
printf("Factorials:\n");
for (i = 0; i <= 10; i++) {
printf("%d! = %lld\n", i, factorial(i));
}
printf("\nFibonacci sequence (first 10):\n");
for (i = 0; i < 10; i++) {
printf("fib(%d) = %d\n", i, fibonacci(i));
}
printf("\nSum 1 to 10 = %d\n", sumN(10));
return 0;
}
5.8 Static Variables in Functions
static variable ក្នុង function រក្សាតម្លៃ រហូតដល់ program បញ្ចប់ (មិនត្រូវ reset ពេល function ហៅឡើងវិញ):
#include <stdio.h>
void counter(void) {
static int count = 0; /* initialized once only */
count++;
printf("Function called %d time(s)\n", count);
}
int main() {
counter(); /* 1 */
counter(); /* 2 */
counter(); /* 3 */
return 0;
}
5.9 Function Scope
Scope កំណត់ថា variable visible/accessible ពីណា:
#include <stdio.h>
int globalVar = 100; /* Global: accessible everywhere */
void showScope(void) {
int localVar = 200; /* Local: accessible only in this function */
printf("Global: %d\n", globalVar); /* OK */
printf("Local : %d\n", localVar); /* OK */
}
int main() {
printf("Global: %d\n", globalVar); /* OK */
/* printf("%d", localVar); */ /* ERROR - not visible */
showScope();
return 0;
}
ឧទាហរណ៍ពេញលេញ - Student Grade System:
#include <stdio.h>
/* Prototypes */
char getGrade(float score);
int isPassed(float score);
void printHeader(void);
void displayStudent(char name[], int age, float score);
int main() {
printHeader();
displayStudent("Sokha", 20, 85.5);
displayStudent("Dara", 21, 72.0);
displayStudent("Bopha", 22, 55.0);
return 0;
}
char getGrade(float score) {
if (score >= 90) return 'A';
else if (score >= 80) return 'B';
else if (score >= 70) return 'C';
else if (score >= 60) return 'D';
return 'F';
}
int isPassed(float score) {
return score >= 60;
}
void printHeader(void) {
printf("========================================\n");
printf(" Student Information System \n");
printf("========================================\n");
}
void displayStudent(char name[], int age, float score) {
printf("Name : %s\n", name);
printf("Age : %d\n", age);
printf("Score: %.2f\n", score);
printf("Grade: %c\n", getGrade(score));
printf("Status: %s\n", isPassed(score) ? "PASS" : "FAIL");
printf("-------------------\n");
}
លំហាត់ប្រចាំមេរៀនទី 5 - Functions (prototypes, recursion, scope)
- បង្កើត Function
greetUser()ដែលគ្មាន parameter និងគ្មាន return ដើម្បីបង្ហាញពាក្យ "Welcome!" រួចហៅវាប្រើក្នុងmain()។ - បង្កើត Function
addNumbers(int a, int b)ដើម្បីបូកលេខពីរ រួច return លទ្ធផលទៅកាន់main()។ - បង្កើត Function គណនាផ្ទៃក្រឡារង្វង់ ដែលទទួលយកកាំ (radius) និង return លទ្ធផលជា
float។ - សរសេរកម្មវិធីដែលមាន Function Prototypes ប្រកាសនៅខាងលើ
main()ហើយតួ Function ពេញលេញសរសេរនៅខាងក្រោម។ - សរសេរកម្មវិធីបង្ហាញពីភាពខុសគ្នារវាង Local Variable (ប្រកាសក្នុង function) និង Global Variable (ប្រកាសក្រៅ function ទាំងអស់)។
- បង្កើត Function មួយដើម្បីរកចំនួនតូចបំផុតក្នុងចំណោមពីរចំនួន ដោយប្រើប្រាស់អនុគមន៍បញ្ជូនតម្លៃ (Pass by value)។
- បង្កើត Recursive Function ដើម្បីគណនាហ្វាក់តូរីយ៉ែល (Factorial,
n!) នៃចំនួនគត់ n។ - បង្កើត Recursive Function ដើម្បីរកតម្លៃនៃតួទី n របស់ស្វីត Fibonacci។
- បង្កើត Function សម្រាប់បំប្លែងសីតុណ្ហភាពពីអង្សាសេ ទៅអង្សាហ្វារិនហៃ។
- បង្កើត Function ដែលទទួលយកចំនួនគត់មួយ ហើយត្រឡប់តម្លៃ 1 បើវាជា Prime Number និង 0 បើមិនមែនជា Prime Number។
❖ 6. Arrays in C
6.1 Introduction to Arrays
Array ជា collection នៃ elements ដែលមានប្រភេទដូចគ្នា រក្សាទុកក្នុង memory locations ជាប់គ្នា (contiguous)។
ហេតុអ្វីប្រើ Arrays:
- រក្សាទុក data ច្រើន (scores, names...) ក្នុង variable តែ 1
- ដំណើរការ data ដោយ loop ងាយស្រួល
- Access element ណាមួយ ដោយ index បានលឿន
6.2 Array Declaration
Syntax:
dataType arrayName[size];
int numbers[5]; /* array of 5 integers */
double prices[10]; /* array of 10 doubles */
char letters[26]; /* array of 26 characters */
char name[50]; /* C-string: char array for names */
- Element ទីមួយ:
array[0] - Element ទីចុងក្រោយ:
array[size-1] - C មិន check array bounds → access index ខុស = undefined behavior!
6.3 Array Initialization
#include <stdio.h>
int main() {
/* 1. Initialize at declaration */
int arr1[5] = {10, 20, 30, 40, 50};
/* 2. Partial initialization - rest = 0 */
int arr2[5] = {10, 20}; /* {10, 20, 0, 0, 0} */
/* 3. All zeros */
int arr3[5] = {0}; /* {0, 0, 0, 0, 0} */
/* 4. Size auto-determined */
int arr4[] = {100, 200, 300}; /* size = 3 */
/* 5. Calculate size at runtime */
int size = sizeof(arr4) / sizeof(arr4[0]);
printf("arr4 size = %d\n", size); /* 3 */
/* Access and modify */
arr1[0] = 99;
printf("arr1[0] = %d\n", arr1[0]);
return 0;
}
6.4 Array with Loops
Input/Output Array:
#include <stdio.h>
int main() {
int i;
int numbers[5];
int size = 5;
/* Input */
printf("Enter %d numbers:\n", size);
for (i = 0; i < size; i++) {
printf("Number[%d]: ", i);
scanf("%d", &numbers[i]);
}
/* Output */
printf("\nYou entered: ");
for (i = 0; i < size; i++) {
printf("%d ", numbers[i]);
}
printf("\n");
return 0;
}
Array Statistics:
#include <stdio.h>
int main() {
int i;
int numbers[] = {45, 12, 78, 23, 90, 34, 56};
int size = sizeof(numbers) / sizeof(numbers[0]);
int sum = 0, max, min;
max = min = numbers[0];
for (i = 0; i < size; i++) {
sum += numbers[i];
if (numbers[i] > max) max = numbers[i];
if (numbers[i] < min) min = numbers[i];
}
printf("Array: ");
for (i = 0; i < size; i++) printf("%d ", numbers[i]);
printf("\n");
printf("Sum = %d\n", sum);
printf("Average = %.2f\n", (double)sum / size);
printf("Maximum = %d\n", max);
printf("Minimum = %d\n", min);
return 0;
}
6.5 Character Arrays (Strings in C)
ក្នុង C គ្មាន string type ដូច C++ ទេ ។ Strings ត្រូវបានតំណាងដោយ char arrays ដែលបញ្ចប់ដោយ null character '\0'。
'\0' នៅចុងបញ្ចប់ ។ ដូច្នេះ array size ត្រូវ = string length + 1 ។ ឧទាហរណ៍ "Sokha" (5 chars) ត្រូវការ char name[6] យ៉ាងតិច ។
#include <stdio.h>
#include <string.h> /* for string functions */
int main() {
/* Declaration and Initialization */
char name1[20]; /* ទុកទំហំ */
char name2[] = "Sokha"; /* size = 6 (5+'\0') */
char name3[20] = "Dara";
char name4[] = {'B','o','p','h','a','\0'}; /* explicit '\0' */
/* Print strings */
printf("name2 = %s\n", name2);
printf("name3 = %s\n", name3);
printf("name4 = %s\n", name4);
/* String length (not counting '\0') */
printf("Length of name2 = %lu\n", strlen(name2)); /* 5 */
/* Copy string */
char dest[20];
strcpy(dest, name2);
printf("Copied: %s\n", dest);
/* Concatenate */
char full[50] = "Hello, ";
strcat(full, name2);
printf("Concat: %s\n", full); /* Hello, Sokha */
/* Compare */
if (strcmp(name2, "Sokha") == 0)
printf("name2 equals 'Sokha'\n");
/* Compare n chars */
if (strncmp(name2, "Sok", 3) == 0)
printf("name2 starts with 'Sok'\n");
return 0;
}
String Input/Output:
#include <stdio.h>
int main() {
char word[50], sentence[200];
/* scanf reads until whitespace */
printf("Enter a word: ");
scanf("%s", word); /* no & needed for arrays */
printf("Word: %s\n", word);
/* fgets reads the entire line including spaces */
printf("Enter a sentence: ");
scanf(" "); /* clear buffer */
fgets(sentence, sizeof(sentence), stdin);
printf("Sentence: %s", sentence);
/* gets() - avoid! unsafe (buffer overflow) */
/* Use fgets() instead */
return 0;
}
String Functions (string.h):
| Function | Description | Example |
|---|---|---|
| strlen(s) | ប្រវែង string | strlen("Hi") → 2 |
| strcpy(dst, src) | copy string | strcpy(a, "Hi") |
| strncpy(dst, src, n) | copy n chars (safe) | strncpy(a, b, 10) |
| strcat(dst, src) | concatenate | strcat(a, " World") |
| strncat(dst, src, n) | concat n chars (safe) | strncat(a, b, 5) |
| strcmp(s1, s2) | compare (0=equal) | strcmp("a","a") → 0 |
| strncmp(s1, s2, n) | compare n chars | strncmp(a, b, 3) |
| strchr(s, c) | រក char ក្នុង string | strchr("Hello", 'l') |
| strstr(s1, s2) | រក substring | strstr("Hello","ll") |
| strupr/strlwr | upper/lower case | platform-specific |
| sprintf(buf,...) | format to string | sprintf(s, "%d", 42) |
ctype.h - Character Functions:
#include <stdio.h>
#include <ctype.h>
int main() {
char c = 'A';
printf("isalpha('%c') = %d\n", c, isalpha(c)); /* 1 */
printf("isdigit('5') = %d\n", isdigit('5')); /* 1 */
printf("islower('a') = %d\n", islower('a')); /* 1 */
printf("isupper('A') = %d\n", isupper('A')); /* 1 */
printf("isspace(' ') = %d\n", isspace(' ')); /* 1 */
printf("tolower('A') = %c\n", tolower('A')); /* a */
printf("toupper('a') = %c\n", toupper('a')); /* A */
return 0;
}
6.6 Multi-dimensional Arrays
C គាំទ្រ multi-dimensional arrays ។ 2D array ប្រើច្រើនបំផុត (matrix):
#include <stdio.h>
int main() {
int i, j;
/* 2D array declaration */
int matrix[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
/* Print matrix */
printf("Matrix:\n");
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
printf("%3d", matrix[i][j]);
}
printf("\n");
}
/* Sum of diagonal */
int diagSum = 0;
for (i = 0; i < 3; i++) {
diagSum += matrix[i][i];
}
printf("Diagonal sum = %d\n", diagSum);
/* Matrix of strings */
char students[3][20] = {"Sokha", "Dara", "Bopha"};
printf("\nStudents:\n");
for (i = 0; i < 3; i++) {
printf("%d. %s\n", i+1, students[i]);
}
return 0;
}
ឧទាហរណ៍ - Sort and Search:
#include <stdio.h>
/* Bubble Sort */
void bubbleSort(int arr[], int size) {
int i, j, temp;
for (i = 0; i < size - 1; i++) {
for (j = 0; j < size - i - 1; j++) {
if (arr[j] > arr[j+1]) {
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
/* Linear Search */
int linearSearch(int arr[], int size, int target) {
int i;
for (i = 0; i < size; i++) {
if (arr[i] == target) return i;
}
return -1;
}
/* Display Array */
void displayArray(int arr[], int size) {
int i;
for (i = 0; i < size; i++) printf("%d ", arr[i]);
printf("\n");
}
int main() {
int numbers[] = {64, 34, 25, 12, 22, 11, 90};
int size = 7;
printf("Original: ");
displayArray(numbers, size);
int idx = linearSearch(numbers, size, 25);
if (idx != -1)
printf("Found 25 at index %d\n", idx);
else
printf("25 not found\n");
bubbleSort(numbers, size);
printf("Sorted : ");
displayArray(numbers, size);
return 0;
}
ឧទាហរណ៍ - Student Grade Report:
#include <stdio.h>
#define MAX_STUDENTS 5
int main() {
int i;
char names[MAX_STUDENTS][30];
float scores[MAX_STUDENTS];
char grades[MAX_STUDENTS];
/* Input */
printf("===== Enter Student Info =====\n");
for (i = 0; i < MAX_STUDENTS; i++) {
printf("\nStudent %d:\n", i+1);
printf("Name : "); scanf("%s", names[i]);
printf("Score: "); scanf("%f", &scores[i]);
if (scores[i] >= 90) grades[i] = 'A';
else if (scores[i] >= 80) grades[i] = 'B';
else if (scores[i] >= 70) grades[i] = 'C';
else if (scores[i] >= 60) grades[i] = 'D';
else grades[i] = 'F';
}
/* Statistics */
float sum = 0, highest = scores[0], lowest = scores[0];
int hiIdx = 0, loIdx = 0;
for (i = 0; i < MAX_STUDENTS; i++) {
sum += scores[i];
if (scores[i] > highest) { highest = scores[i]; hiIdx = i; }
if (scores[i] < lowest) { lowest = scores[i]; loIdx = i; }
}
/* Output Report */
printf("\n===== Student Report =====\n");
printf("%-15s %-8s %-6s\n", "Name", "Score", "Grade");
printf("------------------------------\n");
for (i = 0; i < MAX_STUDENTS; i++) {
printf("%-15s %-8.2f %-6c\n", names[i], scores[i], grades[i]);
}
printf("\n===== Statistics =====\n");
printf("Average : %.2f\n", sum / MAX_STUDENTS);
printf("Highest : %.2f (%s)\n", highest, names[hiIdx]);
printf("Lowest : %.2f (%s)\n", lowest, names[loIdx]);
return 0;
}
លំហាត់ប្រចាំមេរៀនទី 6 - Arrays & Strings (char arrays, string.h)
- ប្រកាស Array មួយប្រភេទ
intអាចផ្ទុកបាន ៥ធាតុ។ បញ្ចូលតម្លៃវាដោយប្រើ Loop ហើយបង្ហាញវាមកវិញ។ - សរសេរកម្មវិធីរកផលបូក និងមធ្យមភាគនៃគ្រប់ធាតុទាំងអស់ក្នុង Array ដែលមាន n ធាតុ។
- សរសេរកម្មវិធីរកតម្លៃធំបំផុត និងតូចបំផុតក្នុង Array នៃចំនួនគត់។
- សរសេរកម្មវិធីប្រើប្រាស់ 2D Array សម្រាប់បង្កើតម៉ាទ្រីស (Matrix) ទំហំ 3x3 រួចបង្ហាញវាតាមទម្រង់ជួរដេក និងជួរឈរ។
- សរសេរកម្មវិធីគណនាផលបូកនៃម៉ាទ្រីសពីរ (2D Arrays ទំហំ 2x2) រួចរក្សាទុកលទ្ធផលក្នុងម៉ាទ្រីសទី៣។
- ប្រកាស Char Array (String) ដើម្បីទទួលយកឈ្មោះពេញរបស់អ្នកប្រើប្រាស់ (ប្រើ
gets()ឬfgets()) ហើយបង្ហាញវាមកវិញ។ - សរសេរកម្មវិធីប្រើអនុគមន៍
strlen()ពីបណ្ណាល័យ<string.h>ដើម្បីរាប់ប្រវែង (ចំនួនតួអក្សរ) នៃ String មួយ។ - សរសេរកម្មវិធីប្រើ
strcpy()ដើម្បីចម្លងទិន្នន័យពី String មួយទៅកាន់ String មួយទៀត។ - សរសេរកម្មវិធីប្រើ
strcat()ដើម្បីតភ្ជាប់ String ពីរចូលគ្នាជា String តែមួយ។ - សរសេរកម្មវិធីប្រើ
strcmp()ដើម្បីប្រៀបធៀប String ពីរ ថាដូចគ្នា ឬខុសគ្នា។
❖ 7. Pointers in C
7.1 Introduction to Pointers
Pointer ជា variable ដែលរក្សាទុក memory address របស់ variable មួយទៀត ។ Pointers ជា feature ដ៏ powerful និងសំខាន់បំផុតក្នុង C ។
ហេតុអ្វីប្រើ Pointers:
- Pass by Reference - ផ្លាស់ប្ដូរ original variables ពី functions
- Dynamic Memory - allocate memory ក្នុង runtime
- Arrays & Strings - efficient array processing
- Data Structures - Linked Lists, Trees, Graphs
- Function Pointers - ផ្ទេរ functions ជា arguments
- Low-level Programming - hardware, OS development
7.2 Memory Concept
ស្មំថា variable int x = 10:
- Computer allocate 4 bytes ក្នុង RAM
- Address ឧទាហរណ៍:
0x7fff5c4e3a1c - Pointer រក្សាទុក address
0x7fff5c4e3a1c - Dereference pointer = access value
10ដែលស្ថិតនៅ address នោះ
7.3 Pointer Declaration
Syntax:
dataType *pointerName;
int *ptr; /* pointer to int */
double *dptr; /* pointer to double */
char *cptr; /* pointer to char (C-string) */
void *vptr; /* generic pointer */
7.4 Address Operator (&) and Dereference (*)
| Operator | Name | Description | Example |
|---|---|---|---|
| & | Address-of | ទទួល address របស់ variable | ptr = # |
| * | Declaration | ប្រកាស pointer variable | int *ptr; |
| * | Dereference | access value នៅ address | value = *ptr; |
#include <stdio.h>
int main() {
int num = 42;
int *ptr;
ptr = # /* ptr holds address of num */
printf("Value of num : %d\n", num);
printf("Address of num : %p\n", (void*)&num);
printf("Value of ptr (addr): %p\n", (void*)ptr);
printf("Value via ptr (*ptr): %d\n", *ptr);
/* Modify via pointer */
*ptr = 100;
printf("\nAfter *ptr = 100:\n");
printf("num = %d\n", num); /* 100 */
printf("*ptr = %d\n", *ptr); /* 100 */
return 0;
}
/* Sample Output:
Value of num : 42
Address of num : 0x7ffd1234
Value of ptr (addr): 0x7ffd1234
Value via ptr (*ptr): 42
After *ptr = 100:
num = 100
*ptr = 100 */
7.5 NULL Pointer
NULL pointer ជា pointer ដែលមិនកំណត់ទៅ address ណាទេ ។ ប្រើ NULL ពី <stdio.h> ឬ <stddef.h>:
#include <stdio.h>
int main() {
int *ptr = NULL; /* NULL pointer - safe initialization */
/* Always check before dereferencing */
if (ptr != NULL) {
printf("Value: %d\n", *ptr);
} else {
printf("Pointer is NULL - cannot dereference!\n");
}
/* Never do this - undefined behavior! */
/* *ptr = 10; */ /* CRASH! */
return 0;
}
7.6 Pointer to Pointer (**)
Pointer to pointer រក្សាទុក address របស់ pointer មួយទៀត:
#include <stdio.h>
int main() {
int num = 42;
int *ptr = # /* pointer to int */
int **pptr = &ptr; /* pointer to pointer to int */
printf("num = %d\n", num);
printf("*ptr = %d\n", *ptr);
printf("**pptr = %d\n", **pptr);
/* Modify via double pointer */
**pptr = 999;
printf("\nAfter **pptr = 999:\n");
printf("num = %d\n", num); /* 999 */
return 0;
}
7.7 Pointer Arithmetic
Pointer arithmetic អនុញ្ញាតឱ្យ move pointer ទៅ elements ជាប់គ្នា:
#include <stdio.h>
int main() {
int arr[5] = {10, 20, 30, 40, 50};
int *ptr = arr; /* ptr points to arr[0] */
int i;
printf("Array via pointer arithmetic:\n");
for (i = 0; i < 5; i++) {
printf("ptr+%d: address=%p, value=%d\n",
i, (void*)(ptr+i), *(ptr+i));
}
/* ptr++ moves to next element (not just +1 byte, but +sizeof(int)) */
printf("\nUsing ptr++:\n");
ptr = arr;
for (i = 0; i < 5; i++) {
printf("%d ", *ptr);
ptr++;
}
printf("\n");
/* Difference between pointers */
int *start = arr;
int *end = &arr[4];
printf("\nElements between start and end: %ld\n", end - start); /* 4 */
return 0;
}
7.8 Pointers and Arrays
ក្នុង C, Array name ជា constant pointer ទៅ first element:
#include <stdio.h>
/* Array as function parameter (actually pointer) */
void displayArray(int *arr, int size) {
int i;
for (i = 0; i < size; i++) {
printf("%d ", arr[i]); /* same as *(arr+i) */
}
printf("\n");
}
void doubleAll(int *arr, int size) {
int i;
for (i = 0; i < size; i++) {
*(arr + i) *= 2; /* modifies original array */
}
}
int main() {
int numbers[] = {1, 2, 3, 4, 5};
int size = 5;
printf("Original: ");
displayArray(numbers, size); /* numbers = &numbers[0] */
doubleAll(numbers, size);
printf("Doubled : ");
displayArray(numbers, size);
/* Equivalent notations */
int arr[] = {10, 20, 30};
int *p = arr;
printf("\narr[1] = %d\n", arr[1]); /* 20 */
printf("*(arr+1) = %d\n", *(arr+1)); /* 20 */
printf("p[1] = %d\n", p[1]); /* 20 */
printf("*(p+1) = %d\n", *(p+1)); /* 20 */
return 0;
}
7.9 Pointers and Strings
#include <stdio.h>
#include <string.h>
int main() {
/* String literal (read-only) */
char *str1 = "Hello"; /* pointer to string literal */
/* str1[0] = 'h'; */ /* UNDEFINED - read-only! */
/* Char array (modifiable) */
char str2[] = "Hello"; /* modifiable copy */
str2[0] = 'h'; /* OK */
printf("str2 = %s\n", str2); /* hello */
/* Pointer to traverse string */
char name[] = "Sokha";
char *p = name;
printf("Characters: ");
while (*p != '\0') {
printf("%c ", *p);
p++;
}
printf("\n");
/* String length using pointer */
char s[] = "Programming";
char *q = s;
int len = 0;
while (*q++) len++;
printf("Length = %d\n", len);
return 0;
}
7.10 Dynamic Memory Allocation
Dynamic allocation ប្រើ malloc(), calloc(), realloc(), free() ពី <stdlib.h>:
| Function | Description |
|---|---|
| malloc(size) | Allocate size bytes, uninitialized |
| calloc(n, size) | Allocate n×size bytes, initialized to 0 |
| realloc(ptr, size) | Resize allocated memory |
| free(ptr) | Release allocated memory |
#include <stdio.h>
#include <stdlib.h>
int main() {
int n, i;
printf("Enter number of students: ");
scanf("%d", &n);
/* Dynamic allocation */
int *scores = (int*)malloc(n * sizeof(int));
if (scores == NULL) {
printf("Memory allocation failed!\n");
return 1;
}
/* Input */
printf("Enter %d scores:\n", n);
for (i = 0; i < n; i++) {
printf("Score[%d]: ", i+1);
scanf("%d", &scores[i]);
}
/* Process */
int sum = 0;
for (i = 0; i < n; i++) sum += scores[i];
printf("Average = %.2f\n", (double)sum / n);
/* Free memory - MUST! */
free(scores);
scores = NULL; /* good practice */
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
int n = 5;
/* calloc - allocate + initialize to 0 */
int *arr = (int*)calloc(n, sizeof(int));
printf("calloc initialized: ");
int i;
for (i = 0; i < n; i++) printf("%d ", arr[i]); /* 0 0 0 0 0 */
printf("\n");
/* Fill array */
for (i = 0; i < n; i++) arr[i] = (i+1) * 10;
/* realloc - resize to 8 elements */
arr = (int*)realloc(arr, 8 * sizeof(int));
for (i = 5; i < 8; i++) arr[i] = 0;
printf("After realloc(8): ");
for (i = 0; i < 8; i++) printf("%d ", arr[i]);
printf("\n");
free(arr);
arr = NULL;
/* Dynamic string */
char *name = (char*)malloc(50 * sizeof(char));
strcpy(name, "Sokha Chan");
printf("Name: %s\n", name);
free(name);
return 0;
}
- រាល់
malloc/calloc/reallocត្រូវមានfree()ផ្គូ - Always check return value ≠ NULL មុន use
- កុំ free() pointer ដែលគ្មាន allocated ឬ freed ហើយ
- Set pointer = NULL ក្រោយ free()
- Memory leak = allocate ប៉ុន្តែ forget free → program ប្រើ RAM ច្រើនខ្លាំង
7.11 Function Pointers
Function pointers រក្សាទុក address នៃ functions អាចប្រើ call functions dynamically:
#include <stdio.h>
double add(double a, double b) { return a + b; }
double sub(double a, double b) { return a - b; }
double mul(double a, double b) { return a * b; }
double dvd(double a, double b) {
if (b == 0) { printf("Error!\n"); return 0; }
return a / b;
}
/* Function pointer type */
typedef double (*Operation)(double, double);
double calculate(double a, double b, Operation op) {
return op(a, b);
}
int main() {
/* Declare function pointer */
double (*fp)(double, double);
fp = add;
printf("10 + 5 = %.2f\n", fp(10, 5));
fp = sub;
printf("10 - 5 = %.2f\n", fp(10, 5));
/* Array of function pointers */
Operation ops[4] = {add, sub, mul, dvd};
char *opNames[] = {"Add", "Sub", "Mul", "Div"};
int i;
printf("\nAll operations on 10, 5:\n");
for (i = 0; i < 4; i++) {
printf("%-4s: %.2f\n", opNames[i], calculate(10, 5, ops[i]));
}
return 0;
}
7.12 Pointers to Structs (Preview)
Struct ជា user-defined type ដែលប្រមូល data fields ផ្សេងៗ:
#include <stdio.h>
#include <string.h>
/* Define struct */
struct Student {
char name[50];
int age;
float gpa;
};
void displayStudent(struct Student *s) {
printf("Name: %s, Age: %d, GPA: %.2f\n",
s->name, s->age, s->gpa);
/* s->name is same as (*s).name */
}
int main() {
struct Student s1;
struct Student *ptr = &s1;
/* Access via pointer - use -> operator */
strcpy(ptr->name, "Sokha");
ptr->age = 20;
ptr->gpa = 3.85;
displayStudent(ptr);
/* Array of structs */
struct Student students[3];
strcpy(students[0].name, "Dara");
students[0].age = 21;
students[0].gpa = 3.70;
struct Student *p = students;
printf("First: %s\n", p->name);
return 0;
}
ឧទាហរណ៍ពេញលេញ - Dynamic Array of Students:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char name[50];
int age;
float score;
} Student;
void inputStudent(Student *s, int index) {
printf("\nStudent %d:\n", index+1);
printf("Name : "); scanf("%s", s->name);
printf("Age : "); scanf("%d", &s->age);
printf("Score: "); scanf("%f", &s->score);
}
void displayAll(Student *arr, int n) {
int i;
printf("\n%-15s %-5s %-6s\n", "Name", "Age", "Score");
printf("------------------------------\n");
for (i = 0; i < n; i++) {
printf("%-15s %-5d %-6.2f\n",
arr[i].name, arr[i].age, arr[i].score);
}
}
float average(Student *arr, int n) {
float sum = 0;
int i;
for (i = 0; i < n; i++) sum += arr[i].score;
return sum / n;
}
int main() {
int n;
printf("Number of students: ");
scanf("%d", &n);
/* Dynamic allocation */
Student *students = (Student*)malloc(n * sizeof(Student));
if (!students) { printf("Memory error!\n"); return 1; }
int i;
for (i = 0; i < n; i++) inputStudent(&students[i], i);
displayAll(students, n);
printf("\nClass average: %.2f\n", average(students, n));
free(students);
students = NULL;
return 0;
}
លំហាត់ប្រចាំមេរៀនទី 7 - Pointers & Dynamic Memory (malloc, free)
- ប្រកាស Pointer (
int *p) ចង្អុលទៅកាន់អថេរintមួយ។ បង្ហាញតម្លៃនៃអថេរ និងអាសយដ្ឋាន (Memory Address) របស់វា។ - សរសេរកម្មវិធីផ្លាស់ប្តូរតម្លៃនៃអថេរដើមដោយប្រយោល (Indirectly) តាមរយៈការប្រើប្រាស់ Pointer។
- សរសេរកម្មវិធីបង្ហាញពី Pointer Arithmetic ដោយរុញ Pointer ទៅមុខដើម្បីអានធាតុបន្តបន្ទាប់នៅក្នុង Array (
*(p+i))។ - បង្កើត Function
swap(int *a, int *b)ដើម្បីផ្លាស់ប្តូរតម្លៃអថេរពីរ ដោយប្រើយន្តការឆ្លងកាត់អាសយដ្ឋាន (Call by Reference)។ - សរសេរកម្មវិធីរកប្រវែងនៃ String មួយ ដោយប្រើតែ Pointer ជំនួសឱ្យការប្រើ Index នៃ Array (អត់ប្រើ strlen)។
- សរសេរកម្មវិធីប្រើ
malloc()ដើម្បីបម្រុងទុកអង្គចងចាំសម្រាប់ Array ដែលមាន n ធាតុ រួចបញ្ចូលទិន្នន័យ។ - សរសេរកម្មវិធីរកផលបូកនៃធាតុក្នុង Array ដែលត្រូវបានបម្រុងទុកដោយប្រើ
malloc()។ - សរសេរកម្មវិធីប្រើ
calloc()ដើម្បីបម្រុងទុកអង្គចងចាំ និងកំណត់តម្លៃដើមនៃគ្រប់ប្លុកទៅជា 0 ដោយស្វ័យប្រវត្តិ។ - សរសេរកម្មវិធីប្រើ
realloc()ដើម្បីពង្រីកទំហំ Dynamic Array បន្ថែមធាតុថ្មីដោយមិនបាត់បង់ទិន្នន័យចាស់។ - សរសេរកម្មវិធីដោយមានបញ្ចូលអនុគមន៍
free()នៅចុងបញ្ចប់ ដើម្បីលុប (Deallocate) អង្គចងចាំវិញ បន្ទាប់ពីប្រើប្រាស់ Dynamic Memory រួចរាល់ ដើម្បីជៀសវាង Memory Leak។