Си++ хэлний тухай товчхон
Орчин үеийн зарим автомат төхөөрөмж урьдчилан бэлдэж өгсөн зааврын дагуу уг төхөөрөмж дээр биелэгдэх боломжтой олон тооны эгэл үйлдлүүдийг дараалан биелүүлэх замаар илүү нарийн төвөгтэй үйлдлийг гүйцэлдүүлдэг. Ерөнхийд нь, ийм заавар бэлдэж өгөх үйл ажиллагааг програмчлал, уг төхөөрөмжид “ойлгогдохоор” заавар бэлдэх аргыг програмчлалын хэл гэнэ. Жишээлбэл, зарим тооны машин дээр дараах мөрийг шууд бичиж өгч бодуулж болно: “5*(2+3)”. Энд бид тооны машинд “2 дээр 3-ыг нэмээд үр дүнг нь 5-аар үржүүл” гэсэн заавар өгсөн хэрэг. Энэ жишээнд програмчлалын хэл маань тоонууд, арифметикийн үйлдлүүд ба хаалтуудыг ашиглаж зөв илэрхийлэл бичих дүрмүүдээс тогтоно гэсэн үг. Бидний бичсэн дээрх “програмыг” ажиллуулахын тулд “=” товчийг дарах шаардлагатай боловч үүнийг манай “програмын” хэсэг биш гэж үзэж болно.
Хамгийн анхны програмчлалын хэл Чарльз Баббажийн аналитик машинтай хамт үүссэн гэж үзэж болно. Аналитик машины үндэс нь механикийн араанууд байсан ба араануудыг том эсвэл жижиг араануудаар солих замаар програмчлах зарчимтай байжээ. 1942 онд бүтээгдсэн анхны электрон компьютер ENIAC үндсэндээ аналитик машины цахилгаан хувилбар нь байсан бөгөөд түүнийг програмчлах арга нь (програмчлалын хэл нь) одоогийн гэр ахуйн цахилгаан халаагуурын тохируулгыг санагдуулам олон тооны утаснуудын холболтыг өөрчлөх явдал байсан байна.
Жон фон Нейман 1945 онд Жон Маухли, Преспер Эккерт нартай хамтаар EDVAC компьютерийн дизайн дээр ажиллаж эхлэх үедээ компьютерийг програмчлахын тулд утаснуудыг сольж холбох нь бүдүүлэг хэрэг бөгөөд програм нь компьютерийн санах ойд хадгалагдаж, компьютер түүнийг уншиж зохих үйлдлүүдийг гүйцэтгэдэг байх боломжтой гэдгийг анх тоймлож үзүүлсэн. Түүнээс өмнө компьютерүүд оролтын ба гаралтын өгөгдөл болон тооцооны үед бий болсон завсрын үр дүнгүүдийг хадгалах санах ойтой байсан ба энэ санах ойд програмыг хадгалах, өөрөөр хэлбэл компьютер ямар ямар үйлдлийг гүйцэтгэх вэ гэсэн зааврыг оролтын өгөгдлийн нэг хэсэг мэтээр үзэх нь цоо шинэ санаа байжээ. Энэ арга нь юуны түрүүнд програмыг соронзон хальсан дээр хадгалах, дахин ачаалах боломжийг өгнө. Үүнтэй холбоотой өөр нэг боломж бол програм ажиллах явцад буй болсон завсрын үр дүнгээс хамаарч санах ойн хаана байрлаж буй зааврыг гүйцэтгэх вэ гэдгийг шийдэж болох боломж юм.
Фон Нейман ба түүний хамтрагчдын дэвшүүлсэн компьютерийн архитектурын бүдүүвч бүтцийг авч үзье (Зураг 1). Уг бүдүүвч ёсоор компьютер нь төв процессор, шуурхай санах ой ба оролт гаралтын төхөөрөмжүүд гэсэн үндсэн хэсгүүдтэй. Шуурхай санах ойг дараалсан олон нүднүүдээс тогтох маш урт туузаар төсөөлж болно. Ихэнх компьютерийн хувьд санах ойн эдгээр нүд болгон 0-ээс 255-ын хооронд орших ямар ч бүхэл тоог хадгалах чадвартай бөгөөд нүд болгон өөрийн гэсэн дугаартай байдаг. Нэг ийм нүдийг нэг байт мэдээлэл хадгалах чадвартай гэж ярьна. Мэдээллийг хадгалах бусад байгууламжууд, жишээлбэл хатуу диск, оптик диск ба флаш-санах ой бүгд ийм байтуудын дарааллыг хадгалах зориулалттай, ер нь компьютер нь ийм байтуудын дарааллыг боловсруулах зориулалттай гэж үзэж болно. Ийм олон тоог хадгалах, боловсруулах ямар шаардлага байна, үүнээс гадна бид нар компьютерийн дэлгэц дээр дан тоо хардаггүй, гараас зөвхөн тоо оруулдаггүй шүү дээ гэж та эргэлзэж байж болох юм. Тэгэхээр санах ойд хадгалагдаж, компьютерээр боловсруулагдаж буй тоонууд ямар нэг мэдээллийг төлөөлж буйг үргэлж санах хэрэгтэй. Өөрөөр хэлбэл эдгээр тоонуудыг яаж тайлбарлах вэ гэдгийг компьютер ямар нэг хэлбэрээр “мэддэг” байх ёстой. Тухайлбал, текстийг компьютерээр боловсруулахын тулд үсэг, цэг, таслал гэх мэт тэмдэгт болгонд тоо харгалзуулсан дүрэм боловсруулж ашигладаг. Үүнд гараас текст оруулах, текстийг дэлгэц эсвэл цаасан дээр хэвлэх болгонд энэ дүрмээ ашиглан дотоод тоон дүрслэл ба хүний ойлгох дүрслэл хоёрын хооронд хөрвүүлэх ажиллагаа явагдана. Латин ба кирилл үсгүүд, бусад олон туслах тэмдэгтүүдтэйгээ нийлээд 200 орчим тэмдэгт болох учир нэг тэмдэгтийг нэг байтаар дүрслэхэд хангалттай. Ингэж кодлох олон янзын стандарт байдгийн хамгийн өргөн тархсан нь ASCII кодчилол юм. Энд жишээ нь латин А үсгийн код 65, B үсгийн код 66 байдаг. Харин олон янзын бичгийг зэрэг хэрэглэх, ялангуяа ханз үсэг хэрэглэх тохиолдолд дор хаяж хоёр байтын комбинацаар нэг тэмдэгтийг кодлох шаардлага гарна. Ийм кодчиллын тоонд Unicode стандарт багтана.
Тэмдэгтийг ингэж кодчилохтой төстэйгээр төв процессорын гүйцэтгэх боломжтой коммандууд мөн тодорхой тоонуудаар кодчилогсон байдаг. Ийм коммандуудыг машины коммандууд гэх бөгөөд төв процессор шуурхай санах ойн нүднүүдийг дэс дараалан уншиж тэнд бичигдсэн машины коммандуудыг гүйцэтгэх замаар компьютер ажилладаг. Энэ тоон кодуудын цогц нь тухайн процессорын хувьд програмчлалын хэл болох ба үүнийг машины хэл гэж ярьна. Машины хэл дээр программ бичихийн тулд ямар коммандыг ямар тоогоор дүрсэлдгийг (машины кодыг) цээжлэх шаардлагатайн дээр том програмыг уншиж ойлгох болон засварлахад маш хүндрэлтэй байх нь ойлгомжтой. Жишээлбэл, 80x86 төрлийн (Pentium гэх мэт) процессоруудын хувьд, EAX регистрт (регистр гэдэг нь процессор дотор орших тусгай санах ойн нэр) буй тоог EBX регистр дэх тоон дээр нэмээд үр дүнг нь EAX регистрт хадгалах коммандын машины код нь
3 195
хэмээх хоёр байтаас тогтоно.
Програмд олон дахин ашиглагддаг хэсэг үйлдлийг санах ойд үндсэн програмаас тусдаа байрлуулаад хэрэгтэй үед хаягаар нь дуудаж ашиглаж болно. Ингэж үндсэн програмаас тусдаа байрласан, програмд шаардлагатай ямар нэг бодлогыг бие дааж шийдвэрлэх чадвартай бүлэг үйлдлийг дэд програм гэж ярьдаг. Дэлгэц дээр үсэг гаргах, дискний файлаас өгөгдөл унших гэх мэт маш ерөнхий зориулалттай дэд програмуудыг санах ойд байнга байрлуулж, тухайн үед ажиллаж буй програм нь шаардлагатай дэд програмаа сонгон авч хэрэглэдэг байвал эдгээр дэд програмуудыг програм болгон өөртөө “тээж” явах албагүй болно. Ийм дэд програмуудын сан нь програм зохиогчийн ажлыг маш ихээр хөнгөвчлөх ба ерөнхийдөө машины хэлийг өргөтгөж түүнд өргөн хэрэглэгддэг олон чухал коммандуудыг нэмсэн мэт үйлчлэл үзүүлдэг.
Програм бичих ажиллагааг ассемблер хэл ихээр хөнгөвчилдөг. Ассемблер хэл дээр бичигдсэн програм нь жирийн текст бөгөөд ассемблер програмын мөр болгон машины нэг коммандад харгалзана. Жишээ нь, дээрх машины коммандыг ассемблер хэл дээр бичвэл
add eax, ebx
болно (add – англиар “нэм” гэсэн үг). Бэлэн болсон ассемблер програмыг машины хэл рүү хөрвүүлэхийн тулд ассемблерын хөрвүүлэгч хэмээх тусгай програмыг ашигладаг. Ассемблерын хөрвүүлэгчийг өөрийг нь бол шууд машины хэл дээр бичиж болно. Машины коммандуудын цогц тухайн процессорын төрлөөс хамааран янз бүр байдаг тул машины коммандуудын тоон кодчиллыг процессорын төрөл болгонд адилхан байхаар стандартчилах боломжгүй. Тэгэхээр ассемблер хэл мөн процессорын төрлөөс хамаарч өөр өөр байна гэсэн үг. Үүнтэй холбогдуулан машины хэл ба ассемблер хэлийг доод түвшний програмчлалын хэл гэх нь бий.
Тэмдэглэл. Зарчмын хувьд санах ойд тоог дүрслэх маш олон арга байж болох боловч одоо үеийн бараг бүх тоон төхөөрөмжид хоёртын системийг ашигладаг. Бидний сайн мэдэх аравтын системд дүрслэгдсэн тооны орон бүр 10-ын тодорхой зэрэг уг тоонд хэдэн удаа агуулагдсаныг заадаг билээ. Жишээ нь, 902.3 гэсэн тоонд 9 ширхэг 100; 0 ширхэг 10; 2 ширхэг 1; ба 3 ширхэг 0.1 агуулагдсан байна. Үүнтэй төстэйгээр, хоёртын системд дүрслэгдсэн тооны орон бүр 2-ын зэргүүд уг тоонд хэдэн удаа агуулагдсаныг заана. Жишээ нь, хоёртын дүрслэл нь 101 байх тоо аравтын системд 8 + 0 + 1 = 9 гэж бичигдэнэ. Хоёртын нэг оронг нэг бит хэмээдэг бөгөөд нэг бит нь 0 юм уу 1 утгын аль нэгийг авч болдог. Мөн нэг байт нь 8 биттэй тэнцүү болох нь тодорхой. Хоёртын тооллын систем нь техникийн үүднээс хялбар, 8 нь хоёрын бүхэл зэрэг бөгөөд бидний хэрэглэдэг ихэнх тэмдэгтүүдийг 8 битийн комбинацаар дүрсэлж болдог нь бит ба байтын үүсэлд нөлөөлсөн хэрэг.
Нэгэнт машины хэлийг стандартчилж болохгүй учир ямар ч програм зөвхөн тодорхой төрлийн компьютерт л зориулагдсан байх ёстой. Жишээлбэл, Микрософт Виндоус (Microsoft Windows) програмыг Макинтош төрлийн компьютер дээр суулгаж ажиллуулах гэж оролдвол цагийн гарз болох вий. Цаашилбал, ямар ч програм зөвхөн тодорхой орчинд (эсвэл платформд) ажиллахаар зориулагдсан байдаг. Програмын ажиллах орчин гэдэгт компьютерийн төрөл, үйлдлийн систем, түүнчлэн уг програмын ажиллагаанд зайлшгүй шаардлагатай төхөөрөмжүүд ба програмуудын цогцыг ойлгоно. Ажиллах орчны гол үзүүлэлт бол үйлдлийн систем мөн. Үйлдлийн систем нь програмд хатуу диск, дэлгэц, гар, хэвлэгч гэх мэт системийн төхөөрөмжүүдийг ашиглах, бусад програмуудтай харилцан үйлчлэх, хэрэглэгчтэй стандарт маягаар харьцах зэрэг боломжийг олгож, тусгай дэд програмуудын санг гаргаж өгдөг. Эдгээр дэд програмуудын сан үйлдлийн системээс хамааран өөрчлөгдөх тул програм нь зөвхөн нэг л үйлдлийн систем дээр ажиллаж чадна. Жишээлбэл, Виндоус системд зориулагдсан програмыг Линукс (Linux) систем дээр (шууд) ажиллуулж болохгүй. Линукс системд Виндоус орчинг зохиомлоор бүрдүүлж дотроо Windows програм ажиллуулдаг тийм програмууд байдаг. Энэ тохиолдолд манай програмын ажиллах орчин бүрэлдчихсэн байгаа нь илт бөгөөд түүнийг Линукс дээр ажиллаж байна гэж үзэх хэрэггүй юм.
Ассемблер нь машины хэлний “махчилсан” орчуулга учраас түүн дээр, ялангуяа том програм бичих нь маш төвөгтэй. Програмын текстэнд алдаа байвал түүнийг олоход үлэмж хэцүү болохоос гадна платформ болгонд тохируулж програмаа дахин дахин бичих шаардлагатай. Ассемблерын энэ дутагдлыг арилгахын тулд зохиогдсон илүү дээд түвшний програмчлалын хэлнүүд уншиж ойлгоход хялбар, баргийн санамсаргүй алдааг хэл нь өөрөө зааж өгөх механизмтай, платформоос хамааралгүй програм бичих боломжтой болсноороо компьютерийн програм хангамжийг шинэ шатанд гаргасан юм. Дээд түвшний хэл дээр бичигдсэн програм нь жирийн текст файл бөгөөд дээд түвшний хэлний нэг коммандад машины хэдэн арван комманд харгалзаж болно. Бэлэн болсон програмын текст файлыг хөрвүүлэгч буюу компилятор хэмээх тусгай програмыг ашиглан машины хэлэнд хөрвүүлж бие даан ажиллах чадвартай програмын ажиллах файл (буюу биелэх файл) болгодог. Хөрвүүлэгдээгүй байгаа програмын текстийг мөн програмын эх код гэж нэрлэдэг. Програмын эх кодыг хэд хэдэн платформ дээр хөрвүүлж болдог байхаар бичиж болно. Ингэснээр бид зөвхөн нэг эх кодноос нэг програмын өөр өөр платформ дээр ажиллах чадвартай хувилбаруудыг гарган авна гэсэн үг.
Түүх сөхвөл. Хамгийн анхны дээд түвшний програмчлалын хэлийг Жон Маухли 1949 онд UNIVAC компьютерт зориулан зохиосон Богино Код (Short Code) хэмээх програмдаа хэрэгжүүлсэн гэж үздэг. Энэ програм нь өгөгдсөн алгебрын томъёонуудын дагуу тооцоо хийж үр дүнг нь гаргадаг програм ажээ. 1950 оноос фон Нейман АНУ-д шинээр дэвшигдэж байгаа болон дундаа явагдаж буй технологийн төслүүдийг хянах зөвлөгчөөр ажиллаж байв. 1954 оны нэгэн ийм “шүүх ажиллагаанд” дээд түвшний анхны хэлнүүдийн нэг болох Фортран хэлний төслийг IBM компанийн Жон Бакус авч оржээ. Фон Нейман үүнийг ямар ч шинэ зүйл гэж үзсэнгүй, “яагаад машины хэлнээс өөр юм чамд хэрэгтэй байгааг ойлгохгүй байна” хэмээсэн ба уг төслийг “үндсэндээ Жон Маухлийн Богино Код програмын санааг ашигласан энгийн зүйл байна“ гэж үзээд хэрэгсэхгүй орхисон байна. Мөн түүний оюутнууд бүх програмыг машины хэл рүү гараараа хөрвүүлдэг байсан тухайгаа сүүлд дурдсан байдаг. Нэгэн оюутан ассемблерын хөрвүүлэгч бичиж энэ ажиллагааг автоматжуулах гэж оролдож байгааг фон Нейман мэдээд “шинжлэх ухааны үнэтэй цайтай төхөөрөмжийг бичиг цаасны ажилд хэрэглэж үрэн таран хийх нь” хэмээн маш ихээр хилэгнэж байжээ. Жон Бакус фон Нейманы энэ байр суурийг хайхралгүй ажилласаар 1957 онд Фортран хэлний анхны хувилбарыг гаргасан ба сүүлд 1970-аад оноос фон Нейманы архитектурыг ноцтойгоор шүүмжлэгчдийн нэг болсон юм. Фон Нейманы архитектурын нэг гол дутагдал нь төв процессор ба шуурхай санах ойн хоорондох “нэг удаа хэдэн байт” дамжуулах боломжтой “фон Нейманы хүзүү” гэж нэрлэгддэг маш нарийн суваг бөгөөд энэ нарийн “хүзүү” нь зөвхөн тухайн нэг програмын өгөгдлийн чөлөөтэй урсгалыг хязгаарлаад зогсохгүй, өнөөгийн програм зохиогчдын оюун ухаанд нягт шингэж тэднийг “нэг удаа хэдэн байт” хэлбэрээр сэтгэхэд дасгадаг сэтгэхүйн өрөөсгөл хэв маяг юм. Анхны загваруудаас хойш компьютерын бүтцэд их бага олон төрлийн өөрчлөлт хийгдэж үйл ажиллагаа нь төсөөлшгүй ихээр сайжирсан боловч үндсэн бүтцэд нь фон Нейманы архитектур амь бөхтэй оршсоор байгаа болно.
Машины хэл болон ассемблер дээрх дээрх бидний жишээ програмчлалын Си хэл дээр яаж бичигдэж болохыг сонирхъё. Жирийн үед Си хэл процессорын регистрүүд болон санах ойтой шууд ажиладаггүй бөгөөд програмын өгөгдлүүдийг хувьсагчаар төлөөлүүлдэг. Хувьсагч гэдгийг санах ойн (дараалсан хэдэн байтаас тогтох) нэг хайрцагт өгсөн нэр гэж үзэж болно. Жишээ нь, a нэртэй хайрцагт буй тоон дээр b нэртэй хайрцагт буй тоог нэмээд гарсан үр дүнг нь a нэртэй хайрцагт хадгал гэхийг
a = a + b;
гэж бичнэ. Энэ бичлэг дунд сургуулийн алгебрын томъёотой төстэй боловч зарчмын хувьд ялгаатай гэдгийг анхаараарай. Хэрэв дээрх бичлэг ийм томъёо байсан бол b=0 гэж гаргах байсан. Гэвч энд “=” тэмдэгтийн баруун тал дахь (a+b) утгыг зүүн талд буй (a) хайрцагт хадгалах ажиллагаа явагдах ба a хайрцагт өмнө нь байсан утга арчигдаж хэрэгцээгүй болж байна. Үүнд a ба b нь санах ойн яг хаана байгаа хайрцгууд болох нь хөрвүүлэгч ба үйлдлийн системээс хамаарах бөгөөд энэ мэдээллийг Си хэл биднээс “нууж” компьютерийн физик бүтцээс илүү дээгүүр түвшний нэгэн хийсвэр давхарга оруулж ирж буй хэрэг.
Дээд түвшний програмчлалын хэлнүүд нь компьютерийн техник хангамж, үйлдлийн систем зэргээс хамаарахгүйгээр аливаа програмыг хялбархан бичих боломжийг бий болгох зорилготой. Энэ зорилгыг гүйцэлдүүлэхийн тулд програмчлалын хэл болгон өөрийн гэсэн хийсвэр ойлголтууд, эдгээр ойлголтуудыг ашиглан програмыг алдаагүй бичих дүрмүүдийг (ө.х. уг хэлний зөв бичих дүрмийг) оруулж ирдэг. Тэгэхээр ямар нэг програмчлалын хэл дээр програм бичих нь уг програмчлалын хэлийг шууд ойлгож биелүүлэх чадвартай хаа нэгтээ байгаа хийсвэр компьютерт (виртуaль машинд) зориулан програм бичиж байгаатай адил юм. Програм нь энэ виртуаль машины шаардлагад зохицсон байх ёстой бөгөөд програм бичиж буй хүн уг виртуаль машины боломжид тохируулан сэтгэх хэрэгтэй болно. Тэгвэл хөрвүүлэгч нь виртуаль машины хэл дээрх програмыг бодит машины хэл рүү орчуулах үүрэгтэй болж таарна. Хэрэв виртуаль машин нь бодит компьютерээс хэт их ялгаатай бол энэ орчуулах ажиллагаа хүндрэлд орж үр дүнд нь маш удаан програм гарч ирнэ. Нөгөө талаас виртуаль машин нь бодит компьютерт хэт ойр бол програмчлалын хэл маань ассемблертэй улам бүр төстэй болж ирнэ. Энэ хоёр заагийн “алтан дундаж” болох платформоос хамааралгүй бөгөөд програм бичихэд хялбар, мөн хурдан ажилладаг програм боловсруулах боломжтой тийм програмчлалын хэл амжилт олох магадлал их. Ийм програмчлалын хэлнүүдийн нэг бол Си хэл юм. Үүнтэй холбоотойгоор Си хэлийг дунд түвшний хэл гэж ярих нь ч бий. Си хэл нь өнөөдөр манай гариг дээр хамгийн өргөн тархсан програмчлалын хэл бөгөөд Юникс (Unix), Виндоус, Макинтош (MacOS), ба Линукс үйлдлийн системүүд болон тэдгээр дээрх хэрэглээний програмуудын ихэнх хэсэг энэ хэл дээр бичигдсэн аж. 1970-аад оны сүүлчээр програмчлалын шинэ хүчирхэг технологи болох Объект Хандалтат Програмчлал (ОХП, OOP – Object Oriented Programming) боловсруулагдаж бий болсон. ОХП-ын технологи нь том хэмжээний програм бичих, бодит болон хийсвэр системүүдийг загварчлахад маш тохиромжтой. Энэ технологийг ашиглан Си хэлний унаган хүч чадлыг зөвөөр зохион байгуулж ашиглах зорилгоор Си++ (“си плас плас” эсвэл “си нэмэх нэмэх” гэж уншина) хэмээх хэл 1980-аад оны эхээр зохиогдсон. Си++ хэл нь үндсэндээ Си хэлний нэгэн өргөтгөл бөгөөд Си хэлний хурд, олон төрлийн компьютер дээр ажиллах чадварыг нь өвлөн авсан, ОХП-ын технологийг (хийсвэр биш) практик байдлаар хэрэгжүүлэх боломжоор дээд зэргээр хангагдсан орчин үеийн хамгийн боловсронгуй програмчлалын хэл мөн.
Cи++ хэлний товч түүх
Програмчлалын хэлнүүд бие биетэйгээ маш нягт уялдаатай хөгжиж ирсэн учир нэг хэлний хөгжлийг бусдаас нь салангид авч үзэх боломжгүй юм. Хамгийн анхны дээд түвшний хэл болох Фортран нь бусад бүх дээд түвшний хэлнүүдийн хөгжилд их бага ямар нэг хэмжээгээр нөлөөлсөн байдаг. Фортран (FORTRAN – FORmula TRANslating system – томъёог орчуулагч систем) нь 1957 онд IBM компани дээр шинжлэх ухааны тооцоо хийхэд зориулан зохиогдсон. Санах ойн хэдэн байтыг хамтад нь хувьсагчийн нэрээр төлөөлүүлэн харьцдаг ба програмын бүх хувьсагчид юу хадгалж байгаагаа илтгэх төрөлд хуваагддаг. Тухайлбал, програмд INTEGER K REAL P гэж “зарлагдсан” бол K нь бүхэл, P нь бутархай утга авах хувьсагчид болох ба K+1 ба P+1 гэсэн үйлдлүүд хоорондоо үндсээрээ ялгаатай машины коммандуудад хөрвүүлэгдэнэ. Фон Нейманы компьютер ямар ч өгөгдлийг ямар нэг бүхэл тоогоор (ө.х. битүүдын дарааллаар) дүрслэхийг шаардах ба бүхэл болон бутархай тоог санах ойд хадгалах дүрслэлүүд нь хоорондоо ялгаатай учраас тэр. Хэрэв Фортранд төрөл байхгүй байсан бол програм зохиогч маань хувьсагчид дээр үйлдэл хийх агшинд уг хувьсагчид хадгалагдаж буй “бүхэл тоог” бүхэл гэж үзэх үү эсвэл бутархай гэж үзэх үү гэдгийг шийдэж зохих коммандыг бичих хэрэгтэй болно. Мөн жишээ нь, санах ойд бүхэл тоо 4 байт, бутархай тоо 8 байт зай эзэлдэг байж болно. Энэ үед хэрэв програм зохиогч хайхрамжгүйгээр “бүхэл байх ёстой” хувьсагч дээр бутархай тооны үйлдэл гүйцэтгэсэн бол уг бүхэл тоогоор зогсохгүй түүний дараачийн 4 байт мөн хайхрамжгүй үйлдлийн золиос болно. Гэвч аз болоход Фортран төрөлтэй учраас ийм буруу үйлдэл хийх болгонд компилятор алдааг олж илтгэдэг. Хувьсагчийн төрөл хэмээх ойлголтыг оруулж ирснээр програм зохиогчийн эрх чөлөөг хязгаарлаж байгаа биш, харин түүнийг алдаагүй програм бичих, алдаагаа хялбар олох боломжийг олгож байгаа хэрэг юм.
Фортран нь хэдийгээр тоонуудтай ажиллахдаа маш сайн байсан боловч оролт гаралттай ажиллахдаа тийм ч сайн биш, том програмыг уншиж ойлгоход хүндрэлтэй, програмын текстийг бичих хэт явцуу дүрэмтэй зэрэг дутагдлуудтай байсан. Ерөнхийдөө Фортран хэл нь зүгээр л ассемблер дээрх програмуудад маш олон тохиолддог нь ажиглагдсан хэсэг бүлэг коммандуудыг бүлэглэн авч шинэ нэрнүүд өгөх замаар програмыг товчилж бичсэнтэй ялгаагүй зүйл байсан юм. Түүнд өөрийн гэсэн маяг найруулга, дэгжин чамин шинж байхгүй гэж хэлж болно. Фортраны дараахан 1958 онд зохиогдсон Алгол хэл (ALGOL – ALGOrithmic Language – алгоритмчлалын хэл) нь энэ дутагдлуудыг арилгасан бөгөөд өөрийгөө дууддаг дэд програм гэх мэт хэд хэдэн шинэ боломжийг бүрдүүлж өгсөн. Алгол нь алгоритмуудыг маш ойлгомжтойгоор илэрхийлж чаддаг, математикийн үүднээс бол их “дэгжин чамин” хэл юм. Гэвч Алгол-68 хэмээх дараачийн хувилбар нь хэт нүсэр болсон тул Паскаль гэх мэт жижиг хэлнүүдэд зайгаа тавж өгөх хэрэгтэй болсон аж. 1968 онд Никлаус Вирт анх оюутнуудад програмчлал заахад зориулан Паскаль хэлийг зохиосон нь сүүлдээ хамгийн өргөн тархсан хэлнүүдийн нэг болсон юм. Паскаль хэл нь тухайн үед өргөн хэрэглэгддэг байсан Фортран, Алгол болон Кобол хэлнүүдийн сайн чанаруудыг шүүн авч, муу чанаруудыг цэвэрлэсэн нь олонд түгэхэд нөлөөлсөн хэрэг. Паскаль хэл нь “заагч” гэгдэх төрлийг анх түрүүнд хэрэгжүүлсэн нь бөгөөд Си хэлний бүтцэд маш ихээр нөлөөлсөн хэл юм.
Си хэлний өвөг эцэг гэж болохоор хэл бол БСиПЛ (BCPL – Basic Combined Programming Language – програмчлалын нэгтгэсэн хэл) мөн. 1960-аад оны дундуур Массачуссетийн Технологийн Институтэд (МТИ) Кэмбрижээс айлчилж байсан Мартин Ричардс БСиПЛ хэлийг зохиожээ. БСиПЛ хэлний хөрвүүлэгчийн жижиг цөм ассемблер дээр бичигдсэн ба энэ цөмийг л шинэ машинд тохируулан өөрчилчихвөл БСиПЛ хэлний (БСиПЛ хэл дээр бичигдсэн) үлдсэн хэсгийг энэ цөмөө ашиглан шууд хөрвүүлэх боломжтой байсан нь түүнийг олон шинэ машинууд дээр тархахад нөлөөлсөн байна. Энэ хэлийг МТИ, Женерал Электрик, ба Белл лабораторийн (Bell labs, одоогийн AT&T Labs) хамтарсан Мултикс (Multics – олон “икс”) хэмээх үйлдлийн систем зохиох төсөлд хэрэглэж эхэлсэн бөгөөд 1969 он гэхэд уг төсөл нь хэрэгжүүлэхэд хэцүү хэтэрхий их зүйл амласан, зөвхөн хугацаа ихээр оройтож өндөр үнээр дуусах төсөл болох нь тодорхой болсон. Ингээд Белл лабораторийн Кен Томпсоноор удирдуулсан бүлэг судлаачид Мултиксаас хялбар бөгөөд хямд хувилбар хайж эхэлжээ. Энэ оролдлого эцэстээ Юникс (Unix – нэг “икс”) үйлдлийн системийг бий болгосон ба уг үйлдлийн системд зориулж БСиПЛ хэлийг Томпсон өөрчилж түүнийгээ Би (B – BCPL нэрний товч хэлбэр, эсвэл Томпсоны зохиосон өөр нэг хэл болох Bon гэдгийн товчлол) хэл хэмээн нэрийдэв. Би хэл нь төрөлгүй хэл, өөрөөр хэлбэл бүх өгөгдлийг бүхэл тоо гэж үздэг хэл байсан бөгөөд бутархай тоотой ажилладаг шинэ ПДП-11 компьютер Белл лабораторид ирнэ гэсэн сургаар Деннис Риччи 1971 оноос Би хэлийг сайжруулж эхэлжээ. Үүний үр дүнд бүхэл ба тэмдэгт, тэдгээрийн “цуврал” ба “заагч” төрөл бүхий ЭнБи (NB – New B – Шинэ Би) хэл бий болсон аж. Үүнээс илүү олон төрөл хэрэгжүүлэх шаардлага Риччийг Си (C – цагаан толгойн, эсвэл BCPL нэрэн дэх дарааллаар B-ийн дараачийн үсэг) хэлийг боловсруулахад хүргэсэн. 1973 он гэхэд Си хэлний үндсэн бүтэц тодорхой болсон ба 1973 оны зун Белл лабораторийн хэсэг судлаачид Юникс системийн цөмийг бүхэлд нь Си хэл дээр бичиж дуусгасан байна. Ингэснээр Си хэлний компилятор бүхий компьютерүүдэд Юникс системийг ашиглах боломжтой болсон бөгөөд энэ нь өөрийн ээлжинд Си хэлийг тархахад ихээхэн нөлөөлсөн байна. Энэ хэл нь системийн програм бичихэд зориулан зохиогдсон тул компьютерийн техник хангамжтай “шууд тулж ажилладаг”, Алголын бүлийн бусад хэлнүүдийг бодвол маш энгийн бүтэцтэй, баргийн алдааг хөрвүүлэгч “тоодоггүй”, өөрөөр хэлбэл “програм бичигчийн үргэлж зөв” хэмээх зарчмаар ямар ч байсан хөрвүүлэлтийг дуусгах гэж оролддог зэрэг онцлогуудтай. Эдгээр онцлогууд нь програм зохиогчид өргөн боломж, өндөр хариуцлагыг зэрэг олгодог юм. 1978 онд Риччи, Брайн Кернигантай хамтаар “Програмчлалын Си хэл” номыг бичсэн нь Си хэл гэж юу юм бэ гэдэгт хариулсан анхны баримт бичиг байжээ. Си хэлний асар хурдан тархалт ба хөгжилтийн улмаас 1982 он гэхэд уг хэлийг стандартчилах хэрэгтэй нь тодорхой болсон ба 1983 оноос Америкийн Үндэсний Стандартын Хорооноос (ANSI) X3J11 нэртэй хэсэг байгуулагдан ажиллаж 1989 онд Си хэлний Америкийн стандартыг баталсан. Дараахан нь энэ стандартыг Олон Улсын Стандартын Байгууллага ISO/IEC 9899-1990 нэрийн дор хүлээн зөвшөөрсөн байна.
Алгол хэлийг Америкт гарч ирсний дараахан 1967 онд Норвегийн зэвсэгт хүчний компьютерийн төвийн ажилтан Кристен Нигаард ба Оле-Иоган Даал нар Симула хэлний Симула-67 (Simula67) хувилбарыг зохиов. Симула нь Алгол дээр үндэслэгдсэн, системийн симуляци, загварчлал хийхэд зориулагдсан хэл юм. Системийн загварчлал гэдэгт, жишээлбэл, онгоцны буудлын талбай дээрх нисэх онгоцнуудын хөдөлгөөнийг загварчлах байж болно. Симула хэлэнд ямар ч системийг хоорондоо харилцан үйлчлэгч тусгаар хэсгүүдийн цогц хэмээн үзнэ. Эдгээр тусгаар хэсэг бүр нь програмын “объект” болох бөгөөд програм зохиогчийн үндсэн үүрэг нь системд ямар ямар объектууд байх ёстойг шийдэж тэдгээрийн бусадтайгаа харилцан үйлчлэлцэх шинж чанаруудыг тодорхойлж өгөх явдал юм. Нэгэнт объектууд тодорхойлогдсон бол Симулагийн “хугацаа урсаж” эхлэх ба системийн объектууд яаж хоорондоо харилцан үйлчлэлцэж, яаж өөрчлөгдөж байгааг “гаднаас нь” ажиглах боломжтой. Дээрх онгоцны буудлын жишээнд системийн объектууд нь талбай дахь нисэх онгоцнууд, удирдлагын цамхаг, нар, салхи зэрэг байж болно. Тэгвэл програм зохиогч жишээ нь, удирдлагын цамхагийн “4-р зам дээр оч” гэсэн коммандад нисэх онгоц ямар хариу үйлдэл үзүүлэх, салхины чиглэл ба хурд удирдлагын цамхгийн шийдвэрт яаж нөлөөлөх вэ гэдгийг тодорхойлох хэрэгтэй гэсэн үг.
1978 онд Кембриж дэх компьютерийн лабораторид Бьярн Страуструп компьютерийн сүлжээг загварчлах судалгааны ажлыг эхлэв. Страуструпын хэлснээр “хамгийн анхны жинхэнэ объект хандалтат хэл” болох Симула нь түүний зорилгод яг нийцэхээр байсан боловч ганц дутагдал нь хэтэрхий удаан байсан тул тэрбээр шинэ объект хандалтат хэл зохиохоор шийджээ. Си хэл нь түүний хэлснээр “олон чадвартай, товч тодорхой, харьцангуй доод түвшний”, “системийн програмчлалд маш тохиромжтой”, “хаана ч юун дээр ч ажилладаг”, бөгөөд “Юникс програмчлалын орчинд зохицсон” тул Страуструп шинэ хэлнийхээ суурь болгож Си хэлийг сонгосон гэдэг. Ингээд Си ба Симула хэлнүүдийн нэгдэл болох “Ангит Си” нэртэй Си хэлний нэгэн хувилбарыг 1980 онд Страуструп Белл лабораторид ажиллаж байх үедээ гаргажээ. “Ангит Си” явсаар 1983 онд (Рик Масситтийн бодож олсон нэр) Си++ нэртэй болсон ба энэ нэр Си ба Си++ хэлнүүдэд хоёуланд нь “Си-гийн дараачийн” гэсэн утга илэрхийлдэг ажээ. Си++ хэлийг үндсэн гурван зорилгыг хэрэгжүүлдэг гэж үзэж болно. Үүнд, сайжруулсан Си, өгөгдлийн хийсвэр төрөл, ба объект хандалтат програмчлал юм. Си хэл дээр бичигдсэн програмыг Си++ хэлний хөрвүүлэгчээр хөрвүүлж болно. Гэвч Си++ хэл нь Си-г бодвол илүү “хатуу” хэлзүйн дүрмүүдтэй учир Си хөрвүүлэгчээр ямар ч асуудалгүй хөрвөж байсан програм Си++ хөрвүүлэгчээр хөрвөхдөө олон анхааруулга, зарим тохиолдолд алдаа гаргаж болзошгүй. Ингэснээр програм ажиллах үед гарч болзошгүй олон алдаанаас сэргийлэх боломжтой. Өгөгдлийн хийсвэр төрлийг хэрэгжүүлснээр програмд хэрэглэгдэж буй нарийн нийлмэл өгөгдлүүдтэй харьцах нь Си хэлний үндсэн төрлийн өгөгдлүүдтэй харьцахтай өнгөн дээрээ яг адил байхаар програмчлах боломжийг олгодог. Энэ нь анги хэмээх хэрэглэгч шинээр өөрийн төрлийг тодорхойлох, үүнчлэн “+”, “-“, “*”, “/” гэх мэт үйлдлүүдийг энэ шинэ төрөлдөө тохируулан өргөтгөн тодорхойлох механизмуудын тусламжтай хэрэгждэг. Хоорондоо төстэй олон төрлүүдийн гадаад байдал адил тул эдгээр төрлүүд дээр ажиллах боломжтой кодуудыг ганц ерөнхий эх загварыг үндэслэн хөрвүүлэгч нь өөрөө автоматаар генерацлаж (гаргаж авч) болдог. Си++ хэлэнд ийм үйл ажиллагааг хэвүүд (templates) буюу параметрчлэгдсэн төрлүүдийг ашиглан биелүүлнэ. Ингэснээр өргөтгөсөн програмчлал (generic programming) хэмээгдэх объект хандалтат програмчлалын дараагийн шатыг хэрэгжүүлэх боломжтой болсон. Объект хандалтат програмчлалыг Си++ хэлэнд үндсэндээ өгөгдлийн хийсвэр төрлүүд ба тэдгээрийн хоорондох удамшлын харьцааг хэрэглэн гүйцэтгэдэг. Үүнд найзын харьцаа, ангиудын удамшил, виртуаль функцүүд, нэрийн огторгуй, онцгой тохиолдол, хувьсагчийн төрлийг динамикаар тодорхойлох зэрэг олон ойлголтууд хамрагдана.
Женерал Электрик компанийн Нью Йорк дахь судалгааны төвд ажиллаж байсан Александр Степанов ихэнх алгоритмууд өгөгдлийн бүтцийн дотоод зохион байгуулалтаас хамаардаггүй, зөвхөн түүний гадаад орчинтой харьцаж буй гадаргуугийн цөөн хэдэн шинж чанаруудаас хамаардаг болохыг 70-аад оны сүүлчээр ажигласан байна. Тэгэхээр програмд хэрэглэгдэж буй өгөгдлийн бүтцийг өөрчлөх болгонд уг өгөгдөлтэй ажиллах алгоритмуудыг дахин дахин бичих шаардлагагүй. Маш олон туршилт хийсний үр дүнд Степанов ажиллах хурданд нь муугаар нөлөөлөхгүйгээр алгоритмуудыг ингэж хийсвэрлэх боломжтой болохыг олж тогтоов. Ийм алгоритмуудыг өргөтгөсөн алгоритмууд (generic algorithms), эдгээрийг ашиглан програм бичих арга зүйг өргөтгөсөн програмчлал гэх болсон. 1987 он гэхэд Степанов бээр Тектон, Лисп, Ада, болон Си++ хэл дээр өргөтгөсөн алгоритмуудын санг бичиж дуусгасан боловч төдийлэн амжилт олсонгүй. Тухайлбал Си++ хэлний ангиудын удамшил өргөтгөсөн алгоритмуудыг хэрэгжүүлэхэд хэтэрхий явцуу болох нь мэдэгдсэн. Энэ байдал Страуструпыг ангийн болон функцийн хэвүүдийг Си++ хэлэнд оруулахад нөлөөлсөн бөгөөд 1992 оноос Степанов найман хүнтэй бүлгийг толгойлон Хьюлетт Паккард (Hewlett Packard) компанийн лабораторид Си++ хэлний хэвүүдийг ашиглан өргөтгөсөн алгоритмуудын сан бичих төслийг эхэлжээ. Төслийн орон тоо цөөрсөөр сүүлдээ Степанов ба Менг Ли хоёул үлдэж цөхрөлтгүй ажилласаар 1995 он гэхэд Стандарт Хэвүүдийн Санг (СХС, STL – Standard Template Library эсвэл STepanov and Lee) бичиж дуусгасан нь (үл ялиг өөрчлөлттэйгөөр) Си++ хэлний Стандарт Сангийн бүрэлдэхүүнд орсон юм. Си++ хэлний Стандарт Санд энэхүү сангаас гадна Си хэлний стандарт сан болон оролт гаралтын стандарт сан багтдаг.
1989 онд Америкийн Үндэсний Стандартын Хороо NCITS/X3J16 нэртэй хэсгийг Си++ хэлний Америкийн стандартыг гаргах зорилгоор байгуулав. Хоёр жилийн дараа 1991 онд Олон Улсын Стандартын Байгууллагаас JTC1/SC22/WG14 нэртэй хэсэг Си++ хэлний олон улсын стандартыг үүсгэх зорилгоор томилогдсон. Үүнээс хойш хоёр хэсэг нэгдэн ажиллаж, 1998 онд Си++ хэлний олон улсын стандартыг ISO/IEC 14882-1998 нэрийн дор эцэслэн баталжээ. Энэ стандартыг АНУ, Их Британи, Герман болон бусад олон улс гүрнүүд өөрсдийн үндэсний стандарт мэтээр өвлөн авч баталсан байна.