#Struct Rational Task

1 messages · Page 1 of 1 (latest)

stark rivet
#

this task has 4 branches and i currently solved the first one with searching the same multiplier of a and b

#include <stdio.h>

int kgV(int a, int b){

    int a0=a;
    int b0=b;
    int kgv=0;
    if(a>b){
        a+=a0;
        while(a%b != 0){
            a += a0;
        }
        kgv=a;
    } else{
        b+=b0;
        while(b%a !=0){
            b+=b0;
        }
        kgv=b;
    }
    return kgv;
}

int main(){
    int a,
        b;
    printf("Type a \n");
    fflush(stdout);
    scanf("%d",&a);

    printf("Type b \n");
    fflush(stdout);
    scanf("%d",&b);


    printf("kgV of a[%d] and b[%d] is %d", a, b, kgV(a, b));
    return 0;
}
vale heraldBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

stark rivet
#

even though i imported stdio

#

i get an "cannot be resolved" warning on my fflush statement

twin gate
#

did you save the file ?

stark rivet
#

yup

twin gate
#

what does gcc -v tell

stark rivet
#

not sure

twin gate
#

well run it

stark rivet
twin gate
#

duh

stark rivet
#

the programm is running

twin gate
#

then your LSP is going haywire

stark rivet
#

what does that mean

#

programm running and giving results while an error is existing

#

i always get this with fflush

stark rivet
#

is the member acces operator " . " always call by value ?

#
void verschiebeFlaeche(Rechteck_typ *r,
                        int dx,
                        int dy){
    r->xpos += dx;
    r->ypos += dy;
}

void verschiebeFlaeche2(Rechteck_typ r,
                        int dx,
                        int dy){
    r.xpos += dx;
    r.ypos += dy;
}
#

i tried this

#

and the second one doesnt change the struct values

#

i thought structs are objects

#

and it behaves like in java

#

do structs always initialize from top to bottom ?

twin gate
#

they appear in the order you defined them

stark rivet
#

if i have this

typedef struct{
    int xpos;
    int ypos;
    int breite;
    int hoehe;
}Rectangle_typ;

#

Rectangle rec1 = { xpos, ypos, breite, hoehe }

#

is the initialisation like this always ?

#

i dont realy get the difference between

--> pointer acces

#

and

. member acces

twin gate
twin gate
#

you use -> when a is a pointer to a struct

stark rivet
#

i somehow cant access my value

#
#include <stdio.h>
#include <math.h>
int kgV(int a, int b){

    int a0=a;
    int b0=b;
    int kgv=0;
    if(a>b){
        a+=a0;
        while(a%b !=0){
            a += a0;
        }
        kgv=a;
    } else{
        b+=b0;
        while(b%a !=0){
            b+=b0;
        }
        kgv=b;
    }
    return kgv;
}

typedef struct {
    double zaehler;
    double nenner;
} Rational;


void kuerzen(Rational *Bruch){

    double zaehler= Bruch->zaehler;
    double nenner= Bruch->nenner;

    if(zaehler>nenner){
        while(nenner !=0){
            double tmp=nenner;
            nenner = fmod(zaehler,nenner);
            zaehler=tmp;
        }
    } else {
        double tmp = zaehler;
        zaehler = nenner;
        nenner=tmp;
        while (nenner != 0) {
            double tmp = nenner;
            nenner = fmod(zaehler, nenner);
            zaehler = tmp;
        }
    }

    Bruch->zaehler /= zaehler;
    Bruch->nenner /= zaehler;

}

Rational addbruch(Rational *a, Rational *b){
    double kgv = kgV(a->nenner,b->nenner);
    Rational c;
    c->zaehler=(a->zaehler)+(b->zaehler);
}
#

invalid type argument of '->' (have 'Rational')

#

i want to return a fracture

#

that is a struct

#

but i cant acces the 2 values of the fracture

#

i dont think call by reference is necessary

#

call by value should do it

#

since i create a new fracture

#

both operators can be user for struct ?

#

-> for setting

#

. for returning ?

#

oh

#

c.zaehler

twin gate
#

c is not a pointer (to a struct)

stark rivet
#

i dont see much difference ?
is the struct parameter an object and pointer a reference variable ?

#

both methods seem to have almost the same effect if you change some parameters

#

how can i print an object in c ?

#

when i have to return a fracture ?

#

or better to say a struct

twin gate
stark rivet
#

if i do fracture addition

twin gate
#

printf("%i", a.m);

stark rivet
#

and then member acces its values ?

#
Rational subtrahiere(Rational a, Rational b) {
    double kgv = kgV(a.nenner, b.nenner);
    Rational c;
    c.zaehler = (a.zaehler) - (b.zaehler);
    c.nenner = kgv;

    return c;
}
#

the frunciton looks like this

twin gate
#
Rational ergebnis = subtrahiere(a, b);
printf("%f/%f\n", ergebnis.zähler, ergebnis.nenner);
stark rivet
#

so you also know german 😄

#

so this is the only way ?

#

in java i can create a toString() method that is the default call for objects

#

and i can overwrite that

#

are you also studying computer science

#

this feels

#

not so cool

#

when i cant print a struct with its variable alone

#

ahh

#

i just need to make a function

#

yey

#

this is better

#

by a ton

#
void RationalPrint(Rational r){
    printf("Bruch1 und Bruch2 subtrathiert\nZaehler[%lf]\nNenner [%lf]",r.zaehler,r.nenner);
}
#

it prints the return struct of a function

#
    RationalPrint(subtrahiere(Bruch1,Bruch2));

#

but i have to write a default text

#

"operated" for every arithmetik operation

stark rivet
#

i made a print function

#

for every arithmetic function

#
    Print_kuerze(kuerze(Bruch1));
    Print_add(addiere(Bruch1,Bruch2));
    Print_sub(subtrahiere(Bruch1,Bruch2));
    Print_mul(multipliziere(Bruch1,Bruch2));
    Print_div(dividiere(Bruch1,Bruch2));

#

nekrooo

#

i need you wisdom

#

can a function acces the command-arguments ?

forest horizon
# stark rivet can a function acces the command-arguments ?

Yes you can make a function access command line arguments as long as you pass the function that needs them as arguments. There are other ways to access comandline arguments without passing them in, but those are either OS specific or promote general bad practices.

void do_something(int argc, char** argv)
{
    if(argc > 2)
    {
        printf("%s", argv[1]);
    }
}
int main (int argc, char** argv)
{
    do_something(argc, argv);
}
stark rivet
#

thx

stark rivet
#
int verschiebeFlaeche(Rechteck_typ *r,
                        int dx,
                        int dy){
    r->xpos += dx;
    r->ypos += dy;

    return r->xpos*r->ypos;
}```
#

does somone know why this isnt working

twin gate
#

what are you expecting it to do, and how does that deviate from what you get

stark rivet
#

i expect to return the same way as i would acces with "."

twin gate
#

then you need to return a struct

stark rivet
#
typedef struct{
    int xpos;
    int ypos;
    int breite;
    int hoehe;
}Rechteck_typ;

long berechneFlaeche(Rechteck_typ r){
    return(r.breite*r.hoehe);
}

void verschiebeFlaeche(Rechteck_typ *r,
                        int dx,
                        int dy){
    r->xpos += dx;
    r->ypos += dy;
}
Rechteck_typ verschiebeFlaeche2(Rechteck_typ *r,
                        int dx,
                        int dy){
    r->xpos += dx;
    r->ypos += dy;

    return r;
}

// das ist call by value und ändert den wert nicht ! pointer acces muss genutzt werden
//void verschiebeFlaeche2(Rechteck_typ r,
//                        int dx,
//                        int dy){
//    r.xpos += dx;
//    r.ypos += dy;
//}

int main() {


    Rechteck_typ fenster = {2,3,4,5};

    printf("%d", verschiebeFlaeche2(&fenster,3,3));
}```
#

it doesnt work

#

incompatible types when returning type 'Rechteck_typ *' but 'Rechteck_typ' was expected

forest horizon
stark rivet
#
long verschiebeFlaeche2(Rechteck_typ *r,
                        int dx,
                        int dy){
    r->xpos += dx;
    r->ypos += dy;

    return *r->xpos+*r->ypos;
}
#

like this

shadow hare
#

Single Responsibility Principle.
Or "do one thing only".

Here you have a function that translates a rectangle by dx and dy.
Yet it does more than just that.
It adds the new X and Y coordinates together and returns this.

Clients who call this function will confuse others as a result of it.

It's much clearer if the code read instead:

Rechteck_typ fenster = {2,3,4,5};
verschiebeFlaeche2(&fenster,3,3);
printf("%d", berechneFlaeche(&fenster));

When compared to

Rechteck_typ fenster = {2,3,4,5};
printf("%d", verschiebeFlaeche2(&fenster,3,3));

(as an example, because I don't believe adding X and Y yields the surface of a rectangle)

modern light
stark rivet
#

and why is this not working
printf("%d", fenster->xpos);

#

is it not the same as fenster.xpos

shadow hare
#

Is "fenster" a pointer?
It wasn't in your earlier example.

stark rivet
#

its a struct

#

Rechteck_typ fenster = {2,3,4,5};

shadow hare
#

But a pointer to a struct?
Or "just a struct"?

stark rivet
#

whats the difference ?

#

its a pointer i think

#

stuct type is Rechteck_typ

shadow hare
#
Rechteck_typ fenster;   // not a pointer
Rechteck_typ* pfenster; // pointer
stark rivet
#

what is fenster then? a reference variable ?

#

if its not a pointer

shadow hare
#

So here

Rechteck_typ fenster = {2,3,4,5};

variable "fenster" is not pointer, and...

printf("%d\n", fenster.x);

Should work.

stark rivet
#

pointer acces works like this then?

    Rechteck_typ fenster = {2,3,4,5};
    Rechteck_typ *pfenster = &fenster;
    verschiebeFlaeche(&fenster,3,3);
    printf("%d\n", pfenster->xpos);
    printf("%d", fenster.xpos);

shadow hare
#

If you did

Rechteck_typ fenster = {2,3,4,5};
Rechteck_typ* pfenster = &fenster;

Then "pfenster" is a pointer and...

printf("%d\n", pfenster->x);

Should work.

stark rivet
#

ok but why am i using pointer dereference in parameter when fenster is not a pointer ?

#

what is fenster ? ?

shadow hare
#

You could have...

Rechteck_typ fenster = {2,3,4,5};
Rechteck_typ *pfenster = &fenster;

verschiebeFlaeche(pfenster,3,3); // same as &fenster obv.
printf("%d\n", pfenster->xpos);
printf("%d", fenster.xpos);
#

Do keep in mind that a printf() that does not end with "\n" may not print to the screen immediately because it remains buffered.

stark rivet
#

ok and what is fenster xD ?

#

does it not hold the address of the object

shadow hare
#

No, it's a stack variable.
It represents the amount of stack memory to hold the struct of type Rechteck_typ.

stark rivet
#

stack variable

#

🤯

#

🤯 🤯 🤯

#

not connected to heap ?

shadow hare
#

No, stored on the stack frame of the function being run.
Will cease to exist when function returns.

#

Also, a pointer does not automatically mean it's heap memory.

stark rivet
#

but its in the main method

shadow hare
#

And the main method is a function like any other.
A bit more special maybe, but a function nonetheless.

stark rivet
#

that means anything except pointers are stack variables ?

#

pointers interact with heap ?

shadow hare
#

No, as I said just a minute or two ago, a pointer does not necessarily mean it's pointing at heap memory.

stark rivet
#

it can also point to a primitive type that is a stack variable ?

#

ok what is stored in the heap ? 😄

shadow hare
#
long verschiebeFlaeche2(Rechteck_typ *r,
                        int dx,
                        int dy){
    r->xpos += dx;
    r->ypos += dy;

    return *r->xpos+*r->ypos;
}

int main()
{
  Rechteck_typ fenster = {2,3,4,5};
  verschiebeFlaeche2(&fenster, 3, 3);
}

In this example, variable "r" in function verschiebeFlaeche2() is pointing at stack memory.

stark rivet
#

because fenster is in stack memory

shadow hare
#

However, same function / different main

long verschiebeFlaeche2(Rechteck_typ *r,
                        int dx,
                        int dy){
    r->xpos += dx;
    r->ypos += dy;

    return *r->xpos+*r->ypos;
}

int main()
{
  Rechteck_typ* pfenster = malloc(sizeof(Rechteck_typ));
  verschiebeFlaeche2(pfenster, 3, 3);
  free(pfenster);
}

Now variable "r" in function verschiebeFlaeche2() is pointing at heap memory.

stark rivet
#

i need to allocate memory ?

#

is the JVM doing this automaticly in java ?

shadow hare
#

If you want to use the heap, you must ask for it. Yes.

stark rivet
#

puhh that means i must be careful not to bring java confusion into c

shadow hare
#

Forget Java when programming C.
They are not comparable.

stark rivet
#

ok

#

does it also mean that the heap is still active after main function is closed

shadow hare
#

Of course.
The heap is managed by the OS.
The heap is a large pool of memory that any program can dip into.
Your internet browser for instance is very thirsty for heap memory.
Just open up your task manager and look at what programs use up the most memory.

#

But if you want to be a nice program on your computer, you will give back any heap memory you "borrow" from the OS.

You give back heap memory using free().
Just moments ago, I edited my simple example and added the free() to show how.

stark rivet
#

it bothers me a lot that i dont know more about this

#

i have nothing about this in my scripts

shadow hare
#

If you don't give back heap memory, then you are said to be "leaking memory".

shadow hare
#

Well, stack is RAM too.
Nothing you run is in the ROM.

stark rivet
#

any article/website i can read to quickly get some info ?

#

y see where i lack knowledge 😄

shadow hare
#

I had a look and I couldn't find anything quickly.

forest horizon
#

That's more OS based, but it does explain stack and heaps

#

I remember watching this video 6 years when I was a student. It will probably answer your questions.

stark rivet
#

that means memory=RAM ?

forest horizon
#

Yes.

#

But don't look too deep into it as a beginner

stark rivet
#

if i call a function with 3 integer types my memory looks like this

32GB - 12 Bytes

forest horizon
#

In the simplest case. Yes

stark rivet
#

and is released when main function closes ?

#

only heap pointers have to be free() ed

forest horizon
#

If created on the stack yes

#

If create on the heap, then free()

stark rivet
#

and if i type static variables and code text it is permanently placed in the RAM as long as the IDE has opened the source code ?

#

if i have a source code of thousands of lines, can the global and code segment be 10 GB ?

forest horizon
#

This is an advance OS topic, but here. It depends on the mechanism of loading code from disk to ram. Some OS will only do pieces at a time, others will do it all at once.

stark rivet
#

i remember something called "stackoverflow"

forest horizon
#

In a general case, the global and code segment could be 10 GB or more.

stark rivet
#

when ram isnt enough and function-calls take to much memory

forest horizon
#

So a stack overflow is more common when you have a recursive function push its local variables onto the stack until the process doesn't have any more stack to "allocate"

shadow hare
#

In very simple terms, the OS gives any program "some" memory.
It will be quite minimal and it won't be the same for all programs either.
That memory is the program's stack memory.
It cannot grow beyond that, or it will crash.

All stack variables are stored within this memory.
But keep in mind that all variables are limited in lifetime to the duration of a function.
So variables in main() for instance will live as long as the program runs.
But any variables in any functions called by main() will only live for as long as that function runs.

If a program needed more memory, or you wanted to store a particular large variable outsided of your stack memory, then you can ask the OS for more memory. This is the heap.
Any variables you store in the heap remain there forever UNLESS you delete these.

Using stack is easy, because variable lifetime is automatically managed for you.
But stack memory is limited.

When you use heap, looking after it becomes your responsibility. No one but you will clean up after you.
But the benefit of heap is that it is bountiful.

stark rivet
#

im thinking about allocating 10GBs in the IDE to just check what happens in the task manager 😄

#

and why is stack memory limited ?

forest horizon
#

So normally the OS will keep track of memory allocated to the process for the heap. Once the process is killed or exits, the OS can free the memory. But relying on the OS to handle freeing memory is a recipe for issues.

stark rivet
#

since every segment acceses RAM, it has the same limit but different functionality

forest horizon
#

It's limited because there are times where it isn't needed for your use case, why have a stack that's 10 GB when you only need 4 bytes for an int.

#

Additional the complier can calculate how much stack a given function will need and keep it within that limit.

stark rivet
#

noob-question.
the operating systems has million lines of code ?
how is it working with RAM ?

shadow hare
#

If I did this...

int main()
{
  LargeStruct* p = malloc(sizeof(LargeStruct));
  // free(p);
}

So deliberately not returning the heap I borrowed, then this is not a disaster.
I only requested one block of memory once.
This is returned to the OS when I exit.

But if I did this...

int main()
{
  LargeStruct* p = NULL;
  while (true) {
    p = malloc(sizeof(LargeStruct));
  }
  free(p);
}

You are leaking memory very, very quickly.
Worse; because you overwrite the pointer "p" with every new heap allocation, you cannot possibly give the other memory back. You no longer have that pointer.
Even if that free() at the end could be reached somehow, it would only return the memory for the last allocation you made.

The others are all lost. You cannot give that back, even if you wanted to.
Your program will eventually crash, and if you haven't managed to take the OS down with it, then all that memory will be taken back in one fell swoop.

#

The message is:
If you allocate heap memory, then do NOT lose that pointer.

stark rivet
shadow hare
#

Correct.

In programs like valgrind this memory is designated "permanently lost".

But only for your program.
As said, once the program terminates, the OS will take it back.
It still remembers what it gave you.

stark rivet
#

will this result in blue screen ?
Your program will eventually crash, and if you haven't managed to take the OS down with it, then all that memory will be taken back in one fell swoop

#

what do you mean with taken back

shadow hare
#

I need to drive home now.
That should explain radio silence from me from here on.

stark rivet
#

im not sure how this memory problem could potentially happen ?
If someone knows this, how can he reallocate memory to a pointer he initiliazed before ?

#

you just need to keep something like a list of initiliazed pointers

#

can i not "add" memory ?
malloc always reallocates new memory and forgets the previous memory-address

#

extend the previous int-address by 4 bytes

#

realloc

forest horizon
#

Memory leaks happen when you allocate memory, lose the pointer to that memory, never free it and continue to run the program.

#

That memory is lost in your program and can't be accessed, but it was allocate to your process so the memory can't be taken away from your process and given to another process.

stark rivet
#
    int *a;
    int n;
    n = 10;
    a = (int*) malloc(n * sizeof(int));
    a[0] = 1;
    for (i = 1; i < n; i++) {
        a[i] = a[i - 1] + 2;
    }
    free(a);

#

does this pointer to an integer address in the heap become an array when the size is multiplied by n ?

#

that means after

a = (int*) malloc(n * sizeof(int));
#

it becomes a[10] ?

#

before it was int a = 0 ?

#

is this not working 😄

forest horizon
#

Well, you have a return type expected in that function and you aren't returning anything.

#

Sizeof(800000) returns the size of int and is probably not what you intended.

#
a = (int *) malloc( sizeof(int) * 800000);
stark rivet
#

i only want to see my ram spiking 😄

#

but i will come back at this when its needed

#

still need to do some tasks

#
Task 4: Struct/Union Color
In this task, a new data type is to be defined to describe the color values ​​of a pixel. The data type should be able to store the color values ​​both as RGB values ​​and as HEX values.
a) Implement a struct that contains the color values ​​R, G and B. The values ​​are in the range 0 to 255.
b) Define a new data type that can also represent this struct as an unsigned integer. Use the data type union for this.
c) Test the new data type in a complete C program

Im currently at this stage ...

#include <stdio.h>

typedef struct {
    unsigned char R;
    unsigned char G;
    unsigned char B;
    long hexR;
    long hexG;
    long hexB;
    long hex;
} RGB;


typedef union {
    RGB rgb;


} uINT;

main(){
    const unsigned char R = 255;
    char R2 = '99';


    printf("%d\n",R);
    printf("%d\n",R2);
    printf("%d\n",'c');
    printf("%x\n",R);
    return 0;
}
#

not understanding what b) wants

#

a struct has multiple values

fallow bloom
#

a) Implement a struct that contains the color values R, G and B. The values are in the range 0 to 255.
So you did this, but you also added hexR, hexG, hexB, and hex as fields to the struct, which isn't what a) asks you to do, so remove those

#

b) Define a new data type that can also represent this struct as an unsigned integer. Use the data type union for this.
So they want you to leave your RGB struct type alone, and make a new type. They don't explicitly specify which type they expect you to make it, but they expect you to make it a union, which you did. You correctly put RGB rgb; in it, but a union should always contain more than just one field. I recommend looking at online examples of unions to get what they're for, and to figure out what other field they're asking you to put in the union.

stark rivet
#

yes i was confused lol

#

i hate tasks that are like this

#

im still on it

#

i have to go to sizeof to see it but even there its not explained

quartz valley
stark rivet
#

is anyone codign with eclipse ?

#

i still couldnt find a way to implement auto completion or proposals

#

it only shows errors

shadow hare
#

No, people using Eclipse is rare these days.
I know ST MicroElectronics provide their own IDE which is basically just rebranded Eclipse.

I used Eclipse a looong time ago. It was okay, but not easy to set up or use.
You keep having to switch "perspectives" I seem to recall.
One for editing.
Another for running/debugging
And one for version control.

But there were several other perspectives that I probably never even used.

I am not endorsing Eclipse.
Not to beginners or more advanced users.
But keep in mind; that's just my opinion.

stark rivet
#

im so into eclipse that i don't want anything else lol

#

it was indeed a bit difficult to setup

#

it has different perspectives yes but i don't see much problem

#

only auto completion is like non existent

#

only when i type member acces with "."

#

i get proposals

#

the proposal variation when i use eclipse for java is much greater

stark rivet
#

and im thinking to put this union inside the struct

#

i come up with something like this but im still not sure if its what the task wanted

#include <stdio.h>

// Definiere einen struct für RGB-Farbwerte
struct RGBColor {
    unsigned char red;
    unsigned char green;
    unsigned char blue;
};

// Definiere einen union-Typ, der RGB-Werte als vorzeichenlose Integer speichert
union ColorValue {
    struct RGBColor rgb;
    unsigned int hex;
};

int main() {
    // Erstelle eine Instanz des union-Typs
    union ColorValue color; // {0,0,0,{0}}

    // Setze RGB-Werte
    color.rgb.red = 255;
    color.rgb.green = 128;
    color.rgb.blue = 64;

    // Zeige die RGB-Werte an
    printf("RGB-Werte: R=%d, G=%d, B=%d\n", color.rgb.red, color.rgb.green, color.rgb.blue);

    // Setze HEX-Wert
    color.hex = 0xFF8040;

    // Zeige den HEX-Wert an
    printf("HEX-Wert: 0x%X\n", color.hex);

    printf("RGB-Werte: R=%d, G=%d, B=%d\n", color.rgb.red, color.rgb.green, color.rgb.blue);

    return 0;
}

#

because b) says that i can represent the struct as unsigned integer

#

the value alone in the union doesn't look like having a connection to the struct

#

when i only assign red

#

RGB-Werte: R=255, G=0, B=0
HEX-Wert: 0xFF

#

i get this

#

and the union hex value is 0xFF 255

#

when i only assign green

#

the hex value is

#

HEX-Wert: 0x8000

#

32768 unsigned integer

fallow bloom
#

The connection to the struct is very loose, but the connection is that both the struct and the integer take a similar number of bytes

#

I'd use uint32_t by the way instead of unsigned int, since it is more explicit with the fact that you're just viewing it as bytes, and more importantly because unsigned int on some computers is only 2 bytes large, since that's the minimum size C guarantees it to be. So your program wouldn't work on those computers.

stark rivet
#

also 32 bit ?

#

is this correct ?

    union ColorValue color; // { {0,0,0}, 0}

    // Setze RGB-Werte
//    color.rgb.red = 255;
    color.rgb.green = 128; // { { 0,125,0}, 0}
//    color.rgb.blue = 64;
#

probably not because hex is also manipulated

#

the brackets ?

#

this is rly deep stuff lol

#

byte manipulation

#

i didnt think i would enter this sphere in this task

#
//    Diese Variablen haben jeweils 1 Byte
//  0000 0000 | 1000 0000 | 0000 0000
    unsigned char red;
    unsigned char green;
    unsigned char blue;
};

// Definiere einen union-Typ, der RGB-Werte als vorzeichenlose Integer speichert
union ColorValue {
    struct RGBColor rgb;
//     0000 0000 | 0000 0000 | 1000 0000 | 0000 0000 // 1 byte wird links hinzugefügt
    unsigned int hex;
};
#

so struct has 3 bytes of unsigned char

#

if i only manipulate green

#

the middle byte is manipulated

#

and the hex integer of the union adds 1 additional byte in big endian style from the left

#

and if i print hex, it prints green-bits with additional bits right to it from the variable of the data type below it in the struct

#

thats how i get 0x8000 hex

#

32768 decimal

#

omg

#

but nothing changes if i change blue datatype

struct RGBColor {
//    Diese Variablen haben jeweils 1 Byte
//  0000 0000 | 1000 0000 | 0000 0000
    unsigned char red;
    unsigned char green;
    unsigned int blue;
};
#

RGB-Werte: R=0, G=128, B=0
HEX-Wert: 0x8000
RGB-Werte: R=0, G=128, B=0

#

oh wait

#

because union cuts the bytes that are too much ?

#

1+1+4 = 6 bytes

#

the largest single member is int

#

in the union ?

#

even if change to long

#

nothing changes

#

there is something else

stark rivet
#

is my learning spirit good ? any advices

#

how is this

// Definiere einen struct für RGB-Farbwerte
struct RGBColor {
//    Diese Variablen haben jeweils 1 Byte
//    0-255        0-255        0-255
//    rrrr rrrr | gggg gggg | bbbb bbbb
//  0000 0000 | 1000 0000 | 0000 0000
    unsigned char red; // INDEX 0 ?? in bytes ?
    unsigned char green; // INDEX 1 ?? in bytes ?
    unsigned char blue; // INDEX 2 ?? in bytes ?
};

// Definiere einen union-Typ, der RGB-Werte als vorzeichenlose Integer speichert
union ColorValue {
    struct RGBColor rgb;
//     0000 0000 | 0000 0000 | 1000 0000 | 0000 0000 // 1 byte wird links hinzugefügt
//  0000 0000 | bbbb bbbb | gggg gggg | rrrr rrrr // 1 byte wird links hinzugefügt
    unsigned int hex;
};
stark rivet
#

be cursed union !!

stark rivet
#

dimwiiiiiiiiiiiit my heroo when do you have a bit time

shadow hare
#

Bit busy with life.
Maybe later or tomorrow.

fallow bloom
fallow bloom
#

So if your union has a field that is a uint32_t, and another field that is a uint64_t, then the union is guaranteed to be sizeof(uint64_t) bytes large (which is 8 bytes)

#

I recommend writing a function that prints the r, g, and b values, and then also prints the unsigned int, so that you can easily test what gets printed when you set say the g field to 42

stark rivet
#

i have print statements

#

this is the full code

#
/*
 * RGB.c
 *
 *  Created on: 11.06.2024
 *      Author: Strider_Hien
 */
#include <stdio.h>

// Definiere einen struct für RGB-Farbwerte
struct RGBColor {
//    Diese Variablen haben jeweils 1 Byte
//    0-255        0-255        0-255
//    rrrr rrrr | gggg gggg | bbbb bbbb
//  0000 0000 | 1000 0000 | 0000 0000
    unsigned char red; // INDEX 0 ?? in bytes ?
    unsigned char green; // INDEX 1 ?? in bytes ?
    unsigned char blue; // INDEX 2 ?? in bytes ?
    unsigned char gray; // INDEX 3 ?? in bytes ?
    unsigned char yellow; // INDEX 4 ?? in bytes ?
};

// Definiere einen union-Typ, der RGB-Werte als vorzeichenlose Integer speichert
union ColorValue {
    struct RGBColor rgb;
//                        64            128            255
//     0000 0000 | 0000 0000 | 1000 0000 | 0000 0000 // 1 byte wird links hinzugefügt
//  0000 0000 | bbbb bbbb | gggg gggg | rrrr rrrr // 1 byte wird links hinzugefügt
//    unsigned int hex;
    unsigned long long hex;
};

int main() {
    // Erstelle eine Instanz des union-Typs
    union ColorValue color; // { {0,0,0}, 0}

    // Setze RGB-Werte
    color.rgb.red = 255;
//  0000 0000 | 1000 0000 | 0000 0000 // mittele byte wird auf
    color.rgb.green = 128; // { { 0,125,0}, 0}
    color.rgb.blue = 64;
    color.rgb.gray = 1;
    color.rgb.yellow = 2;

    // Zeige die RGB-Werte an
    printf("RGB-Werte: R=%d, G=%d, B=%d\n", color.rgb.red, color.rgb.green, color.rgb.blue);

    // Zeige den HEX-Wert an
    printf("HEX-Wert: 0x%X\n", color.hex);
//    color.hex=5;

    printf("%zu\n", sizeof(unsigned long long));
    printf("%zu\n", sizeof(color));
    printf("RGB-Werte: R=%d, G=%d, B=%d\n", color.rgb.red, color.rgb.green, color.rgb.blue);

    return 0;
}

stark rivet
#

to 8 bytes to see if i can add additional colors but somehow it only adds colors until it reaches the 5th Byte sorry

#

and prints the hex

HEX-Wert: 0x14080FF

#

but yellow 2 isn't printed ?

#

5th bytee

#

it reaches gray

#

0x1

fallow bloom
# stark rivet i have print statements

I know you have print statements, but what I was saying was that it'd be useful during testing to just have a function you can pepper around your code that does all the printing for you

stark rivet
#

oh you mean a print function ?

fallow bloom
#

Yeah, just cause your main() is kind of unreadable to me with all those long printf statements

#

I can't tell the actual code apart from the printing

#

So just a print function that takes a ColorValue and returns void

stark rivet
#
void colorprint(union ColorValue color){
    printf("RGB-Werte: R=%d, G=%d, B=%d, G=%d, Y=%d\nHEX-Wert: 0x%X\n", color.rgb.red, color.rgb.green, color.rgb.blue, color.rgb.gray, color.rgb.yellow, color.hex);
}
int main() {
    // Erstelle eine Instanz des union-Typs
    union ColorValue color; // { {0,0,0}, 0}

    // Setze RGB-Werte
    color.rgb.red = 255;
//  0000 0000 | 1000 0000 | 0000 0000 // mittele byte wird auf
    color.rgb.green = 128; // { { 0,125,0}, 0}
    color.rgb.blue = 64;
    color.rgb.gray = 1;
    color.rgb.yellow = 2;

    // Zeige die RGB-Werte an
    colorprint(color);

    printf("%zu\n", sizeof(unsigned long long));
    printf("%zu\n", sizeof(color));
    colorprint(color);

    return 0;
}

#

i also added hexprint in colorprint

#

lol

#

i somehow get this now

format '%X' expects argument of type 'unsigned int', but argument 7 has type 'long long unsigned int' [-Wformat=]

#

can %X not convert long long hex ?

#

lol i feel like it could be a conversion specifcier issue

#

oh my god

#

the program worked correctly but

#

THE SPECIFICATOR was wrong-.-

#

🤯

#

i was rly blind and didnt see it

#

phind didnt catch the problem either

stark rivet
#

that means even though the hex value was bigger

#

%X only printed what i could do

#

and ignore the bits greater

#

to 4 bytes

shadow hare
#

You can also use bit-fields for the RGB struct.

#

;compile

#include <assert.h>

/*
    Task 4: Struct/Union Color
    In this task, a new data type is to be defined to describe the color values ​​of a pixel. The data type should be able to store the color values ​​both as RGB values ​​and as HEX values.
    a) Implement a struct that contains the color values ​​R, G and B. The values ​​are in the range 0 to 255.
    b) Define a new data type that can also represent this struct as an unsigned integer. Use the data type union for this.
    c) Test the new data type in a complete C program
*/

union colour
{
    struct
    {
        unsigned blue  : 8;
        unsigned green : 8;
        unsigned red   : 8;
        unsigned       : 8;
    } rgb;
    unsigned raw;
};

int main()
{
    // https://html-color.codes/red
    union colour salmon;
    salmon.rgb.red = 250;
    salmon.rgb.green = 128;
    salmon.rgb.blue = 114;

    assert(salmon.raw == 0x00fa8072);

    // https://html-color.codes/purple
    union colour soap;
    soap.rgb.red = 206;
    soap.rgb.green = 200;
    soap.rgb.blue = 239;

    assert(soap.raw = 0x00cec8ef);
}
native citrusBOT
#
Compilation successful

No output.

shadow hare
#

what?

#

Silly me. Fixed.

#

The layout is ofc

31               0
 ┌───┬───┬───┬───┐ 
 │ 0 │ R │ G │ B │ 
 └───┴───┴───┴───┘ 

So the RGB components must be declared in reverse order to make it read "R G B".

  • blue in: 0 - 7
  • green in : 8-15
  • red in : 16 - 23
  • bits 24 - 31 are unused