Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > help understanding character arrays

Reply
Thread Tools

help understanding character arrays

 
 
dj
Guest
Posts: n/a
 
      05-18-2004
I've read section 6 of the FAQ, but still am a bit confused...
Please refer to the comments in the following
code for my questions:
-----------------------------------------------------------
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>


#define L_DATE 8

typedef struct
{
char date1[L_DATE];
char date2[L_DATE];
} my_record_t;

my_record_t my_rec;

void my_func(void);

int main(void)
{
char my_char[L_DATE];
memcpy(my_rec.date1, "20040101", L_DATE);
memcpy(my_rec.date2, "20040202", L_DATE);

/*
** I understand that "my_char" is the same as
** "&my_char[0]", but what about "&my_char"?
** I was surprised to find out that
** "my_char" == "&my_char"! (that is an exclamation,
** not a "not").
*/
printf("my_char = %p -> %p\n", &my_char, my_char );

/*
** I'm wondering if this is "defined" behavior, or if
** it just happens to work like this on my system?
**
** I'm asking because I saw some code which uses this
** "&my_char" in a memcpy, similar to what is done in
** my_func(), and I'm wondering if it is ok or not.
*/
printf("before: date1 = %.*s, date2 = %.*s\n",
L_DATE, my_rec.date1, L_DATE, my_rec.date2 );
my_func();
printf("after: date1 = %.*s, date2 = %.*s\n",
L_DATE, my_rec.date1, L_DATE, my_rec.date2 );

return EXIT_SUCCESS;
}

void my_func(void)
{
char local_date[L_DATE] = "19700101";
my_record_t *rec_p = &my_rec;

/*
** this doesn't look right to me, but it
** seems to work...
*/
memcpy( &rec_p->date2, &local_date, L_DATE );
}
--------------------------------------------------------


any help or comments are appreciated.

thanks,

-dj

 
Reply With Quote
 
 
 
 
Arthur J. O'Dwyer
Guest
Posts: n/a
 
      05-19-2004

On Tue, 18 May 2004, dj wrote:
>
> #include <stdlib.h>
> #include <stdio.h>
> #include <memory.h>


Non-standard header. You mean #include <string.h>, which is where
the standard functions like 'memcpy' and 'memmove' live.

> #define L_DATE 8
>
> typedef struct
> {
> char date1[L_DATE];
> char date2[L_DATE];
> } my_record_t;
>
> my_record_t my_rec;
>
> void my_func(void);
>
> int main(void)
> {
> char my_char[L_DATE];
> memcpy(my_rec.date1, "20040101", L_DATE);
> memcpy(my_rec.date2, "20040202", L_DATE);


This is not relevant to your question, but better style would
be to write:
strncpy(my_rec.date1, "20040101", sizeof my_rec.date1);
if you mean to fill 'my_rec.date1' with data from a string.
Using 'memcpy' is okay, but it leaves the possibility that
some maintainer will come along and change the date string to
a shorter one, like this:
memcpy(my_rec.date1, "0000", L_DATE); /* just zeroes for now */
and then the code will break horrifically. 'strncpy' has its
own pitfalls, of course, but they're pitfalls more suited to
this task than are the pitfalls of 'memcpy'.

> /*
> ** I understand that "my_char" is the same as
> ** "&my_char[0]", but what about "&my_char"?


'&mychar' is the address of 'mychar'. Since (the object) 'mychar'
is an array of 8 chars, (the expression) '&mychar' is a pointer to an
array[8] of char. The expression 'mychar', on the other hand, is
what you get when the object 'mychar' "decays" to a pointer to its
first element: a pointer to char.
The address of the array is the same as the address of its first
element, by definition. But the two expressions have different types:
one is a pointer to char and the other is a pointer to an array.
This is known in these parts as "The Rule," and I expect you can
Google for it. Look for Chris Torek's posts.

> ** I was surprised to find out that
> ** "my_char" == "&my_char"! (that is an exclamation,
> ** not a "not").


The value is the same; the type is not.

> */
> printf("my_char = %p -> %p\n", &my_char, my_char );


Using "%p" is a good way to experiment, but don't expect it
to produce definitive answers. Especially not if you invoke
undefined behavior by forgetting the casts:

printf("my_char = %p -> %p\n", (void*)&my_char, (void*)my_char);

If you don't understand the line above, then that would be a sign
that you should not be messing with this stuff yet.

> /*
> ** I'm wondering if this is "defined" behavior, or if
> ** it just happens to work like this on my system?
> **
> ** I'm asking because I saw some code which uses this
> ** "&my_char" in a memcpy, similar to what is done in
> ** my_func(), and I'm wondering if it is ok or not.
> */


It is. But IMHO it's more clear (and less typing!) to use
the unadorned 'my_char'. Adding superfluous '&'s to the source
code is just obfuscation in this case.

<snip>
> memcpy( &rec_p->date2, &local_date, L_DATE );


Better IMHO:
memcpy(rec_p->date2, local_date, sizeof local_date);

HTH,
-Arthur

 
Reply With Quote
 
 
 
 
Vijay Kumar R Zanvar
Guest
Posts: n/a
 
      05-19-2004

"dj" <(E-Mail Removed)> wrote in message news(E-Mail Removed)...
> I've read section 6 of the FAQ, but still am a bit confused...
> Please refer to the comments in the following
> code for my questions:
> -----------------------------------------------------------
> #include <stdlib.h>
> #include <stdio.h>
> #include <memory.h>
>
>
> #define L_DATE 8
>
> typedef struct
> {
> char date1[L_DATE];
> char date2[L_DATE];
> } my_record_t;
>
> my_record_t my_rec;
>
> void my_func(void);
>
> int main(void)
> {
> char my_char[L_DATE];
> memcpy(my_rec.date1, "20040101", L_DATE);
> memcpy(my_rec.date2, "20040202", L_DATE);
>
> /*
> ** I understand that "my_char" is the same as
> ** "&my_char[0]", but what about "&my_char"?
> ** I was surprised to find out that
> ** "my_char" == "&my_char"! (that is an exclamation,
> ** not a "not").
> */


A simple example should be helpful for you to understand the difference between
`my_char' and `&my_char'. Their values, thought numerically, are same but their
semantic meanings are not.

The address-of operator when applied to an object yields a pointer to (the
location of) that object. For example,

int a, *p;
p = &a;

&a yields the address of the integer object a. An address can be represented by
a pointer. In other words, a pointer is an object which can store the lvalue of
a compatible object. So the declaration,

int *p;

says that p is pointer to an int, and can store the lvalue of a (&a).
Similarly the declaration,

char my_char[L_DATE];

says my_char is an array of char. And, the address-of operator would yield the
address of the array object as it did for the integer object above. Now, what
should be the pointer type to store the address of the array? Let us build the
declaration of pointer to an array of char:

The basic type of pointer is `char', and the pointer declaration is

char *ptr;

but, this not a pointer to an array; it is, but, pointer to a char. So, a
pointer to the array is:

char (*ptr)[L_DATE];

Now, the address can be taken.

ptr = &my_char;


Save my English, I think the above points are OK. Another point, I think,
is using identifiers beginning with "L_" is reserved (but, I'm not sure).

What Mr. Arthur was saying about "The Rule" is here:
http://web.torek.net/torek/c/expr.html#therule

[..]
> any help or comments are appreciated.
>
> thanks,
>
> -dj
>


--
"Thinking should become your capital asset, no matter whatever
ups and downs you come across in your life."
- Dr. APJ Abdul Kalam, The President of India


 
Reply With Quote
 
Barry Schwarz
Guest
Posts: n/a
 
      05-23-2004
On Tue, 18 May 2004 23:29:12 GMT, dj <(E-Mail Removed)>
wrote:

>I've read section 6 of the FAQ, but still am a bit confused...
>Please refer to the comments in the following
>code for my questions:
>-----------------------------------------------------------
>#include <stdlib.h>
>#include <stdio.h>
>#include <memory.h>
>
>
>#define L_DATE 8
>
>typedef struct
>{
> char date1[L_DATE];
> char date2[L_DATE];
>} my_record_t;
>
>my_record_t my_rec;
>
>void my_func(void);
>
>int main(void)
>{
> char my_char[L_DATE];
> memcpy(my_rec.date1, "20040101", L_DATE);


It doesn't affect your code but I wanted to emphasize that
my_rec.date1 does not contain a string at this point because the
terminating '\0' was not included in the count of characters to be
copied.

> memcpy(my_rec.date2, "20040202", L_DATE);
>
> /*
> ** I understand that "my_char" is the same as
> ** "&my_char[0]", but what about "&my_char"?
> ** I was surprised to find out that
> ** "my_char" == "&my_char"! (that is an exclamation,
> ** not a "not").


They only appear to be the same because you use memcpy in my_func.
Others have explained the difference. You can see it for yourself by
changing the calls to memcpy to strncpy. memcpy works because its
pointer parameters are pointers to void which are compatible with any
pointer type while strncpy's pointer parameters are pointers to char
which are not compatible with pointers to array of char.

> */
> printf("my_char = %p -> %p\n", &my_char, my_char );
>
> /*
> ** I'm wondering if this is "defined" behavior, or if
> ** it just happens to work like this on my system?
> **
> ** I'm asking because I saw some code which uses this
> ** "&my_char" in a memcpy, similar to what is done in
> ** my_func(), and I'm wondering if it is ok or not.
> */
> printf("before: date1 = %.*s, date2 = %.*s\n",
> L_DATE, my_rec.date1, L_DATE, my_rec.date2 );
> my_func();
> printf("after: date1 = %.*s, date2 = %.*s\n",
> L_DATE, my_rec.date1, L_DATE, my_rec.date2 );
>
> return EXIT_SUCCESS;
>}
>
>void my_func(void)
>{
> char local_date[L_DATE] = "19700101";
> my_record_t *rec_p = &my_rec;
>
> /*
> ** this doesn't look right to me, but it
> ** seems to work...
> */
> memcpy( &rec_p->date2, &local_date, L_DATE );
>}
>--------------------------------------------------------
>
>
>any help or comments are appreciated.
>
>thanks,
>
>-dj




<<Remove the del for email>>
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Understanding Arrays within Arrays MG Javascript 5 04-16-2010 08:08 PM
Multidimensional arrays and arrays of arrays Philipp Java 21 01-20-2009 08:33 AM
Problem understanding pass by value and pass by reference of arrays and what happens in the memory venkatagmail C++ 11 10-03-2007 02:00 PM
Do I lack understanding or arrays? Hakusa@gmail.com Ruby 4 05-27-2007 11:39 PM
Understanding Arrays and enumeration Christopher T King Javascript 3 08-14-2004 01:07 AM



Advertisments