On Monday 18 April 2005 05:48, Colin Carter wrote:
On Monday 18 April 2005 12:00, Synthetic Cartoonz wrote:
To make a FORTRAN character string acceptable to a C routine one might use: StringFred(1:6) = "Hello" // char(0) where // is the FORTRAN symbol for concatenate.
How does the C macro work? [snip] NULL is most correctly used to describe a pointer value, but depending on it's context in the code, NULL could be used as a 0 value char, long,
On Sunday 17 April 2005 12:22, Colin Carter wrote: [snip] pointer, etc, though some compilers might cough up warnings about type conversions.
Hi Synthetic, and thanks, This is what I thought, but because, as you said, some programmers use the symbol NULL as a substitute for an integer zero, I became confused.
Though there is really nothing wrong with it, most C code wouldn't terminate a string by stuffing NULL into a character position. (assuming char a[2] and char * b pointing to something usable...)
a[0] = NULL; or *b = NULL;
Instead you'll usually see:
a[0] = '\0'; or *b = '\0';
How about: char Buffer[] = "Hello Charlie"; Buffer[5] = '\0' Is this 'stuffing a NUL' ?
Yes. You turned Buffer into the string "Hello".
Or would you do a strncpy() ?
In FORTRAN we have a nice (called obsolete) facility called EQUIVALENCE used like:
integer (kind=4):: iArray(64) character(kind=1,len=256):: cArray equivalence (iArray, cArray)
This same memory can be referenced as a character string or an array of integers.
char Buffer[] = "Hello Charlie"; int * danger = (int *) Buffer; There ya go. Same thing in C. "danger" has to be managed very carefully, or you'll end up dereferencing danger outside of the space of Buffer. IF this must be done it would be safer to define Buffer to a multiple of the sizeof the largest type that you were doing "equivalence". (Which is basically what you do in your FORTRAN equivalance example: integer 4 * 64 == 256 . character 1 * 256 == 256 .) Maybe like.... char Buffer[ sizeof(long) * 5]; long * danger = (long *) Buffer; strcpy(Buffer, "Hey There Charlie"); assumming 4 byte longs then *danger would point to the value incorporating "Hey ". Depending on the cpu word/byte endian organization that value as a long might be 0x48657920 or some other juggling of those four hex pairs. Still, in C or any other language permitting real address pointers this is flirting with doom if you are not careful. However, a long time ago I recall seeing something similar. A C compiler implemented long words as the smallest allocation unit, so the assembly implementation of the standard C libraries could copy, compare, and count multiple bytes at a time resulting in very fast string/memory operations. The string handling code relied on the fact that a flag was set when any byte within the long register was zero, so the code knew when it reached the actual end of the strings. This, of course, is entirely dependent on CPU architecture.
Maybe someone can answer this: In the old cpu's the copy of an integer array required, in Assembler, the loading of each element into a register followed by the storage of the element into the new array. And the associated maintanace of a counter in another register.
Whereas copy of a string involved placing the address of each string into a register, and the number of characters to move, followed by one assembler instruction and the hardware did the rest at the speed of light.
Thus, copying the string equivalent was much faster than copying an array of integers.
This would be CPU architecture dependant. If a CPU does not support this, then the implementation of strcpy and similar functions in the libraries would look just like the long, slow(er) integer copy operation.
I have done no Assembler since M$ Windows 95. Does anybody know enough about modern cpu's to answer my question?