LIZAK98%SNYBUFVA.BITNET@cornellc.cit.cornell.edu (A SHOW OF HANDS) (04/01/89)
This one is probably old hat for any of you C programmers out there,
but I am having a hell of a time writing this little routine. Awhile
back I wrote a BBS program that is a C-Net look alike, however, because
the only language that I knew that I had on my Amiga was BASIC, I had to
use that. The thing runs toooo slow for any real application other than
saying, oh it looks nice... too bad it doesnt keep up with 2400 baud...
Anyways, the output routine was written something like this (it's more
complex as it checks for control characters, etc before printing, but this
is the major part):
FOR I=1 TO LEN(A$)
PRINT MID$(A$,I,1);
NEXT I
I posted this to a BBS and asked for a C equivlent, however, what I got was
a fragment of what I really needed... here is what was posted for me...
for(i=0;a[i]=!'\0';i++)
printf("%c",a[i]);
no matter what I put for the declaration... it wouldnt work! I added this
to the program to try to make it work... whats wrong with this?
main()
{
char *a;
int i;
a="This is a test string...";
...above code....
}
How must I declare a? How must I define the string?
Thanks,
#####################################################################
# #
# Rob Lizak Jr. Bitnet ID: LIZAK98@SNYBUFVA #
# DECNet ID: BSCOLA::LIZAK98 #
# #
# "Once YOU buy a prize, it's YOURS to keep!" #
# #
#####################################################################
cmcmanis%pepper@Sun.COM (Chuck McManis) (04/01/89)
In article <12000@louie.udel.EDU> (Rob Lizak Jr.) writes: > FOR I=1 TO LEN(A$) > PRINT MID$(A$,I,1); > NEXT I C equivalent might be more syntactically written as for (i=0; i < strlen(a); i++) printf("%c", a[i]); Get a copy of the book "Programming in C" by Stephen G. Kochan, ISBN 0-8104-6261-3, it has a good discussion of strings. >no matter what I put for the declaration... it wouldnt work! I added this >to the program to try to make it work... whats wrong with this? char *a; /* This is a pointer to a string */ char a[80]; /* this is a pointer to a string with 80 bytes allocated */ Outside of a function you can declare : char *a = "this is a test string."; /* the auto allocates space */ -or- char a[80]; /* Global variable */ main() { char b[80]; /* Local variable */ /* this copies a string into your string buffer a */ strcpy(a,"this is a test string"); strcpy(b,a); /* Copy string a into string b */ } ----- --Chuck McManis uucp: {anywhere}!sun!cmcmanis BIX: cmcmanis ARPAnet: cmcmanis@sun.com These opinions are my own and no one elses, but you knew that didn't you. "A most excellent barbarian ... Genghis Kahn!"
kevin@uts.amdahl.com (Kevin Clague) (04/01/89)
In article <97113@sun.Eng.Sun.COM> cmcmanis@sun.UUCP (Chuck McManis) writes: >In article <12000@louie.udel.EDU> (Rob Lizak Jr.) writes: >> FOR I=1 TO LEN(A$) >> PRINT MID$(A$,I,1); >> NEXT I > >C equivalent might be more syntactically written as > for (i=0; i < strlen(a); i++) > printf("%c", a[i]); > >Get a copy of the book "Programming in C" by Stephen G. Kochan, ISBN >0-8104-6261-3, it has a good discussion of strings. > >>no matter what I put for the declaration... it wouldnt work! I added this >>to the program to try to make it work... whats wrong with this? > >char *a; /* This is a pointer to a string */ >char a[80]; /* this is a pointer to a string with 80 bytes allocated */ > >Outside of a function you can declare : >char *a = "this is a test string."; /* the auto allocates space */ >-or- >char a[80]; /* Global variable */ >main() >{ > char b[80]; /* Local variable */ > /* this copies a string into your string buffer a */ > strcpy(a,"this is a test string"); > strcpy(b,a); /* Copy string a into string b */ > >} >----- > >--Chuck McManis >uucp: {anywhere}!sun!cmcmanis BIX: cmcmanis ARPAnet: cmcmanis@sun.com >These opinions are my own and no one elses, but you knew that didn't you. >"A most excellent barbarian ... Genghis Kahn!" I had a hard time understanding from the posting at what level "things didn't work". I presumed Rob had gotten the thing to compile, and the problem was with "buffered I/O". Since Rob had no newline characters in his test string (and it was so short), the I/O buffers would not be flushed, and therefore he would get no output. I sent email suggesting this as a possible explanation. To really be compatible with basic (since he had no newlines), I think he would have to fflush(stdout) after every printf(), no? for (i = 0; i < strlen(a); i++) { printf("%c",a[i]); fflush(stdout); } or the less obvious, but more efficient (but Chuck knows this): char *b; b = a; while (*b) { printf("%b",*b++); fflush(stdout); } Kevin -- UUCP: kevin@uts.amdahl.com or: {sun,decwrl,hplabs,pyramid,seismo,oliveb}!amdahl!kevin DDD: 408-737-5481 USPS: Amdahl Corp. M/S 249, 1250 E. Arques Av, Sunnyvale, CA 94086 [ Any thoughts or opinions which may or may not have been expressed ] [ herein are my own. They are not necessarily those of my employer. ]
joe@dayton.UUCP (Joseph P. Larson) (04/02/89)
In article <97113@sun.Eng.Sun.COM> cmcmanis@sun.UUCP (Chuck McManis) writes: >In article <12000@louie.udel.EDU> (Rob Lizak Jr.) writes: >> FOR I=1 TO LEN(A$) >> PRINT MID$(A$,I,1); >> NEXT I > >C equivalent might be more syntactically written as > for (i=0; i < strlen(a); i++) > printf("%c", a[i]); Oh, but people... Don't use Chuck's code. It appears very straightforward, except that you can't convince C not to execute the strlen() every time. Yes, boys and girls -- Chuck's code will execute strlen(a) strlen(a)+1 times. So what you might want to do is: for (i = 0, count = strlen(a); i < count; i++) printf("%c", a[i]); Now, I realize most people out there KNOW C is going to do this to them, but as long as we're giving C lessons to begin with, we might as well make sure the novices are aware that C executes all parts of the conditional in a for-loop exactly one more time than the number of iterations through the loop. (The test is at the top of the loop, so it checks once for each loop plus takes the time that the condition fails.) Of course, printf("%s", a) will work, too, but that's beside the point. -Joe -- Life is a cabaret (old chum). UUCP: rutgers!dayton!joe (Picts 1-13 are DHDSC - Joe Larson/MIS 1060 ATT : (612) 375-3537 now ready.) 700 on the Mall, Mpls, Mn. 55402
jms@antares.UUCP (Joe Smith) (04/02/89)
I have seen 2 follow ups to this question, neither of which addresses the real problem. In article <12000@louie.udel.EDU> LIZAK98%SNYBUFVA.BITNET@cornellc.cit.cornell.edu (A SHOW OF HANDS) writes: > >for(i=0;a[i]=!'\0';i++) > printf("%c",a[i]); The above piece of code will set every character in the string "a" to a Control-A (ASCII code 001) and will continue past the end of the sting and wipe out your program. '\0' is zero !0 is one a[i] = !0 sets a[i] to one Note that the bad code has =! instead of !=. The correct code is for(i=0;a[i]!='\0';i++) { a bunch of "if" statements that handle special characters else printf("%c",a[i]); } -- Joe Smith (408)922-6220 | jms@antares.Tymnet.COM or jms@opus.Tymnet.COM McDonnell Douglas FSCO | UUCP: ...!{ames,pyramid}!oliveb!tymix!antares!jms PO Box 49019, MS-D21 | PDP-10:JMS@F74.Tymnet.COM CA license plate:"POPJ P," San Jose, CA 95161-9019 | narrator.device: "I didn't say that, my Amiga did!"
cmcmanis%pepper@Sun.COM (Chuck McManis) (04/03/89)
[Not at Kevin, just Kevin happened to post, everyone else just sent mail :-)] In article <13.6va2CVf1010TxC9.@amdahl.uts.amdahl.com> (Kevin Clague) writes: > or the less obvious, but more efficient (but Chuck knows this): > > char *b; > > b = a; > > while (*b) { > printf("%b",*b++); > fflush(stdout); > } > Several people sent me messages ranging from, "how could someone like you post such stupid C code?" to the more helpful "... didn't you know it would be _much_ more efficient if you did it like this ..." [insert Kevin's example here.] To keep from having to send everyone copies I've decided to post my thinking on this matter, fortunately this is not in c.s.a.t since it has very little technical content : This is a _BASIC_ programmer we are talking to. Not your everyday pro ok? He writes : 10 FOR I = 1 TO LEN$(A$) 20 PRINT MID$(A$, I, I) 30 NEXT I Now when one is teaching someone a new language, especially someone who's been damaged by learning BASIC first, one starts with direct equivalences. Token substitution and such. This trains the students eyes into seeing the new syntax but keeps some anchor points so that they don't loose sync. Once they understand the construction of for(;;){} loops one moves on to talk about pointers, while loops etc. The favorite example : char *foo = a; while(*foo) printf("%c",*foo++); Introduces no less than 5 totally radical ideas to the BASIC programmer. They are 1) String Pointers, 2) Non-Boolean loop conditions, 3) While loops, 4) Pointer arithmetic and implied assignment (++), and 5) NULL termination of C strings. That makes it a _lousy_ example. Your BASIC programmer is not only lost, he doesn't even know where to start asking questions! You've gone way over his head. So as an eventual programming goal to shoot for this if fine. In the mean time lets not make him feel totally stupid shall we? --Chuck McManis uucp: {anywhere}!sun!cmcmanis BIX: cmcmanis ARPAnet: cmcmanis@sun.com These opinions are my own and no one elses, but you knew that didn't you. "A most excellent barbarian ... Genghis Kahn!"
hcj@lzaz.ATT.COM (HC Johnson) (04/05/89)
In article <12000@louie.udel.EDU>, LIZAK98%SNYBUFVA.BITNET@cornellc.cit.cornell.edu (A SHOW OF HANDS) writes: > > FOR I=1 TO LEN(A$) > PRINT MID$(A$,I,1); > NEXT I > > > for(i=0;a[i]=!'\0';i++) > printf("%c",a[i]); The C construct for not equal is != also useful <= and >=. The =! has meanings you are not ready for. Howard C. Johnson ATT Bell Labs att!lzaz!hcj hcj@lzaz.att.com
dmg@ssc-vax.UUCP (David Geary) (04/06/89)
In article <97113@sun.Eng.Sun.COM>, Chuck McManis writes: >In article <12000@louie.udel.EDU> (Rob Lizak Jr.) writes: >> FOR I=1 TO LEN(A$) >> PRINT MID$(A$,I,1); >> NEXT I > >> for(i=0;a[i]=!'\0';i++) >> printf("%c",a[i]); >> >>no matter what I put for the declaration... it wouldnt work! I added this >>to the program to try to make it work... whats wrong with this? > >char *a; /* This is a pointer to a string */ >char a[80]; /* this is a pointer to a string with 80 bytes allocated */ No! char a[80] is not a pointer at all. It is an array. Using the name of an array *under certain conditions* is equivalent to a pointer to the first element of the array, but an array is very different from a pointer (one aspect of C that can be quite confusing). Anyway, what Rob is trying to do is perfectly legal. The problem arises in the for loop: for(i=0; a[i]=!`\0`; i++) ^^ This should be: for(i=0; a[i]!=`\0`; i++) ^^ Instead of the conditional part of the loop checking to see if the next char. is NULL, a[i] is ASSIGNED a value. Since '\0' is equivalent to 0 on most systems, we get a[i] = !0. !0 is not false, so it is true. In C, true, (when it's the result of logical operators) is 1. Therefore, Rob is assigning every character in the array the value of 1. Not quite what was intended! Two other notes: Cramming everything together with no spaces is not good style. I would have written the for loop thusly: for(i = 0; a[i] != NULL; i++) This is much more readable, and I suspect it would be easier to spot if the ! and = were in the wrong order. Secondly, this would be more appropriate for comp.lang.c ps: Sorry if someone else has already pointed this out, but I'm way behind on my news reading, and there aren't many questions in this newsgroup that I find I can answer ;-). David Geary -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~ David Geary, Boeing Aerospace, ~ ~ #define Seattle RAIN ~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
deven@pawl.rpi.edu (Deven Corzine) (04/07/89)
In article <2570@ssc-vax.UUCP> dmg@ssc-vax.UUCP (David Geary) writes: [...] >Since '\0' is equivalent to 0 on most systems, [...] Excuse me? Name ONE system where '\0' is NOT zero??? Deven -- ------- shadow@pawl.rpi.edu ------- Deven Thomas Corzine --------------------- Cogito shadow@acm.rpi.edu 2346 15th Street Pi-Rho America ergo userfxb6@rpitsmts.bitnet Troy, NY 12180-2306 (518) 272-5847 sum... In the immortal words of Socrates: "I drank what?" ...I think.
hans@nlgvax.UUCP (Hans Zuidam) (04/07/89)
>In article <97113@sun.Eng.Sun.COM>, Chuck McManis writes: >>char *a; /* This is a pointer to a string */ >>char a[80]; /* this is a pointer to a string with 80 bytes allocated */ In article <2570@ssc-vax.UUCP> dmg@ssc-vax.UUCP (David Geary) writes: > No! char a[80] is not a pointer at all. It is an array... Please check your K&R before responding: K&R 7.1, pg. 185: An identifier is a primary expression, provided it has been suitably declared as discussed below. If the type of the identifier is "array of ...", then the value of the identifier-expression is a pointer to the first object in the array, and the type of the expression is "pointer to ...". and K&R 7.1, pg. 186: The expression E1[E2] is identical (by definition) to *((E1)+(E2)). This is from: "The C programming language", Kernighan, Brian W., Ritchie, Dennis M. Prentice-Hall Software series, 1978. So: 'char *a' is *identical* to 'char a[80]' *except* for the fact that in the second definition 'a' is a *constant* pointer. That is: you cannot assign a value to 'a'. Ponder these: c = "ABCDEF"[i] a[i] and i[a] and *(a + i) /* The function */ f(a, b) char a[], b[]; /* Called by */ char *c, *d; f(c, d) And so on. A useful cosequence of this is that one can construct flexible arrays: int *p, i; p = (int *) malloc(NrOfElements * sizeof(int)); for (i = 0; i < NrOfElements; i++) p[i] =0; p = (int *) realloc(p, NewNrOfElements * sizeof(int)); /* and so on... */ Hans -- Hans Zuidam E-Mail: hans@pcg.philips.nl Philips Telecommunications and Data Systems, Tel: +31 40 892288 Project Centre Geldrop, Building XR Willem Alexanderlaan 7B, 5664 AN Geldrop The Netherlands
kevin@cbmvax.UUCP (Kevin Klop) (04/08/89)
In article <231@nlgvax.UUCP> hans@nlgvax.UUCP (Hans Zuidam) writes: >>In article <97113@sun.Eng.Sun.COM>, Chuck McManis writes: >>>char *a; /* This is a pointer to a string */ >>>char a[80]; /* this is a pointer to a string with 80 bytes allocated */ > >In article <2570@ssc-vax.UUCP> dmg@ssc-vax.UUCP (David Geary) writes: >> No! char a[80] is not a pointer at all. It is an array... > [Several K&R quotations deleted] >So: > 'char *a' is *identical* to 'char a[80]' *except* for the > fact that in the second definition 'a' is a *constant* > pointer. That is: you cannot assign a value to 'a'. Actually, there is a difference between 'a' in the following two declarations: char a[80]; char *a; To demonstrate, though, let us look at the following statement: *a = '\3'; in assembly code, this would translate to (I have made the assumption that both declarations are GLOBAL in scope rather than allocated on the local stack): ; For the declaration "char a[80];" move.b #3,a ; move a byte into location referenced by 'a' ; For the declaration "char *a;" movea.l a,A0 ; get the pointer from memory move.b #3,(A0) ; and place a 3 into where it points you will notice that for the declaration "char *a;" we have to do the equivalent of a store indirect through a, whereas in the declaration "char a[80];" we store to the location "a". Note that this is hand coded assembly equivalences, and your compiler mileage may vary... :^) Thus, there is a very real difference between the two declarations. Usually there is no problem treating the two of them identically since the compiler takes care of it for you. However, since the identifier "a" has to be referenced differently for the two declarations, the following scenario can cause one many problems: Module 1: char a[80] main() { /* I don't know, put some of your favorite code here...*/ } Module 2: extern char *a; anotherfunction() { *a = '\0'; /* Insure a 0 length string */ . . . } the code generated in Module 2, "anotherfunction" is going to incorrectly reference the array. In fact, what it is going to do is concatenate the first four entried from the array, form those into a pointer, and store a byte length 0 whereever the concatenation points to. This is a BAD thing to do, in general. [More deleted here] >-- >Hans Zuidam E-Mail: hans@pcg.philips.nl -- Kevin -- Kevin Klop {uunet|rutgers|amiga}!cbmvax!kevin Commodore-Amiga, Inc. The number, 111-111-1111 has been changed. The new number is: 134-253-2452-243556-678893-3567875645434-4456789432576-385972
peter@sugar.hackercorp.com (Peter da Silva) (04/09/89)
In article <DEVEN.89Apr7055409@daniel.pawl.rpi.edu>, deven@pawl.rpi.edu (Deven Corzine) writes: > In article <2570@ssc-vax.UUCP> dmg@ssc-vax.UUCP (David Geary) writes: > [...] > >Since '\0' is equivalent to 0 on most systems, > [...] > Excuse me? Name ONE system where '\0' is NOT zero??? I don't know if a 'C' compiler exists for the CDC 6400, but in their 6-bit character set ' ' has the ascii value '\00'. The only unused value, I think, is '\77'. -- Peter "Have you hugged your wolf today" da Silva `-_-' ...texbell!sugar!peter, or peter@sugar.hackercorp.com 'U`
dinsdale%liaison@Sun.COM (Tom van Peer) (04/11/89)
Could you guys please move this discussion to comp.lang.c or to your local bar. I don't think this discussion fits this newsgroup anymore. Thanks. Tom van Peer. tom@pcg.philips.nl or dinsdale@liaison.sun.com (whichever is closer to you)
fred@maccs.McMaster.CA (Fred Whiteside) (04/11/89)
In article <3697@sugar.hackercorp.com> peter@sugar.hackercorp.com (Peter da Silva) writes: <In article <DEVEN.89Apr7055409@daniel.pawl.rpi.edu>, deven@pawl.rpi.edu (Deven Corzine) writes: <> In article <2570@ssc-vax.UUCP> dmg@ssc-vax.UUCP (David Geary) writes: <> [...] <> >Since '\0' is equivalent to 0 on most systems, <> [...] < <> Excuse me? Name ONE system where '\0' is NOT zero??? < <I don't know if a 'C' compiler exists for the CDC 6400, but in their 6-bit <character set ' ' has the ascii value '\00'. The only unused value, I think, <is '\77'. <-- <Peter "Have you hugged your wolf today" da Silva `-_-' <...texbell!sugar!peter, or peter@sugar.hackercorp.com 'U` Gee, Peter, On our old CDC it was the colon ':' that had a six bit value of zero. Space ' ' was 55 (octal). Remember that good old =xzfn routine? I never did figure out how that one worked ... Ah the fun of printing ":D" to a users terminal ... (Sorry about the non-amiga stuff) BTW has anyone plugged an ASDG 8M for the 1000 into a SupraDrive 4x4 before? I thought that I had read that there was a problem with the memory not being real close to the machine ie. first in line. Actually, I mean plugging a mini-rack C into the Supra; the 8M is just a card .... -fred whiteside uunet!utai!utgpu!maccs!fred fred@maccs.McMaster.CA fred@130.113.1.9
kevinh@pnet51.cts.com (Kevin Herrboldt) (04/11/89)
peter@sugar.hackercorp.com (Peter da Silva) writes: >I don't know if a 'C' compiler exists for the CDC 6400, but in their 6-bit >character set ' ' has the ascii value '\00'. The only unused value, I think, ^^^^^^^^^^ That's not right. 8) (Back in the stone age when all we had to use were Cybers, we referred to CDC's 6-bit character set as POOPSII.) UUCP: {rosevax, crash}!orbit!pnet51!kevinh ARPA: crash!orbit!pnet51!kevinh@nosc.mil INET: kevinh@pnet51.cts.com
ejkst@cisunx.UUCP (Eric J. Kennedy) (04/12/89)
In article <6542@cbmvax.UUCP> kevin@cbmvax.UUCP (Kevin Klop) writes: >Actually, there is a difference between 'a' in the following two >declarations: > >char a[80]; >char *a; [explanation and demonstration deleted] I've always thought that there was another difference besides what you described--one with more important and practical consequences. I've often had trouble with this stuff, being an inexperienced C programmer, so somebody please tell me if this isn't right! I just didn't see anything like this addressed in Kevin's article. It has been my understanding that "char *a;" gives you a pointer, (pointing to some arbitrary place), while "char a[80];" actually allocates 80 bytes of memory, and gives you a pointer to it, one that you can't (or shouldn't) change. Thus, char a[80]; main() { strcpy(a,"hello"); } is okay, while char *a; main() { strcpy(a,"hello"); } will cause real problems, like overwriting your program or another task with the word "hello". You'd have to do a malloc() or AllocMem() or something to have a safe place to put the "hello". So, is this right, or is my feeling of confusion justified? -- Eric Kennedy ejkst@cisunx.UUCP
peter@sugar.hackercorp.com (Peter da Silva) (04/12/89)
In article <2393@maccs.McMaster.CA>, fred@maccs.McMaster.CA (Fred Whiteside) writes: > In article <3697@sugar.hackercorp.com> peter@sugar.hackercorp.com (Peter da Silva) writes: > <I don't know if a 'C' compiler exists for the CDC 6400, but in their 6-bit > <character set ' ' has the ascii value '\00'. The only unused value, I think, > <is '\77'. You know, Peter, that's really amazingly stupid phrasing. "ascii value" indeed. > Gee, Peter, On our old CDC it was the colon ':' that had a six bit value > of zero. Space ' ' was 55 (octal). Hmm. There were at least two character sets (one with 64 characters and one with 63... with '\77' unused). > Remember that good old =xzfn routine? Nope. -- Peter "Have you hugged your wolf today" da Silva `-_-' ...texbell!sugar!peter, or peter@sugar.hackercorp.com 'U`
kevin@cbmvax.UUCP (Kevin Klop) (04/13/89)
In article <17491@cisunx.UUCP> ejkst@unix.cis.pittsburgh.edu (Eric J. Kennedy) writes: >It has been my understanding that "char *a;" gives you a pointer, >(pointing to some arbitrary place), while "char a[80];" actually >allocates 80 bytes of memory, and gives you a pointer to it, one that >you can't (or shouldn't) change. > >Thus, > >char a[80]; >main() >{ > strcpy(a,"hello"); >} > >is okay, while > >char *a; >main() >{ > strcpy(a,"hello"); >} > >will cause real problems, like overwriting your program or another task >with the word "hello". You'd have to do a malloc() or AllocMem() or >something to have a safe place to put the "hello". > >So, is this right, or is my feeling of confusion justified? > >-- >Eric Kennedy >ejkst@cisunx.UUCP You are correct in your statements. However, the I was addressing the common practice of thinking of the symbol 'a' in the following code: char a[80] as a pointer to the array, and using it as such. While this works most of the time, it is not 100% correct. For example, in most instances, the following code will have the same effect: function1() { char array[80]; char *a; a = array; strcpy (a,"Hello"); } and function2() { char array[80]; strcpy(array,"Hello"); } In both instances, "hello" will be placed into array[]; However, look at the definition of strcpy. It requires a char * for both its arguments. the identifier 'array' is not truly a char *, but can be used as such in this instance. This common practice is fine normally, but there are a few times that it can bite you. I think (but don't know for sure), that the technical definition of "array" in the above examples is really "&array[0]". -- Kevin -- Kevin Klop {uunet|rutgers|amiga}!cbmvax!kevin Commodore-Amiga, Inc. The number, 111-111-1111 has been changed. The new number is: 134-253-2452-243556-678893-3567875645434-4456789432576-385972 Disclaimer: _I_ don't know what I said, much less my employer.
nsw@cord.UUCP (Neil Weinstock) (04/13/89)
In article <6597@cbmvax.UUCP> kevin@cbmvax.UUCP (Kevin Klop) writes: >In article <17491@cisunx.UUCP> ejkst@unix.cis.pittsburgh.edu (Eric J. Kennedy) writes: [ stuff about pointers vs. arrays deleted ] There is a good discussion of this stuff in Chapter 3 of Andrew Koenig's "C Traps and Pitfalls." I would recommend the book to anyone trying to figure out some of the subtle nuances in C. Koenig, Andrew, "C Traps and Pitfalls," Addison-Wesley, 1989, ISBN 0-201-17928-8. /.- -- .. --. .- .-. ..- .-.. . ... .- -- .. --. .- .-. ..- .-.. . ...\ / Neil Weinstock / att!cord!nsw \ "Actually, it's still 256K, and we \ | AT&T Bell Labs / or \ fit MultiFinder in there, too." | \ Liberty Corner / nsw@cord.att.com \ - jimm, re: Amiga ROMs / \.- -- .. --. .- .-. ..- .-.. . ... .- -- .. --. .- .-. ..- .-.. . .../
darin@nova.laic.uucp (Darin Johnson) (04/13/89)
As an example of the difference between "char *a", and "char a[100]", here is a piece of code that bit me recently: put_args(xdr_wrapstring, &str) Where I had assumed str was a "char *", but instead, was really an array. The routine needed the ADDRESS of the string pointer, not the pointer. As such, the compiler gave me a rude warning - "thou shalt not take the address of an array!". This was on UNIX. I was surprised since I do this sort of stuff in VMS, where a temporary variable is created automatically (I can pass variables of the sort "&0", etc.). The fix was simple: register char *sp; ... intervening code ... sp = str; /* or instead, s = &str[0] */ put_args(xdr_wrapstring, &sp); Of course, if you pass an array or pointer as an argument to a routine, then inside the routine, you don't have a problem, since you can always take the address of the parameter - which is on the stack or in a temporary. Darin Johnson (leadsv!laic!darin@pyramid.pyramid.com) Can you "Spot the Looney"?
jimm@amiga.UUCP (Jim Mackraz) (04/14/89)
)>In article <97113@sun.Eng.Sun.COM>, Chuck McManis writes: )>>char *a; /* This is a pointer to a string */ )>>char a[80]; /* this is a pointer to a string with 80 bytes allocated */ )In article <2570@ssc-vax.UUCP> dmg@ssc-vax.UUCP (David Geary) writes: )> No! char a[80] is not a pointer at all. It is an array... In article <231@nlgvax.UUCP> hans@nlgvax.UUCP (Hans Zuidam) writes: )Please check your K&R before responding: ) ) K&R 7.1, pg. 185: ) An identifier is a primary expression, provided it has been ) suitably declared as discussed below. If the type of the identifier ) is "array of ...", then the value of the identifier-expression is a ) pointer to the first object in the array, and the type of the ) expression is "pointer to ...". )So: ) 'char *a' is *identical* to 'char a[80]' *except* for the ) fact that in the second definition 'a' is a *constant* ) pointer. That is: you cannot assign a value to 'a'. A fine reading of K&R, but if you declare char a[80]; in one file, and extern char *a; in another, your code won't run, regardless of how you interpret K&R. For the former, the symbol 'a' resolves to the address of 80 bytes of storage, for the latter, 'a' resolves to an address which may contain the address of some storage. They differ by one level of indirection. As a convenience, the syntax rules for using arrays and pointers are interchangable. In the case of function parameters, the parameter is a pointer in either case (the address of storage, either the constant or the *contents* of a pointer) is pushed on the stack in either case.) When evaluating the argument, the stack location *contains* the address of some storage. So, K&R stress that the declarations themselves (not just the usage syntax) are interchangable. But, what they do NOT stress, is that in GENERAL (i.e., for globals) the declarations are NOT interchangable, and no compiler will help you, no debugger will help you, and you will be dead. Only lint will help you, or the benefit of being killed in a previous life ... jimm -- Jim Mackraz, I and I Computing "He's hidden now, but you can see {cbmvax,well,oliveb}!amiga!jimm The holes where he breathes." - Shriekback Opinions are my own. Comments are not to be taken as Commodore official policy.
dmg@ssc-vax.UUCP (David Geary) (04/15/89)
In article <231@nlgvax.UUCP>, Hans Zuidam writes: ||In article <97113@sun.Eng.Sun.COM>, Chuck McManis writes: |||char *a; /* This is a pointer to a string */ |||char a[80]; /* this is a pointer to a string with 80 bytes allocated */ | |In article <2570@ssc-vax.UUCP> dmg@ssc-vax.UUCP (David Geary) writes: || No! char a[80] is not a pointer at all. It is an array... | |Please check your K&R before responding: | | K&R 7.1, pg. 185: | An identifier is a primary expression, provided it has been | suitably declared as discussed below. If the type of the identifier | is "array of ...", then the value of the identifier-expression is a ^^^^^^^^ Please *understand* your K&R before responding ;-) Of course, this is true - the *value* of the identifier-expression is a pointer to the first object in the array. What this means is: main() { char a[80]; /* an ARRAY - NOT a pointer */ DoSomething(a); /* here, the value of a is equivalent to &a[0], which is a pointer to the first object in the array a. This means we could have written: DoSomething(&a[0]); and gotten the same result. */ } | pointer to the first object in the array, and the type of the | expression is "pointer to ...". | |and | | K&R 7.1, pg. 186: | The expression E1[E2] is identical (by definition) to *((E1)+(E2)). Yes, this is true. | |So: | 'char *a' is *identical* to 'char a[80]' *except* for the | fact that in the second definition 'a' is a *constant* | pointer. That is: you cannot assign a value to 'a'. No! (no no no ;-) - This is a common misconception that many of my students in my introductory C class make. char *a is NOT identical to char a[80]; While it's true that in char a[80], the *value* of a is a constant pointer, and in char *a, a is a variable pointer, there is more difference than that: char *a; This gives you a pointer, period. a can hold the address where a char sits in memory: --------- | |-----------> --------- char a[80]; This gives you an actual array of characters, there is no pointer involved: --------- | a[0] | --------- | a[1] | --------- | a[2] | --------- . . . If you think that char *a and char a[80] are *identical* , *except* for the fact that the second definition...(as stated above), try this: main() { char a[80], *p; strcpy(a, "I can fit in array a, because there is memory allocated for me"); strcpy(p, "This is nothing but trouble"); } Notice that the second strcpy is going to cause you severe headaches (especially on an Amiga). -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~ David Geary, Boeing Aerospace, Seattle ~ ~ "I wish I lived where it *only* rains 364 days a year" ~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
donw@zehntel.zehntel.com (Don White) (04/15/89)
In article <522@lzaz.ATT.COM> hcj@lzaz.ATT.COM (HC Johnson) writes: >In article <12000@louie.udel.EDU>, LIZAK98%SNYBUFVA.BITNET@cornellc.cit.cornell.edu (A SHOW OF HANDS) writes: >> for(i=0;a[i]=!'\0';i++) >The =! has meanings you are not ready for. >Howard C. Johnson Sorry about this but, ... I HATE being told I'm not ready for something! Just in case (A SHOW OF HANDS) feels the same way ... Using =! instead of != in this case means that you are ASSIGNING the logical negation of '\0'. And '\0' equals 0. And !0 equals 1. So, a[i] is being set equal to 1. Since the value of the assignment is one (i.e. it is TRUE) and the phrase "a[i]=!'\0'" is the conditional part of a for loop, the loop would never exit. There now. Isn't that special? :-) Don White zehntel!donw Box 271177 Concord, CA. 94527-1177