char türünden gösterici ve dizi farkı

Başlatan Ali Osman, 17 Ocak 2017 - 14:08:28

« önceki - sonraki »

0 Üyeler ve 1 Ziyaretçi konuyu incelemekte.

Ali Osman

Bu aralar basit kodlarla başım dertte. Aşağıda iki diziyi birbirine kopyalamaya çalışıyorum. (strcpy kullanmadan). Kodda i'yi for parantezleri içinde arttırdığım zaman sorun yok ama 5. satırda d[i++] yaptığım zaman hatalı çalışıyor. Şimdi şöyle düşünülebilir; madem for parantezleri içinde i'yi artırdığında düzgün çalışıyor neden bunu illa indis içinde yapıyorsun? Tamam da char p[4] yerine char *p yaptığımda i'yi indis inçinde de olsa for parantezleri içindede artırsam düzgün çalışıyor. Bu fark neden kaynaklanıyor acaba bir tülrü çözemedim.

1    int i;
2   char d[4]="ali";
3   char p[4];
4   for(i=0;d[i]!='\0';)
5        p[i]=d[i++];//bu satıra dokunmadan 3. satırı char *p diye değiştirdiğimde çalışıyor.
6    puts(p);

bugra9

Yazdığın şekilde döngünün 1. aşamasında,
p[1]=d[0];
gibi bir şey oluyor ve bundan dolayı istediğiniz gibi çalışmıyor. i++ yerine ++i kullanmayı tercih ederseniz bu tarz durumlarla karşılaşmazsınız.
Alıntı YapIn any case, follow the guideline "prefer ++i over i++" and you won't go wrong.
http://stackoverflow.com/questions/24853/what-is-the-difference-between-i-and-i


for(i=-1;d[i]!='\0';)
p[i]=d[++i];

Erdem

#include <stdio.h>

int main(void)
{
    char isim[4] = "ali";
    char digerIsim[4];
    int i = -1;

    while (isim[i] != '\0')
        //    digerIsim[i] = isim[++i];
        digerIsim[i] = *(isim + ++i);
   
    puts(digerIsim);
    return 0;
}


Ya da döngü değişkenini -1'den başlatabilirsiniz.
Alıntı YapdigerIsim = isim[++i];
de aslında
Alıntı YapdigerIsim = *(isim + ++i);
'a eşit olmuş oluyor.

Ali Osman

#3
Arkadaşlar söylediğiniz gibi çeşitli döngü yöntemleriyle kodu denedim tamam hepsi de iyi çalışıyor ama problem şurda;
Şimdi aşağıdaki kodu inceleyin
1    int i=0;
2   char d[4]="ali";
3   char p[4];
4   for(;i<strlen(d); )
5        p [ i ]=d[i++];
6    puts(p);

Bu kodun hiç bir yerini değiştirmeden 5. satırdaki p[ i ] kısmını *(p+i) diye diğiştirip çalıştırın. İlkinde p dizisi kopyaladığı elemanları 1. elemanından itibaren yazarken 2.sinde p dizisi kopyaladığı elemanları 0. elemandan itibaren yani olması gerektiği gibi yazıyor. Diyelimki önce p[ i  ]=d[i++] ifadesinde sağ tarafta i değeri 0 olarak dizi indisi içine girdi d[0] işlemi yapıldı ve i bir artırıldı. Sonra eşitliğin sol tarafına geçerken p[ i ] ifadesi içindeki i değeri 1 oldu. Yani işlem önceliği sağdan sola doğru. İyi ama p[ i ] yerine *(p+i) yapınca buradaki i sol taraftaki indis içine sıfır olarak girip sonra artıyor. (Ayrıca ubuntu'da gcc ile derlediğim bu kodu windows'ta mingw ile derledim her iki durumda da yani 5. satır hem  p=d[i++]; hem de  * (p+i)=d[i++]; yazdım sorunsuz çalıştı. Üstüne bir de bunu ekleyin.)

Amenofis

Demekki tanımsız davranışlardan kaçınmak lazımmış. Adamlar herşeyi en ince ayrıntısına kadar standarta bağlayacak değiller. Çoğu şey derleyicinin insiyatifine bırakılmış. Gerekli parametreleri açarsanız derleyiciniz sizi uyarır.

Mesela gcc dedi ki; "warning: operation on 'i' may be undefined"
clang ise şöyle dedi; "warning: unsequenced modification and access to 'i'

++i kısmını for parantezi içine yaz ve sorun kalmasın.

Ali Osman

Evet demek ki şüpheli kodlardan uzak durmak lazım. Derleyici yazanlar bu tür ifadeleri en mantıklı şekilde asm koduna çevirecek şekilde kod yazarlar. Fakat bazen biz aynı kodlar için farklı bir mantık yürütürüz. Tabi sonuçta derleyici bildiğini okuyor.