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

Frage Entwicklung C und C++

C++ Problem mit Pointer

Mitglied: Maik87

Maik87 (Level 2) - Jetzt verbinden

21.07.2014, aktualisiert 13:02 Uhr, 1410 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
Linux

Meltdown und Spectre: Linux Update

Information von Frank vor 4 StundenLinux

Meltdown (Variante 3 des Prozessorfehlers) Der Kernel 4.14.13 mit den Page-Table-Isolation-Code (PTI) ist nun für Fedora freigegeben worden. Er ...

Tipps & Tricks

Solutio Charly Updater Fehlermeldung: Das Abgleichen der Dateien in -Pfad- mit dem Datenobject ist fehlgeschlagen

Tipp von StefanKittel vor 22 StundenTipps & Tricks

Hallo, hier einmal als Tipp für alle unter Euch die mit der Zahnarztabrechnungssoftware Charly von Solutio zu tun haben. ...

Sicherheit

Meltdown und Spectre: Wir brauchen eine "Abwrackprämie", die die CPU-Hersteller bezahlen

Information von Frank vor 23 StundenSicherheit12 Kommentare

Zum aktuellen Thema Meltdown und Spectre: Ich wünsche mir von den CPU-Herstellern wie Intel, AMD oder ARM eine Art ...

Sicherheit

Meltdown und Spectre: Realitätscheck

Information von Frank vor 1 TagSicherheit9 Kommentare

Die unangenehme Realität Der Prozessorfehler mit seinen Varianten Meltdown und Spectre ist seit Juni 2017 bekannt. Trotzdem sind immer ...

Heiß diskutierte Inhalte
Netzwerkgrundlagen
Welches Modem für VDSL 50000 der T-Com
gelöst Frage von Windows10GegnerNetzwerkgrundlagen21 Kommentare

Hallo, ein Kollege von mir will sich VDSL50000 von der T-Com holen, um daran einen Server zu betreiben. Ich ...

Sicherheit
Meltdown und Spectre: Die machen uns alle was vor
Information von FrankSicherheit18 Kommentare

Aktuell sieht es in den Medien so aus, als hätten die Hersteller wie Intel, Microsoft und Co den aktuellen ...

Ubuntu
Ubuntu - Starter für nicht vertrauenswürdige Anwendungen
Frage von adm2015Ubuntu17 Kommentare

Hallo zusammen, Ich verwende derzeit die Ubuntu Versionen 17.10 bzw. im Test 18.04. Ich habe mehrere .desktop Dateien in ...

Netzwerke
Packet loss bei "InternetLeitungsvollauslastung"
gelöst Frage von Freak-On-SiliconNetzwerke17 Kommentare

Servus; Ja der Titel klingt komisch, is aber so. Wenn die Internetleitung voll ausgelastet ist, hab ich extreme packet ...