Си хэл

C буюу Си нь 1969-өөс 1973 оны хооронд AT&T-ийн Беллийн Лабораторид Деннис Ритчи зохиосон ерөнхий зориулалтын програмчлалын хэл.
Си нь бүх цагийн хамгийн өргөн хэрэглэгдэж буй програмчлалын хэлнүүдийн нэг бөгөөд Си хэлний хөрвүүлэгч нь ихэнх компьютерын архитектур, үйлдлийн системд бий.
Сүүлд гарсан олон хэлнүүд Си-гээс шууд болон шууд бусаар зээлсэн байдаг. Тухайлбал C#, D, Go, Rust, Java, JavaScript, Limbo, LPC, Objective-C, Perl, PHP, Python, Verilog, Unix-ийн Си бүрхүүл багтана.
Си хэл баталгаажихаас өмнө хөгжүүлэгчид Деннис Ритчи, Брайан Керниган хоёрын гаргасан номоор явж байлаа. Баталгаажаагүй энэхүү Си хэлийг "K&R" С гэдэг. 1989 онд Америкийн хэмжил зүйн байгууллагаас "ANSI C" (C89) хэлийг батлаж гаргажээ. Дараа жил нь Олон улсын хэмжил зүйн байгууллага С90-г баталж гаргажээ. ISO дараа нь 1995 онд олон улсын дэмжлэгийг гаргасан бөгөөд 1999 онд (C99) дахин хянагдсан. 2011 оны 12-р сард С11 хэмээх стандарт нь батлагдсан.
Си хэл нь процедурын хэл. Тиймээс Си нь системийн програмчлал мэтийн ассемблер хэлээр бичигддэг програмуудад хэрэгтэй юм.
Си хэл нь доод түвшний програмчлал хийж чаддаг систем голдоггүй (Анг. platform independent) зохиогдох эхлэлийг тависан. Олон төрлийн төхөөрөмж болон үйлдлийн системд Си программаа ажиллуулахад үндсэн кодод нээх их өөрчлөлт ордоггүй. Си хэл бол микроконтроллероос авахуулаад суперкомпьютерыг ч хүртэл програмчилдаг.
Си-д бүх код нь "функц" гэдэг дэд програмууд дотор бичигддэг. Функцийн параметрууд нь үргэлж утгаар дамждаг. Параметрт хувьсагч дамжуулахдаа "заагч" төрлийг ашигладаг. Си програмын код нь баригдмал бус, цэгтэй таслалаар төгсгөх командыг хэрэглэдэг, угалзан хаалтаар кодоо бүлэглэдэг.
Си хэл нь дараах шинж чанартай:
Процедур (утга буцаадаггүй дэд програм)-ыг утгагүй void буцаах төрөлтэй функцээр илэрхийлдэг.
AT&T-ийн Беллийн Лабораторид 1969-өөс 1973 оны хооронд анх хөгжүүлсэн бөгөөд 1972 онд хамгийн оргил үе нь байжээ. Кен Томпсоны BCPL програмчлалын хэлний хялбаршуулсан хувилбар болох B ("Би" гэж дуудна) гэдэг хэлнээс хөгжүүлсэн учир Си гэдэг нэр өгчээ.
Си хэлний үүсэл нь Ритчи, Томпсон хоёрын PDP-7 машины ассемблер хэлээр хөгжүүлсэн Unix үйлдлийн системтэй салшгүй холбоотой юм. Тэгтэл үйлдлийн системээ PDP-11 уруу шилжүүлэхээр болж. B хэл нь PDP-11 машинаа бүрэн ашиглаж чадахгүй байсан тул Си хэлийг хөгжүүлэх шалтгаан болжээ.
Анхны PDP-11 машины Unix систем нь ассемблер хэлээр хийгдсэн. 1973 онд Си хэл нь struct төрлийг нэмснээр Unix-ийн цөмийн ихэнх хэсгийг бичиж чадах чадамжтай болжээ. Энэ нь үйлдлийн системийн цөмийг анх удаа ассемблер хэлнээс өөр хэлээр програмчилсан явдал юм. 1977 оны үеэр Ритчи, Стивен Си.Жонсон хоёр Unix үйлдлийн системийг шилжих (portable) чадвартай болгохоор Си хэлэнд өөрчлөлт оруулав. Жонсоны Шилчих Чадвартай Си-гийн Хөрвүүлэгч нь шинэ системүүдэд Си хэлний хөгжүүлэлт хийхэд ашиглагдсан.
1978 онд Брайан Керниган, Деннис Ритчи нар "The C Programming Language" гэдэг номоо гаргав. Энэхүү ном нь олон жилийн турш уг хэлний тухай сурах бичиг болсон бөгөөд Си хэлний програмистууд уг номыг "K&R" гэж нэрлэдэг. Номонд гарч буй Си хэлний хувилбарыг K&R C гэдэг. Хоёр дахь хэвлэлээсээ ANSI C стандартаар гаргажээ.
K&R нь дараах зүйлсийг багтаана:
1989 онд Си хэлний стандарт гарсан ч гэлээ олон жил K&R C хэл Си хэлний програмистуудад хэрэглэгдсээр байсан бөгөөд хуучин хөрвүүлэгчид хэрэглээнээс гараагүй, мөн зөв бичсэн K&R C нь стандарт Си-тэй нийцдэг байсантай холбоотой юм.
Си хэлний анхны хувилбаруудад функц нь int төрлөөр утга буцааж байвал функцийн зарлагаанд буцаах утгын төрлийг заах шаардлагагүй байсан.
Жишээ нь:
Тайлбарт оруулсан int-үүдийг K&R C-д хасаж болдог байсан ч сүүлд гарсан стандартаар заавал тавьдаг болсон.
K&R функцийн зарлагаанд функцийн аргументийн тухай мэдээлэл байдаггүй, функцийн параметрийн төрлийг шалгадаггүй, мөн зарим хөрвүүлэгчид нь дотоод функцийн аргументийн тоо зөрөх юм уу аргументийн тоо, төрөл зөрсөн гадаад функцийг олон дуудахад анхааруулгын мэдээд өгдөг байв. Код дахь функцийг шалгадаг Unix-ийн "lint" мэтийн тусдаа хэрэгслүүд хөгжүүлэгдэв.
K&R C хэвлэгдсэн онд AT&T болон өөр бусад компаниудаас гаргасан хөрвүүлэгчдийг дэмжих үндсэн бус зүйлүүд Си хэлэнд орж ирэв. Тэдгээр нь:
Си хэл түгэхийн хэрээр олон тооны нэмэлтүүд гарч тэдгээр бүгдийг стандартад оруулах шаардлага гарсан.
1970 оны сүүлчээс эхлэн Си хэл нь олон төрлийн мейнфрейм компьютер, миникомпьютер, микрокомпьютер, ялангуяа нэлээд алдартай болж байгаа IBM PC-д гарав.
1983 онд Америкийн Үндэсний Хэмжилзүйн Байгууллага (ANSI) Си хэлний стандарт буюу X3J11-ийг гаргав. 1989 онд "Програмчлалын Си хэл" ANSI X3.159-1989 Си хэлний стандарт батлагдав. Энэ хувилбарыг ANSI C, Стандарт Си, заримдаа С89 гэдэг.
1990 онд ANSI C стандартыг Олон Улсын Хэмжилзүйн Байгууллага (ISO)-аас ISO/IEC 9899:1990 стандартад авав . Заримдаа С90 ч гэдэг. Тиймээс "С89", "С90" хоёр нь адилхан програмчлалын хэлнүүд юм.
ANSI/ISO-ын стандарчлалаас хойш Си хэл 7 жил шинэчлэгдээгүй. 1995 оны 1990 оны Си-гийн стандартын Нормжуулсан Сайжруулалт 1 (ISO/IEC 9899/AMD1:1995 буюу С95) олон хэлний тэмдэгтүүдийг дэмждэг, бас бусад зүйлсийг зассанаар хэвлэгдэв. 1990 оны сүүлжээр Си хэлний стандартыг дахин хянасан нь 1999 оны ISO/IEC 9899:1999 буюу С99 гарахад хүргэсэн юм. Үүнээс хойш гурван удаа засвар орсон.
С99-д inline функц, шинэ өгөгдлийн төрлүүд (Жишээ нь: long long int, complex), хэмжээ нь хувьсдаг цуваа, IEEE 754 хөвөх таслалтай тоо, хувьсагчтай макро, нэг мөр тайлбар (//-аар эхэлдэг) нар шинээр орсон. Эднээс ихэнх нь хэд хэдэн Си-гийн хөрвүүлэгчдэд дэмжигдээд эхэлсэн байсан.
2007 онд Си-гийн стандартыг дахин шинэчлэх ажил эхэлсэн бөгөөд 2011 оны 12-р сарын 8-нд стандарт гарах хүртлээ "C1X" гэж нэрлэгдэж байлаа.
Си хэл нь Си хэлний стандартад заасан дүрмийн дагуу бичигддэг. Си хэлний код нь чөлөөт бичиглэлтэй буюу нэг мөрөнд хэдэн ч үйлдлийг багтааж болдог. Тайлбар оруулахдаа /* */ гэсэн хоёр зааглагчийн хооронд юм уу //-аас хойшхи мөрөнд бичдэг. Тайлбар дотор тайлбар хийж болохгүй. Тайлбар доторх ямар ч код ажиллахгүй.
Си хэлний код нь зарлагаа болон функцийн тодорхойлолтоос тогтоно. Функцийн тодорхойлолт нь зарлагаа болон командуудаас тогтоно. Зарлагаа нь өгөгдлийн төрөл, хувьсагчийн нэрээс тогтоно. Өгөгдлийн төрөл нь struct, union, enum-аар шинэ тодорхойлогдсон шинэ төрөл байж болно. Угалзан хаалтаар ({}) кодоо бүлэглэнэ. if-else нөхцөлт үйлдэл, do-while, while, for-оор давталт ашиглан "Бүтэцлэгдсэн Програмчлал"-ыг хэрэгжүүлдэг.
Ихэнх команд нь цэгтэй таслалаар нь төгсдөг.
Си хэлний цагаан толгойд:
Шинэ мөр нь мөрийг төгсгөх үйлдэл бөгөөд яг нэг тэмдэгт байдаггүй ч Си хэлэнд нэг тэмдэгтээр тооцдог.
Си хэлний сүүлчийн хувилбар (C11)-т Unicode дэмжигдсэн бөгөөд \uDDDD (DDDD нь Unicode тэмдэгтийн код байна) хэлбэртэйгээр хэрэглэгдэнэ. Гэвч бүрэн нэвтэрч чадаагүй байна.
Си хэлэнд дуу гаргах (alert), арагшаа тэмдэгт устгах (backspace), шинэ мөр (carriage return) гэх мэт тэмдэгтүүд бий. Си хэлний стандартыг өөрчлөх бүрийд цагаан толгой нь нэмэгдсээр байгаа билээ.
C89 нь 32 түлхүүр үгтэй:
C99 нь нэмэлт 5 түлхүүр үг оруулж ирсэн:
C11 нь 7 түлхүүр үгийг нэмсэн:
Сүүлд нэмэгдсэн түлхүүр үгс нь доогуур зураастай томоор эхэлсэн байгаа нь Си хэлний хөгжүүлэлтэд зориулж нөөцөлсөн үгтэйгээ давхцахгүйн тулд юм.
Си хэлний үйлдлүүд:
Си хэл нь = үйлдлээр математикийн тэнцүүг илэрхийлэлгүй Fortran, PL/I хэлийг дагаж утга олгох үйлдлийг илэрхийлдэг. Си хэлэнд =, == үйлдлүүд нь хоорондоо төстэй учир хооронд нь хольж солих явдал их байдаг. Андуурч бичсэн ихэнх тохиолдолд хөрвүүлэгч алдаа өгдөггүй. Жишээ нь: if(a=b+1) гэдэг нөхцөлт илэрхийлэлд a-д утга олгосны дараа a нь 0-ээс ялгаатай бол үнэн нөхцлийг илэрхийлнэ. Си хэл үйлдлүүдийн эрэмбээ өөрөө тохируулдаггүй. Тухайлбал == нь & | хоёроос өндөр эрэмбэтэй тул x & 1 == 0 гэдэг илэрхийлэлд эхлээд == үйлдлийг хийх тул (x & 1) == 0 гэж бичвэл зөв илэрхийлэл болох юм.
"hello, world" жишээ програмыг K&R номын анхны хувилбарт Си хэлний удиртгал програм болгон ашиглажээ. Энэхүү програм нь стандарт гаралтын төхөөрөмж буюу дэлгэцэд "hello, world" гэж хэвлэдэг.
Анхны хувилбар:
Стандартын дагуу:
Эхний мөрөнд урьдчилан боловсруулах файл #include-ээр эхэлсэн байна. Өөрөөр хэлбэл stdio.h файлын бүх текстийг уг мөрөнд орлуулж тавина гэсэн үг. printf функц stdio.h толгой файлд тодорхойлогдсон учир заавал зааж өгөх ёстой. Толгой файл нь өнцөгтэй хаалтан дотор заасан бол үндсэн толгой файлын хаягаас хайх бол давхар хашилтан (") дотор байвал зааж өгсөн хаягаас хайдаг.
Дараагийн мөр нь main функц. Си хэлэнд main функц нь их чухал үүрэгтэй. Програм ажиллахдаа main функцээс эхэлж ажилладаг. Өмнөх int гэдэг нь main функцийн буцаах утгын төрлийг заадаг. Дугуй хаалтан дотор void гэж байгаа нь функц аргументгүй гэдгийг илэрхийлнэ.
Нээж байгаа угалзан хаалтнаас main функцийн тодорхойлолт эхэлнэ.
Дараагийн мөрөнд стандарт сангийн printf функцийг "hello, world\n" аргументтэй дуудаж байна. printf функц нь өгөгдсөн форматтын дагуу хэлбэржүүлсэн тэмдэгт мөрийг (format string) хэвлэдэг. \n нь шинэ мөрийн тэмдэгтийг илэрхийлдэг. printf функц нь int төрлийн утга буцаадаг боловч уг буцаасан утгыг ашигласан зүйл байхгүй учир зүгээр хаягдах юм. Төгсгөлд нь цэгтэй таслал байх бөгөөд командыг төгсгөдөг үйлдэл юм.
Хаасан угалзан хаалтаар main функцийн тодорхойлолт дуусна.
C99 стандартад main функц нь заавал int утга буцаах ёстой байдаг бөгөөд хаасан угалзан хаалтын өмнө return 0; гэсэн мөрийг бичдэг. main функц 0 утгыг буцааж байвал програм алдаагүй ажилласаныг илэрхийлдэг.
Зарим програмын хэл нь толгой файл ашигладаг.Энэ нь програмчидад эх кодын тодорхой элемэнтдүүдийг ахин ашигладдаг файл болгодог. Си хэлний толгой файлууд нь .h өргөтгөлтэй текст файл байх бөгөөд толгой файлыг програмд холбож өгснөөр түүн дотор тодорхойлогдсон функц, макро, төрөл, тогтмолуудыг хэрэглэх боломжтой болдог. Си хэлэнд дараах стандарт толгой файлд бий. <stdio.h> <math.h> <string.h> <time.h> <float.h> <[[<stdlib.h]]>
Си хэлний Цуваа төрөлд заавал хэмжээг нь зааж өгсөн байх ёстой. (С99 стандартад цувааны хэмжээг хувьсагчаар илэрхийлж болдог болсон.) Харин ажиллаж байх үед цувааны уртыг стандарт сангийн malloc функцийн тусламжтайгаар санах ойгоос зай нөөцөлж авах боломжтой. Си хэлэнд цуваа, заагч хоёр нь нэг нэг рүүгээ хувирч болдог.
Цувааны элементэд заагчаар хандаж болдог учир цуваанд хандахад цувааны урт дотор эсэхийг шалгадаггүй учир зарим хөрвүүлэгчид цувааны хязгаарыг шалгадаг сонголттой байдаг. Програмаа бичихдээ цувааны хязгаарыг сайн тооцохгүй бол зөвшөөрөлгүй санах ой руу хандах, буруу өгөгдөл өөрчлөх, буффер дүүрэх, ажиллах үеийн алдаа гэх мэт янз бүрийн хүсээгүй үр дүн гаргадаг. Автоматаар хязгаараа боловсруулдаггүй учир сайн тооцох хэрэгтэй.
Си хэлэнд тусдаа олон хэмжээстэй цуваа зарлах гэж байдаггүй ч цуваануудын цуваагаар дүрсэлдэг.
Олон хэмжээст цуваа нь ихэвчлэн тоон алгоритм (ихэвчлэн шугаман алгебр)-т матриц хадгалахад хэрэглэгддэг. Гэхдээ цуваа гэдэг маань цаанаа заагчид байдаг учир цувааны хязгаарыг сайн тодорхойлох шаардлагатай.