Advertisement
Scroll to top
Read Time: 16 min

() translation by (you can also view the original English article)

Bitweise Operatoren sind solche seltsam aussehenden Operatoren, die schwer zu verstehen sind... aber nicht mehr! Dieser leicht verständliche Artikel hilft Ihnen zu verstehen, was sie sind und wie man sie verwendet. Er enthält auch einige praktische Beispiele, die Ihnen zeigen, wann und warum Sie sie benötigen.


Einführung

Bitweise Operatoren sind Operatoren (genau wie +, *, && usw.), die mit ints und uints auf Binärebene arbeiten. Dies bedeutet, dass sie direkt auf die Binärziffern oder Bits einer Ganzzahl schauen. Das klingt alles beängstigend, aber in Wahrheit sind bitweise Operatoren recht einfach zu bedienen und auch sehr nützlich!

Es ist jedoch wichtig, dass Sie sich mit Binärzahlen und Hexadezimalzahlen auskennen. Wenn Sie dies nicht tun, lesen Sie bitte diesen Artikel - er wird Ihnen wirklich helfen! Im Folgenden finden Sie eine kleine Anwendung, mit der Sie die verschiedenen bitweisen Operatoren ausprobieren können.

Machen Sie sich keine Sorgen, wenn Sie noch nicht verstehen, was los ist, wird bald alles klar sein...


Erkennen der bitweisen Operatoren

Werfen wir einen Blick auf die bitweisen Operatoren, die AS3 bereitstellt. Viele andere Sprachen sind ziemlich ähnlich (zum Beispiel haben JavaScript und Java praktisch identische Operatoren):

  • & (bitweises UND)
  • | (bitweises ODER)
  • ~ (bitweise NICHT)
  • ^ (bitweises XOR)
  • << (bitweise Linksverschiebung)
  • >> (bitweise Rechtsverschiebung)
  • >>> (bitweise vorzeichenlose Rechtsverschiebung)
  • &= (bitweise UND-Zuordnung)
  • |= (bitweise ODER-Zuordnung)
  • ^= (bitweise XOR-Zuweisung)
  • <<= (bitweise Linksverschiebung und Zuordnung)
  • >>= (bitweise Rechtsverschiebung und Zuordnung)
  • >>>= (bitweise vorzeichenlose Rechtsverschiebung und Zuordnung)

Es gibt ein paar Dinge, die Sie daraus ziehen sollten: Erstens sehen einige bitweise Operatoren den zuvor verwendeten Operatoren ähnlich (& vs. &&, | vs. ||). Dies liegt daran, dass sie etwas ähnlich sind.

Zweitens haben die meisten bitweisen Operatoren eine zusammengesetzte Zuweisungsform für sich. Dies entspricht der Verwendung von + und +=, - und -= usw.


Der & Operator

Zuerst oben: der bitweise AND-Operator &. Ein kurzes Heads-up: Normalerweise belegen ints und uints 4 Bytes oder 32 Bit Speicherplatz. Dies bedeutet, dass jedes int oder uint als 32 Binärziffern gespeichert ist. In diesem Tutorial werden wir manchmal so tun, als ob ints und uints nur 1 Byte belegen und nur 8 Binärziffern haben.

Der Operator & vergleicht jede Binärziffer von zwei Ganzzahlen und gibt eine neue Ganzzahl mit einer 1 zurück, wenn beide Zahlen irgendwo anders eine 1 und eine 0 hatten. Ein Diagramm sagt mehr als tausend Worte. Hier ist eines, um die Dinge zu klären. Es repräsentiert 37 & 23, was 5 entspricht.

Bitwise And operator example

Beachten Sie, wie jede Binärziffer von 37 und 23 verglichen wird und das Ergebnis eine 1 hat, wo immer 37 und 23 eine 1 hatten, und das Ergebnis ansonsten eine 0 hat.

Eine übliche Art, über Binärziffern nachzudenken, ist true oder false. Das heißt, 1 ist gleichbedeutend mit true und 0 ist gleichbedeutend mit false. Dies macht den Operator & sinnvoller.

Wenn wir zwei Boolesche Werte vergleichen, machen wir normalerweise boolean1 && boolean2. Dieser Ausdruck ist nur wahr, wenn sowohl boolean1 als auch boolean2 wahr sind. Auf die gleiche Weise sind integer1 & integer2 äquivalent, da der Operator & nur dann eine 1 ausgibt, wenn beide Binärziffern unserer beiden Ganzzahlen 1 sind.

Hier ist eine Tabelle, die diese Idee darstellt:

Bitwise AND table

Eine nette kleine Verwendung des Operators & besteht darin, zu überprüfen, ob eine Zahl gerade oder ungerade ist. Für ganze Zahlen können wir einfach das Bit ganz rechts (auch als niedrigstwertiges Bit bezeichnet) überprüfen, um festzustellen, ob die ganze Zahl ungerade oder gerade ist. Dies liegt daran, dass bei der Konvertierung in Basis 10 das Bit ganz rechts 20 oder 1 darstellt. Wenn das Bit ganz rechts 1 ist, wissen wir, dass unsere Zahl ungerade ist, da wir 1 zu einem Bündel von Zweierpotenzen hinzufügen, die immer gerade sind. Wenn das Bit ganz rechts 0 ist, wissen wir, dass unsere Zahl gerade ist, da es einfach darin besteht, eine Reihe von geraden Zahlen zu addieren.

Hier ist ein Beispiel:

1
var randInt:int = int(Math.random()*1000);
2
if(randInt & 1)
3
{
4
	trace("Odd number.");
5
}
6
else
7
{
8
	trace("Even number.");
9
}

Auf meinem Computer war diese Methode etwa 66% schneller als die Verwendung von randInt % 2, um nach geraden und ungeraden Zahlen zu suchen. Das ist ein ziemlicher Leistungsschub!


Die | Operator

Als nächstes folgt der bitweise ODER-Operator |. Wie Sie vielleicht erraten haben, ist die | Operator ist zum || Operator als & Operator ist für den Operator &&. Die | Der Operator vergleicht jede Binärziffer über zwei Ganzzahlen und gibt eine 1 zurück, wenn eine von beiden 1 ist. Auch dies ist ähnlich wie bei || Operator mit Booleschen Werten.

Bitwise OR table

Schauen wir uns das gleiche Beispiel wie zuvor an, außer dass wir jetzt das | verwenden Operator anstelle des Operators &. Wir machen jetzt 37 | 23, was 55 entspricht:

Bitwise OR tableBitwise OR tableBitwise OR table

Flags: Eine Verwendung der & und | Betreiber

Wir können das & und | nutzen Operatoren, damit wir mehrere Optionen an eine Funktion in einem einzigen int übergeben können.

Schauen wir uns eine mögliche Situation an. Wir erstellen eine Popup-Fensterklasse. Am Ende können wir eine Schaltfläche Ja, Nein, Okay oder Abbrechen oder eine beliebige Kombination davon haben - wie sollen wir das tun? Hier ist der harte Weg:

1
public class PopupWindow extends Sprite
2
{
3
	// Variables, Constructor, etc...

4
5
6
	public static void showPopup(yesButton:Boolean, noButton:Boolean, okayButton:Boolean, cancelButton:Boolean)
7
	{
8
		if(yesButton)
9
		{
10
			// add YES button

11
		}
12
		
13
		if(noButton)
14
		{
15
			// add NO Button

16
		}
17
		// and so on for the rest of the buttons

18
	}
19
}

Ist das schrecklich? Nein. Wenn Sie Programmierer sind, ist es jedoch schlecht, bei jedem Aufruf der Funktion die Reihenfolge der Argumente nachschlagen zu müssen. Es ist auch ärgerlich - wenn Sie beispielsweise nur die Schaltfläche Abbrechen anzeigen möchten, müssen Sie alle anderen Booleans Werte auf false setzen.

Verwenden wir das, was wir über & und | gelernt haben um eine bessere Lösung zu finden:

1
public class PopupWindow extends Sprite
2
{
3
	public static const YES:int = 1;
4
	public static const NO:int = 2;
5
	public static const OKAY:int = 4;
6
	public static const CANCEL:int = 8;
7
8
	public static void showPopup(buttons:int)
9
	{
10
		if(buttons & YES)
11
		{
12
			// add YES button

13
		}
14
		
15
		if(buttons & NO)
16
		{
17
			// add NO button

18
		}	
19
	}
20
}

Wie würde ein Programmierer die Funktion aufrufen, damit die Tasten Ja, Nein und Abbrechen angezeigt werden? So was:

1
PopupWindow.show(PopupWindow.YES | PopupWindow.NO | PopupWindow.CANCEL);

Was ist los? Es ist wichtig zu beachten, dass unsere Konstanten im zweiten Beispiel alle Zweierpotenzen sind. Wenn wir uns also ihre binären Formen ansehen, werden wir feststellen, dass sie alle eine Ziffer gleich 1 und der Rest gleich 0 haben. Tatsächlich haben sie jeweils eine andere Ziffer gleich 1. Dies bedeutet, dass unabhängig davon, wie wir sie mit | kombinieren, jede Kombination eine eindeutige Nummer ergibt. Anders betrachtet, Ergebnis unserer | Anweisung wird eine Binärzahl mit einer 1 sein, wo immer unsere Optionen eine 1 hatten.

Für unser aktuelles Beispiel haben wir PopupWindow.YES | PopupWindow.NO | PopupWindow.CANCEL entspricht 1 | 2 | 8, die binär umgeschrieben ist, ist 00000001 | 00000010 | 00001000, was uns ein Ergebnis von 00001011 gibt.

In unserer Funktion showPopup() überprüfen wir nun mit &, welche Optionen übergeben wurden. Wenn wir beispielsweise die buttons & YES aktivieren, sind alle Bits in YES gleich 0, mit Ausnahme der am weitesten rechts stehenden. Wir prüfen also im Wesentlichen, ob das Bit ganz rechts in den Schaltflächen eine 1 ist oder nicht. Wenn dies der Fall ist, sind die buttons & YES nicht gleich 0, und alles in der if-Anweisung wird ausgeführt. Wenn umgekehrt das Bit ganz rechts in den Schaltflächen 0 ist, sind die buttons & YES gleich 0, und die if-Anweisung wird nicht ausgeführt.


Der ~ Operator

Der bitweise NOT-Operator unterscheidet sich geringfügig von den beiden bisher betrachteten. Anstatt auf jeder Seite eine Ganzzahl zu verwenden, wird erst danach eine Ganzzahl verwendet. Das ist genau wie das! Operator, und es überrascht nicht, dass es eine ähnliche Sache macht. In der Tat genauso! kippt einen Booleschen Wert von true nach false oder umgekehrt, der Operator ~ kehrt jede Binärziffer in einer Ganzzahl um: von 0 nach 1 und von 1 nach 0:

Bitwise OR table

Ein kurzes Beispiel. Angenommen, wir haben die Ganzzahl 37 oder 00100101. ~37 ist dann 11011010. Was ist der Basiswert 10 davon? Gut...


Two's Complement, uint vs. int und mehr!

Jetzt beginnt der Spaß! Wir werden uns die Binärzahlen auf einem Computer genauer ansehen. Beginnen wir mit der uint. Wie bereits erwähnt, ist ein uint normalerweise 4 Byte oder 32 Bit lang, was bedeutet, dass es 32 Binärziffern hat. Dies ist leicht zu verstehen: Um den Basis-10-Wert zu erhalten, konvertieren wir die Zahl einfach regelmäßig in Basis-10. Wir werden immer eine positive Zahl bekommen.

Aber wie wäre es mit dem int? Es werden auch 32 Bit verwendet, aber wie werden negative Zahlen gespeichert? Wenn Sie vermutet haben, dass die erste Ziffer zum Speichern des Zeichens verwendet wird, sind Sie auf dem richtigen Weg. Werfen wir einen Blick auf das Komplementsystem der beiden zum Speichern von Binärzahlen. Obwohl wir hier nicht auf alle Details eingehen werden, wird ein Zweierkomplementsystem verwendet, da es die binäre Arithmetik vereinfacht.

Um das Zweierkomplement einer Binärzahl zu finden, drehen wir einfach alle Bits um (d. h. Tun, was der Operator ~ tut) und addieren eins zum Ergebnis. Probieren wir das einmal aus:

Two's Complement of 37

Wir definieren unser Ergebnis dann als den Wert -37. Warum diesen komplizierten Prozess machen und nicht einfach das erste Bit umdrehen und das -37 nennen?

Nehmen wir einen einfachen Ausdruck 37 + -37. Wir alle wissen, dass dies gleich 0 sein sollte, und wenn wir die 37 zum Zweierkomplement addieren, erhalten wir Folgendes:

37 + -37 in binary

Beachten Sie, dass unsere Ganzzahlen nur acht Binärziffern enthalten, die 1 in unserem Ergebnis gelöscht wird und wir am Ende 0 haben, wie wir sollten.

Um es noch einmal zusammenzufassen, um das Negativ einer Zahl zu finden, nehmen wir einfach das Zweierkomplement. Wir können dies tun, indem wir alle Bits invertieren und eins hinzufügen.

Möchten Sie dies selbst versuchen? Hinzufügen trace(~37+1); in eine AS3-Datei, kompilieren Sie sie und führen Sie sie aus. Sie werden sehen, dass -37 gedruckt wird, wie es sein sollte.

Es gibt auch eine kleine Verknüpfung, um dies von Hand zu tun: Arbeiten Sie von rechts nach links, bis Sie eine 1 erreichen. Drehen Sie alle Bits links von dieser ersten 1.

Two's Complement of 37 Shortcut

Wenn wir eine vorzeichenbehaftete Binärzahl betrachten (mit anderen Worten, eine, die negativ sein kann, ein int kein uint), können wir anhand der am weitesten links stehenden Ziffer feststellen, ob sie negativ oder positiv ist. Wenn es eine 0 ist, ist die Zahl positiv und wir können in Basis 10 konvertieren, indem wir einfach ihren Basis 10-Wert berechnen. Wenn das Bit ganz links eine 1 ist, ist die Zahl negativ, also nehmen wir das Zweierkomplement der Zahl, um ihren positiven Wert zu erhalten, und fügen dann einfach ein negatives Vorzeichen hinzu.

Wenn wir beispielsweise 11110010 haben, wissen wir, dass es sich um eine negative Zahl handelt. Wir können das Zweierkomplement finden, indem wir alle Ziffern links von der am weitesten rechts stehenden 1 umdrehen und 00001110 erhalten. Dies entspricht 13, sodass wir wissen, dass 11110010 gleich -13 ist.


Der ^ Operator

Wir kehren zu den bitweisen Operatoren zurück, und als nächstes folgt der bitweise XOR-Operator. Es gibt keinen äquivalenten booleschen Operator zu diesem.

Der Operator ^ ähnelt dem Operator & und | Operatoren, dass es auf beiden Seiten ein int oder uint braucht. Bei der Berechnung der resultierenden Zahl werden die Binärziffern dieser Zahlen erneut verglichen. Wenn das eine oder das andere eine 1 ist, wird eine 1 in das Ergebnis eingefügt, andernfalls wird eine 0 eingefügt. Hier kommt der Name XOR oder "exklusiv oder" her.

Bitwise XOR table

Schauen wir uns unser übliches Beispiel an:

Bitwise XOR exampleBitwise XOR exampleBitwise XOR example

Der Operator ^ hat Verwendungszwecke - er eignet sich besonders zum Umschalten von Binärziffern -, aber wir werden in diesem Artikel keine praktischen Anwendungen behandeln.


Der << Operator

Wir sind jetzt bei den Bitverschiebungsoperatoren, speziell bei der bitweisen Linksverschiebungsoperator hier.

Diese funktionieren etwas anders als zuvor. Anstatt zwei Ganzzahlen wie &, | und ^ zu vergleichen, verschieben diese Operatoren eine Ganzzahl. Auf der linken Seite des Operators befindet sich die Ganzzahl, die verschoben wird, und auf der rechten Seite wird angegeben, um wie viel verschoben werden soll. So verschiebt beispielsweise 37 << 3 die Zahl 37 um 3 Stellen nach links. Natürlich arbeiten wir mit der binären Darstellung von 37.

Schauen wir uns dieses Beispiel an (denken Sie daran, wir werden nur so tun, als hätten ganze Zahlen nur 8 statt 32 Bits). Hier haben wir die Nummer 37, die auf ihrem schönen Speicherblock sitzt, der 8 Bit breit ist.

Bitwise Left Shift exampleBitwise Left Shift exampleBitwise Left Shift example

Okay, lassen Sie uns alle Ziffern um 3 nach links verschieben, wie es 37 << 3 tun würde:

Bitwise Left Shift exampleBitwise Left Shift exampleBitwise Left Shift example

Aber jetzt haben wir ein kleines Problem - was machen wir mit den 3 offenen Speicherbits, aus denen wir die Ziffern verschoben haben?

Bitwise Left Shift exampleBitwise Left Shift exampleBitwise Left Shift example

Natürlich! Alle leeren Stellen werden nur durch Nullen ersetzt. Am Ende haben wir 00101000. Und das ist alles, was es auf der linken Seite gibt. Denken Sie daran, dass Flash immer denkt, das Ergebnis einer linken Bitverschiebung sei ein int, kein uint. Wenn Sie also aus irgendeinem Grund eine uint benötigen, müssen Sie sie in eine uint wie diese umwandeln: uint(37 << 3). Dieses Casting ändert keine der binären Informationen, nur wie Flash sie interpretiert (die komplementäre Sache der beiden).

Ein interessantes Merkmal der linken Bitverschiebung ist, dass es dasselbe ist wie das Multiplizieren einer Zahl mit zwei mit der VerschiebungAmount-ten Potenz. Also, 37 << 3 == 37 * Math.pow(2,3) == 37 * 8. Wenn Sie die Linksverschiebung anstelle von Math.pow verwenden können, werden Sie eine enorme Leistungssteigerung sehen.

Möglicherweise haben Sie bemerkt, dass die Binärzahl, mit der wir endeten, nicht gleich 37 * 8 war. Dies liegt nur daran, dass wir nur 8 Bit Speicher für Ganzzahlen verwenden. Wenn Sie es in ActionScript versuchen, erhalten Sie das richtige Ergebnis. Oder probieren Sie es mit der Demo oben auf der Seite!


Der >> Operator

Nachdem wir die linke Bitverschiebung verstanden haben, wird die nächste, die rechte Bitverschiebung, einfach sein. Alles wird nach rechts verschoben, um den von uns angegebenen Betrag zu ermitteln. Der einzige kleine Unterschied besteht darin, womit die leeren Teile gefüllt werden.

Wenn wir mit einer negativen Zahl beginnen (eine Binärzahl, bei der das Bit ganz links eine 1 ist), werden alle leeren Stellen mit einer 1 gefüllt. Wenn wir mit einer positiven Zahl beginnen (wobei das Bit ganz links oder die höchstwertige Zahl ist) Bit, ist eine 0), dann werden alle leeren Räume mit einer 0 gefüllt. Auch dies geht alles auf das Zweierkomplement zurück.

Das klingt zwar kompliziert, behält aber im Grunde nur das Vorzeichen der Zahl bei, mit der wir beginnen. Also -8 >> 2 == -2, während 8 >> 2 == 2. Ich würde empfehlen, diese selbst auf Papier auszuprobieren.

Da >> das Gegenteil von << ist, ist es nicht überraschend, dass das Verschieben einer Zahl nach rechts dasselbe ist wie das Teilen durch 2 durch die Potenz von shiftAmount. Möglicherweise haben Sie dies anhand des obigen Beispiels bemerkt. Wenn Sie dies verwenden können, um das Aufrufen von Math.pow zu vermeiden, erhalten Sie eine erhebliche Leistungssteigerung.


Der >>> Operator

Unser letzter bitweiser Operator ist die bitweise vorzeichenlose Rechtsverschiebung. Dies ist der regulären bitweisen Rechtsverschiebung sehr ähnlich, außer dass alle leeren Bits auf der linken Seite mit Nullen gefüllt sind. Dies bedeutet, dass das Ergebnis dieses Operators immer eine positive Ganzzahl ist und die zu verschiebende Ganzzahl immer als vorzeichenlose Ganzzahl behandelt wird. Wir werden in diesem Abschnitt kein Beispiel dafür durchgehen, aber wir werden in Kürze eine Verwendung dafür sehen.


Verwenden von bitweisen Operatoren zum Arbeiten mit Farben

Eine der praktischsten Anwendungen von bitweisen Operatoren in Actionscript 3 ist die Arbeit mit Farben, die normalerweise als uints gespeichert werden.

Das Standardformat für Farben besteht darin, sie hexadezimal zu schreiben: 0xAARRGGBB - jeder Buchstabe steht für eine hexadezimale Ziffer. Hier repräsentieren die ersten beiden hexadezimalen Ziffern, die den ersten acht Binärziffern entsprechen, unser Alpha oder unsere Transparenz. Die nächsten acht Bits repräsentieren die Menge an Rot in unserer Farbe (also eine ganze Zahl von 0 bis 255), die nächsten acht die Menge an Grün und die letzten acht die Menge an Blau in unserer Farbe.

Ohne bitweise Operatoren ist es extrem schwierig, mit Farben in diesem Format zu arbeiten - aber mit ihnen ist es einfach!

Herausforderung 1: Ermitteln der Blaumenge in einer Farbe: Versuchen Sie mit dem Operator &, die Blaumenge in einer beliebigen Farbe zu ermitteln.

1
public function findBlueComponent(color:uint):uint
2
{
3
	// Your code here!

4
}

Wir brauchen eine Möglichkeit, alle anderen Daten in color zu löschen oder zu maskieren und nur die blaue Komponente übrig zu haben. Das ist eigentlich einfach! Wenn wir color & 0x000000FF - oder einfacher gesagt color & 0xFF - nehmen, erhalten wir nur die blaue Komponente.

Bitwise Left Shift exampleBitwise Left Shift exampleBitwise Left Shift example

Wie Sie von oben sehen und in der Beschreibung des Operators & erfahren haben, ist jede Binärziffer & 0 immer gleich 0, während jede Binärziffer & 1 ihren Wert behält. Wenn wir also unsere Farbe mit 0xFF maskieren, das nur 1s hat, wo sich die blaue Komponente unserer Farbe befindet, erhalten wir nur die blaue Komponente.

Herausforderung 2: Ermitteln der Rotmenge in einer Farbe: Versuchen Sie mit zwei bitweisen Operatoren, die Rotmenge in einer beliebigen Farbe zu ermitteln.

1
public function findRedComponent(color:uint):uint
2
{
3
	// Your code here!

4
}

Wir haben tatsächlich zwei Lösungen für dieses Problem. Eine wäre return (color & 0xFF0000) >> 16; und der andere wäre return (color >> 16) & 0xFF;

Dies ist Herausforderung 1 sehr ähnlich, außer dass wir unsere Antwort irgendwann ändern müssen.

Herausforderung 3: Ermitteln der Transparenz einer Farbe: Versuchen Sie mit nur einem bitweisen Operator, das Alpha einer Farbe zu ermitteln (eine Ganzzahl von 0 bis 255).

1
public function findAlphaComponent(color:uint):uint
2
{
3
	// Your code here!

4
}

Dieser ist ein bisschen kniffliger. Wir müssen vorsichtig sein, mit welchem Rechtsschichtbetreiber wir uns entscheiden. Da wir mit den am weitesten links stehenden Ziffern einer uint arbeiten, möchten wir den Operator >>> verwenden. Unsere Antwort lautet also einfach return color >>> 24;.

Letzte Herausforderung: Erstellen Sie eine Farbe aus ihren Komponenten: Verwenden Sie die << und | Operatoren, nehmen Sie die Komponenten einer Farbe und führen Sie sie zu einer uint zusammen.

1
public function createColor(a:uint, r:uint, g:uint, b:uint):uint
2
{
3
	// Your code here!

4
}

Hier müssen wir jede Komponente an ihre richtige Position verschieben und sie dann zusammenführen. Wir möchten, dass Flash es als vorzeichenlose Ganzzahl behandelt, also wandeln wir es in eine uint: return uint((a << 24) | (r << 16) | (g << 8) | b);


Zusammengesetzte Operatoren

Sie haben vielleicht bemerkt, dass ich es versäumt habe, die zusammengesetzten bitweisen Operatoren zu erklären. Stellen Sie sich vor, wir haben eine ganze Zahl x. Dann ist x = x & 0xFF dasselbe wie x &= 0xFF, x = x | 256 ist dasselbe wie x |= 256 und so weiter für den Rest der zusammengesetzten Operatoren.


Abschluss

Vielen Dank für das Lesen dieses Artikels! Ich hoffe, Sie verstehen jetzt bitweise Operatoren und können sie in Ihrem AS3-Code (oder in vielen anderen Sprachen!) Verwenden. Wie immer, wenn Sie Fragen oder Kommentare haben, lassen Sie diese bitte unten.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.