Arrays

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm still learning C after programming AVR's with assembler for several years.

My question is about arrays. I've been reading that it is best to avoid using global variables. What about arrays? If you have an array that you need to access from several functions what's the best way to do it?

Regards,
Stewart.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I've been reading that it is best to avoid using global variables.
That depends on what you are programming. In programming microcontrollers, Global variables are often good to have. Passing variables around can use more ram than a global variable. This can become very important in microcontrollers where ram is at a premium.
Quote:
What about arrays? If you have an array that you need to access from several functions what's the best way to do it?
Arrays are not really any different. It all depends on what you are using it for.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The things to know about arrays in this respect are

Array notation is just syntactic sugar on top of pointers. So, simplifying some, a

char a[10];

is really a

char * a;

pointing to an allocated area (10 chars in this case).

Accessing eg

a[4] = ...

is really

*(a+4) = ...

And finally, when passing an array to a function you are really passing the pointer not the whole array.

(For structs its a whole different thing though. Just mentioning it because that was one of my major "C revelations" all those years ago.)

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the replies.
I'll have to look into pointers, arrays and structs some more.

Stewart.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I've been reading that it is best to avoid using global variables.

Don't believe everything you read.
(this post itself may, of course, be a bit like Epimenides paradox!)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

On Global Variables, and the Evils Therein: :twisted:

In the beginning, there was Computer. And it was understood only Machine Language and the Assembler thereof. And its Memory was flat and featureless, without form. And the Programmer saw the Memory and ordered it, each according to its kind and his desire, and labeled it. The Programmer could thus use the Memory in the Computer and his listings reflected the names of the locations thereof in the Memory. And it was good.

But the Programmer grew tied of typing in his programs in a single line. And He saw that certain parts of the Program were repeated and could be combined into a single piece of code. Thus the Programmer created Subroutines. And the Programmer realized the Subroutines could call Subroutines. And to keep order in his calling of subroutines, He created the Stack, upon which he would place the address of the calling Routine so that the Subroutine might return to the proper place. And since He still partook of assembly language He was able to assign Memory for the passing of Parameters to the Subroutine and assign more Memory for the use of the Subroutine and the values it should work upon. And it was good.

It was then that the Memory cried out, saying, "Thou art infinite, but I am limited." And the Programmer grew tired of assigning space in Memory for the passing of a Parameter to each Subroutine. And the Programmer grew tired of assigning temporary space in Memory for each Subroutine.

Then the Programmer thought of reusing Memory that was only needed temporarily in the Subroutine. And He saw the Stack was an ideal place for such temporary storage and Parameters. So the Programmer placed the Parameters and temporary storage on the Stack. And He passed back the Result upon the Stack (or in the Registers of the Machine). And he called the temporary variables Local and the permanent variables Global. And thus he separated the Local Variables from the Global Variables. And the Results of the Subroutine were returned in the Global Variables. And it was good.

And, having seen than passing of Parameters to the Subroutine was good, the Programmer decided that a Subroutine could return Results the same way. And so the Subroutine could return its Results either through the changing of the Global Variable or by returning a Result Parameter. And this delighted the Programmer.

And all the Programs were written in Assembly. But the Programmer grew tied of typing Assembly as the Programs could become long and tedious. So the Programmer invented Languages. And since the Languages allowed Him to abstract his Programs, and since the Computers and their Memory kept increasing, the Programmer stopped paying attention to how Memory was allocated.

But soon the Programmer's programs became large and and complicated. For the Programmer would often pay attention only to the Result returned by the Subroutine, and He would often lose track of changing the values of the Global Variables in the Subroutine. And such changing of Global Variables became known as the Side Effect. And the changes to the Global Variables became large and untraceable. And the Side Effects became numerous and spread throughout the Program. And many Bugs were introduced through the Side Effect. And there was much wailing and gnashing of teeth and tearing out of hair and rending of clothes. And the Programmer's Manager beat upon him, saying, "Thou art useless!"

Thus it was that the Programmer decided that the Global Variable with its associated Side Effect was Evil. And so He declared that there should not be Global Variables and that Subroutines would only return its results through the Result Parameters.

And He thus banished the Global Variable with its associated Side Effect to Hell so that it would not be heard from again.

The cost of the banishment was that a Subroutine could change a Variable only if it was passed as a Parameter or returned as a Result Parameter. But since the Computer Industry was bountiful and had multiplied, the size of the Memory had increased many-fold And the use of the Stack for Parameters and Temporary Variables was declared Holy.

And the use of Memory concerned the Programmer not at all, since he had Memory galore and the Languages allowed him to forget its allocation.

But then a form of Computer called the Microcontroller was formed. And lo, it was speedy and cheap and small, thus allowing the Hardware Engineer to choose Cheap, Fast, and Good all at the same time. But Microcontroller was cursed with a small Memory. But the Hardware Engineer cared not, for he only knew that it had the proper wires and everything else was a Software Problem. And he declared victory and was declared a Hero.

And so the Programmer started the Project. And the Programmer ran out of Memory. And the project began to fail. And the Programmer's Manager came to the Programmer, saying, "Thou art behind schedule and over budget. Thine code sucketh. Repair thine mistakes or find thee another job!" And this disturbed the Programmer greatly, for without a job he might find himself covered in ashes, clothed in sack cloth and living in a cardboard box.

And the Global Variable called to the Programmer, saying "Thou art foolish. The use of Me can save thee Time and Memory, if used judiciously. With care, thou can use me without the return of Side Effects." And the Programmer saw that if Global Variables were changed in only one Subroutine and used as Read Only values elsewhere, that the Side Effects could be controlled. And since the Global Variables could be used to communicate with his Interrupt Service Routines, which had no Parameters to be called, and the returning of Results thereof, they had great value.

And the Programmer released Global Variables from Hell, to be governed by the rules of Limited Access. And the Project was saved, and the Programmer's Manager grunted and said, "About bloody time."

And thus it was that the Programmer discovered that Rules were Important. But it was also important to know When to break the Rules.

Thus endeth this lesson.

:twisted:

Stu

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:
The things to know about arrays in this respect are

Array notation is just syntactic sugar on top of pointers. So, simplifying some, a

char a[10];

is really a

char * a;

pointing to an allocated area (10 chars in this case).

Not exactly.

char a[10];

does not allocate space for a pointer, it allocates only sizeof(char) * 10 memory, and sizeof(char) is by definition 1 in C. There is no hidden, secret storage for the "a" pointer added.

On the other hand

char * a;

only allocates memory for a pointer, sizeof(char *) memory, not anything more.

The trick in C is that if you have a

char a[10];

then "a" is a shortcut / syntactic sugar for

&(a[0])

and that expression results in a value(!) of type "char *". It still doesn't allocate any memory for an "a" pointer.

But since the expression is of type "char *" C's pointer arithmetic can be used on it like on any other pointer value.

We just recently had a similar discussion:

char a[6] = "12345";

and

char *a = "12345";

are not the same. Try to assign a NULL pointer to the first, and to the second and the compiler will inform you of its opinion that they aren't the same:

$ cat a.c
int main() {
	char a[6] = "12345";
	char *b = "12345";

	a = 0;
	b = 0;
}
$ cc a.c
a.c: In function 'main':
a.c:5: error: incompatible types in assignment

Stealing Proteus doesn't make you an engineer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, Arnold. I guess "simplifying" was not the thing to do, as it rather became a "non-truth". The gist of it though still is that passing an array as a parameter actually passes a pointer only.

On the subject in general, it seems to me that people coming from higher level languages like Pascal, Java or C# often have a problem to fathom how crude strings, and arrays in general, are in C. IMO you really need to understand pointers in order to get it. This is not the case in those other languages, where strings are more of strong and prime types of their own.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]