BİL131 – DERS 8 // 17.12.2013

0 57
DİZİLER
Dizi (array) aynı tipteki verilerin bir araya getirilmiş halidir. Her bir veri dizinin bir elemanıdır. Veriler karakterler, tam sayılar, ondalık sayılar vb. olabilir. Dizi elemanlarının hepsi aynı tipte ve aynı depolama sınıfından olmalıdırlar. Bir dizinin bir tek adı vardır ve elemanları altsimgelerle (indeks, subscript) belirlenir. Her dizi elemanından sonra, her biri köşeli parantezler içinde olmak kaydıyla, bir veya daha fazla altsimge yer alır.
A[i] örneğinde, A dizinin adı, i ise altsimgedir. Her altsimge negatif olmayan bir tam sayıyla ifade edilmelidir. Altsimgelerin sayısı dizinin boyutlarını belirler. Dizi tek altsimgeye sahipse tek boyutlu (A[i] olarak tanımlanır), iki altsimgeye sahipse iki boyutlu (A[i][j] olarak tanımlanır), üç altsimgeye sahipse üç boyutlu (A[i][j][k] olarak tanımlanır) …dur.
n elemanlı tek boyutlu A dizisinde, dizi elemanları A[0], A[1], A[2],…, A[n-1]’dir. Her altsimgenin değeri sabit bir tam sayı, bir tam sayı değişken veya daha karmaşık yapılı bir tam sayı değer olabilir.
5.1 DİZİNİN TANIMLANMASI
Tek boyutlu bir dizi tanımı şu şekilde yapılabilir:
depolama_sınıfı veri_tip dizi_adı[ifade];
ifade dizi elemanlarının sayısını belirten pozitif bir tam sayıdır.
Dizi_adı dizinin adıdır.
depolama_sınıfı isteğe bağlıdır; bir fonksiyon içinde tanımlanmış bir dizi için default değerler automatic iken, fonksiyon dışında tanımlananlar içinexternal’dır.
Örnek 5.1. Tipik tek boyutlu dizi tanımları aşağıda gösterilmiştir.
int A[100];
char satır[80];
static float x[12];
İlk satırda A 100 elemanlı bir tam sayı dizisi, ikinci satırda line 80 elemanlı bir karakter dizisi olarak tanımlanmıştır. Üçüncü satırdaki x ise 12 elemanlı statik bir ondalık sayı dizisi olarak tanımlanmıştır.
Bazen dizilerin boyutunu sabit bir tam sayı değer yerine sembolik bir sabitle tanımlamak daha uygundur. Bu program içinde dizinin uzunluğunun kolayca değiştirilebilmesini sağlar.
Bu durumda, dizinin deklarasyonundan önce #define ifadesi kullanılarak sabitin değeri tanımlanmalıdır.
Örnek 5.2.
#define N=200
75
#define ÖLÇÜ=80
. . .
int B[N];
char satır[ÖLÇÜ];
B 200 elemanlı bir tam sayı dizisi- text ise 80 elemanlı bir karakter dizisidir. Dizi tanımları tam sayı değerler atanarak da yapılabilir. 
Depolama_sınıfı veri_tip dizi_adı[ifade]={değer1,değer2,…,değern}
value 1 ilk elemanın değerine, value 2 ikinci elemanın değerine, … karşılık gelmektedir. Dizi elemanlarına kendilerine ait olan altsimge aracılığıyla erişilebilir.
Örnek 5.3.
extern int A[4]={1,2,3,4,5};
static float x[5]={4.5, 0.25, 0, -0.50, 0, 0.4};
char isim[4]={R,U,F,A,T};
Kendilerine doğrudan değer atanmayan dizi elemanlarının değerleri otomatik olarak sıfır olur. Örneğin, int A[4]={8,5,5};
ifadesi sonucunda A[0]=8, A[1]=5, A[2]=5, A[3]=0, A[4]=0 olur.
Dizi elemanlarının başlangıç değerleri dizi tanımlanırken verildiğinde dizi boyutunu belirtmeye gerek kalmaz.
Örnek 5.4.
int B[]={1,2,3,4,5};
static float x[]={4.5,0.25,0,-0.50};
Dizi elemanları B[0]=1, B[1]=2, B[2]=3, B[3]=4, B[4]=5;
x[0]=4.5, x[1]=0.25, x[2]=0, x[3]=0, x[4]=-0.50  olacaktır.
5.2. ÇOK BOYUTLU DİZİLER
Çok boyutlu diziler, her altsimge için gereken köşeli parantez çifti dışında, tek boyutlu dizilerle aynı mantıkla tanımlanırlar. Çok boyutlu bir dizi tanımı şu şekilde yapılabilir.
depolama_sınıfı veri_tip dizi_adı[ifade 1][ifade 2]…[ifade n];
depolama_sınıfı dizinin depolama sınıfına, veri_tip veri tipine, array_isim dizinin adına ve ifade 1, ifade 2, . . . , ifade n her bir altsimgeyle ilişkilendirilen dizi elemanlarının sayısını belirten pozitif değerli tam sayılara karşılık gelmektedir. Depolama_sınıfı’ın yazılması isteğe bağlıdır. Varsayılan değerler bir fonksiyonun içindeyken automatic, fonksiyonların dışındaykenexternal’dır.
Örnek 5.5. Çeşitli çok boyutlu dizi tanımları aşağıda gösterilmiştir.
float matrix[50][50];
char page[24][80];
static double records[Z][M][N];
Örnek 5.6. Aşağıdaki iki boyutlu dizi tanımını ele alalım:
int A[3][4]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
veya
int A[3][4]={{ 1, 2, 3, 4 },{ 5, 6, 7, 8 },{ 9, 10, 11, 12}};
A dizisinin üç satır ve dört sütundan oluşan bir tablo gibi düşünülebileceğine dikkat ediniz (her satırda dört eleman).
5.3 DİZİLERLE İŞLEM YAPMA
Diziler üzerindeki işlemler elemanları temel alınarak yapılır. a ve b aynı veri tipine,
tamamıyla aynı boyuta sahip iki siziyse, dizi elemanları üzerinde atama, karşılaştırma vb. işlemler yapılabilir. Bu işlemler genelde bir döngü kullanılarak yapılır. Bu yüzden, döngüden geçiş sayısı, işlem yapılan dizi elemanlarının sayısına eşit olacaktır.
Örnek 5.7. Maksimumu Bulma. n tane ondalıklı dizi elemanı arasından en büyük olanını bulmaya çalışalım.
#include <stdio.h>
main()
{
int n, i;
float max;
float A[100];
/* n için bir değer oku */
printf(“\n Kaç eleman ? “);
scanf(“%d”, &n);
/* dizi elemanlarının değerlerini oku*/
for (i = 0; i < n; ++i)
scanf(“%f”, &A[i]);
max=A[0];
for (i = 1; i < n; ++i)
if (max<=A[i]) max=A[i];
printf(“\n Maksimim eleman %7.3f “, max);
return 0;
}
Dizi elemanlarını (for döngüsü içindeki ikinci scanf fonksiyonu) okumak için A[i]’ye karşılık gelen (&) işareti kullanılır. Bu işaret bütün diziye değil de yalnızca bir elemana karşılık gelmektedir.
Örnek 5.8. Ortalama Değer Etrafındaki Sapmalar. n tane ondalıklı değeri okuyarak bunların ortalamasını hesaplayan bir program yazalım. Ek olarak, her sayısal değerin ortalamaya göre sapmasını aşağıdaki formüle göre hesaplayalım.
d = xi-avg
i = 1, 2, …, n olmak üzere xi verilen değerleri, avg de hesaplanan ortalamayı belirtmektedir.
Problemi çözebilmek için, verilen değerlerin her birini tek boyutlu bir ondalık sayı dizisinde tutmalıyız.
/* n sayının ortalamasını hesaplayarak, her sayının
ortalamaya göre sapmasını bul. */
#include <stdio.h>
main( )
{
int n, i;
float avg, d, sum = 0;
float A[100];
/* n değerini al */
printf(“\n Kaç sayı ? “); scanf(“%d”, &n);
/* sayıları al ve toplamlarını bul*/
for (i = 0; i < n; ++i)
{
printf(“i = %d x = “, i+ 1);
scanf(“%f”, &A[i]);
sum += A[i];
}
/* ortalamayı hesapla ve ekrana yaz */
avg = sum / n;
printf(“\n Ortalaması %5.2f \n”, avg);
/* ortalamaya göre sapmaları hesapla ve ekrana yaz */
for (i = 0; i < n; ++i)
{
d = A[i]-avg;
printf(” A[%d] =%5.2f d =%5.2f\n”, i, A[i], d);
}
}
Bazı uygulamalarda, dizinin elemanlarına başlangıç değerleri atanması istenebilir. Bu durum dizinin global ya da yerel (bir fonksiyon içinde) bir statik dizi olarak tanımlanmasını gerektirir. Sıradaki örnek global dizi tanımının kullanımını göstermektedir.
Örnek 5.9. Karelerin Toplamını Bulma. Ai dizi elemanlarının karelerinin toplamını bulan bir program yazalım. Ai, i=1…n.


#include <stdio.h>
#include <math.h>
main()
{
int i,n; float a[100];
float s=0;
printf(“\n Kaç eleman? “);
scanf(“%d”,&n);
printf(“\n Dizi elemanların verin “);
for(i=0;i<n;i++)
{
scanf(“%f ”,&a[i]);
s+=pow(a[i],2);
}
printf(“\n Toplam %f”,s);
}
Örnek 5.10. Dizi elemanlarının çarpımlarının kökünü bulan bir program yazalım.


#include <stdio.h>
#include <math.h>
float a[]={3,5,4,6,8};
main()
{
int i;
float s=1;
for(i=0;i<=4;i++)
{
printf(“\n%i %f”,i,a[i]);
s*=sqrt(a[i]);
}
printf(“\n%f”,s);
}
Örnek 5.11. Tek boyutlu bir karakter dizisine girdileri alan, bütün elemanları büyük harfe çeviren, sonrasında da değiştirilmiş diziyi ekrana yazan bir program aşağıda verilmiştir.
#include <stdio.h>
#define SIZE 80
main()
{
char letter[SIZE];
int i;
/* satırı oku */
for (i = 0; i<SIZE; ++i)
letter[i]=getchar();
/* satırı büyük harfle yaz */
for (i = 0; i<SIZE; ++i)
putchar(toupper(letter[i]));
return 0;
}
Örnek 5.12. Aşağıdaki ifadeyi hesaplayan bir program yazalım


#include <stdio.h>
#include <math.h>
int a[]={3,5,4,6,8};
int b[]={2,7,3,5,4,6,2,8};
int c[]={7,11,3,8,7,5,6,12};
void main()
{
int i, j,s,s1=1;
int s2=0;
for(i=0;i<=4;i++)
s1*=sqrt(a[i]);
for(j=0;j<=7;j++)
s2+=(b[j]+pow(c[j],2));
s=s1+s2;
printf(“\n%d”,s);
}
Örnek 5.13. Aşağıdaki ifadeyi hesaplayan bir program yazalım. si=3*ai²+5; i=1…n
#include <stdio.h>
#include <math.h>
main()
{
int i,n;
float s[100],a[100];
printf(“\n Kaç eleman? “);
scanf(“%d”,&n);
for(i=0;i<n;i++)
{
scanf(“%f”,&a[i]);
s[i]=3*pow(a[i],2)+5;
80
printf(“\n %d %f %f\n”,i,a[i],s[i]);
}
}
Çok boyutlu bir dizide işlem yapabilmek için, dizinin her indisi için bir döngü oluşturmalıyız. Aşağıdaki örnek iki dizinin nasıl toplanacağını göstermektedir. İki dizinin de aynı sayıda sıra ve sütunlara sahip olması gerektiği dikkat edilmesi gereken bir unsurdur.
Örnek 5.14. İki boyutlu dizilerin toplanması
#include <stdio.h>
main()
{
int i,j,nr,nc;
float x[10][10],y[10][10],z[10][10];
printf(“\n Satır ve sütunları verin \n”);
scanf(“%d %d”,&nr,&nc);
printf(“\n x ve y dizi elemanların değerlerini verin \n”);
for(i=0; i<nr; ++i)
for(j=0; j<nc; ++j)
{
printf(“\n x=”);
scanf(“%f”,&x[i][j]);
printf(“\n y=”);
scanf(“%f”,&y[i][j]);
}
for(i=0; i<nr; ++i)
for(j=0; j<nc; ++j)
{ z[i][j]=x[i][j]+y[i][j];
printf(“\n z[%d][%d]=%f”,i,j,z[i][j]);
}
}
5.4 DİZİLERİ FONKSİYONA GEÇİRME
Bir dizi elemanı veya dizinin tamamı fonksiyonlara geçirebilir. Dizi elemanı fonksiyona geçirilirken, basit bir değişken gibi belirtilir. Döngü, programın fonksiyonu çağırdığı yerde her dizi elemanının fonksiyona geçirilmesi için kullanılacaktır. Aşağıdaki örnekte dizi elemanlarının karelerinin hesaplanması için bir fonksiyon kullanılmıştır.
Örnek 5.15. Dizi elemanlarının kareleri
#include <stdio.h>
#include <math.h>
main()
{
int i; float a[10], b[10];
float square(float);
printf(“\n Dizi elemanların değerlerini verin “);
for(i=0;i<=10;i++)
{
scanf(“%f “,&a[i]);
b[i]=square(a[i]);
printf(“%f \n”,b[i]);
}
return 0;
}
float square(float x)
{
return pow(x,2);
}
Dizinin tümü fonksiyona geçirildiğinde, bir dizi ismi ( diziye işaretçi) fonksiyonun argümanı olarak kullanılabilir. Dizinin ismi, herhangi bir parantez veya altsimge kullanılmadan, fonksiyon çağrısında gerçek bir argüman olarak bulunmalıdır. Buna karşılık gelen aynı mantıkla yazılmış formel argüman ise, formel argüman deklarasyonları dahilinde bir dizi olarak deklare edilmelidir. Tek boyutlu bir diziyi formel argüman olarak deklare ederken, dizinin ismi bir çift köşeli parantezle beraber yazılmalıdır. Fonksiyon prototipleri düşünüldüğünde, belirtilen argümanın bir dizi olduğunu anlatmak için, her dizi argümanının veri tipinden sonra bir çift köşeli parantez yazılmalıdır. Benzer şekilde, fonksiyon tanımının ilk satırı formel argüman deklarasyonları içeriyorsa, formel argüman olan her dizi isminden sonra bir çift boş köşeli parantez gelmelidir.
Örnek 5.16. Aşağıdaki program parçası, programın ana kısmından fonksiyona dizi
geçirilmesini göstermektedir.
main()
{
int n; /* değişken deklarasyonu*/
float avg; /* değişken deklarasyonu*/
float x[l00]; /* dizi deklarasyonu */
float average(int,float[]); /* fonksiyon deklarasyonu*/
. . .
avg average(n, x); /* fonksiyonu çağırma*/
. . .
}
float average(int k, float a[]) /* fonksiyon tanımı */
{
. . .
}
main programı içinde average fonksiyonuna bir çağrı yapıldığını görüyoruz. Bu fonksiyon çağrısı tam sayı değişken n ile tek boyutlu ondalık sayı dizisi list isimli iki gerçel argüman içermektedir.
Fonksiyon tanımının ilk satırı k ve a adlı iki formel argüman içermektedir. formel argüman deklarasyonları, k’nın tam sayı değişken, a’nın da tek boyutlu ondalık sayı dizisi olduğunu belirtmektedir. Bu yüzden, n gerçel argümanıyla k formel argümanı arasında bir uyumluluk söz konusudur. Aynı şekilde, x gerçel argümanı da a formel argümanıyla örtüşmektedir.
Aşağıdaki program bütün dizinin programın ana kısmından fonksiyona aktarılışını
göstermektedir.
Örnek 5.17. Aşağıda dizi elemanlarının karelerini toplayıp eleman sayısına bölen bir
program verilmiştir.


#include <stdio.h>
#include <math.h>
main()
{
int i, n;
float avgs;
float x[100];
float average(int,float[]); /* fonksiyon deklarasyonu*/
printf(“\n Kaç eleman? “);
scanf(“%d”,&n);
printf(“\n Dizi elemanların değerlerini verin \n”);
for(i=0;i<n;++i)
scanf(“%f”,&x[i]);
avgs = average(n, x); /* fonksiyon çağırma*/
printf(“\n The result is : %f “,avgs);
}
float average(int n, float x[]) /* fonksiyon tanımı */
{
float temp, s=0;
int i;
for(i=0;i<n;++i)
s+=pow(x[i],2);
temp=s/n;
return(temp);
}
Örnek 5.18. Dizinin sıralanması. Aşağıda dizi elemanlarını gittikçe artacak şekilde sıralayan bir program verilmiştir. Dizi elemanlarını sıralamak için sort fonksiyonu kullanılmıştır.
/*Tek boyutlu tam sayı dizisinin elemanlarının küçükten büyüğe doğru sıralanması*/
#include <stdio.h>
#define M 100
main()
{
int i, n, x[M];
void sort(int n, int x[]);
printf(“\n Kaç sayı? “);
scanf(“%d”, &n);
/* sayıları oku */
for ( i = 0; i<n; ++i )
{
printf(“i = %d x = “, i + 1);
scanf(“%d”, &x[i]);
}
sort(n, x); /* dizi elemanlarını sırala*/
printf(“\n Sıralanmış sayılar: \n”);
for (i = 0; i < n; ++i)
printf(“x[%d] = %d \n”, i + 1, x[i]);
}
void sort(int n, int x[])
{
int i, j, temp;
for(j = 0; j< n-1; ++j)
for(i = j + 1; i < n; ++i)
if (x[i]<x[j] )
{
temp = x[j];
x[j] =x[i];
x[i] = temp; /*iki elemanın yerlerini değiştir*/
}
}
Çok boyutlu dizileri fonksiyona geçirirken, fonksiyon tanımındaki formel argüman
deklarasyonları ilki dışındaki tüm altsimge pozisyonlarındaki boyutları belirtmelidir. İlk altsimge pozisyonu yerine boş köşeli parantezler konulabilir. Aşağıdaki program iki boyutlu bir dizinin fonksiyona geçirilişini göstermektedir.
Örnek 5.19. Aşağıda iki boyutlu dizi elemanlarını toplayarak ortalamasını alan bir program verilmiştir.


#include <stdio.h>
#define COL 10
main()
{
int i,j, n, m;
float avgs;
float x[10][10];
float average(int,int,float x[][COL]); /* fonksiyon deklarasyonu*/
printf(“\n Kaç satır ve sütun? “);
scanf(“%d %d”,&n,&m);
printf(“\n Dizi elemanların değerlerini verin \n”);
for(i=0;i<n;++i)
84
for(j=0;j<m;++j)
scanf(“%f”,&x[i][j]);
avgs = average(n,m,x); /* fonksiyonu çağırma*/
printf(“\n Sonuc : %f “,avgs);
}
float average(int n, int m, float x[][COL]) /* fonksiyon tanımı */
{
float temp, s=0;
int i,j;
for(i=0;i<n;++i)
for(j=0;j<m;++j)
s+=x[i][j];
temp=s/(n+m);
return(temp);
}

Senin bu konuya yorumun ne olacak?

Gerekli *

HAKKIMIZDA

facebook twitter youtube flickr ENOTLAR TV LOGOSU_Artboard 13 - ENOTLAR TV LOGO

Arşivler

KAREKOD-umuz

Lower-Third-(Enotlar)