Wednesday, September 17, 2014

C++: Փոփոխական

C++ լեզվով գրված ծրագրերի առանցքային բաղադրիչներից մեկը փոփոխականն է։ Ծրագրի տեսակետից փոփոխականը մի անվանված օբյեկտ է, որին կարելի է ծրագրի կատարման տարբեր պահերին վերագրել տարբեր արժեքներ։ Օրինակ, եթե պետք է ունենալ մի փոփոխական, որի մեջ պահելու ենք շրջանի շառավիղը, ապա կարող ենք գրել.
double radius;
Այս արտահայտություն կոչվում է փոփոխականի հայտարարություն. C++ լեզվի double ծառայողական բառը նշում է, որ raduis փոփոխականը հայտարարված է որպես կրկնակի ճշտության (double precision) իրական թիվ։ Կամ ասում են, որ radiusտիպը double է։ Այդ տիպով է որոշվում ԷՀՄ-ի հիշողության մեջ փոփոխականի զբաղեցրած չափը և նրա հետ թույլատրելի գործողությունները։

Մի որևէ տիպի չափն իմանալու համար կարելի է օգտագործել sizeofգործողությունը։ Այն իր արգումենտում սպասում է տիպի կամ փոփոխականի անուն և վերադարձնում է դրա չափը։ Օրինակ, համոզվելու համար, որ կրկնակի ճշտության իրական թվերի double տիպը զբաղեցնում է հիշողության 8 բայթ (64 բիթ), բուլյան bool տիպը՝ 1 բայթ, ամբողջ թվերի int տիպը՝ 4 բայթ և այլն, կարող ենք օգտագործել հետևյալ ծրագիրը.
#include <iostream>

int main()
{
    using namespace std;
    cout << "  bool " << sizeof(bool) << endl;
    cout << "  char " << sizeof(char) << endl;
    cout << "   int " << sizeof(int) << endl;
    cout << "double " << sizeof(double) << endl;
}
Փոփոխականը հայտարարելիս ցանկալի է նշել նաև նրա սկզբնական արժեքը, հակառակ դեպքում հայտնի չէ, թե կատարման ժամանակ այն ինչպիսին կլինի։ Սկզբնական արժեքը տալու համար այն պետք է պարզապես գրել փոփոխականի անունից հետո՝ վերցրած «{» և «}» փակագծերի մեջ։ Օրինակ, count և length ամբողջաթիվ փոփոխականները հայտարարելու և նրանց 0 սկզբնական արժեքը տալու համար պետք է գրել.
int count{0}, length{0};
Փոփոխականի հայտարարությունը ուժի մեջ է այն լեքսիկական բլոկում, որտեղ ինքը սահմանված է։ Այդ բլոկը որոշվում է կամ {} փակագծերով, կամ ղեկավարող կառուցվածքների մարմնով։ Օրինակ, հետևյալ ծրագրի կատարման արդյունքում կարտածվի թվերի 10, 20, 10 հաջորդականությունը, որից էլ երևում է, որ տեքստի 7-րդ տողում սկսվող և 10-րդ տողում ավարտվող բլոկում սահմանված x փոփոխականը և 5-րդ տողում սահմանված x փոփոխականն ունեն տարբեր տեսանելիության տիրույթներ (scope).
#include <iostream>

int main()
{
    int x{10};
    std::cout << x << ", ";
    {
        int x{20};
        std::cout << x << ", ";
    }
    std::cout << x << std::endl;
}
Փոփոխականի ընթացիկ արժեքը փոխվում է (նրան նոր արժեք է վերագրվում) վերագրման (=) գործողության միջոցով։ Օրինակ, վերը հայտարարված radius փոփոխականին \(2.54\) արժեքը (1 մատնաչափ, դյույմ) վերագրելու համար պետք է գրել.
radius = 2.54;
Վերագրման գործողությունը կարելի է օգտագործել նաև փոփոխականի հայտարարության մեջ, նրան սկզբնական արժեք տալու համար։ Օրինակ, սահմանենք area փոփոխականը և նրան վերագրենք radius շառավղով շրջանի մակերեսը.
auto area = radius * radius * 3.1415;
Եթե փոփոխականի հայտարարման ժամանակ տիպի փոխարեն գրված է auto ծառայողական բառը, ապա կոմպիլյատորը փոփոխականի տիպը որոշում է ըստ նրան վերագրված արժեքի. կատարվում է տիպի արտածում (տիպի դուրսբերում)։ Քանի որ radius փոփոխականի և \(3.1415\) թվի տիպերը double են, և բազմապատկման (*) գործողությունն էլ վերադարձնելու է double տիպի արժեք, ապա կոմպիլյատորը եզրակացնում է, որ area փոփոխականի տիպը նույնպես պետք է լինի double։

Գրենք մի ծրագիր, որն օգտագործողից հարցնում է շրջանի շառավիղը և արտածում է այդ նույն շրջանի մակերեսն ու եզրագծի երկարությունը։ Նորից գործարկենք տեքստային խմբագրիչը և ստեղծենք ex04.cpp ֆայլը՝ հետևյալ պարունակությամբ.
#include <iostream>

int main()
{
    std::cout << "ներմուծեք շրջանի շառավիղը ";
    double radius{0.0};
    std::cin >> radius;

    const double pi = 3.14159265358979323846;

    auto length = 2 * pi * radius;
    auto area = pi * radius * radius;

    std::cout << "երկարությունը = " << length << std::endl
              << "      մակերեսը = " << area << std::endl;
}
7-րդ տողում գրված cin (console input) օբյեկտը կապված է համակարգի ստանդարտ ներմուծման հոսքի հետ։ Իսկ >> գործողությունը իր ձախ արգումետից եկած արժեքը գրում է աջ արգումենտի մեջ։ Տվյալ դեպքում cin >> radius արտահայտությունը ստեղնաշարից կարդում է մի թվային արժեք և այն վերագրում radius փոփոխականին։

9-րդ տողում const ծառայողական բառն ասում է, որ պետք է սահմանել pi անունով և \(3.14159265358979323846\) արժեքով իրական հաստատուն։ Հաստատունի արժեքը, բնականաբար, փոխել չի կարելի։ Եթե ծրագրում փորձ կատարվի, օրինակ, pi օբյեկտին նոր արժեք վերագրել, ապա կոմպիլյատորն այդ առթիվ կարտահայտի իր դժգոհությունը և կտա համապատասխան հաղորդագրություն։

10-րդ և 11-րդ տողերում հաշվվում են length (երկարություն) և area (մակերես) փոփոխականների արժեքները։

13-րդ և 14-րդ տողերում կազմված է << գործողությունների շղթա։ Սա հնարավոր է դառնում այն բանի շնորհիվ, որ << գործողությունը որպես արժեք վերադարձնում է իր ձախ արգումենտը։ endl մանիպուլյատորը արտածման հոսքին է ուղարկում նոր տողի անցման նիշը։
Կոմպիլյատորի օգնությամբ թարգմանենք այս ծրագիրը և աշխատեցնենք.
$ g++ -std=c++11 -o ex04 ex04.cpp
$ ./ex04
ներմուծեք շրջանի շառավիղը 2.54
երկարությունը = 15.9593
     շառավիղը = 20.2683
Երբեմն կարող է անհարմարության զգացողություն առաջացնել այն փաստը, որ STL-ի բոլոր օբյեկտների, դասերի կամ ֆունկցիաների անուններից առաջ պետք է գրել stl:: նախդիրը։ Դրանից կարելի է խուսափել main ֆունկցիայի սկզբում գրելով using namespace std; արտահայտությունը։ Սա կոմպիլյատորից պահանջում է տեսանելի դարձնել std անունների տիրույթի բոլոր անունները։ Եթե հարկավոր է տեսանելի դարձնոլ միայն որոշ ընտրված անուններ, օրինակ, cout, cin և endl անունները, ապա կարող ենք using հրամանով թվարկել դրանք.
using std::cin;
using std::cout;
using std::endl;
Այս հայտարարություններից հետո արդեն կարող ենք ծրագրի տեքստում cout, cin և endl անուններից առաջ չգրել stl:: նախդիրը։

Փոփոխականին հատկացված հիշողության տիրույթի առաջին բայթի համարը կոչվում է փոփոխականի հասցե։ Այն կարելի է ստանալ & ունար գործողության միջոցով։ Օրինակ, radius փոփոխականի հասցեն արտածելու համար պետք է գրել.
std::cout << &radius << std::endl;
Փոփոխականի հասցեն կարելի է վերագրել նաև հասցեի տիպ ունեցող մեկ այլ փոփոխականի։ Օրինակ.
auto p_radius = &radius;
Մի որևէ տիպի փոփոխականի հասցե պահելու համար նախատեսված փոփոխական հայտարարելիս պետք է պարզապես հայտարարության մեջ տիպի անունից հետո գրել * նիշը։ Օրինակ,
double* p_radius2{&radius};
Հասցե պարունակող փոփոխականին անվանում են ցուցիչ։ Օրինակ, p_radius և p_radius_2 փոփոխականները double տիպի օբյեկտների ցուցիչներ են։

Եթե ցուցիչի հայտարարման պահին դեռևս հայտնի չէ, թե այն ինչ օբյեկտի է «ցույց տալու», ապա այն պետք է արժեքավորել nullptr արժեքով։ Այսպիսի ցուցիչներին անվանում են զրոյական։

No comments:

Post a Comment