GAZİ ÜNİVERSİTESİ MÜHENDİSLİK FAKÜLTESİ
ELEKTRİK ELEKTRONİK MÜHENDİSLİĞİ BÖLÜMÜ
EM205
C PROGRAMLAMA DİLİ
2014‐2015 GÜZ YARIYILI
1
İÇİNDEKİLER
İÇİNDEKİLER ...1
Deney #1 – C Programlama Diline Giriş, Değişkenler, Operatörler ...2
Deney #2 – Program Kontrol Deyimleri ...7
Deney #3 – Döngüler ... 11
Deney #5 – Diziler ... 20
Deney #6 – Göstericiler... 23
Deney #7 – Dinamik Bellek ... 26
Deney #8 – Yapılar ... 29
Deney #1 – C Programlama Diline Giriş, Değişkenler, Operatörler
1.1. Amaç:
C programlama diline giriş, basit kavramların tanıtılması. “printf” ve “scanf” fonksiyonlarının kullanımı.
Değişken kavramının anlaşılması, değişken türleri, değişkenlerin kapasiteleri ve bellek üzerinde kapladıkları miktar, değişkenlerin ekrana yazma formatı.
Aritmetik, mantıksal ve bit‐işlem operatörleri, mantıksal operatörlerin sayısal işlemlere katılması.
1.2 İlk C Programı:
Aşağıdaki basit C programlarını C derleyici programında yazınız. Yazdığınız dosyaları .c uzantısıyla kaydettikten sonra sırasıyla “Compile”, “Build” ve “Execute” işlemlerini gerçekleştiriniz. Yazdığınız kodda herhangi bir hata varsa compile işlemi sırasında bunları düzeltmeniz gerekmektedir. Aşağıdaki açıklamaları dikkatlice okuyunuz.
Programın uzantısını “c” olarak kaydedilmezse otomatik olarak “cpp” olarak kaydeder.Compile aşamasında system(“pause”) tanımaz ve diğer satırlarda da hata verebilir.
system(“pause”)
Programın çalışmasını durdurur.
1.3. Değişkenler:
C programında verilerin saklanması ve işlenmesi diğer dillerde olduğu gibi değişkenlerle yapılır. Bir değişken programın çalışması sırasında bir değer saklar. Bu değer programın akışına göre (değişken bir işleme girerse) değişebilir.
Bir değişken yalnız bir türde veriyi içerebilir: char (karakter), int (tamsayı), float (kesirli sayı) gibi. Her değişken türüyle birlikte programın başlangıcında tanımlanmak zorundadır.
(Anahtar kelimeler veya diğer bir deyişle deyimler, çalışmalarınızda değişkenlerin ve fonksiyonlardan daha kolay
// 0.1
#include<stdio.h>
main() {
printf (“Hello World\n”);
system(“pause”);
}
Programda kullanılan “printf”
fonksiyonunu içeren başlık dosyasını tanıtmak için “include”
deyimi kullanıldı.
main () komutu C dilinde ana programı belirtmek için kullanılır.
Ana programın başladığı ve bittiği yerleri gösteren köşeli
parantezlere dikkat ediniz. “printf” fonksiyonu ekrana yazı
yazmak için kullanılır.
// 0.2
#include<stdio.h>
main() {
int a , a_kare;
printf ("bir sayi giriniz: ");
scanf ("%d",&a);
a_kare = a*a ;
printf("sayinin karesi :%d\n", a_kare);
system(“pause”);
}
Değişkenlerin tanımlanması.
scanf fonksiyonu “a”
değişkenine klavyeden değer atamak için kullanıldı.
“printf” fonksiyonu kullanarak değişken değerinin ekrana yazılması.
3
Tip Bit Tanım_aralığı
Char 8 ‐128 ile 127
Unsigned char 8 0 ile 255
Short int 16 ‐32.768 ile 32.767
Short Unsigned char 16 0 ile 255
char bir karakteri (a, b, c, 0, 1, $, ? gibi), diğer adıyla alfanumerik değeri saklayan bir değişken türüdür. char türündeki bir değişken esas olarak sakladığı alfanumerik değerin ikili tabandaki ASCII kodunu içermektedir. Bu nedenle bu türdeki değişkene hem sayı, hem de karakter ataması yapılabilir.
Bilgisayar hafızasında tüm değişkenler 0 ve 1’lerle saklanmaktadır. Örneğin 6 tam sayısı hafızada 2’lik düzende karşılığı olan 0000 0110 olarak saklanır. Karakterlerin ise hafızada ne şekilde saklanacağını belirlemek için ASCII (American Standard Code for Information Interchange) tablosu standart kabul edilir. Bu tabloya göre örneğin A harfi hafızada ‘A’ olarak değil 0100 0001 (onluk düzende 65) sayısıyla saklanır.
(ÖDEV: İnternette ASCII tablosunun tamamını bulup inceleyiniz.)
Aşağıdaki örneklerde bir karakter değişkeni hem “karakter” olarak hem de tamsayı olarak ekrana yazdırılmaktadır;
// 1.1
#include<stdio.h>
main() {
char c;
c='A';
printf("%c\n",c);
system(“pause”);
}
// 1.2
#include<stdio.h>
main() {
char c;
c='ABC';
printf("%c\n",c);
system(“pause”);
}
char değişken türü sadece bir tane karakter tutabilir. Yandaki programı inceleyiniz.
// 1.4
#include<stdio.h>
main()
{ char x = 65;
while(x<70) {
printf("Harf: %c ASCII kodu: %d\n" ,x,x);
x = x+1;
}
system(“pause”);
} // 1.3
#include<stdio.h>
main() { char x = 65;
printf("%c harfinin ASCII kodu: %d\n",x,x);
system(“pause”);
}
“while” deyimi döngü kurmak amacıyla kullanılmıştır.
%c formatı değişkeni karakter olarak,
%d formatı ise tamsayı olarak ekrana yazar.
C programlama dilinde tamsayı değişkenleri saklamak için int, kesirli sayıları saklamak içinse float değişken tipleri kullanılabilir. Bir tamsayı float değişkeniyle de tutulabilir ancak bu durumda bellekte daha çok alan kullanılmış olacaktır.
Değişken türlerinin seçiminin yanı sıra ekrana yazdırılırken kullanılan formata da çok dikkat edilmelidir.
Tamsayıları yazdırmak için %d formatı, kesirli sayıları yazdırmak için %f formatı kullanılabilir.
Aşağıdaki örnekleri inceleyiniz. Her iki programda da printf satırlarından hangisinin doğru olduğuna karar veriniz.
sizeof() deyimiyle verinin bellekte kaç bayt yer tuttuğunu bulunabilir.
printf() Fonksiyonu Hakkında:
C dilinde ekrana yazı yazdırmak için kullanılabilecek fonksiyonlardan biri printf()’dir.
Fonksiyona parametre olarak çift tırnak içinde yazılan her şey (% ve \ karakterlerinden sonra gelenler hariç) ekrana aynen yazılır. (Boşluklar, noktalama işaretleri dahil.)
printf() fonksiyonuyla ekrana hiçbir değişken içermeyen mesajlar yazılabilir. Örn: printf(“Bir sayı giriniz”);
Eğer bir değişkenin değeri yazdırılmak isteniyorsa çift tırnak kapatıldıktan sonra virgülle ayrılarak değişken adları yazılır. Bu durumda değişkenin ekrana yazılma formatını ve yerini belirtmek için % karakteri kullanılır. %’den sonra gelen ilk karakter ekrana yazılmaz sadece değişkenin yazım formatını belirtir (tamsayı için %d, karakter için %c gibi.)
Aynı şekilde \ karakterinden sonra gelen karakter de ekrana yazılmaz. Bunun görevi ise yeni satıra atlama (\n), bir
// 1.5
#include<stdio.h>
main() { int a;
float b;
a=5;
b=5;
printf("a =%d\t",a);
printf("a =%f\n",a);
printf("\n");
printf("b =%d\t",b);
printf("b =%f\n",b);
system(“pause”);
}
// 1.7
#include<stdio.h>
main()
{
char a; int k; short int i; float b;
printf(" Degisken turlerinin bellekte kapladigi alanlar;\n ");
printf(" char : %d bayt\n ",sizeof(a));
printf(" short int : %d bayt\n ",sizeof(i));
printf(" int : %d bayt\n ",sizeof(k));
printf(" float : %d bayt\n ",sizeof(b));
system("pause");
}
// 1.6
#include<stdio.h>
main() { int a;
float b;
a=5.5;
b=5.5;
printf("a= %d\t",a);
printf("a= %f\n",a);
printf("\n");
printf("b= %d\t",b);
printf("b= %f\n",b);
system(“pause”);
}
5
ÖDEV: Yukarıdaki programlardaki printf() satırlarını inceleyerek çalışmasını anlamaya çalışınız. İnternetten % ve \ özel karakterlerini listesini bulup kullanımlarını öğreniniz.
scanf() Fonksiyonu Hakkında:
C dilinde klavyeden değişkenlere değer girmek için scanf() fonksiyonu kullanılabilir. Kullanımı printf() fonksiyonuna benzemektedir. Sadece değişken adlarının önüne & (address of) operatörü getirilir. Ayrıca çift tırnak içinde sadece % formatlarının bulunması diğer karakterlerin kullanılmasından kaçınılması gerekmektedir.
Aşağıdaki basit programı inceleyiniz.
Operatörler:
C dilinde değişkenler arasında yapılabilecek aritmetik veya mantıksal işlemleri tanımlamak için operatörler kullanılır. Örneğin “+” iki değişkenin sayısal değerlerini toplamak için kullanılan operatör, “&&” iki değişkeni mantıksal VE işlemine sokmak için kullanılan operatördür. Yapılabilecek işlemler operatörlerle sınırlıdır, örneğin Fortran dilindeki “üs alma” operatörü C’de bulunmamaktadır.
ÖDEV: C dilindeki tüm operatörlerin listesini bulup kullanımlarını inceleyiniz.
Aşağıdaki programların çıktılarını önce kendiniz bulunuz, sonra bilgisayarda çalıştırıp karşılaştırınız.
//1.9
#include<stdio.h>
main () {
int i,k,n;
i=0,k=4,n=7;
i=n+k; printf("i= %d\n",i);
k=k*i; printf("k= %d\n",k);
i=k/n; printf("i= %d\n",i);
n--; printf("n= %d\n",n);
system(“pause”);
}
// 1.8.a
#include<stdio.h>
main () {
int i;
printf(" Bir sayi giriniz : ");
scanf("%d",&i);
printf(" Girilen sayi : %d\n",i);
system(“pause”);
}
“stdio.h” printf ve scanf
fonksiyonlarının tanımlamalarını içeren header (başlık) dosyasıdır.
Bu nedenle printf veya scanf kullanılan tüm programlara eklenmelidir.
(#include deyimi bu amaçla kullanılır)
//1.10
#include<stdio.h>
main () {
int i,k,n;
i=0,k=4,n=7;
i=n%k; printf("i= %d\n",i);
k*=i; printf("k= %d\n",k);
n+=3; printf("n= %d\n",n);
k++; printf("k= %d\n",k);
i=k/n; printf("i= %d\n",i);
n+=(k*i*i+12);printf("n=%d\n",n);
system(“pause”);
}
C dilinde mantıksal operatörler, işlemin sonucunda doğru veya yanlış sonucunu vermezler, yalnız 0 veya 1 tamsayı değerini verirler (doğru ise 1, yanlış ise 0). Bu bakımdan, aritmetik işlemlere doğrudan katılabilirler:
Mantıksal bir işlem, aritmetik bir ifade içerisinde yer alabilir. Aritmetik, mantıksal ve bit işlemleri harmanlanarak ve son derce karışık, birbiri içerisine girmiş bir şekilde kullanılabilir.
Aşağıdaki programların çıktılarını önce kendiniz bulunuz, sonra bilgisayarda çalıştırıp karşılaştırınız.
// 1.11
#include<stdio.h>
main () {
int a=1,b=2,c=-2;
a=(b>-1); // b>-1 ise a=1, değilse a=0 olacaktır.
printf("b>-1 : %d\n",a);
a=(c==-2); // c=-2 ise a=1 , değilse a=0.
printf("c==-2 : %d\n",a);
a=b||c; // b veya c, sıfırdan farklı ise a=1, değilse a=0 printf("b||c : %d\n",a);
a=(b>0)&&(c<-10); // b>0 ve c<-10 ise a=1, değilse a=0 (Bu program için 0) printf("(b>0)&&(c<-10): %d\n",a);
system(“pause”);
}
// 1.12
#include<stdio.h>
main () {
int x=3,y=2;
printf("x= %d, y=%d\n\n",x,y);
printf("(x||y)+4*y = %d\n",(x||y)+4*y);
printf("(x-3)&&y = %d\n",(x-3)&&y);
printf("(x&&y)+(x&&(y-2)) = %d\n",(x&&y)+(x&&(y-2)));
system(“pause”);
}
// 1.13
#include<stdio.h>
main () {
int a,b,c,d;
a=1,b=2,c=0;
d=a&&b&&c;
printf("d= %d\n",d);
d=(a&&b)||c;
printf("d= %d\n",d);
system(“pause”);
}
// 1.14
#include<stdio.h>
main () {
int i,j,k,n,m;
i=k=0,j=2,n=1;
m=((i+j)&&(k+n-1))+2;
printf("m=%d\n ",m);
m=m&&n;
printf("m=%d\n ",m);
j=j||k;
printf("j=%d\n ",j);
k=((j+m+2)&&m)+(n||i)&&2;
printf("k=%d\n ",k);
n=((j+m+2)+m&&(n||i))&&(1-m);
printf("n=%d\n ",n);
system(“pause”);
}
7
Deney #2 – Program Kontrol Deyimleri
2.1. Amaç: Program kontrolü kavramı, kontrolün sayısal işlemler üzerinden yapıldığının anlaşılması, if, if‐else, if‐else if‐else yapıları, switch ifadesi.
2.2. Giriş:
Program kontrol deyimleri programın akışının kontrol edilmesini ve hangi kodun çalıştırılacağına karar verilmesini sağlayan ifadelerdir. Bu laboratuvar kapsamında incelenilecek kontrol deyimleri; if, if‐else, if‐elseif‐else ve switch yapılarıdır.
2.3. IF Yapıları
IF yapıları içerisinde kullanılan ifadeler mantıksal olarak değerlendirilir ve sonucun DOĞRU ya da YANLIŞ olmasına göre hangi kodun işlenileceğine karar verilir. Bu nedenle bazı mantıksal ifadelerin incelenmesi faydalı olacaktır.
‐ Mantıksal veya ilişkisel işlemlerin sonucu daima 0 veya 1 (Yanlış veya Doğru) çıkmaktadır.
‐ Bunun dışında SIFIRDAN FARKLI tüm değerler Doğru (1), SIFIR ise Yanlış (0) olarak değerlendirilir.
Aşağıda bazı ifadelerin mantıksal değerleri verilmiştir;
İfade Mantıksal Karşılığı
3 > 1 1
!(2 < 2) 1
1 || 0 1
!1 0
(3==3) && (5<2) 0
1 || 1 && 0 1 (Operatör önceliğine dikkat ediniz)
‐4 1 (Sıfırdan farklı değer)
3 & 12 0
!(16%4) 1
'E' > 80 0 (E harfinin ASCII kodunu düşününüz)
2.3.a. IF 2.3.b. IF‐ELSE 2.3.c IF‐ELSE IF‐ELSE
if( “ifade” ) {
“kod”
}
“ifade” doğruysa
“kod” işlenir, yanlışsa bir şey yapılmaz.
if( “ifade” ) {
“kod_1”
} else {
“kod_2”
}
“ifade” doğruysa “kod_1”, yanlışsa “kod_2” işlenir.
if( “ifade_1” ) {
“kod_1”
}
else if ( “ifade_2” ) {
“kod_2”
} ...
else {
“kod_3”
}
“ifade_1” doğruysa “kod_1” işlenir.
Yanlışsa “ifade_2” incelenir;
“ifade_2” doğruysa “kod_2”, yanlışsa “kod_3” işlenir.
2.4. Örnekler (IF yapıları)
// 2.1
#include<stdio.h>
main () { int x;
printf("negatif bir sayi giriniz :");
scanf (“%d”,&x);
if (x < 0) x = -x;
printf("sayi pozitif yapildi :%d\n",x);
system(“pause”);
}
Girilen sayının Mutlak değerini alan program;
Sıfır kontrolü yapan program;
// 2.2
#include<stdio.h>
main () { int x;
printf("bir sayi giriniz :");
scanf (“%d”,&x);
if (x == 0)
printf(“Girilen sayi SIFIR\n”);
else
printf(“Girilen sayi SIFIRdan farkli\n”);
system(“pause”);
}
Pozitif/Negatif/Sıfır kontrolü yapan program;
// 2.3
#include<stdio.h>
main () { int x;
printf("bir sayi giriniz :");
scanf (“%d”,&x);
if (x > 0)
printf(“Sayi POZITIF\n”);
else if ( x < 0 )
printf(“Sayi NEGATIF\n”);
else
printf(“Sayi SIFIR\n”);
system(“pause”);
}
ÖNEMLİ HATIRLATMA:
2.1, 2.2 ve 2.3 programlarında görüldüğü gibi if, elseif veya else blokları tek satırdan oluşuyorsa küme parantezleri { } kullanmaya gerek yoktur.
Birden fazla satırdan oluşan tüm blokların { } parantezleri içerisine yazılması gerekir.
Program 2.4’ü inceleyiniz.
// 2.4
// Girilen küçük harfleri büyüğe dönüştüren program
#include<stdio.h>
main () {
char ch;
printf("bir karakter giriniz : ");
scanf("%c",&ch);
if ( !(ch>=65)&&(ch<=90) && !(ch>=97)&&(ch<=122)) printf ("Girilen %c bir harf degil\n",ch);
else if ( (ch>=97)&&(ch<=122) ) {
ch=ch-32;
printf("%c buyuk harfe donusturuldu.\n",ch);
} else
printf("%c\n",ch);
system("pause");
}
9
Aşağıdaki f(x) fonksiyonun alacağı değerleri hesaplamak için 2.5.1 ve 2.5.2 verilmiştir. İki programın çalışmasını inceleyiniz, aralarındaki farkları değerlendiriniz.
10 10 0
0 4
4
;
; 4
; 1
; )
(
3 2 2
x x
x x
x x x x
x x
f
2.5. switch Deyimi
switch de if yapıları gibi program kontrolü sağlamak amacıyla kullanılır. Ancak if’lerden farklı olarak switch satırında yazılan ifade mantıksal olarak (yani sadece Doğru veya Yanlış olarak) değerlendirilmez. Buradaki ifadenin değerine göre program ilgili duruma (case’e) atlar ve buradan devam eder. Örnekleri inceleyiniz.
Program ilgili case’e atlar ve o satırdan devam eder. Eğer diğer durumların işlenmesi istenmiyorsa “break” deyimi kullanılır.
// 2.5.1 (if yapısı)
#include<stdio.h>
int main() {
int x,f;
printf("bir sayi giriniz : ");
scanf("%d",&x);
if(x<-4) {
f = x;
}
if((x>=-4)&&(x<=0)) {
f = x*x-1;
}
if((x >0)&&(x<=10)) {
f = -x*x+4*x;
}
if( x>10) {
f = x*x*x;
}
printf("f(x) = %d\n",f);
system(“pause”);
}
// 2.5.2 (if-else yapısı)
#include<stdio.h>
int main() {
int x,f;
printf("bir sayi giriniz : ");
scanf("%d",&x);
if (x < -4) {
f = x;
}
else if ( (x>= -4) && (x <=0) ) {
f = x*x - 1;
}
else if ( (x > 0) && (x <= 10) ) {
f = -x*x + 4*x;
} else {
f=x*x*x;
}
printf("f(x) = %d\n",f);
system(“pause”);
}
//2.6
#include<stdio.h>
main () {
int k;
printf("0<k<4 arasinda bir sayi giriniz:");
scanf("%d",&k);
switch(k) { case 1: printf("*\n");
case 2: printf("**\n");
case 3: printf("***\n");
}
system(“pause”);
}
// 2.7
#include<stdio.h>
main ()
{ int k;
printf("0<k<4 arasinda bir sayi giriniz:");
scanf("%d",&k);
switch(k) {
case 1: printf("*\n"); break;
case 2: printf("**\n"); break;
case 3: printf("***\n"); break;
}
system(“pause”);
}
Aşağıda switch deyimi kullanılarak dört işlem yapan bir hesap makinesi programlanmıştır;
2.6. Sorular
1. Girilen sayının tek mi çift mi olduğuna karar veren bir program yazınız.
2. if deyimini kullanarak, girilen bir sayının aşağıdaki fonksiyona göre çıktısını veren bir program yazınız.
0
; 1 2
0
; 2
0
; 12 . 2 )
(
2 3
2
x x
x
x x x
x
f
3. “math.h” başlık dosyasındaki “sqrt()” fonksiyonu kullanarak klavyeden girilen sayının karekökünü ekrana yazan bir program yazınız.
NOT: sqrt() fonksiyonu negatif sayıların karekökünü hesaplayamamaktadır. İf deyimleri kullanarak negatif sayıların kareköklerini kompleks sayı gibi yazdırınız. Örn. Sayı: ‐9, Karekökü: j 3
4. switch deyimini kullanarak, 1‐5 arasında girilen her tamsayı için ekrana, sayının karesini yazan bir program yazınız.
// 2.8
#include<stdio.h>
main () {
char operator;
float operand1,operand2;
printf("Sirasiyla sayi,operator(+,-,*,/)ve sayigiriniz(Orn:4+6):");
scanf("%f %c %f",&operand1,&operator, &operand2);
switch(operator) {
case '+':
printf("%f\n",operand1+operand2);
break;
case '-':
printf("%f\n",operand1-operand2);
break;
case '*':
printf("%f\n",operand1*operand2);
break;
case '/':
printf("%f\n",operand1/operand2);
break;
default:
printf("Tanimsiz operator\n");
break;
}
system("pause");
}
switch satırındaki ifadenin durumlardan (case’lerden) hiç birine uymaması halinde
“default” satırına atlanır.
11
Deney #3 – Döngüler
3.1. Amaç: Döngü kavramı, for, while ve do‐while kalıpları.
3.2. Giriş: Döngüler, bir kod parçasının belirli bir sayıda tekrar etmesini sağlayan yapılardır. C dilinde kullanılan başlıca döngü yapıları for, while ve do‐while ‘dir
3.3 FOR Döngüleri
İşlem sırası;
1. Döngü değişkenine ilk değer verme, 2. Kontrol
3. Eğer Kontrol sonucu doğruysa “kod” işlenir (Değilse döngü sonlanır) 4. Değişkenin değeri güncellenir ve 2. adıma dönülür.
// ve /*…*/
ile yazılan yorum satırlarını inceleyiniz.
“döngü değişkenini tanımlama”;
for ( “değişkene ilk değer verme” ; “kontrol” ; “değişkeni güncelleme” ) {
“kod”;
}
// 3.1.a
#include<stdio.h>
main () {
int sayac;
for (sayac=0 ; sayac<10; sayac=sayac+2) { //Küme parantezine Dikkat!
printf("sayac= %d ",sayac);
printf("\n");
}
system("pause");
}
// 3.1.b
#include<stdio.h>
main () {
int sayac;
for (sayac=0 ; sayac<10; sayac=sayac+2)
printf("sayac= %d ",sayac);
printf("\n");
system("pause");
}
// 3.2
#include<stdio.h>
main () {
int i=0;
for (i=4 ; i<3 ; i++)
printf("i=%d\n",i); // Program bu satira gelmez.
for (i=2 ; i<8 ; i++)/* i'yi sıfıra eşitle i<8 ifadesi doğru olduğu sürece devam et, her adımda i'yi bir arttır.*/
{
printf("i=%d\t",i*2); // i'nin değeri değişmiyor.
}
printf("\n");
for (i=2 ; i<8 ; i++) {
i=i*2; /* i'nin değeri değişiyor.Hatalı!.Döngünün indis değeri döngü içinde değiştirilmemeli.*/
printf("i=%d\t",i);
}
printf("\n");
system("pause");
}
İç‐içe For Döngüleri:
// 3.3
#include<stdio.h>
main () {
int i,k;
i=0,k=5;
for(;i<3;i++) {
printf("k=%d i=%d\n",k,i);
k=i<3;
}
printf("1.Donguden cikis degerleri : ");
printf("k=%d i=%d\n",k,i);
printf("---\n");
for(i=0;k;i++) //k doğru olduğu sürece (k!=0)döngüyü tekrarlar.
{
printf("k=%d i=%d\n",k,i);
k=i<3;
}
printf("2.Donguden cikis degerleri : ");
printf("k=%d i=%d\n",k,i);
printf("---\n");
system("pause");
}
// 3.4
#include<stdio.h>//İç İçe For Döngüsü main ()
{
int i,j,k;
for(i=1;i<=3;i++) {
for(j=1;j<=2;j++) {
k=i+j;
printf("i=%d j=%d k=%d\n",i,j,k);
}
printf("k=%d\n\n",k);
}
printf("---\n");
for(i=1;i<=3;i++) for(j=1;j<=2;j++) {
k=i+j;
printf("i=%d j=%d k=%d\n",i,j,k);
}
printf("k=%d\n",k);
system("pause");
}
printf("k=%d\n\n",k);
satırlarının her iki döngüde kaçar kez çalıştırıldığını inceleyiniz.
13
3.4. WHILE ve DO‐WHILE Döngüleri
While döngüleri amaç olarak for döngülerine benzemekle beraber yazım kuralları farklıdır. While satırında sadece kontrol şartı verilir. Şart doğru olduğu sürece while bloğu işlenir.
Do‐while döngüsünün çalışması while ile aynıdır. Tek fark, kontrolün blok bir kez çalıştırıldıktan sonra yapılmasıdır. Başka bir deyişle do‐while döngülerindeki kod bloğu en az 1 kere mutlaka çalıştırılacaktır.
3.5 ve 3.7 programlarındaki “k<10” şartını “k>10” olarak değiştirip tekrar çalıştırınız. Sonuçları yorumlayınız.
3.5. Sorular
1. Kullanıcının girdiği 5 sayının ortalamasını döngü kullanarak hesaplayan bir program yazınız.
2. Kullanıcının girdiği 5 sayıdan en büyüğünü ekrana yazdıran bir program yazınız. (Döngü kullanarak, dizi kullanmadan.)
3. Klavyeden girilen bir sayının faktöriyelini hesaplayınız.
// 3.5
#include<stdio.h>// While döngüsü main ()
{
int k=0;
while(k <=8) {
printf("%3d",k); //%kd formatında k // alan genişliğini belirtir.
k++;
} printf("\n");
system("pause");
}
// 3.6
#include<stdio.h>// While döngüsü main ()
{
int k=8;
while(k) //k, sıfırdan farklı oldugu // sürece döngü tekrarlanır.
{
printf("bir sayi giriniz(ciks=0) :
");
scanf("%d",&k);
printf("k=%d\n",k);
}
system("pause");
}
// 3.7
#include<stdio.h>/*Do-While Döngüsü*/
main () {
int k=0;
do {
printf("%4d",k);
k++;
}
while (k <=8);
printf("\n");
system("pause");
}
Do‐while kalıbında while()’den sonra “;”
kullanıldığına dikkat ediniz.
4. Aşağıdaki matematiksel formüllerin değerlerini hesaplayan programlar yazınız.
a) Cevap: 4.499
b) Cevap: 8.1037
c) Cevap: 76.5872
5. Doğal logaritmanın tabanı olan e sayısının değerini seri yardımıyla hesaplayınız. NOT: Programınızı yazarken N sayısını formüldeki gibi belirsiz bırakamazsınız. N sayısının değeri için yeterince büyük bir sayı seçmeniz gerekmekte. Ancak faktöriyel fonksiyonunun değerinin çok hızlı yükseldiğini unutmayınız.
e=2.71
6. x sayısı biliniyorsa, ex değeri aşağıdaki Mc‐Lauren serisi açılımından bulunabilir:
7. x sayısı biliniyorsa, sin (x) değeri aşağıdaki Mc‐Lauren serisi açılımından bulunabilir:
.... !
! 4
! 3
! 1 2
4 3
2
N x x
x x x
e
N
x
...
.... !
! 7
! 5
! ) 3
sin(
7 5 3
N x x
x x x
x
N
1 ?
50 1
n n
1 ?
6 1
10 1
k i i k 1 ?20 3
10 0
7 1
m l k m k l
15
Deney #4 – Fonksiyonlar
4.1. Amaç: Fonksiyon kavramı, fonksiyonun yazılma amacı, fonksiyonun çalışma biçimi, fonksiyon prototipleri, fonksiyonun başka bir fonksiyonu çağırması, nesnelerin faaliyet alanları.
4.2. Giriş:
Programlama sırasında sürekli tekrar eden ve belirli bir işlevi olan kodları fonksiyon olarak yazmak ve gerekli yerlerde bu fonksiyonu çağırarak çalışmasını sağlamak hem program yazımını hızlandırır hem de programın daha anlaşılır olmasını sağlar.
İlk haftalarda C dilinde tüm kodların fonksiyon formatında yazıldığı, yani main()’in de aslında bir fonksiyon olduğu konuşulmuştu. Aşağıdaki örnekte klavyeden girilen bir sayının mutlak değerini mutlak() adlı bir fonksiyonda hesaplayan bir program verilmiştir. Örnekteki fonksiyon prototipini, fonksiyonun main() içinden çağırılışını ve fonksiyonun tanımlandığı yeri dikkatle inceleyiniz.
NOT: main() fonksiyonu ile mutlak() fonksiyonu arasındaki benzerlikleri ve farklılıkları inceleyiniz.
4.3. Örnek Programlar
// 4.1
#include<stdio.h>
void universite()
{printf("Gazi Universitesi\n");}
void bolum()
{ printf("Elektrik-Elektronik Muhendisligi\n\n");}
float topla(float a) {
a=a+2;
printf("Fonksiyon a= %4.1f\n",a);
return a;
} main()
{ float a=16.5;
universite();
bolum();
printf("Ana program a= %4.1f\n",a);
printf("Fonk.donus a= %4.1f\n",topla(a));
system("pause"); }
# include <stdio.h>
int mutlak(int);
int main() {
int k, m_k;
scanf("%d",&k);
m_k = mutlak(k);
printf("%d\n",m_k);
return 1;
}
int mutlak(int i) {
int t=i;
if (i<0) t = -i;
return t;
}
“mutlak” adlı fonksiyonun prototipi. (fonksiyon tanımı main’den sonra geldiği için prototip gerekli)
“mutlak” fonksiyonu k giriş parametresiyle çağırılıyor.
Fonksiyonun dönüş değeri m_k değişkeninde saklanacak
“mutlak” fonksiyonunun tanımlandığı yer. Tam sayı türünde bir giriş parametresi var. (i değişkeni) Fonksiyonun dönüş değişkeninin türü: integer.
Fonksiyonda hesaplanan t değişkeninin değeri ana programa (fonksiyonun çağırıldığı yere) gönderiliyor.
Yandaki örnekte giriş argümanı ve dönüş değeri olmayan 2 fonksiyon ve giriş argümanı ve dönüş değeri olan 1 fonksiyon verilmiştir.Dönüş değeri
olmaması durumunda fonksiyon adının önünde “void”
kullanıldığına dikkat ediniz.
Geri dönüş değeri olan fonksiyonlar, daha çok amaçlanan bir hesaplamanın sonucunu bildirmek için kullanılırlar. Aşağıdaki örnekte
float daire_alani(float);
fonksiyonu, yarıçapı verilen dairenin alanının bulunması için yazılmıştır. Fonksiyon ana programdan sonra yazıldığından, ana programdan önce prototip tanımlaması yapıldığına dikkat ediniz.
Bir değişken fonksiyona argüman olarak aktarılırsa, fonksiyondan geri döndükten sonra aktarılan argüman değişmemiş olarak kalır. (Değer değiştirmek istenirse gösterici (pointer) kullanmak gerekir.)
// 4.2
#include<stdio.h>
float daire_alani(float); //Fonk.ana programdan sonra yazıldığından PROTOTİP tanımlandı.
main() {
float alan;
alan = daire_alani(1.0);
printf("Yaricap=1, Dairenin alani : %4.2f\n",alan);
alan = daire_alani(2.0);
printf("Yaricap=2, Dairenin alani : %4.2f\n",alan);
printf("Yaricap=5, Dairenin alani : %4.2f\n", daire_alani(5.0));
system("pause");
}
float daire_alani(float yaricap) //Ana programdan sonra fonksiyon tanımı {
return 3.14*yaricap*yaricap;
}
// 4.3
#include<stdio.h>
int fonksiyon(int a) {
a=-a*5;
printf("fonksiyon icinde a=%d\n",a);
return a;
}
main() {
int a=1,b;
printf("fonksiyon cagirilmadan once a= %d\n",a);
b=fonksiyon(a);
printf("fonksiyon cagrildiktan sonra a= %d\n\n",a);
printf("fonksiyonun dondurdugu b=%d\n",b);
system("pause");
}
17
Nesnelerin (Değişkenlerin) Faaliyet Alanları
Bu haftaya kadar yazdığımız programlarda sadece main() fonksiyonu olduğundan değişkenlerin yerel/global olmalarına ve faaliyet alanlarına dikkat etmemiştik. Ancak programımızda birden çok fonksiyon bloğu olduğunda değişkenlerin faaliyet alanları söz konu olmaktadır.
Yerel değişkenlerin tanım satırları herhangi bir bloğun içinde (main, herhangi bir fonksiyon veya if,for vb.
bloklar) olur ve bu değişkenler sadece ilgili blok içinde geçerlidirler. Global değişkenler ise herhangi bir blok içinde tanımlanmazlar ve programın her satırında kullanılabilirler. Başka bir değişle herhangi bir “{“ den sonra tanımlanan değişkenler “}” işaretinden sonra hafızadan silinirler.
Bölge/Değişken s,p a,c,w b,c
1. Anaprogram Erişilebilir Erişilebilir Erişilemez 2. Anaprog. İç Bölge Erişilebilir Erişilebilir Erişilebilir 3. Fonksiyon Erişilebilir Erişilemez Erişilemez
Tablo 4.1 Şekil 4.1
Bu örnekte verilen değişkenlerin ömürleri, program o değişkenin faaliyet alanının bittiği yere ulaşıncaya kadardır.
Faaliyet alanındaki işlemler tanımlandıktan sonra değişkenlerin bellekteki yerleri artık korunmaz. Bir değişkenin program boyunca değerlerinin korunması isteniyorsa, o değişken static tanımı ile ilan edilir.
// 4.4
#include<stdio.h>
float islem(float a, float b) {
a = a + 2;
b = b * 3;
printf(" \t\tFonk. icinde a=%4.1f b=%4.1f\n",a,b);
return a/b;
} main() {
float a=1.0, b=2.0;
printf("a=%4.1f b=%4.1f\n",a,b);
a=islem(a,b);
printf("a=%4.1f b=%4.1f\n",a,b);
b=islem(a,b);
printf("a=%4.2f b=%4.2f\n",a,b);
system("pause");}
Faaliyet alanlarını gösteren bir program taslağı Şekil 4.1’de gösterilmektedir.
Programın başında tanımlanmış olan s ve p değişkenleri global değişkenlerdir. Bu değişkenlere programın herhangi bir kısmından erişilebilir. Bir başka deyişle, fonksiyon ve ana program içinde bu değişkenlere erişilebilir.
Ana programın başlangıcında tanımlanmış olan a,c ve w’ye ise yerel değişkenler olduklarından iç bölge dahil ana programın herhangi bir yerinden erişilebilir, ancak fonksiyon içinden erişilemez.
Fonksiyon içinde tanımlanmış olan k ve m değişkenleri ise fonksiyona ait yerel değişkenlerdir ve sadece fonksiyon içerisinden erişilebilirken, ana programdan erişilemezler.
Fonksiyonların içinde tanımlanan tüm değişkenler ve fonksiyonun giriş argümanları o fonksiyona ait yerel değişkenlerdir. Bu nedenle sadece fonksiyon içerisinde tanımlıdırlar. Ancak, global değişkenlerin faaliyet alanı tüm program satırları olduğu için, bir global değişkenin değeri fonksiyon içerisinde değişebilir.
Aşağıdaki iki programın(4.7.a ve 4.7.b) yapmış olduğu işlem aynı, fakat değişkenlerin tanımlanmış olduğu yerlere göre programların yazımı farklıdır. İnceleyiniz.
// 4.7.a
#include<stdio.h>
//int a; a değişkeni tüm programda tanımlı(global) olur.
fonk(int a) { int b;
b=5;
a*=b;
return a;
}
main()
{int a;//a değişkeni sadece ana prog.içinde tanımlıolur.
printf("Sayi giriniz : ");
scanf("%d",&a);
printf("fonksiyondan once a : %d\n",a);
fonk(a);
printf("fonksiyondan sonra a : %d\n",fonk(a));
system("pause");}
// 4.7.b
#include<stdio.h>
int a; // global değişken tanımı fonk()
{ int b;
b=5;
a*=b;
}
main() {printf("Sayi giriniz : ");
scanf("%d",&a);
printf("fonksiyondan once a : %d\n",a);
fonk();
printf("fonksiyondan sonra a : %d\n",a);
system("pause");}
Aşağıdaki örnekte add fonksiyonu her çağırılışında add'in içinde tanımlanan a'ya add'e aktarılan k kadar ekleniyor. Dolayısıyla program, girilen on adet sayının toplamını ekrana yazmaktadır.
// 4.5
// HATALI SATIRI SİLİNİZ..
#include<stdio.h>
main() {
int i=2, k;
k=i*3;
{ int j;
j=k*i;
printf("j=%d\n",j); // j=12 }
k+=i;
j=k;
printf("i=%d k=%d\n",i,k); //i=2 k=8 system("pause");}
// 4.6
#include<stdio.h>
main() {
int a=0,b=5;
a++;
if(a>0) {
int b;
b=a+7;
printf("b=%d\n",b);
} b=b-2;
printf("b=%d Dikkat!\n",b);
system("pause");
}
19
4.5. Sorular:
1. Faktöriyel hesaplayan bir fonksiyon yazınız. Ana programdan gireceğiniz farklı değerler için fonksiyonu çağırtınız ve sonuçları yine ana programda yazdırınız.
2. Ana programda girilen 3 sayının bir üçgen oluşturup oluşturmayacağını kontrol eden bir fonksiyon yazınız.
(Program ana programa 0 veya 1 değeri dönebilir.)
3. Ana programda girilen bir sayının basamak sayısını bulan bir fonksiyon yazınız.
4. Aşağıdaki formüle göre klavyeden girilen sayının sinüsünü bulan bir program yazınız. Programınızda aşağıda prototipleri verilen 3 fonksiyonu geliştiriniz ve kullanınız.
float dereceden_radyana (int derece); (formül x değerini radyan cinsinde istemektedir) float us_alma(float taban, int us);
int faktoriyel (int sayi);
(Not: N değeri için en fazla 10 alınız.)
5. Aşağıda prototipi verilen fonksiyonu yazınız, ana programdan çağırarak kullanınız.
void birim_matris_yaz(int boyut);
Örn. boyut=3 için ekran çıktısı;
1 0 0
0 1 0 0 0 1
6. Kullanıcının girdiği pozitif sayıların ortalamasını bulan bir program yazınız. Kaç sayı girileceği başlangıçta belli değildir, kullanıcı negatif bir sayı girene kadar okumaya devam edilecektir.
Toplama işlemi ve sayaç işlemleri bir fonksiyon içinde yapılacaktır.
Toplam ve Sayaç GLOBAL değişken olmalıdır.
...
.... !
! 7
! 5
! ) 3
sin(
7 5 3
N x x
x x x
x
N
Deney #5 – Diziler
5.1. Amaç: Dizi kavramı, dizilerin değişkenlerden farkları, çok boyutlu diziler.
5.2. Giriş: Diziler, aynı türden verilerin tek isim altında gruplandırılması olarak düşünülebilir.
Dizi elemanları, bellek üzerinde ardışık olarak yerleşirler. Bu nedenle dizinin ilk değişkeninin bellek üzerindeki yeri biliniyorsa, diğer elemanlarının yerleri de biliniyor demektir. Gerçekte, dizinin ismi dizinin ilk elemanının bulunduğu adresi vermektedir.
Değişkenler bir fonksiyona aktarıldıktan sonra etkilenmezlerken dizi elemanları etkilenirler. Bunun nedeni göstericiler konusundan sonra anlaşılabilecektir.
5. 3. Örnek Programlar
// 5_2
#include<stdio.h>
main() {
int a[12];
int i;
for (i= 0;i < 3;i++) a[i] = 4 * i;
for (i= 0;i< 5;i++)
printf("a[%d]=%2d \n",i,a[i]);
system("pause");
} // 5_1
#include<stdio.h>
#define N 5 int main()
{
int i;
int a[5]={4,6,9,2,5};
int b[N], c[5];
for(i=0; i<5; i++) b[i]=i*i;
for(i=0; i<5; i++) {
printf("c dizisi icin %d. eleman giriniz: ", i);
scanf("%d",&c[i]);
}
for(i=0; i<5; i++)
printf(" a=%2d b=%2d c=%2d\n", a[i], b[i], c[i]);
system("pause");
}
21
5.4. Dizilerin fonksiyona aktarılması: Aşağıdaki programda bulacağınız sonuçları inceleyiniz.
İki Boyutlu Diziler:
//5_4 iki_boyutlu_dizi #include<stdio.h>
#define SATIR 2
#define SUTUN 3 Basla(int a[SATIR][SUTUN])
{ int i,j;
for(i=0;i<SATIR;i++) for(j=0;j<SUTUN;j++) a[i][j]=i+j;
} main()
{
int i,j;
int a[SATIR][SUTUN];
Basla(a);
for(i=0;i<SATIR;i++) for(j=0;j<SUTUN;j++)
printf("a[%d][%d]=%d\n",i,j,a[i][j]);
system("pause");
}
//5_3
#include<stdio.h>
float kare(float b[],int t) {
int i;
t=t*t;
for(i=0;i<5;i++) b[i]=b[i]*b[i];
}
main() {
int i,k=4;
float a[5];
for(i=0;i<5;i++)
{ printf("Bir sayi giriniz: ");
scanf("%f",&a[i]);
}
kare(a,k);
printf("k=%d\n",k);
for(i=0;i<5;i++)
printf("a[%d]=%5.1f\n",i,a[i]);
system("pause");
}
Dizinin her elemanının, fonksiyon içerisindeki değişimi ana programda da görüldü. Değişkenler bir fonksiyona aktarıldıktan sonra etkilenmezlerken dizi elemanları etkilenirler. Bunun nedeni göstericiler konusundan sonra daha iyi anlaşılacaktır.
5.6. SORULAR
1. a)N elemanlı iki vektörü toplayan bir fonksiyon yazınız. Vektörleri tek boyutlu dizi olarak ifade edebilirsiniz.
b) N elemanlı bir vektörün uzunluğunu (mutlak değerini) bulan bir fonksiyon yazınız.
| |= a12 a22a32...
2. Verilen a ve b vektörleri arsındaki açısını bulan bir fonksiyon yazınız.
(math.h’daki acos() fonksiyonunu kullanabilirsiniz.) cos =
|
||
| .
b a
b a
3.
0 3 0
1 4 2
1 0 1
1 2 1
=?
6. Tek boyutlu N elemanlı bir dizinin EN BÜYÜK ve EN KÜÇÜK elamanlarını bulan 2 ayrı fonksiyon ve bu fonksiyonları kullanabileceğiniz bir ana program yazınız.
7. Tek boyutlu N elemanlı bir diziyi küçükten büyüğe doğru sıralayan bir program yazınız. (Sıralama
algoritmaları için internet araştırması yapabilirsiniz.)
a
5. Anxn matrisinin diyagonalinin altında kalan elemanlarından tek boyutlu bir dizi oluşturunuz.
0 35 4
100
13 86 21 54
2 10 3 43
4 1 2 12
4. Anxn matrisinin asal (diyagonal)
elemanların ortalamasını bulunuz
0 3 0 1
1 8 8 0
5 0 3 4
4 1 2 1
23
Deney #6 – Göstericiler
6.1. Amaç: Gösterici kavramı, göstericilerin fonksiyonlarda argüman olarak kullanılması, diziler ile göstericilerin karşılaştırılması.
6.2. Giriş: Göstericiler (pointers) bellekte bulunan bir yerin adresini saklayan bir değişkendir (adres türünde bir değişkendir). Gösterici de int, float veya diğer türdeki değişkenler gibi belleğin belli bir yerine yerleştirilir ve içerik olarak sayısal bir değer içerir. Bu değer bellekteki bir yeri gösteren adrestir.
Göstericiler bu özelliği ile kullanıcının belleğe doğrudan erişim olanağını sağlar. Bu kısımda göstericilerin C dilindeki genel kullanım biçimlerinden bazılarının verilmesi amaçlanmaktadır. Ancak göstericilerin en temel kullanım amacı “Dinamik Bellek Kullanımı” konusunda yer almaktadır.
6.3. Örnek Programlar 1. Temel Gösterici Kullanımı:
Aşağıdaki örneklerde, göstericilerin değişkenle olan ilişkisi incelenmektedir. Bir gösterici, bir değişkenin bellek üzerindeki adresini aldığı zaman, * operatörü ile içeriğinin değiştirilmesini sağlar.
// 6_2
#include<stdio.h>
main() {
int i = 150;
int *p; //değişkenin adresini saklayan gösterici;
p = &i; // p'ye i'nin adresi aktarıldı.
printf("i =%d ", i);
printf("p =%d ", p);
printf("*p=%d \n", *p);
i = 500;
printf("i =%d ", i);
printf("p =%d ", p);
printf("*p=%d \n", *p);
*p = 700;
printf("i =%d ", i);
printf("p =%d ", p);
printf("*p=%d \n", *p);
system("pause");
}
// 6_1
#include<stdio.h>
int main() {
int i=24;
int *p; // int değişkenin adresini saklayan gösterici
p = &i; //p'ye i'nin adresi aktarıldı.
printf(" i : %d\n", i);
printf("*p : %d\n\n", *p);
printf("i'nin adresi &i : %d\n",&i);
printf("p'nin adresi p : %d\n",p);
system("pause");
}
DİKKAT: * karakteri, int * p; şeklinde yazıldığında “integer pointer”,
*p ; şeklinde yazıldığında
“p’nin gösterdiği adresin içeriği