CCS-C ile PIC Programlama, Temel C Bilgisi – 2
Değişkenler, Veri Yapıları ve Operatörler
Malumunuz derslerimiz biraz yavaş gidiyor.:) Konuyla ilgili yayınladığım yazılar hep işin teori yönündeydi. Bu yazımızdan sonra Temel C ile ilgili bir kaç konu anlatımı içeren bir adet yazı daha yayınladıktan sonra, işin zevkli kısmına geçeceğiz. PIC, CCS-C ve Proteus üçlüsüyle çok güzel çalışmalar yapacağız inşallah.
Değişkenler
Değişkenler programların olmazsa olmazlarıdır, belirli tipte verileri tutmak amacıyla programcı tarafından tanımlanırlar. Teknik olarak değişkenler, RAM’deki adres bölgeleri için verilen isimlerdir diyebiliriz. Örneğin long x_degeri; şeklinde bir tanımlama yaptığımızda, x_degeri adında 2 byte uzunluğunda bir değişken kullanacağımızı derleyiciye bildirmiş oluyoruz. Derleyici programı derlerken, x_degeri değişkeni için RAM’de 2 Byte (16 Bit) uzunluğunda bir adres bölgesini x_degeri değişkenine atar.
Aşağıdaki kodda x_degeri değişkenine 12345 değeri atanıyor.
1
|
x_degeri = 12345; |
Bu komut işletildiğinde hafızada x_degeri değişkeni için ayrılan alana 12345 değeri yazılmış olur.
CCS-C Derleyicisinde tanımlanabilecek değişken türleri ve alabilecekleri değerlerlere bir göz atalalım. int1 veri tipi 1 bitlik değerleri tutmak için kullanılır. Alacağı değer 1 veye 0 olabilir. int1 anahtar kelimesi yerine boolean da kullanılabilir.
int1 x; = boolean x;
int8 veri tipi 1 byte’lık değerleri tutmak için kullanılır. Alacağı değer işaretli veya işaretsiz oluşuna göre değişir. int8 anahtar kelimesi yerine int kullanılablir.
değişken tanımlamalarından önce işaret tipi belirtilmezse ön tanımlı olarak işaretsiz olarak kabul edilir.
int x; // x değişkeni işaretsiz 1 byte tam sayı, 0 ile 255 arasında bir değer alabilir.
signed int x; //x değişkeni 1 byte işaretli tam sayı, -128 ile +128 arasında bir değer alabilir
int x; = int8 x;
int16 2 byte lık değerleri tutmak için kullanılır. int16 kelimesi yerine long kullanılabilir
long x; = unsigned long x; // x değişkeni 2 byte işaretsiz tam sayı. 0 ile 65535 arasında bir değer alabilir
signed long x; // x değikeni 2 byte işaretli tam sayı, -32768 ile +32767 arasında bir değer alabilir.
int32 4 byte’lık tam sayı değişkenleri tutmak için kullanılır,.
int32 x; = unsigned int32 x; // x değişkeni 4 byte tam sayı, -2147483648 ile + 2147483647 arasında bir değer alabilir.
float32 Virgüllü sayıları tutmak için kullanılır -1.5xe45 ile 3.4xe38 arasında bir değer alabilir, float32 kelimesi yerine float kullanılabilir. Toplu Örnek
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
#include <16f628A.h> int1 durum,role; // durum ve role değişkenleri 1 Bit uzunluğunda boolean anahtar; // anahtar değişkeni 1 Bit uzunluğunda int8 x,y,z; // x,y,z değişkenleri 1 Byte uzunluğunda int k,l; // k,l değişkenleri 1 Byte uzunluğunda int16 sayac1; // sayac1 adlı değişken 2 Byte uzunluğunda long sayac2; // sayac2 adlı değişken 2 Byte uzunluğunda int32 deger; // deger adlı değişken 4 byte uzunluğunda float bolum; // bolum adlı değişken reel sayı türünde veriler tutacak main() { durum = 1; anahtar = 0; x = 15; k = 200; sayac1 = 12368; sayac2 = 57600; deger = 1254365; bolum = 25,6789; } |
char veri tipi: Karakter verileri tutmak için kullanılır, 1 byte uzunluğundadır.
1
2
3
|
char ch; ch = 'a' ; // bu şekilde atama yapılabilir ch = 97; // bu şekilde de atama yapılabilir (97 = a karakterinin ascii değeri) |
CCS-C derleyicisinde 1 byte’lık değişkenleri tanımlarken int ve int8 kelimelerini klulanacağınız gibi byte anahtar kelimesini de kullanabilirsiniz.
1
|
byte x; // x değeri 1 byte uzunluğunda |
Değişkenler tanımlanırken başlangıç değeri atanabilir.
1
2
|
int x=50,y,z=23; // 1 Byte'lık x,y,z değişkenleri tanımlanıyor ve // başlangıç değeri olarak x = 50, z = 23 yapılıyor. |
Aşağıdaki örnekte görüldüğü gibi, tek satırda bir çok değişkene değer ataması yapılabilir
1
2
3
4
5
6
|
int x,y,z; x=0; y=0; z=0; Yerine x=y=z=0; //bu şekilde atama yapılabilir |
Dizi Değişkenler
C’de diziler şu şekilde tanımlanır.
tip isim[boyut];
Örnek
int dizi[10]; // dizi adlı dizimiz 10 elemanlı ve her bir elemanı int cinsinden yani 1 byte;
Dizinin elemanlarına değer atama.
dizi[0] = 5; // dizinin birinci elemanına 5 değerini atadık
dizi[9] = 56; // dizinin 10. elemanına 56 değerini atadık
dizi[10] = 5; // böyle bir atama yapılamaz çünkü dizimiz 10 elemanlı 0….9
başka örnekler
char yazi[30];
long degerler[20];
Dizilere başlangıç değeri verme
char mesaj[] =”Merhaba Okuyucu”;
int kume[5] = { 12,45,23,68,72 };
char dizi[7] = {‘m’,’e’,’r’,’h’,’a’,’b’,’a’}; Dizilerin kullanımında Kod örneklerimize geçtiğimizde daha ayrıntılı bakacağız.
Veri Yapıları
struct veri yapısı
sutruct veri yapısı istediğiniz tarzda değişken tanımlamanıza ve tanımladığınız değişkene kısmen veya tamamem erişmenize izin verir. Aşağıdaki basit struct örneğini inceleyelim
1
2
3
4
5
6
|
struct koordinat { int x_eksen; int y_eksen; int z_eksen; boolean durum; }; |
Yukarıdaki örnekte koordinat isminde 3 adet 1 Byte’lık tamsayı değişken içeren bir veri yapısı tanımlamış olduk. Veri yapımızı oluşturduğumuza göre artık bu yapı türünden değişkenler oluşturup kullanabiliriz.
1
2
3
4
5
|
struct koordinat gps; //gps değişkenimiz koordinat veri yapısı cinsinden; gps = 0; //gps değişkenine ait x_eksen, y_eksen, z_eksen ve durum değerlerini sıfırla gps.x_eksen = 200; //gps değişkenine ait z_eksen değeri = 200 gps.y_eksen = 125; // y_eksen değeri 125 gps.durum = 1; // durum = 1 |
Görüldüğü gibi yapının bir elemanına ulaşmak için yapı adından sonra nokta konulup elean adı yazılıyor. Yapı tanımlanırken farklı türden elemanlar aynı yapı içerisinde bulunabiliyor.
Struct yapısında bir değişken tanımlanırken de ilk değer ataması yapılabilir.
1
|
struct koordinat gps = {200,125,0,1}; //gibi |
Union Yapısı
Bu yapıda birden fazla değişken aynı adres bloğunu paylaşır. Tanımlaması struct gibidir, daha anlaşılır olması için şöyle bir örnek verelim
1
2
3
4
|
union deger { int x; long y; }; |
Gördüğünüz gibi yapı içerisinde farklı uzunlukta iki değişken tnaımladık. CCS-C derleyicisi için int 1 byte long ise 2 byte uzunluğundadır.
Union yapısı için bellekte en uzun eleman kadar yer ayrılacağından. Tanımladığımız deger adlı union yapı bellekte 2 Byte uzunlukta olacaktır. Union elemanlarına struct yapısındaki gibi ulaşılır. Aşağıdaki örneği inceleyin
1
2
3
|
union deger sayi; sayi.y = 0x1125; // y = 0x1125 hex degerini atadık. |
yukarıdaki atama yapıldıktan sonra. sayi.x = 0×11; olur. İşte unionun farkı burada bir elemana yazılan değer diğerinide etkiliyor, nedeni ise ikisininde aynı adresten başlıyor olması
#define
#define direktifi program için sabit değerler tanımlamanızı sağlar.
1
2
3
4
5
6
7
8
|
#define KONTROL_SURESI 1000 main() { long x; x = KONTOL_SURESI // x = 1000 olur } |
Program içerisinde 1000 değerini bir çok yerde kullandığımızı düşünelim. Her yere elle yazmak yerine bir isim vererek tanımlayıp, bu ismi kullanmak hem programın okunabilirliği açısından faydalı olacaktır hemde size hız kazandıracaktır. Diyelimki KONTROL_SURESIi 1000 denediniz ama olmadı ve 1500 denemek istiyorsunuz.
Tek yapmanız gereken #define KONTROL_SURESI 1500 olarak değiştirmek. Tanımlama yapmamış olsaydınız kod içerisindeki tüm 1000 değerlerini değiştirmek zorunda kalacaktınız.
typedef
typedef direktifini kullanarak int,long,char gibi değişken tipi adlarını değiştirebilirsiniz, şöyleki;
1
2
3
|
typedef int birbyte; // "int" kelimesi yerine "birbyte" kelimesini kulanmak istiyoruz birbyte data; // data 1 byte int tipinde değişken olur |
Operatörler
Karşılaştırma operatörleri
Eşitlik
== // Eşit mi? manasına gelir
Kontrol yapılarına bir sonraki derste bakacağız ama operatörlerin anlaşılması için birkaç örnek verelim şimdiden
1
2
3
4
|
if (x==5) // x degeri 5'e eşit mi? { x = 0; //x 5'e eşit x=0 yap } |
Yukarıdaki kod da x değerinin 5 sayısına eşit olup olmadığına bakılıyor. eşit ise { } süslü parantezler arasındaki kod çalışır yani x = 0;
Büyük
>; operatörü büyüklük kontrolü için kullanılır
1
|
if (x > 5) // x'5 ten büyük mü? |
Büyük Eşit
>;= operatörü eşit veya daha büyük kontrolü için kullanılır
1
|
if (x >= 5) // x 5'e eşit veya daha büyük mü? |
Küçük
<; operatörü küçüklük kontrolü için kullanılır
1
|
if (x < 5) // x 5'ten küçük mü? |
Küçük Eşit
<;= operatörü eşit veya daha küçük kontrolü için kuullanılır
1
|
if (x <= 5) // x 5'e eşit veya daha küçük mü? |
Büyük eşit ve Küçük eşit operatörlerinde “=” sağda olmasına dikkat edin.
Aritmetik Operatörler
+ Toplama – Çıkarma * çarpma / bölme % kalanlı bölme
Operatörleridir.
Örnek
1
2
3
4
5
6
7
|
int a,b; long sonuc sonuc = a * b; sonuc = a - b; sonuc = (a*b) + (a-b) sonuc = (a/b) + (b/a) % operatörü bir sayının diğerine bölümünden kalan sonucu verir. aşağıdaki örneği inceleyelim |
1
2
3
4
|
int a; a = 10; // a değişkenine 10 değerini ata a = 10 % 2; // a = 10 sayısının 2 ye bölümünden kalan, a = 0 olur 10 = 5*2 a = 10 % 3; // a = 10 sayısının 3'e bölümünden kalan, a = 1 olur. 10 = (3 *3) + 1 |
Artırma ve Azaltma Operatörleri
++ operatörü değişken değerini bir artırma , — operatörü ise bir azaltma işlemleri için kullanılır.
1
2
3
4
5
|
int a; a = 10; ++a; // a'yı 1 artır. a = 11 olur --a; // a'yı bir azalt; a++; a--; şeklinde de kullanılabilsede ben birinciyi kullanmaya alışın derim. |
Lojik Operatörler
Lojik operatörler istenilen durumların oluşup oluşmadığının tespiti için kullanılırlar.
&;&; AND, Yani her iki durum da doğrumu manasında || OR, Yani iki durumdan herhangi biri doğru mu manasında ! NOR, Belirtilen durumdan farklı ise
1
2
3
4
5
6
7
|
int x,y,z; x = 5; y = 10; z = 15; if ((x > y) && (x > z)) // x değeri y den ve z den büyük mü? if ((x != 0) || (y > z)) // x değeri sıfırdan farklı veya y değeri z değerinden büyük mü. Burada x sıfırdan büyük ama y z'den büyük değil. Koşul sağlanmış olur. if (!(x==0)) // x sıfıra eşit değilse |
Bit Seviyesinde İşlem Operatörleri
>;>; Sağa kaydırma < ;<; sola kaydırma & ; AND (Ve) | OR (Veya) ^ EXOR (Özel Veya) ~ Inverse (Ters Çevirme)
Şimdi bu operatörleri örnekler vererek açıklayalım.
1
2
3
4
5
6
|
int a; a = 12; 12 sayısının bit olarak gösterilişi. 00001100 şeklindedir. Hex olarak ise 0x0C a>>2 ; // a’yı 2 bit sağa kaydır 00000011. anın yeni değeri = 3 olur. 0×03 Hex a = 12; a<<1; // a'yı bir bit sola kaydır. 00011000 = 24, 0x18 hex |
Demekki bir sayıyı bir bit sola kaydırmak 2 ile çarpmak manasına geliyor 🙂
1
2
3
|
a = 12; // 00001100 b = 48; // 00110000 a & b = 00000000 = 00001100 'olur. Bitler alt alta birbirleriyle And' lenir sonucun bir olması için her iki bit'in de 1 olması gerekir |
1
2
3
4
5
6
|
a = 12; // 12 = 00001100 b = 56; // 56 = 00111000 a & b = 00001000 = 8 a | b = 00111100 = 60 a ^ b = 00110100 = 52 // 1^1 = 0, 1^0=1, 0^1 = 1, 0^0 = 0 ~a = 11110011 olur. (1 ler 0, 0'lar 1 yapılır) |
Faydalı Bilgiler
İşlemlerin Kısa yazılması
1
2
3
4
|
a = a + b; yerine a += b; yazılabilir, bu ifade a = a + b manasına gelir a -= b; // a = a -b; a &= b; // a = a & b; |
Şeklinde örnekleri çoğaltabiliriz.
Değişkenlere Değer atama
CCS-C derleyicisinde değişkenlere decimal, binary veya hex şeklinde değer atayabilirsiniz.
Örneğin bir değişkene 12 değerini atamak istiyorsak
1
2
3
4
|
int a; a = 12; // decimal a = 0x0c; // Hex a = 0b00001100; // Binary |