Need help understanding pointers and various other C stuff
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct dict_pair {
void *key;
void *value;
struct dict_pair *tail;
} dict;
dict* NewDictionary(void) {
dict *dictionary = malloc(sizeof(dict)); //or we can malloc(sizeof(struct dict_pair))
dictionary->tail = NULL;
}
//dict operations
void put(dict *dictionary, void *key, void *value) {
//new pair
dict *new_pair = malloc(sizeof(dict));
new_pair->key = key;
new_pair->value = value;
//chaining
new_pair->tail = NULL;
dict *last_node = dictionary;
while (last_node->tail != NULL) {
last_node = last_node->tail;
}
last_node->tail = new_pair;
}
void* get(dict *dictionary, void *key) {
dict *current_dict = dictionary;
while (1) {
if (current_dict->key == key) {
return current_dict->value;
}
else if (dictionary->tail != NULL) {
current_dict = current_dict->tail;
} else break;
}
return NULL;
}
//end operations
int main(void) {
dict *dictionary = NewDictionary();
put(dictionary,(void *) "buffer1",(void *) "Fake1");
put(dictionary,(void *) "buffer2",(void *) "Fake2");
put(dictionary,(void *) "key",(void *) "This is the value.");
char *result = (char *) get(dictionary, (void *) "key");
printf("%s\n",result开发者_JAVA技巧);
}
So I managed to write the above code to implement a dictionary. While I was able to write the code and compile and get it to work expectedly, there are some stuff which I am not clear about. Mostly regarding pointers:
dict *current_dict = dictionary;
Lets take this line for example. We are declaring a variable which holds dict type. current_dict is a pointer, right? and dictionary is a pointer. However, *current_dict is not a pointer, how can it be assigned to a pointer?
Or do I have to explicitly type this to make it error?
dict (*current_dict) = dictionary;
If so, would this mean that the above line mean that we are declaring a current_dict variable with a dict type, and it is a pointer. Wouldnt that declaration be
(dict*) current_dict = dictionary;
As you can see, the spacing and positioning is confusing me.
Can someone help with explaining the difference in the * positioning?
Thanks!
While dict *dictionary
and dict* dictionary
have the same meaning in C, I prefer the former.
I prefer to think of pointer declarations in these terms:
int x; // x is an int
int *y; // *y is an int
int **z; //**z is an int
If you remember that *y
is the object that y
points to, then it follows that y
must be a pointer-to-an-int. And similarly z
must be a pointer-to-a-pointer-to-an-int.
When you write:
dict * current_dict = dictionary;
this is equivalent to:
dict * current_dict; current_dict = dictionary;
I understand your confusion, because *
is used for two purposes in the C language: One purpose is to declare a pointer in a declaration. The second purpose is to dereference a pointer in an expression.
Your example is a declaration on the left side of the equal sign and an expression on the right side of the equal sign. (Technically it's all a declaration which contains an expression, but that muddies the point of why *
means a particular thing in a particular context.)
// * to the right of a type means a pointer of that type
Dict* dictPtr1 = dictPtr2; // LHS and RHS are pointers
Dict* dictPtr4 = (Dict *) malloc( sizeof(Dict));
// * to the left of a variable means dereference that variable
// the variable must be a pointer
Dict dictObject = *dictPtr; // LHS and RHS are objects
// & to the left of a variable means the address-of the object
Dict* dictPtr3 = &dictObject;
It doesn't matter where * stands in a variable declaration. dict* current
and dict *current
are the same. But if you use a pointer in an expression then *dict
means dereferencing, that is, it returns an object pointed by dict
.
dict *current_dict;
is a pointer, whitespace is not significant here. All these definitions are similar:
dict *current_dict;
dict* current_dict;
dict * current_dict;
dict*current_dict;
In all the above cases, current_dict is of type pointer to dict
Be aware, if you have something like this:
dict * current_dict,other_dict;
You have declared 2 variables; current_dict is of type pointer to dict while other_dict is of type dict
dict *current_dict = dictionary;
Lets take this line for example. We are declaring a variable which holds dict type. current_dict is a pointer, right? and dictionary is a pointer. However, *current_dict is not a pointer, how can it be assigned to a pointer?
This declares current_dict
to be a pointer to a dict
and sets it to point to the same place that dictionary
points to. The positioning of * is only relevant when you declare multiple variables on the same line.
Had you put
dict current_dict = dictionary;
this would not have worked correctly because this declares current_dict
to be the actual struct.
For what it's worth, in your put function there is no reason to do
dict *last_node = dictionary;
and then use last_node rather than dictionary
. They are both pointers to the same thing and when you declare a pointer in your function parameters as you did with dict *dictionary
your function is actually getting a local copy of the pointer from the calling function. Changes to the local copy of the pointer in dictionary
will not affect the pointer in the calling function (if you wanted such a thing you'd need to have a function declaration like void put(dict **dictionary, void *key, void *value)
... but you don't want that here. :) ).
精彩评论