Kann mir jemand erklären warum zwei int's mit gleichem Wert als gleich angesehen werden aber zwei Zeichenketten mit gleichem Inhalt nicht?
Code:
int i1 = 1;
int i2 = 1;
char z1[] = "Hallo";
char z2[] = "Hallo";
if(i1 == i2) {
printf("i1 und i2 sind gleich\n"); }
if(z1 == z2) {
printf("z1 und z2 sind gleich\n"); }
else {
printf("z1 und z2 sind nicht gleich\n"); }
Ausgabe:
i1 und i2 sind gleich
z1 und z2 sind nicht gleich
Zeichenketten sind Arrays, also Zeiger. Du vergleichst, ob z1 und z2 auf die selbe Speicherstelle zeigen.
Mich wundert es aber, dass die Speicherstellen in deinem Beispiel tatsächlich verschieden ist; eigentlich sollte der Compiler den selben statischen Text nur einmal im Speicher ablegen. Vermutlich ist das aber jedem Compiler frei überlassen?
Wenn der String aber nicht statisch ist, klappt das auf keinen Fall, da dann eben der selbe Text zweimal an verschiedenen Stellen im Speicher liegt. Mit strcmp() kannst du dann den Inhalt der beiden verschiedenen (und den nachfolgenden) Speicherstellen vergleichen.
Also als Beispiel, vielleicht sieht dein Speicher so aus:
Code:
z1 z2
V V
|H|a|l|l|o|\0| | |b|a|0|1|H|a|l||l|o|\0
z1 und z2 zeigen auf verschiedene Stellen (--> z1 != z2), an beiden liegt aber der selbe String.
Deine int Variablen sind hingegen keine Zeiger, also wird hier nicht die Speicherstelle sondern direkt der Inhalt verglichen. Die Variante von den Strings würde also dem entsprechen:
Code:
int a1 = 1;
int a2 = 1;
int *p1 = &a1;
int *p2 = &a2;
if (p1 == p2) { ... } else { ... }
Dann vergleichst du wieder die Speicherstellen der Zahlen.
Danke für die super Erklärung!
Ich hätte noch eine Frage:
Angenommen man erstellt ein Array mit der Größe 5: char hallo[5] = "Hallo";
Hier finden alle Zeichen gerade so Platz. Doch wo findet das '\0' Platz, wenn das Array doch mit 5 Bytes eigentlich voll ist?
Das '\0' wird in dem Fall dann einfach abgeschnitten. Wenn du das Array noch kleiner machst, wird der zu große Teil auch abgeschnitten (und der Compiler gibt eine Warnung aus).
Sowas kann dann natürlich zu ungewolltem Verhalten oder Speicherzugriffsfehler führen, wenn später ein '\0' am Ende erwartet wird (fast alle str* Funktionen erwarten das). Die Funktionen würden den String dann solange weiter ablaufen, bis irgendwann zufällig ein '\0' kommt; und wenn auf Speicher dazwischen aus irgendeinem Grund nicht zugegriffen werden darf, gibt es den Speicherzugriffsfehler.
grundsätzlich solltest du bei deinem Beispiel keine größe angeben, sprich 'char *hallo = "hallo";', da es sich um statischen text handelt kümmert der compiler sich um den Speicher. falls du aber variable größen hast, also z.b. irgend einen text einliest, so kannst und solltest du einfach einen pointer erstellen, sprich char *tmp; dort reinschreiben was du brauchst und nur wenn du das auch außerhalb der Funktion brauchst malloc aufrufen mit der passenden Größe. ein Beispiel:
Code:
void irgendwas(char *etwas){
char *buffer;
char *test = "test";
strcpy(buffer, etwas);
strcmp(buffer, test); //falls die Größe bekannt ist, strncmp nutzen
}
Code:
char *irgendwas(char *etwas){
char *buffer;
//vorausgesetzt, dass etwas ein String ist, also mit '\0' abgeschlossen
int length = strlen(etwas);
buffer = malloc(length*sizeof(char));
strcpy(buffer, etwas);
return buffer;
}
das Beispiel ist eher sinnlos, aber so siehst du mal ungefähr wie man in c mit so etwas umgehen kann. alle str Funktionen die String.h liefert fordern einen gültigen String, wenn du in strlen z.b. einfach ein char array rein gibst ohne '\0' oder mit mehreren '\0', dann stürzt entweder dein Programm ab oder du hast nicht den ganzen teil den du haben wolltest.
für allgemeines byte-kopieren o.ä. gibt es Funktionen wie memcmp, memncmp, memcpy, memncpy,... welche byteweise arbeiten und ignorieren was der Inhalt ist.
Startparameter prüfen 05/14/2012 - C/C++ - 10 Replies Huhu,
ich wolte mein programm überprüfen lassen ob er mit einem bestimmten parameter gestartet wurde. soweit so gut hab ich das halbwegs gemacht, nur funktioniert das nicht gescheit
hoffe um hilfe :)
for(int i = 1; i < argc; i++){
if(argv != "lampe"){
MessageBoxA(0, "Execute the launcher", "Error", MB_ICONERROR);
ExitProcess(1);
}
PSN-Code prüfen 12/21/2011 - Off Topic - 2 Replies Hallo,
ich habe hier vor mir einen PSN-Code liegen aber weiß leider nicht, wofür er ist bzw. welchen Wert er hat.
Weiß einer, wie ich das prüfen kann ohne eine Playstation zu haben?
Thxxx
DLL auf inject prüfen 05/16/2011 - AutoIt - 10 Replies Hi,
ist es irgendwie möglich, ob eine spezielle DLL in einen spezifischen Prozess injected wurde?
Speziell geht es mir um den Hack http://www.elitepvpers.com/forum/wow-exploits-hacks -tools-macros/1005654-wowext-xyz-hack-mit-teleport -features.html und die dazugehörige WExt.dll.
sql-injection prüfen 03/10/2011 - General Coding - 3 Replies hey habe gelesen, wie man prüfen kann, ob eine webseite gegen sqlinjection sicher ist.
da steht man soltle z.b. beim login in der adresszeile z.b. &user=test
einfach schreiben &user=test' also mit nem anführungszeichen.
da aber kaum ne webseite login über get macht habe ich einfach n postrequest gesendet halt auch mit &user=test'
es hieß, dass es wenn die seite nicht gg sqlinjection geschützt ist ein fehler kommen sollte.
habs auf eigener webseite probiert (also auf einer, wo ich in...
Sicherheit prüfen 06/08/2006 - Technical Support - 0 Replies Hallo,
ich habe auf meinem Webblog einen Passwortgeschützten Bereich installiert. Jetzt möchte ich die Sicherheit prüfen und benötige ein Programm, dass per Wordlist nur ein Passwort ausprobiert KEINEN username.
Ich habe nämlich keinen Loginbereich mit username und pass sondern einfach nur ein Passwortfeld.
Hier der Quelltext, hab mal geprüft und keine Passwortsource gefunden. Sicher?
<html> <head>
<title>cursusnovus - Weblog @ myblog.de</title>
<meta http-equiv="Content-Type"...