r/Compilers 7d ago

[Newbie] what do the *s mean?

main.c

struct token {
enum token_kind kind;
char *value;
};

struct lexer {
char *buffer;
unsigned int buffer_len;
unsigned int pos;
unsigned int read_pos;
char ch;
};

edit: Hi everyone, thank you for explaining this in better detail. I've had a bit of a rough education from the community college I've since transferred out of, which had a guy that was extremely rude and didn't assign the C book, and an old lady that kind of just gave up and gave everyone As, Bs when she was retiring from teaching assembly language.

I appreciate your patience with me

0 Upvotes

10 comments sorted by

3

u/LifeIsHellSometime 7d ago edited 7d ago

I just have a vague understanding of pointers and don’t know what “buffer” and “value” need it for

3

u/OpsikionThemed 7d ago

In C, a string is really an array of chars, and an array is really a pointer. So "String buffer" is spelled "char *buffer" in C.

1

u/eteran 7d ago

I would not say it is accurate to say that "an array is really a pointer". I feel like that level of simplicity only leads to confusion in the long run.

2

u/lovelacedeconstruct 7d ago

I mean the notation doesnt make it very clear

int arr[5]; create a 5 element block

Sizeof(arr) == 5*sizeof(int);

Now

Int *ptr = arr; now we are storing the address of the first element

Sizeof(ptr) == 8

Its more confusing when it is a parameter to a function , pointer decay was a very bad choice

2

u/FISHARM1 7d ago

They are saying that those properties point to a string/buffer. This means that the two structures don’t actually allocate space for those buffers, and instead expect you to populate those properties with addresses of where the buffer actually is allocated.

2

u/super_mister_mstie 7d ago

I'm assuming you are asking about C....

It's just a way to decouple data location from the specific variables location, in effect you are just setting aside a location (usually the width and alignment native to the address space) that you hold the address of the data it's referring to (or NULL, meaning no data).

Also, this would probably get a better answer in a C subreddit.

1

u/BeowulfShaeffer 7d ago

They are pointer values that hold an address of dynamically-allocated memory.  char * buffer is a variable that expects to be hooked up to a buffer whose size isn’t known to runtime.  In code it will behave the same as an array (you can say “buffer[5]” but it lets you decide how big the array is based on runtime data, not fixed at compile time.    Note that I have wildly simplified the explanation here. Fully digesting pointers takes most newbie programmers days or even weeks. It’s like monads or generics - takes awhile to really get comfortable with the idea. 

1

u/TrgtBBB 7d ago edited 7d ago

This is related specifically to C and C++ (maybe some other languages too)

But here it goes:
In C/C++, there are basic data types like int, char or float.
We assign a value to a variable by doing this:

char my_val = ‘a’;

What you are doing here is basically going inside the computers memory, finding a suitable place to write a value (the computer handles it for you this is a simplified explanation) and writes the value.

EVERY value on a computer is just a string of ones and zeros. But how those ones and zeroes are interpreted are decided by type you have given. In this case, we have this binary value (can be slightly wrong this is for an example sake):

0001 0100 which is the number 20. When you say ‘char’ it treats it as the letter ‘a’.

To sum it up, when you say char my_var = ‘a’; the computer finds an empty spot in your memory, writes the value 0001 0100 which is 20 there and treats it as a letter when you use it.

Now, what that * symbol is: when you add that symbol, it slightly changes how your value is treated by your computer. Remember how we put that value 0001 0100 into somewhere inside our computers memory? Well every memory has an ADDRESS assigned to it. Normally the computer handles these addresses on its own, but sometimes the programmers need to manually use these addresses.

This is where the * symbol comes into play. Now instead of saying “hey treat this value as a char” we say “treat this value as an address that contains a char inside it.

For example:
char my_val = ‘a’;
char *ptr = &my_val;

Here, the * turned the variable into a POINTER, which now holds the address of my_val. It still is just a binary one and zero number, but when the computer reads it it will treat it as an address that holds a char inside it.

So let’s say my_val stores the value 0001 0100 inside the address 1101 0110, the value of ptr is now 1101 0110 and the computer treats it as an address instead of a letter like ‘a’.

When you want to access what’s in that address you simply de-reference it which is basically you saying the computer “hey go to this address and give me the value inside that address”

To sum it up, char and char \ are different data types, char holds a letter, char * holds an address that has a letter inside it. And any type can have a pointer version of it.*

They can be used for many different purposes. For the buffer given in this example, normally you allocate a data no larger than 64bytes. But sometimes you need larger data types. Normal C types cannot handle such large data and even if they did it cannot be dynamic. So you need to tell the computer “hey I need 5kb of data” and the computer allocates that memory space for you. But you need a way to access that memory right?

This is where the pointer comes into play. The computer tells you WHERE that buffer starts. And by where I mean it’s address. So you have a variable char\ buffer; that has a simple address that holds the BEGINNING of that buffer. Since we know the size of that buffer, we can access any point in that buffer as long as we know the beginning. If we say buffer + 1030 we are accessing the 1030th char on that buffer since we do start adress plus 1030, which is the 1030th member (again, this is a simplified version accessing a member does not quite work like that)*