Standart C Programlama Dili


EK F: SEÇİLMİŞ PROBLEMLERE YANITLAR

Bu ekte, her bölümün sonunda verilen problemlerden bazıları için yanıtlar verilmiştir. Bazı problemler için değişik çözümler de sözkonusu olabilir. Burada ilk sayı bölümü, ikinci sayı ise problemi belirtir.

1.1. Şunu deneyin:

int main (void)
{
  int entry;
  return 0;
}

1.4. Evet, x=5; deyimine eşdeğerdir.

1.5. Evet, boş bir blok deyimidir.

1.6.

...
scanf("%f", &x);
printf("%d", (int)x);
...

2.2.

switch (yas)
  case 16 : printf("...");

2.4.

#include <stdio.h>
int main (void)
{
  unsigned  i, n;
  scanf("%u", &n);
  for (i=1; i<=n; i++)
    printf("%u\t%g\n", i*i, 1.0/i);
  return 0;
}

2.6.

#include <stdio.h>
int main (void)
{
  int  p, c, i;
  c = p = getchar();
  i = 1;
  while (c!=EOF) {
    c = getchar();
    if (c==p)
      i++;
    else {
      if (i==3)
        printf("%c ", p);
      p = c;
      i = 1;
    } /* else */
  } /* while */
  return 0;
}

2.8. Satır 32’deki do’yu uygun bir şekilde while’a çevirin.

3.1. Gösterge aritmetiğine karşılık tamsayı aritmetiği. Bu sistemde short’un iki bayt uzunluğunda olduğunu anlarız.

3.2.

#include <stdio.h>
int main (void)
{
  printf("%s-doldurma\n", (-10>>1<0)?"isaret":"sifir");
  return 0;  
}

3.3.

#include <stdio.h>
int main (void)
{
  unsigned  n, b;
  scanf("%u", &n);
  for (b=0; n!=0; n>>=1)
    b += n&1;
  printf("%d bit\n", b);
  return 0;
}

3.4. Eğer a ve b aynı tipten ise içeriklerini değiştirir.

3.7. (a) değişkenlerin boş küme olarak ilklenmesi;
(b) n sayısının kume1’e eklenmesi;
(c) n sayısının kume2’den çıkarılması;
(d) iki kümenin aynı içerikte olup olmadığının denetlenmesi;
(e) iki kümenin bileşimi;
(f) küme farkı;
(g) kume2 veya kume3’te olup ta her iki kümede olmayan sayıların kume1’e konması.

4.1. Hayır! Bundan emin olamayız, çünkü bu, fonksiyon argümanlarının hesaplanma sıralarına bağlıdır.

4.2.

int maks (int x, ...)
{
  int maks, *xg;
  for (maks = *(xg=&x); *xg != 0; xg++)
    if (maks < *xg)
      maks = *xg;
  return maks;
}

Tanımda “...” (üç nokta) geri kalan parametrelerin sayılarının (ve tiplerinin) belirlenmediği anlamına gelir. Ancak, böyle değişken sayıda argümanlı fonksiyon yazmanın taşınabilir yolu bu değildir. Bunun yerine, aşağıda gösterildiği gibi, stdarg.h standart başlık dosyasında tanımlanmış bulunan va_start, va_arg ve va_end makroları kullanılmalıdır.

#include <stdarg.h>
int maks (int x, ...)
{
  int m;
  va_list xg;       /* geri kalan argumanlara gosterge */
  va_start(xg, x);  /* ilk isimlendirilmemis argumana
                     * isaret et */
  for (m = x; x != 0; x = va_arg(xg,int))
    if (x > m)
      m = x;        /* yeni enbuyuk */
  va_end(xg);       /* donmeden once temizlik yap */
  return m;
}

4.3. İlklenmemiş otomatik değişkenler belirsiz değerler taşır. Bu, daha önce aynı adreste saklanmış olan bir otomatik değişkenin değeri olabilir.

4.4. Sadece ilk iki register bildirimi dikkate alınır, geri kalanlar auto gibi işlem görürler. Aynı zamanda bir önceki alıştırmaya bakın.

4.5. Girilen satırdaki karakterleri tersten basar.

4.9. Sudoku bulmacalarını çözen program aşağıda verilmektedir:

#include <stdio.h>

int sayi = 0;
int tahta [9][9];

int tahtaTamam (int r, int c, int d)
{
  int rr, cc;

  for (cc = 0; cc < 9; cc++)
    if (tahta[r][cc] == d)
      return 0;
  for (rr = 0; rr < 9; rr++)
    if (tahta[rr][c] == d)
      return 0;
  for (rr = r/3*3; rr < r/3*3+3; rr++)
    for (cc = c/3*3; cc < c/3*3+3; cc++)
      if (tahta[rr][cc] == d)
        return 0;
  tahta[r][c] = d;
  return 1;
}

void cozumyaz (void)
{
  int r, c;

  printf("\n\n\tCOZUM %d\n\n", ++sayi);
  for (r = 0; r < 9; r++) {
    for (c = 0; c < 9; c++)
      printf("%2d", tahta[r][c]);
    printf("\n");
  }
}

void yerlestir (int pozisyon)
{
  int deger, r, c;

  if (pozisyon == 9*9)
    cozumyaz();
  else {
    r = pozisyon / 9;
    c = pozisyon % 9;
    if (tahta[r][c] == 0) {
      for (deger = 1; deger <= 9; deger++)
        if (tahtaTamam(r,c,deger))
          yerlestir(pozisyon+1);
      tahta[r][c] = 0;
    } else
      yerlestir(pozisyon+1);
  }
}

int main (void)
{
  int r, c;
  char t;

  for (r=0; r<9; r++)
    for (c=0; c<9; c++) {
      do
        scanf("%c", &t);
      while (t=='\n' || t==' ');
      tahta[r][c] = (t>='1' && t<='9') ? (t-'0') : 0;
    }
  yerlestir(0);
  printf("\n\n%d adet cozum bulundu.\n", sayi);
  return 0;
}

5.1. (a) sıfır, yani ilk sayıcı ve (b) belirsiz bir değer.

5.4.

int *tamsayıya gösterge,
int *[3]tamsayıya 3 göstergeden oluşan dizi,
int (*)[3]3 tamsayıdan oluşan diziye gösterge,
int *(float)argümanı float olan ve int’e gösterge döndüren fonksiyon,
int (*)(void)argümanı olmayan ve int döndüren fonksiyona gösterge.

5.5. a[i,j] ile a[(i,j)] eşdeğerdir, bu da a[j]’ye, yani bir göstergeye eşdeğerdir.

5.6. x dizi olmasına karşın, a bir göstergedir.

5.8. a değişmez bir göstergedir; bundan sonra hep &y’yi göstermek zorundadır. Fakat gösterdiği yer, yani y içindeki bilgi değiştirilebilir.

b de değişmez bir göstergedir, bunun yanında gösterdiği yer, yani x de program tarafından değiştirilemez. Buna rağmen, bu yer program dışındaki bir süreç tarafından değiştirilmektedir. Yani b’nin gösterdiği yeri program değiştiremez, sadece okuyabilir.

6.1.

typedef int * gosterge;

ile

#define gosterge int *

birbirine benzemektedir, ama

typedef int dizi[N];

#define ile ifade edilemez, onun için typedef tercih edilir.

6.2.

#define dok(x) printf("x = %d\n", x)

Eğer Standarda uygun bir önişlemciniz varsa, o zaman aşağıdakini kullanın:

#define dok(x) printf(#x " = %d\n", x)

7.9.

#include <stdlib.h>
void temizle (void)
{
  system("CLS");
}