|
|
|||
![]() |
Department of Engineering |
| University of Cambridge > Engineering Department > computing help > Languages > C++ |
Here are some answers to C++-related questions commonly asked at CUED. If you can think of questions that should be added here, mail Tim Love (tl136). A more comprehensive list of C++ Frequently Asked Questions is available, though it's not aimed at absolute beginners.
which looks more vague than the other message, but is actually less confusing, because the problem is that there are too many semi-colons in the program, not too few (see the semicolons question for details - the problem is on line 5 of the code).
So don't expect to the compiler to exactly location and diagnose the problem. The first error in your code may cause lots of further errors, so fix that first.
Sometimes the cause of the error may be a long time before the reported line-number. If you get an error message saying that there's a problem with your final line of code
if (i=1)you are setting i to 1, not comparing i to 1. This isn't illegal (it's equivalent to "if(true)") but you probably meant to use 2 equals signs.
int giveMe();
int main() {
int answer=giveMe();
}
int giveMe() {
int i=0;
}
The trouble is that the giveMe function is supposed to return an integer (i.e. give
an integer as its result) but at the moment it returns nothing. Consequently the answer
variable in the main function won't be set to anything sensible. The warning message
will disappear if the giveMe function is changed to
int giveMe() {
int i=0;
return i;
}
cout << "Hello!" << endl;at the start of your main routine, and
cout << "Goodbye!" << endl;at the end. If only the "Hello" appears, put
cout << "Got here!" << endl;
half way down your program, and continue this way until you've worked out roughly where the problem is.
You may have an "infinite loop" problem. Have a look at this code fragment.
int month[12];to reserve space for 12 integers. The integers would have the names month[0], month[1] ... month[11] because array indexing starts at 0. If you don't want to start at 0 you could ignore the first value and just use month[1], month[2] ... month[12], but you then need 13 integers so you must create the array using
int month[13];The items in the array are usually referred to as elements. They're stored contiguously in memory, so if integers occupy 4 bytes, and the first element starts at memory location 1000 (base 16), the layout of this 13-element array will be
struct Team {
int points;
float goal_average;
string sponsor;
};
Note that this code doesn't in itself create a new variable but a
new type of variable. As well as being able to create standard,
simple variables of type int, float, etc, we've extended the language
so that we can now create a Team as well by doing
Team cambridge;
The fields of this variable can be individually accessed using cambridge.points, cambridge.goal_average, and cambridge.sponsor. Note that you can have arrays inside structures, and you can have structures of arrays - Team teams[22]; would create an array of 22 Teams. Note also that classes can do everything that structures can do, and more.
The memory taken up by a structure may be more than the sum of the sizes of the fields - for speed-efficiency reasons, there are sometimes gaps between fields.
float rectangle_perimeter(float width, float height) {
return 2*width + 2*height;
}
float rectangle_perimeter(float width, float height);(i.e. the same as the first line of the function but with an added semi-colon) This doesn't call the code, it just tells the compiler about the function. The names of the variables here don't matter. It's just as legal to say
float rectangle_perimeter(float, float);
float answer; answer= rectangle_perimeter(5,7); float width=5, float height=7; answer= rectangle_perimeter(width, height);Note that you don't mention the type of the arguments when you call a function - answer=rectangle_perimeter(float width, float height); is wrong. Note also that though the argument names here (width and height) match the names of the arguments in the function code, that's coincidental and irrelevant.
If we want to change main's i we need to "call by reference" - note the added ampersands.
-
Not much. Let's first review what return does.
In a function, return gives a value back to the
calling expression. For example, if you wrote a function called
squareroot that had return root; at the end of it,
then f=squareroot(4); would call squareroot, and
the value of root would be put into the variable f.
ls file1 echo $?will display 0 (because the ls command does return 0; when it succeeds, and the command line has a variable called $? which stores the returned value). If you type
ls file2 echo $?
it will display 2 (because the ls command does return 2; when there's "serious trouble"). This return value is often ignored by users, but it's a good habit to return something from main.
Note that
- Header files are files whose names usually end with .h and contain prototypes, definitions, etc so that you can use some extra routines. By default, C++ doesn't even let you use cout to print to the screen (cout is an "extra" routine), so most programs need to include header files. There are a few dozen standard header files, and you can write your own. Putting #include<iostream> in your program tells the compiler to read in the standard header file(s) for I/O (input/output). But that still
isn't enough to let you use cout. You also need to tell the compiler that the cout routine belongs to the standard part of the library of routines. If you put "using namespace std" at the top of your file, the compiler will look in the std (standard) section for routines.This is true for all the standard files
(cmath, etc). If you're not including any files, or if you're only using
non-standard files (ones you've written yourself for example) then you don't need "using namespace std;".g++ -I/usr/local/include -I/usr/include/GL -L/usr/local/lib -o PlotNormal PlotNormal.cc -lglue -lglui -lglut -lGLU -lGLfollowed by
./PlotNormal
compile1AC++ filename[s]
-
Suppose you have a function called RollDie that simulates the rolling of a die, returning an integer in the range 1 to 6. Suppose you wanted to call RollDie 1000 times and record how many 1s were thrown, how many 2s were thrown, etc. You could have a variable to store
the number of 1s thrown, another to store
the number of 2s thrown, etc. You'd have to set them to 0 intially. You
could do it like this
int frequency_of_1s=0; int frequency_of_2s=0; int frequency_of_3s=0; int frequency_of_4s=0; int frequency_of_5s=0; int frequency_of_6s=0;Then you could roll the die 1000 times, each time adding one to the appropriate total. The code below does that.
int experimentsDone=0;
while(experimentsDone<1000) {
int result=RollDie();
if(result==1)
frequency_of_1s=frequency_of_1s+1;
if(result==2)
frequency_of_2s=frequency_of_2s+1;
if(result==3)
frequency_of_3s=frequency_of_3s+1;
if(result==4)
frequency_of_4s=frequency_of_4s+1;
if(result==5)
frequency_of_5s=frequency_of_5s+1;
if(result==6)
frequency_of_6s=frequency_of_6s+1;
experimentsDone=experimentsDone+1;
}
You could then print out the values at the end of the experiment.
cout << frequency_of_1s << endl; cout << frequency_of_2s << endl; cout << frequency_of_3s << endl; cout << frequency_of_4s << endl; cout << frequency_of_5s << endl; cout << frequency_of_6s << endl;This works, but is tedious and gets more tedious when instead of 6 possible outcomes there are hundreds. Arrays can help. Arrays are groups of variables of the same type. The line
int frequency[600];creates an array called frequency with the space for 600 integers. The first one is frequency[0], the second frequency[1], etc. We'll store the frequency of zeroes in frequency[0], the frequency of 1s in frequency[1], etc. First we need to initialise them all to zero. We could do
frequency[0]=0; frequency[1]=0; ... frequency[599]=0;but loops work well with arrays. We can set all 600 variables to 0 using
int i=0;
while (i<600) {
frequency[i]=0;
i=i+1;
}
The code to run the experiments and record results is shorter too. If we do
int result=RollDie();and result comes out to 3, then we need to add 1 to frequency[3]. More generally, we need to add 1 to frequency[result], so the code reduces to
int experimentsDone=0;
while(experimentsDone<1000) {
int result=RollDie();
frequency[result]=frequency[result]+1;
experimentsDone=experimentsDone+1;
}
Finally we need to print out the answers. Possible is
cout << frequency[0] << endl; cout << frequency[1] << endl; ... cout << frequency[599] << endl;but lazier and better is
i=0;
while(i<600) {
cout << frequency[i] << endl;
i=i+1;
}
Here's a side by side comparison of the 2 versions. Even for only 6 possible outcomes
"the loop and array" version is shorter.
// initialising int frequency_of_1s=0; int frequency_of_2s=0; int frequency_of_3s=0; int frequency_of_4s=0; int frequency_of_5s=0; int frequency_of_6s=0; |
// initialising
int frequency[6];
int i=0;
while (i<6) {
frequency[i]=0;
i=i+1;
}
|
// performing experiment
int experimentsDone=0;
while(experimentsDone<1000) {
int result=RollDie();
if(result==1)
frequency_of_1s=frequency_of_1s+1;
if(result==2)
frequency_of_2s=frequency_of_2s+1;
if(result==3)
frequency_of_3s=frequency_of_3s+1;
if(result==4)
frequency_of_4s=frequency_of_4s+1;
if(result==5)
frequency_of_5s=frequency_of_5s+1;
if(result==6)
frequency_of_6s=frequency_of_6s+1;
experimentsDone=experimentsDone+1;
}
|
// performing experiment
int experimentsDone=0;
while(experimentsDone<1000) {
int result=RollDie();
frequency[result]=frequency[result]+1;
experimentsDone=experimentsDone+1;
}
|
// results cout << frequency_of_1s << endl; cout << frequency_of_2s << endl; cout << frequency_of_3s << endl; cout << frequency_of_4s << endl; cout << frequency_of_5s << endl; cout << frequency_of_6s << endl; |
// results
i=0;
while(i<6) {
cout << frequency[i] << endl;
i=i+1;
}
|
glueWindow(); graphicsfunction (mygraphics); glueGo();at the end of your main function. These lines create a window, tell the computer which of your functions will draw into the window you've created, then give control over to the computer. You won't need to change these lines. There's also a prototype
void mygraphics(int w, int h);in OurTradingHeader.h and the mygraphics function itself in OurTradingFunctions1.cc. Initially the function contains just
void mygraphics(int w, int h) {
color(BLUE);
text("I wish I was a graph", 10, 100);
}
but you can add to this to create axes and lines.
If the window appears but your data-points don't
int speed=3;in a file outside of all functions, then this variable can be accessed from other files as long as the other files have
extern int speed;but if instead of int speed=3; in the first file you have
const int speed=3;the variable isn't visible from other files. Here's a table showing some examples of how the contents of 2 files can interact.
| File 1 | File 2 | Outcome |
int i;
int main()
{
i=5;
}
|
extern int i; |
Compiles. There's only one variable called 'i'. |
int i;
int main()
{
i=5;
}
|
int i; |
Fails (multiple definition of 'i') because when the 2 compiled files are linked together they each have an 'i' that is visible to the other. |
extern int i;
int main()
{
i=5;
}
|
int j; |
Fails (undefined reference to 'i') because File 1 expects an 'i' variable to be available from another file. |
extern int i;
int i;
int main()
{
i=5;
}
|
int j; |
Compiles. The int i; line takes precedence over the extern int i; line. |
static int i;
int main()
{
i=5;
}
|
int i; |
Compiles. File 1's 'i' is private - there are 2 variables called 'i' but they don't clash |
const int i=5;
int main()
{
;
}
|
int i; |
Compiles. File 1's 'i' is private (const vars are static by default) . |
extern const int i=5;
int main()
{
;
}
|
int i; |
Fails (multiple definition of 'i') because when the 2 compiled files are linked together they each have an 'i' that is visible to the other. Why? Because if a variable is declared as extern and it's initialised, then memory for that variable will be allocated. So in this situation there's an 'i' in each file. |
extern const int i=5;
int main()
{
;
}
|
extern const int i; |
Compiles. There's only one 'i' variable in the resulting program - the 'i' in file 2 refers to the 'i' in file 1. If the line in file 2 was extern const int i=2;, linking would fail |
int fish::count=0;" line can't be inside the main
(or any other) function.
| | C++ FAQ LITE Frequently Asked Questions | C++ | Languages | computing help | |