Ich weiß nicht, ob Sie es als einen Sinn betrachten würden, aber abs()
auf einen Wert ohne Vorzeichen angewandt kann sicherlich einen anderen Wert als die übergebenen eines zurückzukehren. Das ist, weil abs()
ein int
Argument verwendet und einen int
Wert .
Zum Beispiel:
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
unsigned u1 = 0x98765432;
printf("u1 = 0x%.8X; abs(u1) = 0x%.8X\n", u1, abs(u1));
unsigned long u2 = 0x98765432UL;
printf("u2 = 0x%.16lX; abs(u2) = 0x%.16lX\n", u2, labs(u2));
return 0;
}
Wenn wie C oder C++ kompiliert (mit GCC 4.9.1 auf Mac OS X 10.10.1 Yosemite), es produziert:
u1 = 0x98765432; abs(u1) = 0x6789ABCE
u2 = 0x98765432; abs(u2) = 0x6789ABCDFEDCBA99
Wenn das hohe Bit Wenn der vorzeichenlose Wert gesetzt ist, ist das Ergebnis von abs()
nicht der Wert, der an die Funktion übergeben wurde.
Die Subtraktion ist lediglich eine Ablenkung; Wenn für das Ergebnis das höchstwertige Bit gesetzt ist, unterscheidet sich der von abs()
zurückgegebene Wert von dem an ihn übergebenen Wert.
Wenn Sie diesen Code mit C++ Header kompilieren, anstelle der C-Header in der Frage gezeigt, dann scheitert es mit mehrdeutigen Aufruf Fehler zu kompilieren:
#include <cstdlib>
#include <iostream>
using namespace std;
int main(void)
{
unsigned u1 = 0x98765432;
cout << "u1 = 0x" << hex << u1 << "; abs(u1) = 0x" << hex << abs(u1) << "\n";
unsigned long u2 = 0x98765432UL;
cout << "u2 = 0x" << hex << u2 << "; abs(u2) = 0x" << hex << abs(u2) << "\n";
return 0;
}
Compilation Fehler:
absuns2.cpp: In function ‘int main()’:
absuns2.cpp:8:72: error: call of overloaded ‘abs(unsigned int&)’ is ambiguous
cout << "u1 = 0x" << hex << u1 << "; abs(u1) = 0x" << hex << abs(u1) << "\n";
^
absuns2.cpp:8:72: note: candidates are:
In file included from /usr/gcc/v4.9.1/include/c++/4.9.1/cstdlib:72:0,
from absuns2.cpp:1:
/usr/include/stdlib.h:129:6: note: int abs(int)
int abs(int) __pure2;
^
In file included from absuns2.cpp:1:0:
/usr/gcc/v4.9.1/include/c++/4.9.1/cstdlib:174:3: note: long long int std::abs(long long int)
abs(long long __x) { return __builtin_llabs (__x); }
^
/usr/gcc/v4.9.1/include/c++/4.9.1/cstdlib:166:3: note: long int std::abs(long int)
abs(long __i) { return __builtin_labs(__i); }
^
absuns2.cpp:10:72: error: call of overloaded ‘abs(long unsigned int&)’ is ambiguous
cout << "u2 = 0x" << hex << u2 << "; abs(u2) = 0x" << hex << abs(u2) << "\n";
^
absuns2.cpp:10:72: note: candidates are:
In file included from /usr/gcc/v4.9.1/include/c++/4.9.1/cstdlib:72:0,
from absuns2.cpp:1:
/usr/include/stdlib.h:129:6: note: int abs(int)
int abs(int) __pure2;
^
In file included from absuns2.cpp:1:0:
/usr/gcc/v4.9.1/include/c++/4.9.1/cstdlib:174:3: note: long long int std::abs(long long int)
abs(long long __x) { return __builtin_llabs (__x); }
^
/usr/gcc/v4.9.1/include/c++/4.9.1/cstdlib:166:3: note: long int std::abs(long int)
abs(long __i) { return __builtin_labs(__i); }
^
Also, der Code in der Frage kompiliert nur, wenn nur die C-style-Header verwendet werden; Es kompiliert nicht, wenn die C++ - Header verwendet werden. Wenn Sie <stdlib.h>
sowie <cstdlib>
hinzufügen, gibt es eine zusätzliche Überladung verfügbar, um die Aufrufe mehrdeutig zu machen.
Sie können den Code kompiliert werden, wenn Sie den Aufforderungen abs()
, und der absolute Wert einer signierten Menge (in) geeignete Abgüsse hinzufügen können vom Original unterzeichnet Menge unterschiedlich sein, die kaum überraschende Nachricht ist:
#include <cstdlib>
#include <iostream>
using namespace std;
int main(void)
{
unsigned u1 = 0x98765432;
cout << "u1 = 0x" << hex << u1 << "; abs(u1) = 0x" << hex << abs(static_cast<int>(u1)) << "\n";
unsigned long u2 = 0x98765432UL;
cout << "u2 = 0x" << hex << u2 << "; abs(u2) = 0x" << hex << abs(static_cast<long>(u2)) << "\n";
return 0;
}
Output:
u1 = 0x98765432; abs(u1) = 0x6789abce
u2 = 0x98765432; abs(u2) = 0x6789abcdfedcba99
Moralische: verwenden Sie die C-Headern nicht für die es C++ Äquivalente in C++ Code; Verwenden Sie stattdessen die C++ - Header.
Da die Werte nicht vorzeichenbehaftet sind, können sie nicht negativ sein, daher ist der Aufruf 'abs() 'nicht sinnvoll. "Abs()" ist jedoch in C++ überladen und könnte auch ein Makro sein, also ist es für mich nicht 100% klar. Es könnte sogar eine Funktion sein, die 'signed long' nimmt, was dann etwas abhängig vom MSB des Arguments macht. Was ist der Grund, den absoluten Wert von etwas zu nehmen, das nicht negativ sein kann? Wenn es keine gibt, entfernen Sie einfach den 'abs()' Anruf. –
Die mögliche Umwandlung von unsigned in int, die den Wert nicht darstellen kann, ist ein nicht definiertes Verhalten. Diese Umwandlung ist auch der einzige Fall, in dem diese Bauchmuskeln einen Unterschied machen würden. –
@UlrichEckhardt Wenn 'a = 10UL;' und 'b = 30UL;', sollte die richtige Antwort '20UL' sein, aber die 'abs' zu fallen würde mir die falsche Antwort geben. –