C++ Char'la oluşturulmuş string ve Pointer'lar nasıl olmalı?

kamuran41

Hectopat
Katılım
6 Temmuz 2022
Mesajlar
80
Çözümler
1
Daha fazla  
Cinsiyet
Erkek
Str: Char[ ]
Benim anladığım String'ler char array'larıdır. Bu şekilde Udemy kursundaki hoca class oluşturuyor ve "operator overloading" anlatıyor. En takıldığım yer char Pointer'ını strlen(str) fonksiyonu ilE arraydaki char sayısını buluyor, strcat(str, baska_str) ile birbirlerine ekliyor.
Str'ın değeri adres değil mi? İşlemleri adres üstünden. Değil *str ile yapması gerekmiyor mu? Tek mantıklı gelen strcpy ama diğerlerini anlayamıyorum.
Ek'deki görüntüden satır 86-88 arasında görüyorsunuz:
 

Dosya Ekleri

  • 1675363855914.png
    1675363855914.png
    51,5 KB · Görüntüleme: 86
Son düzenleyen: Moderatör:
Yardımcı olabileceğim yeri tam anlamadım ama birkaç örnek bırakıyorum umarım yardımcı olur.

Kod:
#include <iostream>
#include <string>

int main() {
  std::string str = "Merhaba Ben Technopattan Recep Baltas";
  std::cout << str << std::endl;
  return 0;
}

Kod:
Char Dizimi

#include <iostream>

int main() {
  char str[] = "Merhaba ben Technopattan Recep Baltas";
  std::cout << str << std::endl;
  return 0;
}

Kod:
Pointer


#include <iostream>

int main() {
  char str[] = "Merhaba ben Technopattan Recep Baltas";
  char *ptr = str;
  std::cout << ptr << std::endl;
  return 0;
}
 
Str: Char[ ]
Benim anladığım String'ler char array'larıdır. Bu şekilde Udemy kursundaki hoca class oluşturuyor ve "operator overloading" anlatıyor. En takıldığım yer char Pointer'ını strlen(str) fonksiyonu ilE arraydaki char sayısını buluyor, strcat(str, baska_str) ile birbirlerine ekliyor.
Str'ın değeri adres değil mi? İşlemleri adres üstünden. Değil *str ile yapması gerekmiyor mu? Tek mantıklı gelen strcpy ama diğerlerini anlayamıyorum.
Ek'deki görüntüden satır 86-88 arasında görüyorsunuz:
1) Lütfen kodları ekran görüntüsü yerine forumdaki kod özelliğini kullanarak paylaşın bir dahaki sefere. Okumamızı kolaylaştırıyor.

2) Paylaştığınız görseldeki kod concatenate (birleştirme) işlemi. Yapılan şey belirli bir büyüklükte buffer oluşturup bu bufferda 2 stringin birleştirilmesi daha sonrasında bu bufferı kullanarak yeni bir nesne oluşturulması ve oluşturulan nesnenin döndürülmesi. *str ile yapmasına gerek yok.

Pointer olarak işaretlenmiş bir değişkenin/nesnenin başına '*'(asterisk) eklenmesi ona dereferans yapıldığı anlamına gelir. Yani yapılan referans adrese değil, adreste depolanan veriyedir.

*str olarak gönderildiğinde adresi değil değeri göndermiş oluyorsunuz. Ancak fonksiyon sizden bir adres istediği için *str olarak yazmıyorsunuz fonksiyona. strcpy ve strcat fonksiyonları 2 adet const char * alır. Birincisi hedef, 2.si kaynaktır. strcpy kaynaktaki veriyi hedefe yazar. strcat ise kaynaktaki veriyi hedefe ekler. Her ikisi içinde hedefin adresini almaya ihtiyacımız var çünkü yapılan işlem geçici bir işlem değil. Kalıcı olarak hedefe yapılmak isteniyor. Bu yüzden *str yerine, str yazıyor.
 
Açıklayacak bir şey yok. Ekran görüntüsü ne yapılmaya çalışıldığını anlamak için fazlasıyla yeterli.

strcpy ile strcat arasında fark yok. İkisi de pointer alıyor. O şekilde gönderilmiş. Diğer türlü değer kopyalanirdi. Alınan pointerın verisine erişmek için fonksiyonda zaten asterisk kullanılıyor. Burada örnek strcat implementasyonunu görebilirsin. İçinde strcpy kullanıldığını görebilirsin. Bu yüzden strcat yerine strcpy ile halletmek özellikle çoklu çağrılarda daha iyi. strcpy implementasyonuna bakarsan memcpy kullanıldığını görürsün. Şahsen bu yüzden strcpy ve strcat bana hep boş gelmiştir. Nasıl kullanıldığı bilindikten sonra memcpy ile yapmayı tercih ederim. memcpy'den sonra işler fazla sarpa sarıyor.

C'de string olarak kullanılan şeyler aslında char pointerları. C++'ta std::string kullanılır. Tonla constructorı falan olduğu için basitçe chat pointerı demeyi doğru bulmuyorum.

Kendi string classınızı yazıyorsunuz gibi duruyor. İmplementasyon isterseniz örnek yazmış olayım. Çalıştırmadım, hata olabilir, classın devamı da lazım. Ama kabaca bu şekilde yapmayı paylaştığınız şekilde yapmaktan tercih ederim. Özellikle zaten döndürülecekse direkt temp MyString oluşturmak yerine char pointerı oluşturma kısmı saçma geliyor. Zaten direkt bu şekilde operator+ olarak oluşturulması da bana pek anlamlı gelmiyor.

Ben null termination da kullanmazdım. Bu string ile yapacağınız tek şey onu yazdırmak. Onun için de size kadar dönen döngü yazarsınız, olur biter.
Kod:
MyString& MyString::operator+=(const MyString& otherStr) {
    auto tempSize{ size + otherStr.size };
    char* tempStr{ new char[tempSize] };
 
    if (tempStr == nullptr) {
        throw(-1);
    }
 
    std::memcpy(tempStr, str, size);
    std::memcpy(tempStr + size, otherStr.str, otherStr.size);
 
    if (str) {
        delete [] str;
    }
 
    size = tempSize;
    str = tempStr;
 
    return *this;
}

MyString MyString::operator+(const MyString& otherStr) const {
    MyString temp{ *this };
    temp += otherString;
    return temp;
}
Tabii burada operator+'nın ilk satırını yazmak için copy ve move constructorlar yazılmış olmalı.
Bir yerlerden hayal meyal new operatörürünün asla null pointer döndürmeyeceği kalmış ama bulamadım. Dokümantasyona baktığımda nothrow olan implementasyonlar olsa da olmayan halleri de söz konusu. O kısım gereksiz olmuş olabilir.
 
Son düzenleme:
1) Lütfen kodları ekran görüntüsü yerine forumdaki kod özelliğini kullanarak paylaşın bir dahaki sefere. Okumamızı kolaylaştırıyor.

2) Paylaştığınız görseldeki kod concatenate (birleştirme) işlemi. Yapılan şey belirli bir büyüklükte buffer oluşturup bu bufferda 2 stringin birleştirilmesi daha sonrasında bu bufferı kullanarak yeni bir nesne oluşturulması ve oluşturulan nesnenin döndürülmesi. *str ile yapmasına gerek yok.

Pointer olarak işaretlenmiş bir değişkenin/nesnenin başına '*'(asterisk) eklenmesi ona dereferans yapıldığı anlamına gelir. Yani yapılan referans adrese değil, adreste depolanan veriyedir.

*str olarak gönderildiğinde adresi değil değeri göndermiş oluyorsunuz. Ancak fonksiyon sizden bir adres istediği için *str olarak yazmıyorsunuz fonksiyona. strcpy ve strcat fonksiyonları 2 adet const char * alır. Birincisi hedef, 2.si kaynaktır. strcpy kaynaktaki veriyi hedefe yazar. strcat ise kaynaktaki veriyi hedefe ekler. Her ikisi içinde hedefin adresini almaya ihtiyacımız var çünkü yapılan işlem geçici bir işlem değil. Kalıcı olarak hedefe yapılmak isteniyor. Bu yüzden *str yerine, str yazıyor.
Çok teşekkürler. Sorunum çözüldü.
 

Technopat Haberler

Geri
Yukarı