473,399 Members | 3,302 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,399 software developers and data experts.

help understanding character arrays

dj
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

Nov 14 '05 #1
3 1410

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

Nov 14 '05 #2

"dj" <dj****@thelamp.homelinux.net> wrote in message news:Pi**************************************@thel amp.homelinux.net...
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
Nov 14 '05 #3
On Tue, 18 May 2004 23:29:12 GMT, dj <dj****@thelamp.homelinux.net>
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>>
Nov 14 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: Foxy Kav | last post by:
Hi everyone, Im currently doing first year UNI, taking a programming course in C++, for one project i have to create a simple array manipulator... that i have done, but i cant figure out how to...
5
by: ali | last post by:
Hi, I'm trying to understand the reason for different output on the following codes Code1: #include <iostream.h> int main()
4
by: CoolPint | last post by:
I would be grateful if someone could point out if I am understanding correctly and suggest ways to improve. Sorry for the long message and I hope you will kindly bear with it. I have to make it...
3
by: s.subbarayan | last post by:
Dear all, I encountered the following piece of program: #include <stdio.h> void strprint(char *str); void main() { char *spr="hello"; strprint(spr); }
33
by: aaron | last post by:
I have a question in my class.. hoping to get some help I need to create a program that will print firstName middleName lastName then their initials User will input: John Smith Doe Output:...
33
by: Martin Jørgensen | last post by:
Hi, In continuation of the thread I made "perhaps a stack problem? Long calculations - strange error?", I think I now got a "stable" error, meaning that the error always seem to come here now...
3
by: c++dummy | last post by:
I got this project for my class and I'm totally lost as to how to copy the 1d array with the bone name into a 2d array using this supposed strncpy function I'm supposed to create. I believe the...
9
by: lilchiko1286 | last post by:
I am taking an intro to C++ course in college. I was assigned a project that i must complete on MS Visual Studio in where I am supposed to prompt the user for a name and then a letter and output...
110
by: fjm | last post by:
For some reason, I have always had a hard time understanding arrays as they pertain to php and databases. I understand associative arrays just fine but when there are multidimensional arrays, I kinda...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.