M
Mark Richards
I've been programming for many years, but have only recently taken a
deep "C" dive (bad pun, i know) and need a lot of explanation from an
expert. My questions center around those mysterious pointer beasties.
The following code is excerpted from digitemp, a program that reads
1-wire devices. Digitemp is the work of Brian C. Lane.
As I walk through this code, I have a number of questions. I'm hoping
someone with experience in pointers can provide a few for me (another
pun) Also, I am sorry that this message is long. I tried to
shorten it, but could not get my questions across any other way.
I have indented the code and my questions and comments are preceded by
// so they will be easier to follow. I hope this is less confusing and
respectful of everyone's time.
// The following _roms structure contains a list of 8 byte addresses...
struct _roms
{
unsigned char *roms; /* Array of 8 bytes */
int max; /* Maximum number */
};
// A variable, sensor_list is initialized...
struct _roms *sensor_list
// The roms part of the structure is filled with an "array" of sorts,
// containing one or more 8-byte addresses. These addresses resolve,
// when printed, as hex values.
// For example: "12BAA91C000000A3" is a valid address string.
// The other variable within the _roms structure is "max" which is
// loaded with the total number of addresses stored in "roms".
// As I understand it, *sensor_list as defined above is a pointer to the
// beginning of the entire structure defined as _roms.
// Is this correct?
// Let's say sensor_list is loaded with one 8-byte-wide address:
// "12BAA91C000000A3".
// Here is how it's passed through in the code:
read_all(&sensor_list);
// Above, read_all(&sensor_list) says "call the read_all function and
// pass as a parameter the (starting) address where the variable
// sensor_list is. Is this a correct reading?
int read_all(struct _roms *sensor_list)
{
int x;
for(x = 0; x < (num_cs + sensor_list->max); x++)
{
read_device(sensor_list, x);
}
return 0;
}
// It appears that a de-referenced pointer to sensor_list is being
// defined in the function header, correct? (Since the address of
// sensor_list was passed in the call to read_all(&sensor_list).)
// From this, is it correct to assume that further de-referencing of
// sensor_list will not be needed?
// Here's where the action takes place:
int read_device(struct _roms *sensor_list, int sensor)
{
...
}
// What seems odd to me is that, again, sensor_list is being defined in
// this function header as a dereferenced pointer. Yet, the calling
// function used a variable (sensor_list) that had already been
// de-referenced. That's why it called read_device with just
// "sensor_list", correct?
// So there is a fundamental here that I am not understanding.
// Within read_device, the sensor_list structure is used to pass a
// complete 8-byte address to a function called owSerialNum:
owSerialNum( 0, &sensor_list->roms[sensor*8], FALSE );
// If I call the function like this:
owSerialNum( 0, "12BAA91C000000A3", FALSE );
// it works perfectly. The documentation for owSerialNum says that the
// second parameter is a buffer containing the address.
// I can see that &sensor_list->roms[sensor*8] is saying, "the address
// of roms[beginning at this offset] within a structure we call
// "sensor_list".
// Since the second parameter in
// owSerialNum( 0,"12BAA91C000000A3",FALSE); is passed through as the
// starting address of a buffer, and since &sensor_list->roms[sensor*8]
// is also the address of a buffer, they must be synonymous, correct?
// Well, they appear not to be so.
// The following code works:
printf(" Address: %s","12BAA91C000000A3");
// This prints garbage:
printf(" Address: %s",&sensor_list->roms[sensor*8] );
// In fact, it looks like it's printing a memory address instead of the
// contents of that address. Why?
// If I do this...
printf("Sensor here: %s\n",sensor_list->roms[sensor*8]);
// I get a segmentation fault (crash).
// If I do this:
printf("Sensor here: %s\n",*sensor_list->roms[sensor*8]);
// The compiler complains: invalid type argument of `unary *'
*********
What I eventually want to do is pass into the application an address as
a string parameter, and be able to pass it into the read_device
function so that it is properly passed to owSerialNum(). It seems
simple enough, but I'm hung up on the above issues at the moment. If I
can be guided through the mud, this once, I think I'll have it.
Help!
deep "C" dive (bad pun, i know) and need a lot of explanation from an
expert. My questions center around those mysterious pointer beasties.
The following code is excerpted from digitemp, a program that reads
1-wire devices. Digitemp is the work of Brian C. Lane.
As I walk through this code, I have a number of questions. I'm hoping
someone with experience in pointers can provide a few for me (another
pun) Also, I am sorry that this message is long. I tried to
shorten it, but could not get my questions across any other way.
I have indented the code and my questions and comments are preceded by
// so they will be easier to follow. I hope this is less confusing and
respectful of everyone's time.
// The following _roms structure contains a list of 8 byte addresses...
struct _roms
{
unsigned char *roms; /* Array of 8 bytes */
int max; /* Maximum number */
};
// A variable, sensor_list is initialized...
struct _roms *sensor_list
// The roms part of the structure is filled with an "array" of sorts,
// containing one or more 8-byte addresses. These addresses resolve,
// when printed, as hex values.
// For example: "12BAA91C000000A3" is a valid address string.
// The other variable within the _roms structure is "max" which is
// loaded with the total number of addresses stored in "roms".
// As I understand it, *sensor_list as defined above is a pointer to the
// beginning of the entire structure defined as _roms.
// Is this correct?
// Let's say sensor_list is loaded with one 8-byte-wide address:
// "12BAA91C000000A3".
// Here is how it's passed through in the code:
read_all(&sensor_list);
// Above, read_all(&sensor_list) says "call the read_all function and
// pass as a parameter the (starting) address where the variable
// sensor_list is. Is this a correct reading?
int read_all(struct _roms *sensor_list)
{
int x;
for(x = 0; x < (num_cs + sensor_list->max); x++)
{
read_device(sensor_list, x);
}
return 0;
}
// It appears that a de-referenced pointer to sensor_list is being
// defined in the function header, correct? (Since the address of
// sensor_list was passed in the call to read_all(&sensor_list).)
// From this, is it correct to assume that further de-referencing of
// sensor_list will not be needed?
// Here's where the action takes place:
int read_device(struct _roms *sensor_list, int sensor)
{
...
}
// What seems odd to me is that, again, sensor_list is being defined in
// this function header as a dereferenced pointer. Yet, the calling
// function used a variable (sensor_list) that had already been
// de-referenced. That's why it called read_device with just
// "sensor_list", correct?
// So there is a fundamental here that I am not understanding.
// Within read_device, the sensor_list structure is used to pass a
// complete 8-byte address to a function called owSerialNum:
owSerialNum( 0, &sensor_list->roms[sensor*8], FALSE );
// If I call the function like this:
owSerialNum( 0, "12BAA91C000000A3", FALSE );
// it works perfectly. The documentation for owSerialNum says that the
// second parameter is a buffer containing the address.
// I can see that &sensor_list->roms[sensor*8] is saying, "the address
// of roms[beginning at this offset] within a structure we call
// "sensor_list".
// Since the second parameter in
// owSerialNum( 0,"12BAA91C000000A3",FALSE); is passed through as the
// starting address of a buffer, and since &sensor_list->roms[sensor*8]
// is also the address of a buffer, they must be synonymous, correct?
// Well, they appear not to be so.
// The following code works:
printf(" Address: %s","12BAA91C000000A3");
// This prints garbage:
printf(" Address: %s",&sensor_list->roms[sensor*8] );
// In fact, it looks like it's printing a memory address instead of the
// contents of that address. Why?
// If I do this...
printf("Sensor here: %s\n",sensor_list->roms[sensor*8]);
// I get a segmentation fault (crash).
// If I do this:
printf("Sensor here: %s\n",*sensor_list->roms[sensor*8]);
// The compiler complains: invalid type argument of `unary *'
*********
What I eventually want to do is pass into the application an address as
a string parameter, and be able to pass it into the read_device
function so that it is properly passed to owSerialNum(). It seems
simple enough, but I'm hung up on the above issues at the moment. If I
can be guided through the mud, this once, I think I'll have it.
Help!