[comp.lang.c] Arrays.

swarbric@tramp.Colorado.EDU (Frank Swarbrick) (05/02/88)

Is there some reason why you can do:

void foo(const int *bar);

main()
{
   int ary[] = {1,2,3,4};

   foo(ary);
}

but you can't do

void foo(const int *bar);

main()
{
   foo({1,2,3,4});
}

Never mind that it seems silly to do this particular thing without any other
parameters.  I was just too lazy to write in the other ones.  This is even
stranger concidering you *can* do

main()
{
   char str[20];

   strcpy(str,"This sucks!");
}

(no,
 strcpy(str,{'T','h','i','s',' ','s','u','c','k','s','\0'});
doesn't work....)

Frank Swarbrick (and his cat)           swarbric@tramp.Colorado.EDU
...!{ncar|nbires}!boulder!tramp!swarbric
"The shifting shafts of shining weave the fabric of their dreams..."

chris@mimsy.UUCP (Chris Torek) (05/03/88)

In article <5773@sigi.Colorado.EDU> swarbric@tramp.Colorado.EDU
(Frank Swarbrick) writes:
-Is there some reason why you can do:
-
-void foo(const int *bar);
-main() {
-   int ary[] = {1,2,3,4};
-   foo(ary);
-}

(Pre-dpANS compilers will not even do this; `ary' must be `static' or
global.  The restriction on automatic aggregate initialisers has been
lifted in dpANS C.)

-but you can't do
-
-void foo(const int *bar);
-main() {
-   foo({1,2,3,4});
-}

Yes: there is no aggregate builder that builds an array of int.

-... This is even stranger concidering you *can* do
-
-main() {
-   char str[20];
-   strcpy(str,"This sucks!");
-}
- strcpy(str,{'T','h','i','s',' ','s','u','c','k','s','\0'});
-doesn't work....

... but there *is* an aggregate builder that builds an array of
char, namely "".  Some of us feel that this is a flaw in the language,
that the only way to get most kinds of aggregates is to provide
names for them.

(Of course, if you add unnamed aggregates, you should also add
unnamed functions.)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

craig@srs.UUCP (Craig Schmackpfeffer) (05/03/88)

In article <5773@sigi.Colorado.EDU> swarbric@tramp.Colorado.EDU (Frank Swarbrick) writes:
>Is there some reason why you can do:
>void foo(const int *bar);
>main()
>{
>   int ary[] = {1,2,3,4};
>
>   foo(ary);
>}
>but you can't do
>void foo(const int *bar);
>main()
>{
>   foo({1,2,3,4});
>}
>

Because {1,2,3,4} is not an array, but merely a convenient way of initializing 
an array.  

>main()
>{
>   char str[20];
>
>   strcpy(str,"This sucks!");
>}
>
>(no,
> strcpy(str,{'T','h','i','s',' ','s','u','c','k','s','\0'});
>doesn't work....)
>
>Frank Swarbrick (and his cat)           swarbric@tramp.Colorado.EDU

A string of characters within double quotes is represented as the array of
those characters followed by a terminating null byte.  It is defined to
return the address of the array.  The second attempt at the {} usage
doesn't work for the same reason the first try didn't work.
-- 
Craig Schmackpfeffer  @ S.R. Systems
{allegra,rutgers,ames}!rochester!srs!craig

rsalz@bbn.com (Rich Salz) (05/04/88)

>Why can't I do this:
>void foo(const int *bar);
>main()
>{
>   foo({1,2,3,4});
>}

Others will point out the reason.  If you want it really badly,
tho, check out the GNU compiler.  For information about GNU, send
to
	info-gnu-request@prep.ai.mit.edu
	mit-eddie!mit-prep!info-gnu-request

The GNU compiler supports K&R, varying levels of ANSI compatibility,
and stuff like anonymous aggregate constructors.  It's not trivial to
use or port, but it does run on lots of machines, and ease-of-use is
just a matter of time.

Careful readers will note I don't call it the GNU _C_ compiler,
because of gunk like the above. :-)
	/r$
-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.

scjones@sdrc.UUCP (Larry Jones) (05/04/88)

In article <5773@sigi.Colorado.EDU>, swarbric@tramp.Colorado.EDU (Frank Swarbrick) writes:
> Is there some reason why you can do:
>    int ary[] = {1,2,3,4};
>    foo(ary);
> but you can't do
>    foo({1,2,3,4});

Yep, there's quite a good reason -- just what is {1,2,3,4} supposed to be?
An array of ints?  An array of chars?  Could even be an array of floats or
doubles!  If the compiler has to see how the thing is being used in order
to figure out what it is, it going to be MUCH harder to write, much larger,
much slower, and probably much less correct!

----
Larry Jones                         UUCP: ...!sdrc!scjones
SDRC                                AT&T: (513) 576-2070
2000 Eastman Dr.                    BIX:  ltl
Milford, OH  45150
"When all else fails, read the directions."

andrew@teletron.UUCP (Andrew Scott) (05/05/88)

In article <11325@mimsy.UUCP>, chris@mimsy.UUCP (Chris Torek) writes:

> (Of course, if you add unnamed aggregates, you should also add
> unnamed functions.)

I think that unnamed aggregates would be a great extension for some compiler
vendor to add to the language, so that there will be "prior experience" when
we get around to designing "D".  (No, I'm *not* trying to start another round
of "D" postings.)

I was struck by Chris' comment, however.  How would unnamed functions be
implemented?  How would they be used?  The { .. } syntax for aggregate declar-
ations seems natural enough to use for unnamed aggregates, but how would it
be done for functions?

I'm just curious.  I can't think of how I would use this sucker.
-- 
Andrew Scott
andrew@teletron.uucp	or	{ihnp4, watmath, ..}!alberta!teletron!andrew

daveb@geac.UUCP (David Collier-Brown) (05/06/88)

| In article <11325@mimsy.UUCP>, chris@mimsy.UUCP (Chris Torek) writes:
| (Of course, if you add unnamed aggregates, you should also add
| unnamed functions.)

In article <282@teletron.UUCP> andrew@teletron.UUCP (Andrew Scott) writes:
| I was struck by Chris' comment, however.  How would unnamed functions be
| implemented?  How would they be used?  The { .. } syntax for aggregate declar-
| ations seems natural enough to use for unnamed aggregates, but how would it
| be done for functions?
| I'm just curious.  I can't think of how I would use this sucker.

 In smalltalk, all over the place. (ie, ifTrue [<unnamed-function>])
 In c, for passing to qsort....

	SYNTAX
             qsort(base, nel, width, compar)
             char *base;
             int (*compar)();

	EXAMPLE
             qsort(base, nel, width, { return zcomp($1,$2) });

	Note the problem with parameters...

--dave
-- 
 David Collier-Brown.                 {mnetor yunexus utgpu}!geac!daveb
 Geac Computers International Inc.,   |  Computer Science loses its
 350 Steelcase Road,Markham, Ontario, |  memory (if not its mind) 
 CANADA, L3R 1B3 (416) 475-0525 x3279 |  every 6 months.

dg@lakart.UUCP (David Goodenough) (05/09/88)

From article <282@teletron.UUCP>, by andrew@teletron.UUCP (Andrew Scott):
> I was struck by Chris' comment, however.  How would unnamed functions be
> implemented?  How would they be used?  The { .. } syntax for aggregate declar-
> ations seems natural enough to use for unnamed aggregates, but how would it
> be done for functions?

Something like this:

	int (*foo)();	/* foo is a pointer to a func returning int */

	foo = (a, b) int a, b;
		{
		return (a < b ? a : b);
		};

would make foo point to an unnamed function that returns the minimum of it's
two arguments.

The most obvious use for such a "feature" (?) would be in the invocation
of routine like qsort, which takes a function as an argument:

	qsort(array, nelem, sizeof(char *),
		(a, b) char **a, **b
		 {
		    return (strcmp(*a, *b));
		 }				);

Kind of ikky, but you get the idea.

P.S. don't suggest this to the ANSI crowd: we don't need another re-run of the
noalias 
-- 
	dg@lakart.UUCP - David Goodenough		+---+
							| +-+-+
	....... !harvard!adelie!cfisun!lakart!dg	+-+-+ |
						  	  +---+

peter@ficc.UUCP (Peter da Silva) (05/18/88)

In article <274@sdrc.UUCP>, scjones@sdrc.UUCP (Larry Jones) writes:
> In article ... swarbric@tramp.Colorado.EDU (Frank Swarbrick) writes:
> > Is there some reason why you can do:
> >    int ary[] = {1,2,3,4};
> >    foo(ary);
> > but you can't do
> >    foo({1,2,3,4});

> Yep, there's quite a good reason -- just what is {1,2,3,4} supposed to be?

Depends on how foo was declared:

	void foo(int *a);
		It's an array of ints.
	void foo(char *a);
		It's an array of chars.
	void foo(double *a);
		It's an array of doubles.
	struct x { int i; char c; float f; double d; };
	void foo(struct x *a);
		It's a pointer to an int, a char, a float, and a double.
This one's kinky:
	void foo(struct x a);

Extra credit question: how does that differ from:
	void foo(int i, char c, float f, double d);
		And called with foo(1, 2, 3, 4);

chris@mimsy.UUCP (Chris Torek) (05/26/89)

In article <96@elf115.uu.net> rec@elf115.uu.net (Roger Critchlow) writes:
>I think of C arrays as syntactic sugar for initialized pointers.
>Thus
>
>	char foo[] = "I am an anonymous char *";
>
>is an abbreviation for
>
>	register char *const foo = "I am an anonymous char *";

The only problem with this is that it is wrong.

Given the first declaration, sizeof(foo) is 25.  Given the second,
sizeof(foo) is typically something like 4.  This is only the most obvious
of many differences.

An array is an array, and a pointer is a pointer, and the twain meet
only in rvalue contexts, where an object of type `array N of T' is
converted to one of type `pointer to T' whose value is &array[0].
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

cfiddyme@gara.une.oz.au (Kith Kanan) (05/21/91)

 hi,
     I'm new to C and have been trying out a few things and have come up with
 a problem. In the code below I am reading a series of three digit numbers
 from a file and storing them as strings in a 2-d array.When I print them out
 strange things happen. Can someone please tell me what is causing this and how
 do I prevent it. Also when I replace the fscanf function with fgets() i get
 errors. Why?
                                 Thanks
                                            Chris.

#include <stdio.h>

main()
{
   char array[10][3];
   char s[3];
   FILE *input,*fopen();
   int i = 0;

   input = fopen("inarray","r");
   while(!feof(input))  {
      fscanf(input,"%s\n",s);
      strcpy((char *) array[i],s);
      i++;
    }
   for(i=0;i<=9;i++)
     fprintf(stdout,"%s\n",array[i]);
}

 This is the output of the program.The input file is just the first three
 digit's of each line.

229657659312999867555664811109
657659312999867555664811109
659312999867555664811109
312999867555664811109
999867555664811109
867555664811109
555664811109
664811109
811109
109

gordon@osiris.cso.uiuc.edu (John Gordon) (05/22/91)

	Well, for one thing, s needs to be 4 bytes long, not 3.  A string
needs to be as long as the longest value that will be stored in it, *plus*
one extra byte for the null terminator.


---
John Gordon
Internet: gordon@osiris.cso.uiuc.edu        #include <disclaimer.h>
          gordon@cerl.cecer.army.mil       #include <clever_saying.h>

eoo@let.rug.nl (Eize Oosting) (05/23/91)

In article <6466@gara.une.oz.au> cfiddyme@gara.une.oz.au (Kith Kanan) writes:
>
> hi,
>     I'm new to C and have been trying out a few things and have come up with
> a problem. In the code below I am reading a series of three digit numbers
> from a file and storing them as strings in a 2-d array.When I print them out
> strange things happen. Can someone please tell me what is causing this and how
> do I prevent it. Also when I replace the fscanf function with fgets() i get
> errors. Why?
>                                 Thanks
>                                            Chris.
>
>#include <stdio.h>
>
>main()
>{
>   char array[10][3];
>   char s[3];
>   FILE *input,*fopen();
>   int i = 0;
>
>   input = fopen("inarray","r");
>   while(!feof(input))  {
>      fscanf(input,"%s\n",s);
>      strcpy((char *) array[i],s);
>      i++;
>    }
>   for(i=0;i<=9;i++)
>     fprintf(stdout,"%s\n",array[i]);
>}
>
> This is the output of the program.The input file is just the first three
> digit's of each line.
>
>229657659312999867555664811109
>657659312999867555664811109
>659312999867555664811109
>312999867555664811109
>999867555664811109
>867555664811109
>555664811109
>664811109
>811109
>109

This is very simple, your subarrays have only three chars, however a real
C string consists of chars terminating with a '\0' (null-char). You do not have
room for these, so when you read a 3 digit string into one element, it's
null-char is put in the first field of the next element (arrays are one block
of memory). This null-char however is overwritten by the next read into THIS
field. The only dangerous situation is your read, because that null-char is
put into a dummy byte (because the next var 's' must be word-aligned). You 
must NOT read bigger numbers than 3 digits with this code, or else you
will overwrite the 'input' var. Consider what happens then.

I will try to graphisize this:

char array[10][3] is a block of 30 bytes, and after that you have s etc:

  0   1   2   3   4   5   6   7   8   9    s    input     i
+---+---+---+---+---+---+---+---+---+---++---+-+--------++--+
|   |   |   |   |   |   |   |   |   |   ||   | |  ptr   ||  |
+---+---+---+---+---+---+---+---+---+---++---+-+--------++--+
                                              ^ 
                                              This is a dummy byte to align
                                              the input var on a word-boundary.

After your first read, s contains '229', however its null-char lies beyond
the memory of 's'. Then you copy this to array[0]. array[0] now contains the
number and the null-char is in array[1].  

  0   1   2
+---+---+---
|229|o  |  ..
+---+---+---

Then you do the second read and copy this to array[1]:

  0   1   2   3
+---+---+---+---
|229|657|o  |  ..
+---+---+---+---

As you can guess, after 10 reads, your array is completely filled with only
digits and the null-char is located at the first byte of 's'. When you
are going to printf() the numbers, printf() searches each time for the 
null-char as the terminator. That's why you get the printf() always producing
this large numbers (strings).

THE SOLUTION: 

Make your arrays 4 digits long. Both array must be [10][4] and s must be [4].
When you are going to read (or copy) strings, ALWAYS have room for this extra
character. You don't see it, but it's there!

Hope this helps!

  /\__________/\   /\___________________________________________________/\
 /              \ /                                                       \
|   Letteren-    |  Marvin Minsky once defined Artificial Intelligence as: |
|   Faculteit    |   '... the science of making machines do things that    |
| R.U. Groningen |   would require intelligence if done by men'.           |
| The Netherlands|                                                         |
|                |  Does this include formatting a floppy?                 |
| eoo@let.rug.nl |                                           Eize Oosting  |
 \  __________  / \  ___________________________________________________  /
  \/          \/   \/                                                   \/