Top-Themen

Aktuelle Themen (A bis Z)

Administrator.de FeedbackApache ServerAppleAssemblerAudioAusbildungAuslandBackupBasicBatch & ShellBenchmarksBibliotheken & ToolkitsBlogsCloud-DiensteClusterCMSCPU, RAM, MainboardsCSSC und C++DatenbankenDatenschutzDebianDigitiales FernsehenDNSDrucker und ScannerDSL, VDSLE-BooksE-BusinessE-MailEntwicklungErkennung und -AbwehrExchange ServerFestplatten, SSD, RaidFirewallFlatratesGoogle AndroidGrafikGrafikkarten & MonitoreGroupwareHardwareHosting & HousingHTMLHumor (lol)Hyper-VIconsIDE & EditorenInformationsdiensteInstallationInstant MessagingInternetInternet DomäneniOSISDN & AnaloganschlüsseiTunesJavaJavaScriptKiXtartKVMLAN, WAN, WirelessLinuxLinux DesktopLinux NetzwerkLinux ToolsLinux UserverwaltungLizenzierungMac OS XMicrosoftMicrosoft OfficeMikroTik RouterOSMonitoringMultimediaMultimedia & ZubehörNetzwerkeNetzwerkgrundlagenNetzwerkmanagementNetzwerkprotokolleNotebook & ZubehörNovell NetwareOff TopicOpenOffice, LibreOfficeOutlook & MailPapierkorbPascal und DelphiPeripheriegerätePerlPHPPythonRechtliche FragenRedHat, CentOS, FedoraRouter & RoutingSambaSAN, NAS, DASSchriftartenSchulung & TrainingSEOServerServer-HardwareSicherheitSicherheits-ToolsSicherheitsgrundlagenSolarisSonstige SystemeSoziale NetzwerkeSpeicherkartenStudentenjobs & PraktikumSuche ProjektpartnerSuseSwitche und HubsTipps & TricksTK-Netze & GeräteUbuntuUMTS, EDGE & GPRSUtilitiesVB for ApplicationsVerschlüsselung & ZertifikateVideo & StreamingViren und TrojanerVirtualisierungVisual StudioVmwareVoice over IPWebbrowserWebentwicklungWeiterbildungWindows 7Windows 8Windows 10Windows InstallationWindows MobileWindows NetzwerkWindows ServerWindows SystemdateienWindows ToolsWindows UpdateWindows UserverwaltungWindows VistaWindows XPXenserverXMLZusammenarbeit

C++ Problem mit Pointer

Mitglied: Maik87

Maik87 (Level 2) - Jetzt verbinden

21.07.2014, aktualisiert 13:02 Uhr, 1422 Aufrufe, 5 Kommentare, 2 Danke

Hallo zusammen,

C++ ist lange bei mir her - die Pointer ebenfalls.

Dennoch versuche ich mich gerade wieder einzuarbeiten und stoße auf folgendes Problem:

01.
typedef union union_bitfeld 
02.
03.
    unsigned char value; 
04.
    struct bitfeld_4 
05.
06.
        unsigned int bit00 : 1; 
07.
        unsigned int bit01 : 1; 
08.
        unsigned int bit02 : 1; 
09.
        unsigned int bit03 : 1; 
10.
    } bitfeld; 
11.
} ubf4; 
12.
 
13.
 
14.
ubf4 test; 
15.
test.value = 123; 
16.
 
17.
 
18.
printf("%d" ,test.value);
Läuft soweit.

Erweitert um:
01.
ubf4 *pTest; 
02.
pTest= &test; 
03.
 
04.
printf("%d" ,*pTest.value);
läuft es nicht mehr!

Was mache ich in der letzten Zeile falsch?

Mitglied: Maik87
21.07.2014, aktualisiert um 13:21 Uhr
Wer googlen kann ist klar im Vorteil:

01.
printf("%d" ,*pTest->value);
Läuft!

Ist es nun noch möglich, die einzelnen bitxx mit einer Schleife zu durchlaufen?
Quasi so etwas:
01.
for(int i = 0; i<4; i++{ 
02.
  printf("%d" ,*pTest->bit0i); 
03.
}
Bitte warten ..
Mitglied: rubberman
21.07.2014, aktualisiert um 22:27 Uhr
Hallo Maik87,

es besteht ein Ungleichgewicht in deiner union zwischen value (8 Bit breit) und struct bitfeld_4 (4 Bit breit oder auch nicht, siehe übernächsten Satz). Das heißt, ein Wert von 123 in value lässt sich nicht mehr in deinem struct abbilden (bei 15 ist Schluss). Darüber hinaus erzeugen Bitfelder in einer union laut Standard undefiniertes Verhalten. Anders gesagt, unter Windows scheint es zu funktionieren (weil die Implementierung es zulässt), auf anderen Betriebssystemen kann das ganz anders aussehen und du darfst dich nicht darauf verlassen, dass Microsoft diese Implementierung nicht irgendwann ändert.

Ist es nun noch möglich, die einzelnen bitxx mit einer Schleife zu durchlaufen?
Nein. Die Kurzerklärung: Nach dem Compilieren gibt es keine Variablennamen mehr.
Du kannst aber durchaus mit bitweisen Operatoren arbeiten. In diesem Fall Shift Right (>>) und Bitweises Und (&).

01.
#include <stdio.h> 
02.
 
03.
typedef union union_bitfeld 
04.
05.
    unsigned char value; 
06.
    struct bitfeld_4 
07.
08.
        unsigned int bit00 : 1; 
09.
        unsigned int bit01 : 1; 
10.
        unsigned int bit02 : 1; 
11.
        unsigned int bit03 : 1; 
12.
    } bitfeld; 
13.
} ubf4; 
14.
 
15.
int main() 
16.
17.
  ubf4 test = {0}; 
18.
  ubf4 *pTest = NULL; 
19.
  int i = 0; 
20.
 
21.
  test.value = 7; 
22.
  pTest = &test; 
23.
 
24.
  printf("%u\n", test.value); 
25.
  printf("%u\n\n", pTest->value); 
26.
 
27.
  printf("%u\n", pTest->bitfeld.bit00); 
28.
  printf("%u\n", pTest->bitfeld.bit01); 
29.
  printf("%u\n", pTest->bitfeld.bit02); 
30.
  printf("%u\n\n", pTest->bitfeld.bit03); 
31.
 
32.
  for (i = 0; i < 4; ++i) 
33.
    printf("%u\n", pTest->value >> i & 1); 
34.
 
35.
  return 0; 
36.
}
Grüße
rubberman
Bitte warten ..
Mitglied: Maik87
22.07.2014 um 09:57 Uhr
Zitat von rubberman:

Hallo Maik87,
Hi Rubberman

es besteht ein Ungleichgewicht in deiner union zwischen value (8 Bit breit) und struct bitfeld_4 (4 Bit breit oder auch
nicht, siehe übernächsten Satz). Das heißt, ein Wert von 123 in value lässt sich nicht mehr in deinem struct
abbilden (bei 15 ist Schluss).
Erwischt! Anfangs war es ein 8bit-bitfeld. Da ich aber nur Zahlen zw. 0 und 9 nutzen möchte, habe ich angefangen, den Code einzuschrumpfen. Scheinbar habe ich das Beispiel nicht komplett überarbeitet


Darüber hinaus erzeugen Bitfelder in einer union laut Standard undefiniertes Verhalten. Anders
gesagt, unter Windows scheint es zu funktionieren (weil die Implementierung es zulässt), auf anderen Betriebssystemen kann
das ganz anders aussehen und du darfst dich nicht darauf verlassen, dass Microsoft diese Implementierung nicht irgendwann
ändert.
Ich liebe es...! Es ging mir aber in dem Fall auch nur ums Verstehen und um eine Notfalllösung. Wird noch überarbeitet!

> Ist es nun noch möglich, die einzelnen bitxx mit einer Schleife zu durchlaufen?
Nein. Die Kurzerklärung: Nach dem Compilieren gibt es keine Variablennamen mehr.
Da lobe ich mir PHP.

Du kannst aber durchaus mit bitweisen Operatoren arbeiten. In diesem Fall Shift Right (>>) und Bitweises Und (&).
Ohje - das schon wieder. Genau damit habe ich gestern paar graue Haare hinzubekommen.

Ich kopiere mal den Schnippsel und versuche mich nochmal!


Danke!

Grüße
Maik87


PS:
Worin unterscheidet sich
#include <stdio.h> und #include <stdio>?
Bitte warten ..
Mitglied: rubberman
22.07.2014, aktualisiert um 19:45 Uhr
Ohje - das schon wieder. Genau damit habe ich gestern paar graue Haare hinzubekommen.
Oooch, kein Grund für graue Haare.
Bitweise Operationen sind relativ einfach. Voraussetzung ist, dass du dir die Zahlenwerte tatsächlich in ihrer binären Entsprechung vorstellst oder aufschreibst.
Nehmen wir mal mein Beispiel 7 und an der Stelle auch nur die niedrigsten 4 Bit (mehr interessiert dich ja eh nicht). Die binäre Entsprechung wäre 0111. Das rechte Bit ist das niedrigste Bit und immer 2^0. Je nach Bitbreite des verwendeten Typs, folgen dann 2^1, 2^2 etc.

Binär, schnell erklärt:
exponentiell 2^3 | 2^2 | 2^1 | 2^0 
dezimal       8  |  4  |  2  |  1 
              x  |  x  |  x  |  x 
7 binär       0  |  1  |  1  |  1 
              ___________________ 
Produkt       0  |  4  |  2  |  1
Die Summe in der letzten Zeile ergibt 7. Ist soweit also ziemlich simpel.

Das Binary And hat folgende Regeln:
0 & 0 = 0 
0 & 1 = 0 
1 & 0 = 0 
1 & 1 = 1
Jedes einzelne Bit wird entsprechend behandelt.

Beispiel 7 & 1
7       0  |  1  |  1  |  1 
&       &  |  &  |  &  |  & 
1       0  |  0  |  0  |  1 
_       ___________________ 
1       0  |  0  |  0  |  1
Ergebnis ist 1. Somit haben wir bereits das niedrigste Bit von 7 ermittelt

Für die restlichen Bits nehmen wir das Shift Right. Dabei werden die Bits eine bestimmte Anzahl nach rechts verschoben. Die selbe Anzahl Nullen wird vorangestellt und die überflüssigen Bits rechts entfernt.

Die Schleife mal durchgespielt, sieht das so aus:
7       0  |  1  |  1  |  1   >> 0 
__      ___________________ 
7       0  |  1  |  1  |  1 
&       &  |  &  |  &  |  & 
1       0  |  0  |  0  |  1 
__      ___________________ 
1       0  |  0  |  0  |  1 
 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
 
7       0  |  1  |  1  |  1   >> 1 
__      ___________________ 
3       0  |  0  |  1  |  1  [  1  ] 
&       &  |  &  |  &  |  & 
1       0  |  0  |  0  |  1 
__      ___________________ 
1       0  |  0  |  0  |  1 
 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
 
7       0  |  1  |  1  |  1   >> 2 
__      ___________________ 
1       0  |  0  |  0  |  1  [  1  |  1  ] 
&       &  |  &  |  &  |  & 
1       0  |  0  |  0  |  1 
__      ___________________ 
1       0  |  0  |  0  |  1 
 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
 
7       0  |  1  |  1  |  1   >> 3 
__      ___________________ 
0       0  |  0  |  0  |  0  [  1  |  1  |  1  ] 
&       &  |  &  |  &  |  & 
1       0  |  0  |  0  |  1 
__      ___________________ 
0       0  |  0  |  0  |  0
In der linken Spalte siehst du jeweils die dezimalen Entsprechungen.
Gar nicht mal sooo kompliziert, oder?

PS:
Worin unterscheidet sich
#include <stdio.h> und #include <stdio>?
Öhm, hauptsächlich darin, dass es <stdio> nicht gibt. Meinst du <cstdio> ?
Also, der Code den du oben geschrieben hast, ist eigentlich C und nicht C++. Da C aber aus Kompatibilitätsgründen fast vollständig in C++ aufgeht, wurden auch die entsprechenden Funktionen in den C++ Standard übernommen. Nun sollen diese unter C++ aber auch im Standard-Namespace (namespace std) landen. Damit das passiert, includiert man in C++ nicht die C-Header (bspw. stdio.h) sondern deren C++ Entsprechungen (bspw. cstdio). Im selben Stil stdlib.h zu cstdlib etc...

Heißt aber ausdrücklich nicht dass man beliebig C-Code in C++ verwendet. Das ist schlechter Stil und wie gesagt vorrangig aus Kompatibilitätsgründen überhaupt möglich.

Grüße
rubberman
Bitte warten ..
Mitglied: Maik87
23.07.2014, aktualisiert um 16:01 Uhr
Super,

vielen vielen Dank für die ausführliche Erklärung!!

Habe meinen Fehler beim bitshifting gefunden Anfänger!!
Ich habe die Zahl zunächst in binär umgewandelt (z.B. 5 -> 0101), in einem string gespeichert und bin dann mit der Schleife dadurch. Dabei geht das viiiiieeeeel einfacher und ich kann nun eine Menge Code auf dem uC einsparen


Noch etwas:
Im Endeffekt möchte ich anhand des Binärmusters mit einem Mikrocontroller LED schalten. Sprich eine 5 heißt dann für vier LED AUS EIN AUS EIN.

Nun wird jeder Port mit einem Byte angesteuert. Jedes Bit steht für einen einzelnen Pin:
PORTB = 0b10000000;
Heißt zum Beispiel, dass die achte LED an wäre, der Rest aus.

Jetzt habe ich z.B. die Zahl 25. Diese soll nicht als 11001 auf den Port, sondern ziffernweise als 0010 und 0101 -> 00100101.
Kann ich nun die beiden halben Bytes zusammensetzen oder wie ist es am sinnvollsten?

Ich könnte auch beide Ziffern nacheinander bitshiften und hintereinander in einen String schreiben. Aber wie bekomme ich die "00100101" dann zu 0b00100101?


Edit:
Ich wandel das ganze in eine künstliche Dezimalzahl um und schick diese ins Register:

01.
int convertDezForRegister(int zahl){ 
02.
  int z1 = zahl/10, z2 = zahl%10; 
03.
  return z1*16+z2; 
04.
}
So wird auch 25 die künstliche Dezimalzahl 37, die Binär 0010 0101 ist und somit meinem Muster entspricht
Bitte warten ..
Ähnliche Inhalte
C und C++
Problem mit C basiertem Text Spiel
Frage von TheBest4everC und C++2 Kommentare

Hi, Ich habe mir als C Anfänger ein textspiel geschrieben und bin dann auf ein Problem gestoßen: ich hab ...

C und C++
C Sharp SQL Abfrage Problem
Frage von 115122C und C++3 Kommentare

Hallo, ich möchte in C# eine Verbindung zu einer DB/Tabelle herstellen, eine Abfrage starten und die Ergebnismenge darstellen. Das ...

LAN, WAN, Wireless
Was ist ein Access point?
Frage von miramaneeLAN, WAN, Wireless4 Kommentare

Hallo, ich werde meinen Hybrid Tarif bei der Telekom kündigen. Mein Arbeitszimmer ist sehr weit weg so gute 7 ...

Voice over IP
OpenVPN Point-to-Point - VoIP Probleme
Frage von erik10Voice over IP12 Kommentare

Hallo zusammen, melde mich hier, weil ich aktuell nicht ganz verstehe was da passiert. Vielleicht kann mir jemand helfen ...

Neue Wissensbeiträge
Humor (lol)
IoT-Gefahr: Smartes Aquarium leckt!
Information von Lochkartenstanzer vor 2 TagenHumor (lol)3 Kommentare

Moin, Die IoT-Manie hat weitere Opfer gefunden. Ein Casino-Leck durch ein smartes Aquarium: Allerdings haben sie kein Wasser, sondern ...

Router & Routing

Alte Fritzbox 7270 mit VPN und SIP-Telefonie hinter O2 Homebox 6641 als "Modem"

Erfahrungsbericht von the-buccaneer vor 2 TagenRouter & Routing3 Kommentare

Nun war es soweit: Auch O2 hat mich mit VOIP zwangsbeglückt. Heute am Privatanschluss, in 2 Wochen ist das ...

Sicherheit

Ungepatchte Remote Code Execution-Lücke in LG NAS

Information von kgborn vor 3 TagenSicherheit

Nutzt wer LG NAS-Einheiten? In den NAS-Einheiten der LG Network Storage-Einheiten gibt es eine sehr unschöne Schwachstelle, die einen ...

Windows Update

Neue Version KB4099950 NIC Einstellungen gehen verloren

Information von sabines vor 3 TagenWindows Update2 Kommentare

Es ist eine neue Version des KB4099950 verfügbar, die das Problem mit den verlorenen Netzwerkeinstellungen lösen soll. Das Datum ...

Heiß diskutierte Inhalte
Netzwerkmanagement
Netzwerkmanagment im Haus mit Switch, Panel und pfsense
gelöst Frage von CorraggiounoNetzwerkmanagement15 Kommentare

hi zusammen, wir sind gerade dabei das ganze Haus bzw. die einzelnen Zimmer mit netzwerkdosen zu versorgen. Vom Keller ...

Linux Netzwerk
Raspberry Pi 3: WLAN Power save deaktivieren
Frage von nordie92Linux Netzwerk14 Kommentare

Moin moin, mein Raspberry Pi 3 Model B benötigt eine dauerhaft aktive WLAN-Verbindung. Leider bricht die WLAN-Verbindung nach einigen ...

Netzwerkgrundlagen
VLAN - Offene Fragen
Frage von KnettenbrechNetzwerkgrundlagen13 Kommentare

Hallo zusammen, ich befasse mich derzeit mit dem Thema VLAN. Hierzu habe ich schon einige Guides gelesen, einschließlich des ...

Google Android
Empfehlung: Android Ortungsapp
gelöst Frage von certifiedit.netGoogle Android13 Kommentare

Guten Morgen, grundsätzlich vorweg, ich wollte mich eben schlau machen, bzgl einer Ortungsapp, welche Androidbasiert einem anderen Androidsmartphone mitteilt, ...