C++ String İfade Karşlaştırması

Başlatan volkanunal, 04 Ağustos 2017, 09:02:55

volkanunal

Merhabalar , normal şartlarda derleyiciler her string için ayrı bir bellek oluşturup daha sonra bu bellekten çıktıyı veriyorlar diye biliyordum ve kıyaslarken farklı adreslerde gösterildiği için karşılaştırma yaparken else bloguna düşmesini bekliyordum ama "ok" çıktısını aldım , bu yanlış değil midir?

Şöyle bir deneme sonucu

if("volkan"=="volkan") cout<<"ok"; else cout<<"no";

Doğrusunun böyle olması gerekmez miydi?

if(strcmp("VOLKAN","VOLKAN")==0) cout<<"okey"; else cout<<"no";
Primum nil nocere

Klein

Muhtemelen derleme esnasında baktı iki metin de aynı. O zaman neden bellekte iki kez oluşturayım dedi ve tek bir dizi oluşturdu.

Adreslerini yazdırıp bi bakın.

JKramer

Operator overloading'e bakın; <,>, ==, vs. kullandığınızda arka planda ilgili fonksiyonu çağırıyordur: http://en.cppreference.com/w/cpp/string/basic_string/operator_cmp

Klein

Böyle bir karşılaştırmada "operator overloading" olduğunu düşünmüyorum.  "String" sınıfı gibi bir sınıfa ait bir nesnenin karşılaştırılmasında olabilir. Ama böyle ham dizide öyle bir şey yaparsa ciddi sıkıntı yaratır bence.

JKramer

#4
Evet, haklısınız. Şimdi denedim, zaten uyarı veriyor:
warning: comparison with string literal results in unspecified behaviour [-Waddress]


Bunlar ("volkan") string literal olarak geçiyormuş.

Düzeltme: Forumda bir sorun var sanırım, kafasına göre font ve size ekliyor.

Ekleme:
https://stackoverflow.com/questions/29087406/comparison-with-string-literal-c
Alıntı YapYou can't compare two C-style strings by ==ing them. (C-style string literals just give you a pointer to the first character in a sequence of characters in RAM, ended by a 0 valued character, so you'd be comparing addresses instead of strings).

What you want to use would be the strcmp function from stdlib.

However, you're writing C++, not C.

So, I recommend using the string class, which has an overloaded == operator, so you can do

if (string1 == string2)

volkanunal

Anladım çok teşekkür ederim , yani en doğrusu string sınıfına ait bir şey oluşturulmadıysa stcmp ile kontrol etmek gerekli diyebilir miyiz temiz olması açısından?
Primum nil nocere

JKramer

Gerekliden ziyade zorunlu diyebiliriz. Uyarıda yazdığı gibi, sonuç "ok" de olabilir else bloğuna düşüp "no" da olabilir.

foseydon

Alıntı yapılan: volkanunal - 04 Ağustos 2017, 09:02:55
Merhabalar , normal şartlarda derleyiciler her string için ayrı bir bellek oluşturup daha sonra bu bellekten çıktıyı veriyorlar diye biliyordum ve kıyaslarken farklı adreslerde gösterildiği için karşılaştırma yaparken else bloguna düşmesini bekliyordum ama "ok" çıktısını aldım , bu yanlış değil midir?

Şöyle bir deneme sonucu

if("volkan"=="volkan") cout<<"ok"; else cout<<"no";

Doğrusunun böyle olması gerekmez miydi?

if(strcmp("VOLKAN","VOLKAN")==0) cout<<"okey"; else cout<<"no";

Dediğin doğru, string tipi her değişken için ayrı hafıza alanı kullanır. Derleyicinin yaptığı işlem doğru, çünkü string değerlerini karşılaştırıyor adreslerini değil. Burada strcmp fonksiyonu senin düşündüğün gibi çalışmıyor yani. Şu şekilde çalışıyor, fonksiyona verdiğin string değişkenlerinin başlangıç adreslerine gidiyor ve bir loop ile "\0" görene kadar tek tek bütün karakterleri karşılaştırıyor, ona göre bir sonuç dönüyor.

bu arada "function overloading" yok.

mir_as82

Hocam burada ki konu tamamen dilin yapısını ilgilendiren bir konu aslında.
Karşılaştırma işlemlerinde iki çeşit karşılaştırma vardır.


1-Shallow compare-sığ
   Adres karşılaştırma(referans)
2-Deep compare-derin
    Adresin gösterdiği yerdeki verileri karşılaştırma.


yamak

C/C++ da literal stringler memory de bir bölgeye yazılır ve işlemler adres üzerinden yapılır. Bu örnekte derleyici aynı iki string karşılaştırıldığı için bu işlemi bile yapmayıp
o if bloğunda sadece cout <<"ok" satırını derleme işlemine tabi tuttu. O stringlerin adreslerini bi pointer a atıp karşılaştırma işlemini pointerlar üzerinden yaparsanız else kısmı çalışır