Apa yang dilakukan operator unary plus?


87

Apa yang dilakukan operator unary plus? Ada beberapa definisi yang saya temukan (di sini dan di sini ) tetapi saya masih tidak tahu untuk apa itu digunakan. Sepertinya tidak melakukan apa-apa tetapi pasti ada alasannya, bukan?


3
Saya pikir alasan historis sangat diremehkan.
Serigala

3
Pertanyaan dengan tiga tag bahasa berbeda cukup ambigu / buruk! Jawabannya sangat berbeda untuk C # (overloadable) dan C (no overloading) dan C ++ (overloadable tetapi mewarisi ini dari C dan karenanya juga propertinya).
legends2k

Saya ingin menambahkan tautan ke 10 kelemahan C # teratas Eric Lippert. Anda akan menemukan operator unary plus di honorable mention: informit.com/articles/article.aspx?p=2425867 Dia pada dasarnya mengatakan itu harus dihapus atau seharusnya tidak pernah ditambahkan.
Noel Widmer

Jawaban:


57

Itu ada untuk dibebani jika Anda merasa perlu; untuk semua tipe standar, ini pada dasarnya tidak ada operasi.

Penggunaan praktis dari operator aritmatika unary no-op cukup terbatas, dan cenderung berhubungan dengan konsekuensi penggunaan nilai dalam ekspresi aritmatika, daripada operator itu sendiri. Misalnya, dapat digunakan untuk memaksa pelebaran dari tipe integral yang lebih kecil ke int, atau memastikan bahwa hasil ekspresi diperlakukan sebagai nilai r dan oleh karena itu tidak kompatibel dengan constparameter non- referensi. Saya menyampaikan, bagaimanapun, bahwa penggunaan ini lebih cocok untuk golf kode daripada keterbacaan. :-)


7
Ini sebenarnya tidak benar, seperti yang ditunjukkan beberapa contoh di bawah ini.
jkerian

3
Oke, saya akan membeli yang memiliki beberapa kegunaan, tetapi sebagian besar penggunaan yang dibahas di bawah berhubungan dengan fakta bahwa itu adalah ekspresi numerik yang dibuat menggunakan operator tanpa operasi: misalnya, mempromosikan ke intdan menghasilkan nilai r adalah efek ekspresi -ness, bukan operator + itu sendiri.
Jeffrey Hantin

119

Sebenarnya, unary ditambah tidak melakukan sesuatu - bahkan dalam C. Ia melakukan konversi aritmatika biasa pada operan dan kembali nilai baru, yang dapat menjadi integer lebar yang lebih besar. Jika nilai asli adalah bilangan bulat unsigned dengan lebar kurang dari int, itu akan diubah menjadi signednilai juga.

Biasanya ini tidak terlalu penting, tetapi dapat berpengaruh, jadi bukan ide yang baik untuk menggunakan unary plus sebagai semacam "komentar" yang menunjukkan bahwa bilangan bulat positif. Pertimbangkan program C ++ berikut:

void foo(unsigned short x)
{
 std::cout << "x is an unsigned short" << std::endl;
}

void foo(int x)
{
 std::cout << "x is an int" << std::endl;
}

int main()
{
 unsigned short x = 5;
 foo(+x);
}

Ini akan menampilkan "x adalah int".

Jadi dalam contoh ini unary plus membuat nilai baru dengan tipe dan tanda tangan yang berbeda .


5
jika Anda menulis kode yang menghasilkan hasil yang diberikan ketika diberi pendek dan int yang sebanding, maka Anda mungkin memiliki masalah yang berbeda
Lie Ryan

1
Terima kasih, itu membuatnya jelas (catatan: Di C, saya tidak bisa mendapatkan contoh untuk bekerja, karena saya tidak bisa membebani fungsi foo)
Binarian

apa yang dimaksud dengan mengatakan an integer of greater width?
yekanchi

dalam konteks ini, "lebar" mengacu pada jumlah byte penyimpanan yang terkait dengan nilai.
giles

41

Dari K&R edisi kedua:

Unary + baru dengan standar ANSI. Itu ditambahkan untuk simetri dengan unary -.


6
Benar. * Ini adalah alasan historis. C ++ harus menyesuaikannya, jadi harus berurusan dengan kelebihan beban.
Serigala

38

Saya telah melihatnya digunakan untuk kejelasan, untuk menekankan nilai positif yang berbeda dari nilai negatif:

shift(+1);
shift(-1);

Tapi itu penggunaan yang cukup lemah. Jawabannya pasti overload.


9
Saya telah melakukan ini juga, terutama ketika berhadapan dengan vektor sepertivec3(+1,-1,-1)
mpen

28

Satu hal yang +dilakukan unary built-in adalah mengubah lvalue menjadi rvalue. Misalnya, Anda bisa melakukan ini

int x;
&x;

tetapi Anda tidak bisa melakukan ini

&+x;

:)

PS "Overloading" jelas bukan jawaban yang tepat. Unary +diwarisi dari C dan tidak ada operator tingkat pengguna yang kelebihan muatan di C.


14

Hal utama yang dicapai unary + adalah promosi tipe ke int untuk tipe data lebih kecil dari int. Ini bisa sangat berguna jika Anda mencoba mencetak data karakter menggunakan std::coutsebagai data numerik.

char x = 5;
std::cout << +x << "\n";

sangat berbeda dari

char x=5;
std::cout << x << "\n";

Ini juga tersedia untuk overloading, tetapi dalam praktiknya overload Anda harus mendekati NOP.


12

Jika Anda perlu mencetak nilai numerik byte mentah (misalnya, angka kecil disimpan sebagai char) untuk debug atau alasan apa pun, unary + dapat menyederhanakan kode cetak. Mempertimbangkan

char c = 42;
cout << c << endl;           // prints "*\n", not what you want in this case
cout << (int)c << endl;      // prints "42\n", ok
cout << +c << endl;          // prints "42\n", much easier to type

Ini hanyalah contoh singkat. Saya yakin ada saat lain unary + dapat membantu memperlakukan byte Anda lebih seperti angka daripada teks.


4

Berita menarik sejarah. Komite standardisasi C99 juga menganggap penggunaan unary plus yang ada cukup langka, sebagaimana dibuktikan dengan pertimbangan mereka untuk menggunakannya kembali untuk mencapai fitur lain dalam bahasa: penghambatan evaluasi waktu terjemahan ekspresi konstan floating-point. Lihat kutipan berikut dari C Rationale, bagian F.7.4:

Versi awal spesifikasi ini memungkinkan aritmatika konstan waktu terjemahan, tetapi memberdayakan operator + unary, ketika diterapkan ke operan, untuk menghambat evaluasi waktu terjemahan dari ekspresi konstan.

Pada akhirnya, semantik dibalik, dengan evaluasi waktu berjalan diberlakukan di sebagian besar konteks (setidaknya hingga aturan "seolah-olah"), dan kemampuan untuk menerapkan evaluasi waktu terjemahan dengan menggunakan penginisialisasi statis. Perhatikan bahwa perbedaan utama terletak pada terjadinya pengecualian floating point, dan pengaturan presisi atau pembulatan floating point lainnya, jika ada.


3

Tidak banyak. Argumen umum untuk mengizinkan overload operator+()adalah bahwa pasti ada penggunaan dunia nyata untuk overloading operator-(), dan akan sangat aneh (atau asimetris) jika Anda mengizinkan overloading operator-()tetapi tidak operator+().

Saya percaya bahwa saya pertama kali membaca argumen ini dari Stroustrop, tetapi saya tidak memiliki hak untuk memverifikasinya. Saya mungkin salah.


3

Unary plus hadir di C, di mana ia sama sekali tidak melakukan apa-apa (seperti autokata kunci). Untuk tidak memilikinya, Stroustrup harus membuat ketidakcocokan dengan C.

Setelah berada di C ++, wajar untuk mengizinkan fungsi kelebihan beban, seperti unary minus, dan Stroustrup mungkin telah memperkenalkannya karena alasan tersebut jika belum ada.

Jadi, itu tidak ada artinya. Ini bisa digunakan sebagai hiasan untuk membuat sesuatu terlihat lebih simetris, gunakan +1,5 sebagai kebalikan dari -1,5 misalnya. Di C ++, ini bisa kelebihan beban, tetapi akan membingungkan jika operator+()melakukan sesuatu. Ingat aturan standar: saat membebani operator aritmatika, lakukan hal-hal seperti ints do.

Jika Anda mencari alasan mengapa itu ada di sana, temukan sesuatu tentang sejarah awal C. Saya kira tidak ada alasan yang baik, karena C sebenarnya tidak dirancang. Pertimbangkan autokata kunci yang tidak berguna (mungkin berbeda dengan static, sekarang sedang didaur ulang di C ++ 0x), dan entrykata kunci, yang tidak pernah melakukan apa pun (dan kemudian dihilangkan di C90). Ada email terkenal di mana Ritchie atau Kernighan mengatakan bahwa, ketika mereka menyadari bahwa prioritas operator bermasalah, sudah ada tiga instalasi dengan ribuan baris kode yang tidak ingin mereka hancurkan.


1
Satu-satunya kelebihan non-aritmatika yang saya lihat yang masuk akal adalah dalam ekspresi reguler atau tata bahasa di mana (+ istilah) berarti satu atau lebih tems. (Yang merupakan sintaks ekspresi reguler standar yang cukup)
Michael Anderson

Tentang entry: ( stackoverflow.com/q/254395/153285 ). Saat ini, jika Anda menginginkan banyak titik masuk, cukup gunakan panggilan ekor dan pengoptimalan yang dipandu profil.
Potatoswatter

Saya percaya bahwa bahkan di C99, mengingat extern volatile int foo;, kompiler yang diberikan pernyataan +foo;akan diminta untuk melakukan pembacaan alamat yang ditunjukkan pada platform apa pun di mana cara apa pun mungkin ada untuk menentukan bahwa pembacaan itu terjadi. Saya tidak yakin itu akan diperlukan jika pernyataan itu hanya "foo", meskipun banyak kompiler akan melakukannya sebagai kesopanan.
supercat

2

Saya tidak dapat mengutip sumber apa pun untuk ini, tetapi saya telah memahaminya untuk promosi tipe eksplisit, yang menyiratkan konversi tipe lossless. Itu menempatkannya di bagian atas hierarki konversi,

  • Promosi: new_type operator+(old_type)
  • Konversi: new_type(old_type)
  • Pemeran: operator(new_type)(old_type)
  • Paksaan: new_type operator=(old_type)

Tentu saja, itu dari interpretasi saya tentang sebuah catatan di salah satu manual c / c ++ microsoft (sangat tua) yang saya baca sekitar 15 tahun yang lalu, jadi ambillah dengan sebutir garam.


1
#include <stdio.h>
int main()
{
    unsigned short x = 5;
    printf ("%d\n",sizeof(+x)); 
    printf ("%d\n",sizeof(x)); 
    return 0;
}

Seperti yang ditunjukkan pada contoh di atas, unary + benar-benar mengubah tipe, ukuran 4 dan 2 masing-masing. Aneh bahwa ekspresi + x memang dihitung dalam ukuran, saya pikir itu tidak seharusnya. Mungkin karena sizeof memiliki prioritas yang sama dengan unary +.


-1

Saya kira Anda bisa menggunakannya untuk selalu membuat angka positif. Hanya membebani operator + unary menjadi abs. Tidak perlu membingungkan sesama pengembang, kecuali jika Anda benar-benar hanya ingin mengaburkan kode Anda. Maka itu akan bekerja dengan baik.


Itu akan membuatnya bukan kebalikan dari minus unary yang akan membingungkan, kecuali jika Anda juga membebani minus unary menjadi abs negatif, yang akan membuat semua jenis matematika menjadi aneh
Davy8

Uhh, ya. Itu sebabnya saya menyarankan untuk tidak melakukannya.
Patrick

1
@ Davy8: Apa yang membuat Anda berpikir unary plus saat ini adalah "kebalikan" dari unary minus? Apa "kebalikan" dari operator pelengkap bitwise ~? Saya tidak yakin apa definisi Anda tentang "lawan", tetapi saya curiga itu bias oleh pengalaman tentang apa yang saat ini dilakukan oleh unary plus dan unary minus.
ndkrempel

-1

EDIT Tulis ulang sepenuhnya, karena saya tidak menjawab dengan jawaban asli saya.

Ini akan memungkinkan Anda untuk menangani pernyataan eksplisit tipe Anda sebagai nilai positif (saya pikir sebagian besar dalam operasi non-matematika). Tampaknya penyangkalan akan lebih berguna, tetapi saya kira inilah contoh di mana hal itu dapat membuat perbedaan:

public struct Acceleration
{
    private readonly decimal rate;
    private readonly Vector vector;

    public Acceleration(decimal rate, Vector vector)
    {
        this.vector = vector;
        this.rate = rate;
    }

    public static Acceleration operator +(Acceleration other)
    {
        if (other.Vector.Z >= 0)
        {
            return other;
        }
        return new Acceleration(other.Rate, new Vector(other.vector.X, other.Vector.Y, -other.vector.Z));
    }

    public static Acceleration operator -(Acceleration other)
    {
        if (other.Vector.Z <= 0)
        {
            return other;
        }
        return new Acceleration(other.Rate, new Vector(other.vector.X, other.Vector.Y, -other.vector.Z));
    }

    public decimal Rate
    {
        get { return rate; }
    }

    public Vector Vector
    {
        get { return vector; }
    }
}

Itu tidak terlihat seperti operasi yang tidak biasa bagi saya. Dibutuhkan dua argumen (April dan Mei) sehingga akan menjadi biner.
BlueMonkMN

Itu plus biner. Unary plus hanya "+1" atau semacamnya, tanpa operan kiri.
Jeffrey Hantin

salahku. lupa CS101 saya. tetap.
Michael Meadows

3
Jika saya menemukan kelebihan beban semacam itu dalam kode produksi, saya pasti akan menandainya sebagai bug dan memperbaikinya sesegera mungkin. Semantik +bukan untuk membuat nilai menjadi positif, tetapi membiarkan tandanya tidak berubah.
Arturo Torres Sánchez

-1

sederhana yang digunakan untuk meyakinkan angka mana yang positif

misalnya;

int a=10;
System.out.println(+x);// prints 10(that means,that number 10 multiply by +1,{10*+1})

//if we use unary minus

int a=10;
System.out.println(-x);//prints -10(that means,that number 10 multiply by +1,{10*-1})
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.