Tekli artı operatörü ne yapar? Bulduğum birkaç tanım var ( burada ve burada ) ama ne için kullanılacağı konusunda hala hiçbir fikrim yok. Hiçbir şey yapmıyor gibi görünüyor ama bunun bir nedeni var, değil mi?
Yanıtlar:
İhtiyaç duyarsanız, aşırı yüklenmek için orada; önceden tanımlanmış tüm türler için temelde işlemsizdir.
İşlemsiz tekli aritmetik operatörün pratik kullanımları oldukça sınırlıdır ve operatörün kendisinden ziyade aritmetik ifadede bir değer kullanmanın sonuçlarıyla ilgili olma eğilimindedir. Örneğin, daha küçük integral türlerinden genişletmeye zorlamak int
veya bir ifadenin sonucunun bir r değeri olarak değerlendirilmesini ve bu nedenle const
referans olmayan bir parametre ile uyumlu olmamasını sağlamak için kullanılabilir . Bununla birlikte, bu kullanımların golfü kodlamak için okunabilirlikten daha uygun olduğunu bildiriyorum. :-)
int
bir r değerine yükseltmek ve bir r değeriyle sonuçlanmak ifadenin etkileridir -ness, + operatörünün kendisi değil.
Aslında, tekli artı etmez bir şey - bile C. Bu gerçekleştirir zamanki aritmetik dönüşüm işlenen ve döner daha büyük bir genişlikte bir tam sayı olabilir, yeni bir değer. Orijinal değer, işaretsiz tam sayıdan daha küçükse int
, bir signed
değere de değiştirilecektir .
Genellikle bu o kadar önemli değildir, ama olabilir o yüzden, bir etkiye sahip değildir bir tamsayı olumlu olduğunu belirten "comment" bir tür tekli artı kullanmak iyi bir fikirdir. Aşağıdaki C ++ programını düşünün:
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);
}
Bu, "x bir int" gösterecektir.
Yani bu örnekte unary plus, farklı bir tip ve imzalı yeni bir değer yarattı.
an integer of greater width
?
Pozitif değeri negatif bir değerden farklı olarak vurgulamak için netlik için kullanıldığını gördüm:
shift(+1);
shift(-1);
Ama bu oldukça zayıf bir kullanım. Cevap kesinlikle aşırı yüklemedir.
vec3(+1,-1,-1)
Unary + 'nın gerçekleştirdiği en önemli şey, int'ten daha küçük veri türleri için int türüne yükseltmedir. Karakter verilerini std::cout
sayısal veriler olarak yazdırmaya çalışıyorsanız, bu oldukça yararlı olabilir .
char x = 5;
std::cout << +x << "\n";
-den çok farklı
char x=5;
std::cout << x << "\n";
Aynı zamanda aşırı yükleme için de mevcuttur, ancak pratikte aşırı yüklemeniz neredeyse NOP olmalıdır .
Hata ayıklama veya herhangi bir nedenle ham baytların sayısal değerini (örneğin, karakter olarak depolanan küçük sayılar) yazdırmanız gerekirse, unary + yazdırma kodunu basitleştirebilir. Düşünmek
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
Bu sadece hızlı bir örnek. Eminim unary + 'nın baytlarınıza metin yerine sayılar gibi davranılmasına yardımcı olabileceği başka zamanlar da vardır.
Tarihsel bir haber. C99 standardizasyon komitesi ayrıca, tekli artı'nın mevcut kullanımlarının, dilde başka bir özellik elde etmek için yeniden kullanmayı düşünmeleriyle kanıtlandığı üzere oldukça nadir olduğunu düşündü: kayan noktalı sabit ifadelerin çeviri zamanı değerlendirmesinin engellenmesi. C Gerekçesi, bölüm F.7.4'ten aşağıdaki alıntıya bakınız:
Bu belirtimin erken bir sürümü, çeviri-zaman sabiti aritmetiğine izin verdi, ancak bir işlenene uygulandığında, sabit ifadelerin çeviri-zamanı değerlendirmesini engellemek için tekli + işlecini güçlendirdi.
Sonunda, çoğu bağlamda uygulanan çalışma zamanı değerlendirmesi (en azından "sanki" kuralı) ve statik başlatıcıların kullanımıyla çeviri zamanı değerlendirmesini uygulama yeteneği ile anlambilim tersine çevrildi. Ana farkın kayan nokta istisnalarının ortaya çıkmasında ve varsa diğer kayan nokta yuvarlama veya hassas ayarlarda yattığını unutmayın.
Fazla değil. Aşırı yüklenmesini sağlayan genel argüman operator+()
gerçek dünya kullandığı aşırı kesinlikle olmasıdır operator-()
ve bu olurdu çok sen aşırı izin olsaydı garip (veya asimetrik) operator-()
ancak operator+()
.
Bu argümanı ilk önce Stroustrop'tan okuduğuma inanıyorum, ancak kitaplarım yanımda bunu doğrulayacak hakkım yok. Yanlış olabilirim.
Unary plus, kesinlikle hiçbir şey yapmadığı C de mevcuttu ( auto
anahtar kelimeye çok benzer ). Buna sahip olmamak için Stroustrup, C ile gereksiz bir uyumsuzluk getirmek zorunda kalacaktı.
C ++ 'a girdikten sonra, tekli eksi gibi bir aşırı yük fonksiyonuna izin vermek doğaldı ve Stroustrup zaten orada olmasaydı bu nedenle onu tanıtabilirdi.
Yani hiçbir anlamı yok. Eşyaların daha simetrik görünmesini sağlamak için bir tür dekorasyon olarak kullanılabilir, örneğin -1.5'in tersi olarak +1.5 kullanılır. C ++ 'da aşırı yüklenebilir, ancak bir operator+()
şey yaparsa kafa karıştırıcı olacaktır . Standart kuralı hatırlayın: Aritmetik operatörleri aşırı yüklerken, int
s'nin yaptığı gibi şeyler yapın .
Neden orada olduğuna dair bir neden arıyorsanız, C'nin erken tarihi hakkında bir şeyler bulun. C gerçekten tasarlanmadığı için iyi bir neden olmadığından şüpheleniyorum. Yararsız auto
anahtar kelimeyi (muhtemelen static
, şimdi C ++ 0x'de geri dönüştürüldüğünün aksine ) ve entry
hiçbir şey yapmayan (ve daha sonra C90'da ihmal edilen) anahtar kelimeyi düşünün . Ritchie veya Kernighan'ın, operatör önceliğinin sorunları olduğunu fark ettiklerinde, kırmak istemedikleri binlerce kod satırı içeren üç kurulum olduğunu söylediği ünlü bir e-posta var.
entry
: ( stackoverflow.com/q/254395/153285 ). Bu günlerde, birden fazla giriş noktası istiyorsanız, yalnızca kuyruk aramalarını ve profil yönlendirmeli optimizasyonu kullanın.
extern volatile int foo;
bir derleyicinin +foo;
, okumanın gerçekleştiğini belirlemek için herhangi bir yolun var olabileceği herhangi bir platformda belirtilen adresi okuması gerekeceğine inanıyorum. İfade sadece "foo" olsaydı bunun gerekli olacağından emin değilim, ancak birçok derleyici bunu bir nezaket olarak yapacak.
Bunun için herhangi bir kaynak belirtemem, ancak bunun kayıpsız tür dönüşümü anlamına gelen açık tür tanıtımı için olduğunu anlamaya başladım. Bu, onu dönüşüm hiyerarşisinin en üstüne yerleştirir,
new_type operator+(old_type)
new_type(old_type)
operator(new_type)(old_type)
new_type operator=(old_type)
Elbette, bu, yaklaşık 15 yıl önce okuduğum microsoft (gerçekten eski) c / c ++ kılavuzlarından birindeki bir nota ilişkin yorumumdan geliyor, bu yüzden onu biraz tuzla alın.
#include <stdio.h>
int main()
{
unsigned short x = 5;
printf ("%d\n",sizeof(+x));
printf ("%d\n",sizeof(x));
return 0;
}
Yukarıdaki örnekte gösterildiği gibi, tekli + gerçekten sırasıyla tip, boyut 4 ve 2'yi değiştirir. + X ifadesinin gerçekten de sizeof cinsinden hesaplanması tuhaf, bunun olmaması gerektiğini düşündüm. Belki de sizeof'un unary + ile aynı önceliğe sahip olmasından kaynaklanmaktadır.
Sanırım bunu bir sayıyı her zaman pozitif yapmak için kullanabilirsin. Unary + operatörünü abs olması için aşırı yüklemeniz yeterli. Kodunuzu gerçekten karmaşık hale getirmek istemediğiniz sürece, geliştirici arkadaşlarınızın kafasını karıştırmaya değmez. O zaman güzel çalışır.
~
? Sizin "zıt" tanımınızın ne olduğundan emin değilim, ancak bunun, tekli artı ve tekli eksi'nin şu anda ne yaptığına dair deneyimlerle önyargılı olduğundan şüpheleniyorum.
DÜZENLE Tamamen yeniden yazdım, çünkü orijinal cevabımda çok kapalıydım.
Bu, türünüzün açık beyanını pozitif bir değer olarak ele almanıza izin vermelidir (Çoğunlukla matematiksel olmayan işlemlerde düşünüyorum). Görünüşe göre olumsuzlama daha yararlı olacak, ancak sanırım burada bir fark yaratabileceği bir örnek var:
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; }
}
}
+
bir değeri pozitif yapmak değil, işaretini değiştirmeden bırakmaktır.
basitçe hangi sayıların pozitif olduğuna ikna etmek için kullanılan
Örneğin;
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})