141 Stimmen

Verborgene Merkmale von C

Ich weiß, dass hinter allen C-Compiler-Implementierungen ein Standard steht, also sollte es keine versteckten Funktionen geben. Trotzdem bin ich sicher, dass alle C-Entwickler versteckte/geheime Tricks haben, die sie ständig anwenden.

0 Stimmen

Es wäre großartig, wenn Sie/jemand die "Frage" bearbeiten würde, um die besten versteckten Funktionen auszuwählen, so wie in den C#- und Perl-Versionen dieser Frage.

115voto

tonylo Punkte 3220

Das ist eher ein Trick des GCC-Compilers, aber Sie können dem Compiler Hinweise auf Verzweigungen geben (im Linux-Kernel üblich)

#define likely(x)       __builtin_expect((x),1)
#define unlikely(x)     __builtin_expect((x),0)

siehe: http://kerneltrap.org/node/4705

Was mir daran gefällt, ist, dass es einigen Funktionen eine gewisse Ausdruckskraft verleiht.

void foo(int arg)
{
     if (unlikely(arg == 0)) {
           do_this();
           return;
     }
     do_that();
     ...
}

77voto

Ben Collins Punkte 20125
int8_t
int16_t
int32_t
uint8_t
uint16_t
uint32_t

Diese sind in der Norm fakultativ, aber es muss sich um ein verstecktes Merkmal handeln, da sie ständig neu definiert werden. Eine Codebasis, an der ich gearbeitet habe (und im Moment immer noch arbeite), hat mehrere Neudefinitionen, alle mit unterschiedlichen Bezeichnern. Meistens geschieht das mit Präprozessormakros:

#define INT16 short
#define INT32  long

Und so weiter. Da möchte ich mir die Haare raufen. Verwenden Sie einfach die verdammten Standard-Integer-Typedefs!

72voto

Ben Collins Punkte 20125

Der Komma-Operator ist nicht weit verbreitet. Er kann sicherlich missbraucht werden, aber er kann auch sehr nützlich sein. Diese Verwendung ist die häufigste:

for (int i=0; i<10; i++, doSomethingElse())
{
  /* whatever */
}

Aber Sie können diesen Operator überall verwenden. Beachten Sie:

int j = (printf("Assigning variable j\n"), getValueFromSomewhere());

Jede Anweisung wird ausgewertet, aber der Wert des Ausdrucks ist derjenige der zuletzt ausgewerteten Anweisung.

63voto

mike511 Punkte 1575

Initialisierung der Struktur auf Null

struct mystruct a = {0};

werden alle Strukturelemente auf Null gesetzt.

62voto

zvrba Punkte 23708

Funktionszeiger. Sie können eine Tabelle mit Funktionszeigern verwenden, um z. B. schnelle Interpreter für indirekt gefädelten Code (FORTH) oder Bytecode-Dispatcher zu implementieren oder um OO-ähnliche virtuelle Methoden zu simulieren.

Dann gibt es noch versteckte Perlen in der Standardbibliothek, wie qsort(), bsearch(), strpbrk(), strcspn() [die beiden letzteren sind nützlich für die Implementierung eines strtok()-Ersatzes].

Ein Manko von C ist, dass ein arithmetischer Überlauf mit Vorzeichen ein undefiniertes Verhalten (UB) ist. Wann immer Sie also einen Ausdruck wie x+y sehen, bei dem es sich um vorzeichenbehaftete Ints handelt, kann es zu einem Überlauf kommen und UB verursachen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X