It's rather annoying to read 4 answers explaining what's wrong, but none explaining how the correct way to fix it. It's probably a safe guess that if the OP doesn't know about scoping he probably also doesn't know about passing variables to a function.
The Problem
You're trying to get at the value of a variable, but the variable is in another function. How can I get at it? Well, the simple answer is, you don't WANT to get at it. You heard me right. The entire reason to use a function is reusability, if you tie your newly created function to another function then you can't use it everywhere. Remember, functions help you be lazy. And a good programmer is a lazy programmer. If you can write a function once and use it in a million places, you're doing it right. ;)
But I still really want to get at the value of that variable
Then you want to use a function parameter to pass the variable to the function.
Functions are named because you can think of them in terms of math. Put variables in, get out useful data after the function has run and done interesting things with those variables. So let's say you have a math function y = f(x)
, the equivalent of this would be int f(int x) { /*stuff here*/ }
then you call it in your main function using int y = f(a)
where a
is some variable or number.
You want to avoid global variables because they don't always do what you expect (especially if you have a lot of code, it's very easy to accidentally use the same name.)
In your case you want the function to print out the contents of a specific variable, so I think perhaps you're seeking a way use that function with any specific variable. So here's how you do that.
void f(); //hi, I'm a function prototype
void f(int a); //hi, I'm a function prototype that takes a parameter
void f(int a, int b); //hi, I'm a function prototype that takes two parameters (both ints)
void f(int a, ...); //hi, I'm a function prototype that takes an int then any number of extra parameters (this is how printf works.)
So what you really want to do is change your code to something like:
header.h:
#ifndef HEADER_H
#define HEADER_H
#include <iostream>
// extern int* a; // We don't need this
void f(int* a)
{
if (a != NULL) //always, always check to make sure a pointer isn't null (segfaults aren't fun)
std::cout<<*a <<std::endl;
//return; //Don't really need this for a function declared void.
}
#endif
main.cpp:
#include "header.h"
int main()
{
int* a = new int(10);
f(a);
return 0; //main is declared as returning an int, so you should.
}
Functions by value, pointer and reference
So, in your examples I gave I used int
rather than int*
in your example. The difference between the two is the first one passes the parameter by value. The other by pointer. When you pass a variable to a function a copy of it is ALWAYS made. If you pass it a int, it makes a copy of the int, if you pass it a 4 MB structure it will make a copy of the 4MB structure, if you pass it a pointer to a 4MB structure is will make a copy of the pointer (not the entire structure.) This is important for two reasons:
- Performance: Making a copy of a 4MB structure takes some time.
- Ability to change contents: If you make a copy of the pointer, the original data is still in the same place and still accessible through the pointer.
What if you want 1 and not 2? Well then you can declare the pointer const
. The prototype looks like this: int f(int const* a);
What if you want 2 and not 1? Tough cookies (there no good reason anyway.)
Finally, you can also declare a function to take a reference and not a pointer, the big difference between a reference and a pointer is a reference will not be NULL (and you can't use pointer arithmetic on a reference.) You will want to use either pass by reference or pass by value normally. Needing to pass by pointer is something that I almost never need to do, in my experience it's more of a special case sort of thing.
Pass by reference: int f(int& a);
Pass by const reference: int f(int const& a);
So to sum up:
if you have function that needs parameters:
then:
if you do not need to modify the contents:
then:
if the size of the variable is small:
pass by value: int f(int a);
else if the size of the variable is large:
then:
if the value of the address can be NULL:
pass by const pointer: int f(int const* a);
else:
pass by const reference: int f(int const& a);
else if you do need to modify the contents:
then:
if the value of the address can be NULL:
pass by pointer: int f(int* a);
else:
pass by reference: int f(int& a);
There's some more cases, but these are the main ones, see this website for more details.