C-Funktion verstehen

Gast #4920596
Hallo,

meine C-Kenntnisse sind eingerostet kann mir bitte einer hierbei 
weiterhelfen?
1
void stepper_set_soll_position (unsigned long ulNewPosition, unsigned char ucMotor)
2
{
3
  ulNewPosition &= (unsigned long)(~1);
4

5
  ucMotor &= 1;
6
}

Was passiert in dieser Zuweisung
1
 ulNewPosition &= (unsigned long)(~1);
 und wofür könnte es gut sein in der Funktion?
Gast #4920603
Ralf schrieb:
> Was passiert in dieser Zuweisung ulNewPosition &= (unsigned long)(~1);
> und wofür könnte es gut sein in der Funktion?

ein Cast auf unsigned long einer bitweisen negation der 1 wird mit 
ulNewPosition verundet und in ulNewPosition gespeichert.
Gast #4920609
Gerhard O. schrieb im Beitrag #4920606:
> Aber wie gesagt, das funktioniert nur wenn die Inputparameter Global
> sind weil diese Funktion nichts zurück geben kann.
Meines Wissens noch nichtmal dann, weil die Neudefinition die globale 
Definition innerhalb der Funktion überdeckt.
#4920638
Ralf schrieb:
>
1
> 
2
> void stepper_set_soll_position (unsigned long ulNewPosition, unsigned 
3
> char ucMotor)
4
> {
5
>   ulNewPosition &= (unsigned long)(~1);
6
> 
7
>   ucMotor &= 1;
8
> }
9
> 
10
>

So wie die Funktion implementiert ist, macht sie vom Ergebnis her genau 
gar nichts.

Es gibt drei sinnvolle Möglichkeiten:

1.) Entweder die Variablen ulNewPosition und ucMotor sind global 
deklariert. Dann ergibt es keinen Sinn, sie der Funktion auch noch zu 
übergeben.

2.) Oder man übergibt der Funktion die Adressen der Variablen, die 
anderswo deklariert sind. Dann brauchen sie nicht global zu sein und man 
kann per Derefenzierung auf sie zugreifen.

3.) Oder man übergibt die Variablen an die Funktion, so wie hier, so 
dass sie auf dem Stack liegen. Dann sollte die Funktion aber auch etwas 
zurückgeben und nicht als void deklariert sein.
#4920725
Joe F. schrieb:
> Wie Dussel sagt: diese Funktion bewirkt rein gar nichts.

Mit etwas Grips könnte man sich leicht denken, daß er nur die ihm 
unverständlichen Zeilen gepostet hat.
Vollständige Funktionen sieht man hier nur sehr selten.

Das Optimum wäre gewesen, die fraglichen Zeilen im Beitrag zu zitieren 
und den kompletten, echten Code als Anhang.
#4920763
S. S. schrieb:
> (unsigned long)(~1);
>
> ist in binärer Schreibweise 11111111111111111111111111111110, also
> 4294967294 dezimal. Mit
>
Bist du dir sicher ?

Die Ziffer 1 ist erst einmal ein integer der bitweise negiert wird und 
wenn du den auf einen long castest wird er mit mit 0 und nicht mit 1 
vorne aufgefüllt.
Moderator Persönliche Seite #4920780
Hans-Georg L. schrieb:
> Die Ziffer 1 ist erst einmal ein integer der negiert wird und wenn du
> den auf einen long castest wird er mit mit 0 und nicht mit 1 vorne
> aufgefüllt.

Das klingt erstmal logisch, ein Versuch belehrt mich aber eines 
besseren:
1
#include <stdio.h>
2
#include <stdint.h>
3

4
int main()
5
{
6
    printf ("sizeof(int):  %ld\n", sizeof(int));
7
    printf ("sizeof(long): %ld\n", sizeof(long));
8

9
    printf ("%x\n", ~1);
10
    printf ("%lx\n", ~1L);
11
    printf ("%lx\n", (unsigned long)(~1));
12
    printf ("%lx\n", (unsigned long)(~1U));
13
    return 0;
14
}
1
$ cc a.c && ./a.out
2
sizeof(int):  4
3
sizeof(long): 8
4
fffffffe
5
fffffffffffffffe
6
fffffffffffffffe
7
fffffffe

Es liegt an der Sign-Extension, dass "(unsigned long)(~1)" trotzdem 
funktioniert. Rufus hatte den richtigen Riecher.
Moderator Persönliche Seite #4920789
Mark B. schrieb:
> Ich finde es interessant, wie hier so gerne auf Details der
> Implementierung herumgeritten wird, wenn das ganze Code-Beispiel an sich
> Müll ist und entsorgt gehört. ;-)

Ich finde es eher interessant, dass Du einen Auszug aus einer Funktion 
nicht akzeptierst und darauf herumreitest. Es ging darum, was eine 
einzelne Zeile bewirkt und nicht darum, was eine ganze Funktion bewirkt.

Der Korinther bist Du, nicht die anderen.
Gast #4920793
Mark B. schrieb:
> 1.) Entweder die Variablen ulNewPosition und ucMotor sind global
> deklariert. Dann ergibt es keinen Sinn, sie der Funktion auch noch zu
> übergeben.
Ich habe es gerade mal kurz mit XCode (meines Wissens gcc) getestet
1
#include <iostream>
2
using std::cout;
3
using std::cin;
4

5
unsigned short int global;
6

7
void Funktion(unsigned short int global);
8

9
int main()
10
{
11
  unsigned short int lokal=5;
12
  global=3;
13
  
14
  Funktion(lokal);
15
  
16
  cout<<"lokal="<<lokal<<"; global="<<global<<"\n";
17
  
18
  return 0;
19
}
20

21
void Funktion(unsigned short int global)
22
{
23
  global=10;
24
}
ergibt als Ausgabe
lokal=5; global=3

Das heißt, wie ich oben schrieb, wird die globale Variable von der 
lokalen Deklaration überdeckt.
#4920794
Hans-Georg L. schrieb:
> S. S. schrieb:
>> (unsigned long)(~1);
>>
>> ist in binärer Schreibweise 11111111111111111111111111111110, also
>> 4294967294 dezimal. Mit
>>
> Bist du dir sicher ?
>
> Die Ziffer 1 ist erst einmal ein integer der bitweise negiert wird und
> wenn du den auf einen long castest wird er mit mit 0 und nicht mit 1
> vorne aufgefüllt.

C99 § 6.3.1.1:
> 1 When a value with integer type is converted to another integer type
>   other than _Bool, if the value can be represented by the new type,
>   it is unchanged.

"1" ist vom Typ "int", also signed, und deshalb auch "~1", also ist "~1" 
negativ (-2), also kann dieser Wert in "unsigned long" nicht 
repräsentiert werden.

> 2 Otherwise, if the new type is unsigned, the value is converted by
>   repeatedly adding or subtracting one more than the maximum value
>   that can be represented in the new type until the value is in the
>   range of the new type.

Dieses Verfahren impliziert, dass ein kleinerer Typ mit dem 
Vorzeichen-Bit aufgefüllt wird, d.h., das Ergebnis ist das selbe wie bei 
"(unsigned long)-2".
#4920796
Frank M. schrieb:
> Mark B. schrieb:
>> Ich finde es interessant, wie hier so gerne auf Details der
>> Implementierung herumgeritten wird, wenn das ganze Code-Beispiel an sich
>> Müll ist und entsorgt gehört. ;-)
>
> Ich finde es eher interessant, dass Du einen Auszug aus einer Funktion
> nicht akzeptierst und darauf herumreitest. Es ging darum, was eine
> einzelne Zeile bewirkt und nicht darum, was eine ganze Funktion bewirkt.
>
> Der Korinther bist Du, nicht die anderen.

Man muss schon ziemlich blind sein oder ein völlig unfähiger 
Programmier, um den hier gezeigten Code in irgend einer Weise als 
sinnvoll zu bezeichnen.
#4920804
Rufus Τ. F. schrieb:
> Hans-Georg L. schrieb:
>> Die Ziffer 1 ist erst einmal ein integer der bitweise negiert wird und
>> wenn du den auf einen long castest wird er mit mit 0 und nicht mit 1
>> vorne aufgefüllt.
>
> "sign expansion", anyone?

Du hast recht es wird eine negativer integer daraus. Aber solche 
Konstruktionen mit Mischmasch aus Artithmetik und Logig sind äusserst 
unübersichtlich ... Ein ~1UL hätte es auch getan.

Und wir wissen ja auch nicht was der Verfasser wirklich gewollt hat.
#4920807
Frank M. schrieb:
> Mark B. schrieb:
>> Man muss schon ziemlich blind sein oder ein völlig unfähiger
>> Programmier, um den hier gezeigten Code in irgend einer Weise als
>> sinnvoll zu bezeichnen.
>
> Es ging nicht um die Sinnigkeit/Unsinnigkeit.

Wer sagt das?

Wenn Du in einem Code Review sitzt und eine völlig unsinnige Funktion 
entdeckst, sprichst Du dann über die Details der Implementierung? Oder 
sagst Du: "Diese Funktion ergibt so keinen Sinn. Bitte wegschmeißen und 
neu schreiben."
Moderator Persönliche Seite #4920829
Mark B. schrieb:
> Woraus schließt Du das?

Kleinhirn an Großhirn:

 "Was soll diese Funktion? Diese ist unsinnig"

Großhirn an Kleinhirn:

 "Möglichkeit 1: Der User ist dumm und kann kein C"
 "Möglichkeit 2: Der User ist intelligient und reduziert den Code
  auf das Wesentliche"

Kleinhirn an Großhirn:

 "Dann hätte auch eine einzelne Zeile gereicht"

Großhirn an Kleinhirn:

 "Dann wären die Typen der Variablen (long oder int) nicht klar gewesen"

Ich habe mich für die Intelligenz des Users entschieden, Du für die 
Dummheit desselben.
#4920840
Frank M. schrieb:
> Mark B. schrieb:
>> Woraus schließt Du das?
>
> Kleinhirn an Großhirn:
>
>  "Was soll diese Funktion? Diese ist unsinnig"
>
> Großhirn an Kleinhirn:
>
>  "Möglichkeit 1: Der User ist dumm und kann kein C"

Er hast selbst gesagt, dass seine C-Kenntnisse eingerostet sind. Und 
Dinge wie Bits setzen, Bits löschen und Bits negieren sind jetzt nicht 
unbedingt das, was ich als fortgeschrittene Themen in der 
C-Programmierung ansehen würde.

Edit:
Um diese Frage hier zu beantworten:

> und wofür könnte es gut sein in der Funktion?

sollte man dann schon die komplette Funktion vorliegen haben. Nicht 
anwesende Code-Teile zu raten ist immer schwierig ;-)
Gast #4921668
>ucMotor wird auf 1 gesetzt, sofern bit0 in ucMotor 1 ist.
Naja.

Es werden alle Bits von ucMotor auf Null gesetzt. Nur das LSB (unterste 
Bit) bleibt auf 1 wenn es vorher schon 1 war.
Gast #4921692
Frank M. schrieb:
> Großhirn an Kleinhirn:
>
>  "Möglichkeit 1: Der User ist dumm und kann kein C"
>  "Möglichkeit 2: Der User ist intelligient und reduziert den Code
>   auf das Wesentliche"

"Möglichkeit 3: Der User Ralf (der sich nicht weiter gemeldet hat,) 
veralbert alle
#4922742
Frank M. schrieb:
> Mark B. schrieb:
>> Wenn Du in einem Code Review sitzt und eine völlig unsinnige Funktion
>> entdeckst, sprichst Du dann über die Details der Implementierung?
>
> Es war offensichtlich, dass die Funktion nur in Auszügen abgebildet
> wurde. Das kann man unter Einsatz des Verstandes leicht erkennen.

Die Überschrift heißt "C-Funktion verstehen", und dann wird eine 
C-Funktion hingeschrieben, die in ihrer so hingeschriebenen Gesamtheit 
keinen Sinn ergibt. Da finde ich nicht so offensichtlich, dass die 
Funktion an sich gar keine Relevanz haben soll.

Frank M. schrieb:
> Ich habe mich für die Intelligenz des Users entschieden, Du für die
> Dummheit desselben.

Intelligent ist, echten Code hinzuschreiben oder wenigstens Änderungen 
gegenüber diesem als solche zu markieren. Dann kann man sich viel 
Diskussion sparen.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 9 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.