Mi az balérték és rvalue, karban, programozás
Ha van egy kis ideje, hogy C-ben programozni, vagy C ++, akkor valószínűleg hallott kifejezések balérték (olvasni, mint „EL-érték”) és rvalue (olvasni, mint „AR-érték”), mert néha megjelennek üzenetek fordító hibát . Van rá esély, hogy néhány megértése, hogy mit jelent ez az egész ugyanaz.
Tekintettel a kétértelműséget a definíciókat balérték és rvalue között helyszíneken, nem vagyok hajlandó nyújtani pontos meghatározásokat. Azonban tudom magyarázni az alapvető keretet a fogalmak közös szabványoknak.
Mint gyakran megesik, homályos fogalmak a nyelvet, akkor tegye fel magának a kérdést - miért kell vigyázni a tudás értelmében balérték és rvalue? Minden tekintetben, ha csak a C, akkor a munka, nem veszik észre, hogy valójában `lvalue 'kifejezések és rvalue. Sok programozó nem csak ezt. De a megértés `lvalue 'kifejezések rvalue és betekintést nyújt a viselkedését beépített szereplők, és a kód, hogy a fordító generál, ha ezeket a nyilatkozatokat. Ha programozni C ++, a megértés a beépített operátorok ad kötelező keretet kiváló minőségű írás újratölthető szereplők (túlterhelt operátorok).
Kernighan és Ritchie vezette be a fogalmat balérték, külön egyiket a másiktól kifejezést. Könyvében: „C programozási nyelv” (Prentice-Hall, 1988), azt írta: „Az objektum manipulált tároló terület; balérték egy kifejezés, amely utal a tárgy neve»balérték«származott értékadás E1 = E2, ahol a bal oldali operandus E1. meg kell egy kifejezés, mint balérték. "
Más szóval, a bal és a jobb oldali operandus egy értékadás külön kifejezéseket. Ahhoz, hogy a feladat az volt, igaz, a bal oldali operandus kell vonatkoznia olyan objektum, amely legyen a balérték. A jobb oldali operandus lehet bármilyen kifejezés, akkor nem feltétlenül kell olyan tulajdonságokkal balérték. Például:
n kijelenti egy objektum, amelynek típusa int. Amikor az n kifejezéseket a feladat, mint:
n jelentése egy expressziós (pontosabban alkifejezésre hozzárendelés expressziós) hivatkozva int objektumot. Expression n jelentése balérték.
Tegyük fel, hogy a swap balra és jobbra szereplők:
Ha nem volt Fortran programozó, akkor nyilvánvaló, hogy ez a legostobább dolog, amit tehetünk. Hozzárendelés módja 3 = n megpróbálja megváltoztatni az értéke egy egész konstans. Szerencsére, a C és C ++ fordító ezt nem teszi lehetővé, és ki fog adni egy hiba. (Megjegyzés fordító :. Mert néha hibáznak írásakor véletlenül helyett == jel = feladat, különösen az üzemeltető == ellenőrzést, bal állandó, a fordító hibát jelzett, ha a feladat egy balérték a bal oldalon, akkor a fordító nem fogja észrevenni a piszkos trükk. és nem hiba bejelentéséhez) Elutasított ilyen művelet -., hogy a bal oldali operandusa 3 a kifejezés nem balérték. Ő a rvalue és nem utal egy objektum egyszerűen képvisel egy bizonyos értéket.
Nem tudom, hol a kifejezés rvalue történt. Egyik szabványos C nem használja, kivéve egy lábjegyzet, amely kimondja, hogy „néha rvalue szabvány írja le, mint a»kifejezés«.
Specifikáció C ++ szabvány kifejezést használja rvalue közvetve meghatározó azt a következő nyilatkozatot: „Minden a kifejezés vagy egy balérték, vagy a rvalue.”. Így, rvalue - bármilyen expressziós, amely nem egy balérték.
Digitális literálok például 3 és 3.14159 vannak rvalue. By rvalue egyaránt karakter literálok, például „a”. Azonosító amely kapcsolódik a tárgy balérték, hanem egy azonosító elnevezési a felsorolt állandók (felsorolás típusú konstans), egy rvalue. Például:
A második hozzárendelés okoz fordítóprogram hibát, mert a kék a rvalue.
Bár nem tudja használni a rvalue mint balérték, akkor balérték mint rvalue. Például az alábbiakat tartalmazza:
Meg lehet rendelni egy értéket n objektum, amely M-mel jelölt:
Ez a kifejezés kifejezést használja balérték-n, mint a rvalue. Szigorúan véve, a fordító végez, amit a szabványos C ++ standard kéri átalakítás balérték rvalue (balérték-to-rvalue konverzió), hogy megkapja a tárolt érték a tárgy, amely jelöli n.
[Lvalue más kifejezések]
Bár lvalue és rvalue kapták nevüket a szerepek (pozíció) egy értékadás, a koncepció a használt fogalmak az összes kifejezést, még azok is, ideértve más integrált üzemeltetők.
Például mindkét operandus beágyazott bináris + kezelő legyen kifejezéseket. Nyilvánvaló, hogy ezek a kifejezések alkalmasnak kell lennie típusok. A transzformációk után a mindkét kifejezés azonosnak kell lennie aritmetikai típusú, vagy egy expressziós kell lennie mutató típusú, és a másik kell egy típusát. De ezek közül bármelyik lehet akár balérték vagy rvalue. Így mind az expressziós x + 2 és 2 + x érvényesek.
Bár az operandusok bináris operátor + lehet balérték, az eredmény mindig is rvalue. Például, mivel az egész tárgyak m és n, valamint a következő kifejezést hibát eredményez:
A + operátor magasabb a precedenciája, mint az üzemeltető =. Így a hozzárendelés kifejezés egyenértékű a következő:
A hiba azért jelentkezik, mert a m + 1 egy rvalue.
bár Unar Ez megköveteli balérték mint egy operandus, az eredmény az ő akarata rvalue. például:
ellentétben Unar * Egyoperandusú kiadja az eredményt balérték. Nem null pointer p mindig rámutat a tárgy, így * p balérték. például:
Bár az eredmény Unar * balérték, az operandus lehet rvalue, mint itt:
[Storage adatai rvalue]
Szerint rvalue alapgondolat egyszerűen egy értéket, akkor nem utal egy objektumot. A gyakorlatban a rvalue utalhat egy tárgyat. Csak nem feltétlenül, amit rvalue utal egy tárgyat. Ezért a C és C ++ ragaszkodnak ahhoz, hogy programozott mintha rvalue nem utalnak tárgyakat.
Az a feltételezés, hogy a rvalue nem utal egy tárgy, így a C fordító és C ++ jelentős szabadságot kódgenerálás rvalue kifejezéseket. Tegyük fel, hogy van egy feladat, mint ez:
Itt, n jelentése egész szám (int). A fordító generálhat a megnevezett adattárat inicializált értéke 1, mintha 1 volt balérték. Ez létrehoz egy kódot másolja a tároló inicializált tároló kiosztott n. Assembly nyelv ez a következőképpen nézhet ki:
Ebben az esetben a rvalue 1 soha nem jelenik meg, mint egy tárgyat az adatmennyiség. Inkább úgy tűnik, az utasításokat a kódot tér.
Egyes processzorok, a leggyorsabb módja annak, hogy az 1 értéket a tárgy -, hogy kitisztuljon, majd az növelés, mint például:
A tisztítást tárgy meghatározza annak tartalmát 0. inkrementálással ad 1. Mégis az adatokat reprezentáló értékek 0 és 1 jelenik meg sehol a kódot.
Bár igaz, hogy rvalue C nyelv nem utal tárgyakat C ++ nem ez a nyelv. A C ++ rvalue, az osztály, lásd a tárgyak, de még mindig nem lvalue. Így minden, amit mondtam, hogy rvalue igaz, hiszen nem foglalkozik rvalue az osztály típusát.
Bár balérték objektumok ábrázolása, nem minden balérték tűnhet, mint a bal oldali értékadó operátor. Köztudott, hogy a kifejezés egy sorozata szereplők és operandusok, amelyek meghatározzák az egyes számításokat. Számítások eredményezhet egy értéket, vagy termelnek mellékhatások (mellékhatások). Hozzárendelés expressziós a formája
ahol E1 és E2 maguk kifejezések. E2 jobb oldali operandus tetszőleges kifejezés, de meg kell hagyni operandusát balérték, akkor hivatkozni kell a tárgy (mint korábban említettük).
Const kulcsszó teszi az alapkoncepciója szemantika balérték elégtelen kifejezéseket. Meg kell, hogy képes legyen megkülönböztetni a különböző típusú balérték.
Const selejtező jelenik meg a nyilatkozatot, és módosítja a típusát a nyilatkozatban, vagy egy részét, például:
Itt nyilvánítják egy objektum típusú „const int” (egész konstans). N a kifejezés egy tárgy, mint ha nincsenek konstansok, azzal az eltéréssel, hogy n jelentése egy objektumot, amely nem tudja megváltoztatni a programot. Például, a hozzárendelési típus a fordítási hibát generál:
Mint kifejezés, amely utal a const tárgy, mint például az N, az valami más, rvalue? A végén, ha átírjuk a kifejezés szó egész helyett n. akkor megkapjuk ugyanazt a hibát:
akkor a következő hozzárendelés fog dobni egy hiba:
Mivel a leadott erők a fordító nem panaszkodnak az átalakítás, akkor ilyesmit nem kívánatos, mert ez egy nehéz hibát találnak.
Így egy kifejezés, amely utal egy objektum const, valóban balérték nem rvalue. Azonban ez egy különleges fajta egy balérték, az úgynevezett nem módosítható balérték (nem módosítható balérték), amely nem lehet módosítani a hivatkozott objektum által balérték. Ez ellentétben van a módosítható balérték (ami bejelentett nélkül const), amelyeket fel lehet használni, hogy módosítsa a tárgy által hivatkozott balérték.
Mivel most már befolyásolni tényező, amely a kulcsszó const, akkor már nem lesz pontos, hogy hívja a bal oldalon az értékadó operátor egy balérték. Inkább azt kell tenni, hogy változtassa meg a nevét balérték (módosítható balérték). Tény, hogy minden aritmetikai értékadó operátor, mint például a + = és * = igényel módosítható balérték, mint a baloldali operandus. Minden skalár típus:
azzal az eltéréssel, hogy X csak egyszer értékelődik. Mivel ez a számtani x hozzárendelés legyen módosítható balérték, szintén egyszerű feladat. Nem minden szolgáltató, amely előírja, hogy balérték operandus van szükség, mert a módosítható balérték. egyoperandusú operátor Ez fogadja operandus a módosítható balérték, és nem módosítható balérték. Például, ha az Ön által megadott:
az m egy érvényes kifejezés, ami visszaadja a fajta „pointer int”, és n is érvényes kifejezés, amely visszaadja az eredményt „a const int pointer”.
[Mi tényleg nem módosítható]
Korábban azt mondta, hogy a nem módosítható balérték egy balérték, akkor nem tudja használni, hogy témát váltson. Figyeljük meg, hogy én nem mondom, hogy nem módosítható balérték kifejezés olyan tárgyat, amit nem lehet megváltoztatni - azt mondta, hogy nem tudja használni a balérték, hogy témát váltson. (Fordító megjegyzése: Imádom ezeket a rejtvényeket izvraschenskih C nyelven!) A különbség minimális, de mégis fontos, mert akkor azt a következő példa. Tegyük fel:
Itt van, hogy p pontot n, úgy, hogy a * p és n egyszerűen két különböző kifejezések utalnak ugyanarra az objektumra. Azonban, * p és n jelentése a különböző típusú. Amint azt a cikk „Mi const jelent valójában” (Mit jelent valójában const) [1], használ megbízás minősítési átalakítás, átalakítani a típusú érték „mutató egy int” a értéke a típus „mutató const int”. Az expressziós n „nincs const int”. Ez van módosítva balérték, így lehet módosítani a tárgyat, amelyre vonatkozik:
Másrészt, p típusú „mutató const int”, így * p const int típusú. Expression * p egy nem módosítható egy balérték, és nem tudja használni a * p módosítani n (akkor is, ha tudod használni, hogy módosítsa a kifejezést n):
Az ilyen szemantikája meghatározó állandó const C és C ++.
Minden expresszióját C és C ++ egy balérték, vagy rvalue. Lvalue egy kifejezés, amely képviseli a tárgy (által hivatkozott egy mutatót, vagy sem). Minden balérték van, viszont vagy módosítható vagy nem módosítható. Azáltal rvalue tartalmaz expressziós, amely nem egy balérték. Működési különbségek rvalue és balérték csökkenteni lehet a tézis:
Ismét, mint már említettük, mindez csak a class rvalue nem (nem osztály) típusú. Osztályba a C ++ elrontani ezeket a fogalmakat még.
1. `lvalue 'kifejezések és rvalue site: embedded.com.
2. Nem módosítható `lvalue 'kifejezések site: embedded.com.