C Programming Variable Scope and Pointers

macrumors 6502

Okay, I'm finally getting to something totally new to me in my "Learn C on a Mac" book.

The book says that in the following code, the error is when the function DrawDots() tries to reference the variable numDots.

Where can I recognize that DrawDots() is trying to reference numDots??
I see that numDots = 500; is directly above DrawDots(); but they are on two separate lines, and i don't see how one has anything to do with the other? Where is DrawDots(); trying to reference numDots;? Each line makes no reference of the other.

macrumors member

numDots was declared in the main() function so only code inside the main() function can see that variable. To every other function, it's as if numDots didn't exist.

If you really need the function DrawDots() to know what numDots is, declare numDots as a global variable (which means every function will be able to see it and change its value) or, better yet, pass it into the DrawDots() function as an argument like such:

thread startermacrumors 6502

So is a "scope" essentially another way of saying "function"?? Two prev posters have mentioned scope like it's a "place" in my program, ie, "not in this scope", or the "main scope" Which is like saying not in "main's function", or declare the variable outside the "main function"

If the variable is located inside a specific function, it's only available to be referenced in that function, if it's outside a function, it can be referenced anywhere in the program, correct?

Lastly, I still get a bit confused with all the terminology and differences between functions, arguments, statements, scope, strings, etc.

Programs are made up of functions, and functions are made up of stmts, how can I recognize a function? Is it always in the form....

name () {body} ??

I just want to be able to quickly look at my code and identify which part is the function.

macrumors member

'scope' isn't just a function. It's basically where in the program your variable is valid. For a particular variable, scope can be the entire program, a single function, or a portion of a function (or other things as well). An example of the last statement is this function:

In this case your code will refuse to compile. The reason is that the scope for the variable 'i' is only within the for loop. In other words, the way i is defined you can only access or modify i within the for loop. This code tries to print the value of i ('The final value of i...'), but the printf function is outside the for loop, in other words, outside the scope of i.

macrumors regular

like you said functions look like <returntype> name (arguments) { body }

Now, whenever you type a { you enter a new scope.

Take this example:

Code:

#include <stdio.h>
int main (int *argc, char *argv[0]) {
int a = 5; // a will be 5
printf("%d\n",a); //we print a
{ // we enter a NEW scope here. a is still 5
int a = 10; // in the NEW scope we declare a NEW a which will be 10
printf("%d\n",a); //we print a
} // end of scope. the NEW a will now go out of scope, as if it never existed
printf("%d\n",a); // we print a (which will be the original a as this statement is in the same outerscope as the original a
};

this prints:

Code:

5
10
5

Why ? Because the a in the innerscope is not the same as the one in the main scope.

macrumors regular

I see that numDots = 500; is directly above DrawDots(); but they are on two separate lines, and i don't see how one has anything to do with the other? Where is DrawDots(); trying to reference numDots;? Each line makes no reference of the other.

Click to expand...

Your are correct in saying that the line

Code:

numDots = 500;

and the reference

Code:

for ( i = 1; i <= numDots; i++ )

in DrawDots have nothing to do with each other,
because each is in a different scope.

A name declared in a block is local to that block; it has block scope. Its potential scope begins at its
point of declaration and ends at the end of its block.

So the error is that the loop in DrawDots tries to make reference to an undeclared symbol.

macrumors 65816

The concept of scope has been explained above, but here's my go at an explanation.

Scope is a place. It's the area in your program where an identifier is visible, that is the area where the identifier can be validly used.

The scope of a local variable, that is the area in your program where you can validly refer to that variable, starts immediately after where the local variable is declared up to immediately before the first closing brace at the next higher level as the local variable's declaration.

The scope of local_var is from immediately after line 4 where it's declared, down to immediately before line 11. That is, local_var can be validly used anywhere between these two points in the program. You cannot use it on or before line 4 and you cannot use it on or after line 11. In particular, it can't be used anywhere inside the definition of functionA on lines 13 and 14.

Notice that local_var's scope doesn't end immediately before line 9. This is because the closing brace on line 9 is at the same level as local_var, not at the next highest level.

Notice the declaration of inner_var on line 7? It's scope is from immediately after line 7 up to immediately before line 9. So it couldn't be used on line 10, for example.

Take note that inner_var also couldn't be used on line 6 even though it's within the same set of { } as inner_var. This is because it's before inner_var's declaration.

There a few different "types" of scope in C. In this example and your example, we've been dealing with local scope.

There's also global scope. Global scope happens when an identifier is declared outside of any function. For example, functionA is in global scope. That's right, functions have scope too, not just variables.

Global scope starts from immediately after the declaration, just like local scope, except it goes all the way down to the end of the file. Actually it's scope is even greater than that, but you'll learn about that when you learn about coding programs that are made up of multiple .c files.

thread startermacrumors 6502

So, int, float, and void are all return types? Again the language threw me off, my first book, C Programming by KN King only said that "all variables are of a type", and int and float were the two "types" I've learned so far.

So I've always known them only as types, now we're talking about "returntype". Everything with computers is always so specific and literal, but in C, it's when we've used different terminology to describe the same thing that's slowing me down. Returntypes are the same thing as types? I gather that to be true based on when I looked on Google, it listed void, int, float and others among return types.

Moderator

Staff Member

A function generally returns something. The data type of that something is the function's return type. For example: the function main typically returns an int. This is why we declare it as "int main(void)" and it is also why main ends with "return 0;".

In general, a function can return any valid C data type, including those you have defined yourself using "struct" or "typedef".

In cases where a function doesn't return anything (which would be called a subroutine in other languages) C provides the "void" data type as a placeholder to say: This function doesn't return anything.

macrumors 68040

So, int, float, and void are all return types? Again the language threw me off, my first book, C Programming by KN King only said that "all variables are of a type", and int and float were the two "types" I've learned so far.

So I've always known them only as types, now we're talking about "returntype". Everything with computers is always so specific and literal, but in C, it's when we've used different terminology to describe the same thing that's slowing me down. Returntypes are the same thing as types? I gather that to be true based on when I looked on Google, it listed void, int, float and others among return types.

Click to expand...

There are types. Different things have types. One such thing is a variable, the first thing you're going to run into. Another is a function's return type. Basically when you run the function, it's going to return a value with that type. Every expression evaluates to a certain type, too. So x * y will evaluate to an int if x and y are ints. You can then assign that expression to another int variable to store its value. Even a = 6 evaluates to an int with value 6, so you can do: a = b = c = 7; and set all of the variables to the same thing, because c = 7 evaluates to 7, and so on. So an expression has a type that it evaluates to, variables have types, functions have types (that they return).

These types are extremely important because in the computer's memory, all of the data is just a bunch of 0s and 1s. The type tells you how many of those 0s and 1s to interpret, and in what manner to interpret them. The same patterns of 0s and 1s could be interpreted as different things based on the type. It also determines what sort of operation is really going to be performed. To a computer multiplying two ints is a much different operation than multiplying two floats.

As has been stated a number of times here, what an author thinks is important and how they present data, is going to be based on their knowledge, understanding, and how they believe information is best presented. This may not fit your learning style, and without being able to ask the author questions, you're stuck with your interpretation of what they've presented. Sometimes re-reading will give you a better understanding and different interpretation, but not always, especially if you don't have any additional information to bring to the table.

thread startermacrumors 6502

I think I got it, int, float, void are types, whatever "type" I expect as the result of my function, ie the type that it "returns" is my "returntype"
Okay, so when I write a function, it should start with a returntype, which......is the type that corresponds to what the final value of my function is expected to be? If I expect the value of my function to be, say, 24 for example, since 24 is an int, my function will start with returntype int?

Do I have a ding ding ding here??

The book shows many examples of func prototypes with (void), assuming the above that I wrote is correct, do I use the int in my function prototype? Or do I only use void?

Since below, the main exits with a value of 0, 0 is an int. so why don't we give the compiler a heads up and use int, rather than void in the f.proto??
Book shows..

macrumors 68040

I think I got it, int, float, void are types, whatever "type" I expect as the result of my function, ie the type that it "returns" is my "returntype"
Okay, so when I write a function, it should start with a returntype, which......is the type that corresponds to what the final value of my function is expected to be? If I expect the value of my function to be, say, 24 for example, since 24 is an int, my function will start with returntype int?

Do I have a ding ding ding here??

The book shows many examples of func prototypes with (void), assuming the above that I wrote is correct, do I use the int in my function prototype? Or do I only use void?

Since below, the main exits with a value of 0, 0 is an int. so why don't we give the compiler a heads up and use int, rather than void in the f.proto??
Book shows..

If you want 24 treated as an int and not some other type, then the return type would be int. main is "special". It is the entry-point to every program. The compiler knows what type it should be. Also, while we've seen examples of it on the forum, it is rare for main to be called by other functions. This means that when the compiler is going through the rest of your code it is unlikely to find a use of main and need to know what sort of thing it is. The purpose of prototypes is to tell the compiler "trust me, this function will look like this" so when it finds it being used it knows what that thing should be because you told it with a prototype.

macrumors 603

So is a "scope" essentially another way of saying "function"?? Two prev posters have mentioned scope like it's a "place" in my program, ie, "not in this scope", or the "main scope" Which is like saying not in "main's function", or declare the variable outside the "main function"

Click to expand...

No because C has the static keyword which means that anything declared with that keyword is only available within that source file. It is sometimes called file scope.

Basically you have global scope (available to the whole program and in general a bad idea for variables), local scope (available just within a certain function or block) and file scope (available just within that compilation unit, i.e file).

The compiler needs to know what to do with the return value when it calls cubeit. It doesn't matter at that point that main will eventually return an int. It needs to know how to interpret the return value of cubeit so it can stuff that in the variable "c".

Up until you need to split your code into multiple files or run into mutually recursive functions I would suggest doing this instead.

macrumors 68000

The book shows many examples of func prototypes with (void), assuming the above that I wrote is correct, do I use the int in my function prototype? Or do I only use void?

Click to expand...

Technically, every function does return some value. If you specify a return value in the function definition, you must include a returntheType; in your function, otherwise the compiler will cough. The void type simply tells the compiler that the return value will be undefined and your function will not have a return statement specifying it.

Note that printf() specifies a return value of int, which typically gets ignored when printing to the console (look up the printf() man page to understand what the return value is used for). Just as you can ignore a return value, theoretically you could obtain a void return value and use it (if you can get the compiler to accept such code), but you have no way of guessing what that void value might be or how it might be useful.

thread startermacrumors 6502

Okay, I fully understand scope, it's a pretty easy concept actually. It's "where" the variable is available to be used. No problem here.

I've also finished reading both books on pointers, I feel pretty good about what they are, how to declare them, the address and indirection operators, and what they do.

What I don't understand (as I don't with many things I'm learning from programming) I don't understand how I will know I need to use a pointer!!!!

If I'm writing a program to do something, how will I know, "okay, I'll need pointers in this program" That's the biggest difficulty I have in understanding some things. I know what they do, and how they do it, but I can't presently think of a program I could write that it would be necessary to take advantage of pointers. Any suggestions? Like, "if you want to do this, you'll need pointers so that you can do this"

I just don't understand their relevance yet. The books don't do a great job in giving a variety of scenarios in which one would want to use a pointer, I think that's just about as important to teach a beginner as what pointers are and how they work.

macrumors 603

What I don't understand (as I don't with many things I'm learning from programming) I don't understand how I will know I need to use a pointer!!!!

Click to expand...

It is pretty straight forward. When you allocate memory using one of the malloc family functions (malloc(), calloc() etc etc) it returns a void pointer which points to the allocated memory. This is the most common use of pointers which is to access dynamically allocated memory. Don't forget to free() the memory when you are done with it though.

Since C is a pass by value language (i.e everything you pass into a function is copied), you might want to pass the address of particularly large data structures rather than the whole data structure itself as that would be a very expensive operation. Therefore functions often take pointers so that they simply need to copy the address rather than the data itself.

The other common use of pointers is that you can pass a pointer to a pointer into a function and use it as a second return value if you want. For instance the function itself could return an int indicating the type of error that occurred and the a function argument which could be a struct might also be set to contain some important information about the error (for instance the author of the function might have a field which tells you the exact time the error occurred). That was a made up example but it should explain another use.

macrumors 65816

What I don't understand (as I don't with many things I'm learning from programming) I don't understand how I will know I need to use a pointer!!!!

Click to expand...

Don't worry about this toooo much. Mostly this comes with the experience of creating actual programs. This experience will give to the instinct to recognise when you need to use a particular tool or combination of tools. For now just become as familiar and comfortable with each of the tools as possible.

Moderator

Staff Member

I just don't understand their relevance yet. The books don't do a great job in giving a variety of scenarios in which one would want to use a pointer, I think that's just about as important to teach a beginner as what pointers are and how they work.

Click to expand...

It'll hit you hard in the next chapter of both books when they introduce arrays after pointers. It seems like King already gave you arrays, but will come back to it now that you have pointers. Learn C on the Mac will introduce malloc and free in the chapter after that. King will wait until Chapter 17 to introduce malloc.

Patience. You're not done with either book, they have to introduce a concept before they show you how to put it together with something else to build something larger.

MacRumors attracts a broad audience
of both consumers and professionals interested in
the latest technologies and products. We also boast an active community focused on
purchasing decisions and technical aspects of the iPhone, iPod, iPad, and Mac platforms.