2018. szeptember 16., vasárnap

Miért írunk programot?

Adatok olvasása és írása. Életre kell a program...




VÁLTOZÓK

Amikor programot írunk, akkor szükség lehet tárolókra, ahová az adatainkat ideiglenesen eltároljuk. Ezeket a tárolókat változóknak nevezzük.
A változók a memória egy (vagy több) cellájára hivatkozó leírók. Egy változót a következő módon hozhatunk létre C# nyelven:



Típus változónév;
A változónév első karaktere csak betű vagy alulvonás jel (_) lehet, a többi karakter szám is. Lehetőleg kerüljük az ékezetes karakterek használatát (bár technikailag nem okoz problémát, nem akadályozza a fordítást)!
Konvenció szerint a változónevek kisbetűvel kezdődnek. Amennyiben a változónév több szóból áll, akkor célszerű azokat a szóhatárnál nagybetűvel “elválasztani” (pl. pirosAlma, vanSapkaRajta stb.)
 

DEKLARÁCIÓ ÉS DEFINÍCIÓ

Egy változó (illetve lényegében minden objektum) életciklusában megkülönböztetünk deklarációt és definíciót. A deklarációnak tartalmaznia kell a típust és azonosítót, a definícióban pedig megadjuk az objektum értékét. Értelemszerűen a deklaráció és a definíció egyszerre is megtörténhet.  

int x; // deklaráció 
x = 10; // definíció
int y = 11; // deklaráció és definíció  
  

TÍPUSOK

A C# erősen (statikusan) típusos nyelv, ami azt jelenti, hogy minden egyes változó típusának ismertnek kell lennie fordítási időben, ezzel biztosítva, hogy a program csakis olyan műveletet hajthat végre, amire valóban képes. A típus határozza meg, hogy egy változó milyen értékeket tartalmazhat, illetve mekkora helyet foglal a memóriában.
A következő táblázat a C# beépített típusait tartalmazza, mellettük ott a .NET megfelelőjük, a méretük és egy rövid leírás:
  


C# típus .NET típus Méret (byte) Leírás
byte System.Byte 1 Előjel nélküli 8 bites egész szám (0..255)
char System.Char 2 Egy Unicode karakter
bool System.Boolean 1 Logikai típus, értéke igaz(1 vagy true) vagy hamis(0 vagy false)
sbyte System.SByte 1 Előjeles, 8 bites egész szám (-128..127)
short System.Int16 2 Előjeles, 16 bites egész szám (-32768..32767
ushort System.Uint16 2 Előjel nélküli, 16 bites egész szám (0..65535)
int System.Int32 4 Előjeles, 32 bites egész szám (–2147483648..
2147483647).
uint System.Uint32 4 Előjel nélküli, 32 bites egész szám (0..4294967295)
float System.Single 4 Egyszeres pontosságú lebegőpontos szám
double System.Double 8 Kétszeres pontosságú lebegőpontos szám
decimal System.Decimal 16 Fix pontosságú 28+1 jegyű szám
long System.Int64 8 Előjeles, 64 bites egész szám
ulong System.Uint64 8 Előjel nélküli, 64 bites egész szám
string System.String N/A Unicode karakterek szekvenciája
object System.Object N/A Minden más típus őse
A forráskódban teljesen mindegy, hogy a “rendes” vagy a .NET néven hivatkozunk egy típusra.
Alakítsuk át a “Hello World” programot úgy, hogy a kiírandó szöveget egy változóba tesszük:
using System;


namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            string uzi = "Szia Világ";
            Console.WriteLine(uzi);
            Console.ReadKey();
        }
    }
}

A C# 3.0-tól kezdve már lehetséges egy metódus hatókörében deklarált változó típusának meghatározását a fordítóra bízni. Általában olyankor tesszük ezt, amikor hosszú típusnévről van szó, vagy nehéz meghatározni a típust. Ezt az akciót a var kulcsszóval kivitelezhetjük. Ez természetesen nem jelenti azt, hogy úgy használhatjuk a nyelvet, mint egy típustalan környezetet! Abban a pillanatban, amikor értéket rendeltünk a változóhoz (ráadásul ezt azonnal meg is kell tennünk), az úgy fog viselkedni, mint az ekvivalens típus. Az ilyen változók típusa nem változtatható meg, de a megfelelő típuskonverziók végrehajthatóak.


int x = 10; // int típusú változó
var z = 10; // int típusú változó
z = "string"; // fordítási hiba
var w; //fordítási hiba 

LOKÁLIS ÉS GLOBÁLIS VÁLTOZÓK

Egy blokkon belül deklarált változó lokális lesz a blokkjára nézve, vagyis a program többi részéből nem látható (úgy is mondhatjuk, hogy a változó hatóköre a blokkjára terjed ki). A fenti példában a message egy lokális változó, ha egy másik függvényből vagy osztályból próbálnánk meg elérni, akkor a program nem fordulna le. Ebben az esetben az IntelliSense sem ajánlaná fel, ez az eszköz tehát erre is segítségünkre van.
Globális változónak azokat az objektumokat nevezzük, amelyek a program bármely részéből elérhetőek. A C# nem rendelkezik a más nyelvekből ismerős globális változóval, mivel deklarációt csak osztályon belül végezhetünk. Áthidalhatjuk a helyzetet statikus változók használatával, erről később szó lesz.
  


KONSTANSOK  

A const típusmódosító kulcsszó segítségével egy objektumot konstanssá, megváltoztathatatlanná tehetünk. A konstansoknak egyetlenegyszer adhatunk (és ekkor kötelező is adnunk) értéket, mégpedig a deklarációnál.
Bármely későbbi próbálkozás fordítási hibát okoz.

const int x; // Hiba
const int y = 10; // Ez jó

x = 11; // Hiba


A FELSOROLT TÍPUS  

A felsorolt típus olyan adatszerkezet, amely meghatározott értékek névvel ellátott halmazát képviseli. Felsorolt típust az enum kulcsszó segítségével deklarálhatunk:

using System;
namespace TestApp
{
class Program
{
enum Animal { Cat, Dog, Tiger, Wolf };
static void Main(string[] args)
{
Console.ReadKey();
}
}
}

Enum típust csakis metóduson kívül (osztályon belül vagy “önálló” típusként) deklarálhatunk, ellenkező esetben a program nem fordul le. Ezután így használhatjuk:

using System;
namespace TestApp
{
class Program
{
enum Animal { Cat, Dog, Tiger, Wolf };
static void Main(string[] args)
{
Animal b = Animal.Tiger;
if (b == Animal.Tiger) // Ha b egy tigris
{
Console.WriteLine("b egy tigris...");
}
Console.ReadKey();
}
}
}

A DINAMIKUS TÍPUS  

A C# 4.0 bevezeti a dynamic kulcsszót, amely használatával dinamikusan típusossá tehetünk objektumokat. Mit
is jelent ez a gyakorlatban? Lényegében azt, hogy minden
dynamic kulcsszóval jelölt objektum bármit megtehet
fordítási időben, még olyan dolgokat is, amelyek futásidejű hibát okozhatnának. Ezenkívül az összes ilyen
„objektum” futásidőben megváltoztathatja a típusát is:
 

using System;namespace TestApp
{
class Program{static void Main(string[] args)
{
dynamic x = 10;Console.WriteLine(x); // x most 10x = "szalámi";Console.WriteLine(x); // x most szalámiConsole.ReadKey();
}
}
}
 

OPERÁTOROK


Amikor programozunk, utasításokat adunk a számítógépnek. Ezek az utasítások kifejezésekből állnak, a kifejezések pedig operátorokból és operandusokból, illetve ezek kombinációjából jönnek létre:  

i = x + y; 

Ebben az utasításban i–nek értékül adjuk x és y összegét. Két kifejezés is van az utasításban:
1. lépés: x + y –> ezt az értéket jelöljük * -gal2. lépés: i = * –> i értékéül adjuk a * -ot

Az első esetben
x és y operandusok, a ‘+’ jel pedig az összeadás művelet operátora. Ugyanígy a második pontban i és * (vagyis x + y) az operandusok, az értékadás művelet (‘=’) pedig az operátor.
Egy operátornak nemcsak két operandusa lehet. A C# nyelv egy- (unáris) és három-operandusú (ternáris) operátorokkal is rendelkezik.
A következő fejezetekben megismerkedünk néhány operátorral, de nem az összessel. Ennek oka az, hogy bizonyos operátorok önmagukban nem hordoznak jelentést, egy-egy speciális részterület kapcsolódik hozzájuk.
Ezért ezeket az operátorokat majd a megfelelő helyen vizsgáljuk meg (pl. az indexelő operátor most kimarad, elsőként a tömböknél találkozhat majd vele a kedves olvasó)

 

OPERÁTOR-PRECEDENCIA  

Amikor több operátor is szerepel egy kifejezésben, a fordítónak muszáj valamilyen sorrendet (ún. precedenciát) felállítani közöttük, hiszen az eredmény ettől is függhet. Például:

10 * 5 + 1 

 Ennél a kifejezésnél - sorrendtől függően - az eredmény lehet 51 vagy 60. A jó megoldás az előbbi, az operátorok végrehajtásának sorrendjében a szorzás és az osztás előnyt élvez (természetesen érvényesülnek a matematikai szabályok). A legelső sorrendi helyen szerepelnek pl. a zárójeles kifejezések, utolsón pedig az értékadó operátor. Ha bizonytalanok vagyunk a végrehajtás sorrendjében, akkor mindig használjunk zárójeleket, ez a végleges programra nézve semmilyen hatással nincs (és a forráskód olvashatóságát is javítja).
A fenti kifejezés így nézne ki helyesen zárójelezve:
 
(10 * 5) + 1

A C# nyelv precedencia szerint 14 kategóriába sorolja az operátorokat (a kisebb sorszámút értékeli ki hamarabb a fordító):

1. Zárójel, adattag hozzáférés (pont (‘.’) operátor), metódushívás, postfix inkrementáló és dekrementáló operátorok, a new operátor, typeof, sizeof, checked és unchecked
2. Pozitív és negatív operátorok (x = -5), logikai és bináris tagadás, prefix inkrementáló és dekrementáló operátorok, explicit típuskonverzió
3. Szorzás, maradékos és maradék nélküli osztás
4. Összeadás, kivonás
5. Bit-eltoló (>> és <<) operátorok
6. Kisebb (vagy egyenlő), nagyobb (vagy egyenlő), as, is
7. Egyenlő és nem egyenlő operátorok
8. Logikai ÉS
9. Logikai XOR
10. Logikai VAGY
11. Feltételes ÉS
12. Feltételes VAGY
13. Feltételes operátor ( ? : )
14. Értékadó operátor, illetve a “rövid formában” használt operátorok (pl: x +=y)
 

 ÉRTÉKADÓ OPERÁTOR

Az egyik legáltalánosabb művelet, amit elvégezhetünk az, hogy egy változónak értéket adunk. A C# nyelvben ezt az egyenlőségjel segítségével tehetjük meg:

int x = 10;

Létrehoztunk egy int típusú változót, elneveztük x–nek, majd kezdőértékének tízet adtunk. Természetesen nem kötelező a deklarációnál megadni a definíciót (amikor meghatározzuk, hogy a változó milyen értéket kapjon), ezt el lehet halasztani:

int x;
x = 10;

Ennek ellenére ajánlott akkor értéket adni egy változónak, amikor deklaráljuk.
Egy változónak nemcsak konstans értéket, de egy másik változót is értékül adhatunk, de csakis abban az esetben, ha a két változó azonos típusú, illetve ha létezik megfelelő konverzió (a típuskonverziókkal egy későbbi fejezet foglalkozik).

int x = 10;
int y = x; // y értéke most 10

MATEMATIKAI OPERÁTOROK

A következő példában a matematikai operátorok használatát vizsgáljuk meg:

using System;
namespace TestApp
{
class Program
{
static void Main(string[] args)
{
int x = 10;
int y = 3;
int z = x + y; // Összeadás: z = 10 + 3
Console.WriteLine(z); // Kiírja az eredményt: 13
z = x - y; // Kivonás: z = 10 - 3
Console.WriteLine(z); // 7
z = x * y; //Szorzás: z = 10 * 3
Console.WriteLine(z);//30
z = x / y; // Maradék nélküli osztás: z = 10 / 3;
Console.WriteLine(z); // 3
z = x % y; // Maradékos osztás: z = 10 % 3
Console.WriteLine(z); // Az osztás maradékát írja ki: 1
Console.ReadKey(); //Vár egy billentyű leütésére
}
}
}

Adatbeolvasás a billentyűzetről, adatkiírás a képernyőre

Leggyakrabban a Console.ReadLine() függvényt használjuk. A billentyűzetről történő adatbevitelt mindig az Enter leütésével kell lezárni. Ha a beolvasott adatot nem szövegként akarjuk kezelni, gondoskodni kell a megfelelő átkonvertálásról. Ha egy sorban több adat szerepel valamilyen elválasztó karakterrel, akkor a beolvasás után megfelelően szétdaraboljuk az elválasztó karakterek mentén a sort.
Console alkalmazások esetén a programablak becsukódását lehet megakadályozni a Console.ReadKey() függvénnyel, ez valamilyen billentyű leütését érzékeli és addig várakoztat, amíg ez meg nem történik. 
Kiírásra a Console.Write(), illetve a Console.WriteLine() függvényeket használjuk, a zárójelben a kiírandó adatokat kell megadni. Ha a Write() függvényt alkalmazzuk, akkor a rákövetkező kiírás folytatólagosan történik, ha a WriteLine() függvényt, akkor a rákövetkező kiírás mindig új sorba kerül. A kiírás tagolására, valamint speciális jelek megjelenítésére az escape szekvenciákat használjuk.






Nincsenek megjegyzések:

Megjegyzés küldése