I’m sort of learning C, I’m not a beginner to programming though, I “know” Java and python, and by the way I’m on a mac (leopard).
Firstly,
1: could someone explain when to use a pointer and when not to?
2:
char *fun = malloc(sizeof(char) * 4);
or
char fun[4];
or
char *fun = "fun";
And then all but the last would set indexes 0, 1, 2 and 3 to ‘f’, ‘u’, ‘n’ and ‘\0’ respectively. My question is, why isn’t the second one a pointer? Why char fun[4] and not char *fun[4]? And how come it seems that a pointer to a struct or an int is always an array?
3:
I understand this:
typedef struct car
{
...
};
is a shortcut for
struct car
{
...
};
typedef struct car car;
Correct? But something I am really confused about:
typedef struct A
{
...
}B;
What is the difference between A and B? A is the ‘tag-name’, but what’s that? When do I use which? Same thing for enums.
4. I understand what pointers do, but I don’t understand what the point of them is (no pun intended). And when does something get allocated on the stack vs. the heap? How do I know where it gets allocated? Do pointers have something to do with it?
5. And lastly, know any good tutorial for C game programming (simple) ? And for mac/OS X, not windows?
PS. Is there any other name people use to refer to just C, not C++? I hate how they’re all named almost the same thing, so hard to try to google specifically C and not just get C++ and C# stuff.
Thanks!!
It was hard to pick a best answer, they were all great, but the one I picked was the only one that made me understand my 3rd question, which was the only one I was originally going to ask. Thanks again!
Because it declares an array. In the two other cases, you have a pointer that refers to data that lives somewhere else. Your array declaration, however, declares an array of data that lives where it’s declared. If you declared it within a function, then data will die when you return from that function. Finally
char *fun[4]would be an array of4pointers – it wouldn’t be a char pointer. In case you just want to point to a block of 4 chars, thenchar*would fully suffice, no need to tell it that there are exactly4chars to be pointed to.The first way which creates an object on the heap is used if you need data to live from thereon until the matching
freecall. The data will survive a return from a function.The last way just creates data that’s not intended to be written to. It’s a pointer which refers to a string literal – it’s often stored in read-only memory. If you write to it, then the behavior is undefined.
Pointers are used to point to something (no pun, of course). Look at it like this: If you have a row of items on the table, and your friend says “pick the second item”, then the item won’t magically walk its way to you. You have to grab it. Your hand acts like a pointer, and when you move your hand back to you, you dereference that pointer and get the item. The row of items can be seen as an array of items:
When you do
item i = row[1];then you first point your hand at the first item (get a pointer to the first one), and then you advance till you are at the second item. Then you take your hand with the item back to you 🙂 So, therow[1]syntax is not something special to arrays, but rather special to pointers – it’s equivalent to*(row + 1), and a temporary pointer is made up when you use an array like that.That’s not valid code. You basically said “define the type
struct car { ... }to be referable by the following ordinary identifier” but you missed to tell it the identifier. The two following snippets are equivalent instead, as far as i can see1)2)In our case, the identifier
carwas declared two times in the same scope. But the declarations won’t conflict because each of the identifiers are in a different namespace. The two namespaces involved are the ordinary namespace and the tag namespace. A tag identifier needs to be used after a struct, union or enum keyword, while an ordinary identifier doesn’t need anything around it. You may have heard of the POSIX functionstat, whose interface looks like the followingIn that code snippet,
statis registered into the two aforementioned namespaces too.struct statwill refer to the struct, and merelystatwill refer to the function. Some people don’t like to precede identifiers always withstruct,unionorenum. Those usetypedefto introduce an ordinary identifier that will refer to the struct too. The identifier can of course be the same (both timescar), or they can differ (one timeAthe other timeB). It doesn’t matter.