A few questions on C++ (from my C++ textbook)

Hello,
I've been studying my C++ textbook and working through some examples.
I had a few questions:

An excerpt from a code in the book:

#include <iostream>

int main()
{
//...
using std::cout;
using std::endl;
//...
}

The operator :: refers to the 'scope resolution'
The book doesn't seem to go into detail on this (at least not where I'm currently at)
Wondering what is exactly meant by 'resolution'?
Also what is meant by 'standard' in std::cout?

Another question:
Regarding bit shift left and right '<< and >>'
Example in code:

//...
cout << "Enter an integer: ";    /*guessing similar to Serial.print("Enter an integer: ")  
    prints "Enter an integer: " to console or serial monitor */

cin >> inputNumber;    /* guessing similar to Serial.write(inputNumber) 
    used to 'enter' or input a variable.  In this case some number. */

I noticed on cout there is a bit shift left (<<) and for cin there is a bit shift right (>>).

Why are these bit shifts necessary here?

Any help appreciated,

t

The "<<" insertion operator is a pipe sort of thing. It means that the thing on the right is sent to the ostream object on the left. Conversely for the ">>". It's defined in the ostream class, http://www.cplusplus.com/reference/iostream/cout/. One thing about C++ that takes some getting used to is that you can redefine operators like that for specific classes.

"using std::cout" tells the compiler which version of several possible "cout" routines to use. See Grey Wolf's posts at what is this operator? - C++ Forum.

Here is an explanation of using Declarations and using directive:
using Declarations, ie:

1
2
3

using std::cout;
using std::cin;
using std::endl

add names to the scope in which they are declared. The effect of this is:
» a compilation error occurs if the same name is declared elsewhere in the same scope;
» if the same name is declared in an enclosing scope, the the name in the namespace hides it.

The using directive, ie using namespace std;, does not add a name to the current scope, it only makes the names accesable from it. This means that:
» If a name is declared within a local scope it hides the name from the namespace;
» a name in a namespace hides the same name from an enclosing scope;
» a compilation error occurs if the same name is made visible from multiple namespaces or a name is made visible that hides a name in the global name space.

Global scope resolution (::Name) tells the compiler to look for the name at global scope rather than local or any other. If you have used a using directive in the global scope all the names are accessible via that scope.

full scope resolutions (namspace::name) tells the compiler exactly where to look.

Also what is meant by 'standard' in std::cout?

A simple program like this outputs to "standard output":

#include <stdio.h>

int main()
{
  printf ("Hello world.\n");
  return 0;
}

The C++ version would be:

#include <iostream>

int main()
{
  std::cout << "Hello world." << std::endl;
  return 0;
}

Now if you compile and run this from a terminal, it will output:

Hello world.

But if you "redirect" the output, eg.

./test > nick.txt

Then the output actually ends up in a file.

Or you can "pipe" the output to another program, eg.

./test | sort

Then the "standard output" from "test" becomes "standard input" to "sort".

First a little history.

C was first designed for use with the Unix (known as Linux on the PC's) each program on Unix is allocated 3 "files", Standard input (stdin), Standard out (stdout) and Standard error. In the first versions of Unix file names had a very limited size this lead to standardio becoming stdio and password becoming passwd.

<< is not a shift operator (in this case) it's an example of operator overloading. C++ allows the redefinition of operators when you define Classes.

Mark

holmes4:
C was first designed for use with the Unix (known as Linux on the PC's) each program on Unix is allocated 3 "files", Standard input (stdin), Standard out (stdout) and Standard error. In the first versions of Unix file names had a very limited size this lead to standardio becoming stdio and password becoming passwd.

What?

C was designed to write unix, which is different from linux (linux is a unix clone, but other less popular versions of unix such as mac OS X and FreeBSD exist).

From what I've heard, there used to be a 14 character limit on filenames in very early unix, but "password" and "standardio" are both less than that. The reason they're shorter is just to save typing.

The first version of Unix that I recall using was System 3 circa 1982 and (I no longer have the man's) but as I recall it was six plus an extension, with a max file name length including all directory names of 256 chars. This was a huge amount for the era!

Yes Unix was written in C. But C was written in C.

Mark

Amusing ...

The 'std::' has nothing to do with I/O. It refers to the 'namespace' 'std', a reserved namespace that all of the C++ Standard Library functions reside.

'::' is the namespace resolution operator. It exists to allow for the partition of symbol names to cut down on the collision of symbol names that are like to happen in todays projects.

'cout', 'cin' and 'cerr' are objects the conform to the 'stream' object paradigm available as part of the C++ Standard Libraries 'std' namespace.

You can create your own namespace where you are free to have symbol names the same as those in the 'std' namespace without fear of collisions which lead to linker errors.

lloyddean:
Amusing ...

The 'std::' has nothing to do with I/O.

I'm glad you enjoyed it. I never said "std::" was (in itself) anything to do with I/O.

I stand by my explanation.

A bad case of quoting in your reply and I misunderstood it as your statement - my apologies!

Apology accepted.

That's a line from Star Wars, isn't it?

Many thanks for the replies and help.

So different ways to express "std::" would be:

#include <iostream>
//...
int main()
{
using std::cout;
using std::endl;
//...
}
//...

And another:

#include <iostream>
using namespace std;
//...
//...

**I had another question regarding functions:
more specifically "void functionName()" and non-void functions.
The book states that "void functions are functions that aren't required to make decisions or return success or failure status. Also void functions cannot return a value..."

#include <iostream>
using namespace std;
void MultiplyNumbers ()
{
  cout << "Enter the first number: ";
  int FirstNumber = 0;
  cin >> FirstNumber;

  cout << "Enter the second number: ";
  int SecondNumber = 0;
  cin >> SecondNumber;

  // Multiply two numbers, store result in a variable
  int MultiplicationResult = FirstNumber * SecondNumber;

  // Display result
  cout << FirstNumber << " x " << SecondNumber;
  cout << " = " << MultiplicationResult << endl;
}
int main ()
{
  cout << "This program will help you multiply two numbers" << endl;

  // Call the function that does all the work
  MultiplyNumbers();

  // cout << FirstNumber <<" x " << SecondNumber;
  // cout << " = " << MultiplicationResult << endl;

  return 0;
}

Here the function "void MultiplyNumbers ()" makes a calculation and is later invoked inside "int main()"
So wouldn't this be returning a value to "MultiplyNumbers();" inside of "int main()" ?

I don't know about them not making decisions.

void functions don't have a return value, that's all.

They can however have side-effects, as in your example it asks for numbers, multiplies them and displays the result.

Example:

void foo (int a, int b)
  {
  // you can do things with a and b here

  return;   // you cannot return a value
  }  // end of foo

int bar (int a, int b)
  {
  return a + b;  // you must return an int
  }  // end of bar

To call those:

int main ()
  {
  foo (1, 2);  // call foo, there is no return value

  bar (4, 5);  // call bar, discard the return value

  int fubar = bar (6, 7);  // call bar, get its return value

  } // end of main

a void function can "return" a value. Example:
there's two ways to return more than one variable. The first is to make a struct to hold two values and return the struct:

struct fooReturn {
  int x;
  int y;
  int z;
};
fooReturn foo(int x, int y) {
  fooReturn ret = {x, y, x+y};
  return ret;
}
void setup() {
  Serial.begin(115200);
  fooReturn fr;
  fr = foo(3, 6);
  Serial.print("Sum is ");
  Serial.println(fr.z);
}
void loop() {}

The other is to pass the function an argument telling it where in memory to put the return value. This is called a pointer.

void foo(int* z, int x, int y) {
  *z = x + y;
}
void setup() {
  Serial.begin(115200);
  int z;
  foo(&z, 3, 6);
  Serial.print("Sum is ");
  Serial.println(z);
}
void loop() {}

In C++ there's also references which can do the same with slightly different syntax, but it's not advisible because the person calling the function won't know if it could change the value. But here's an example:

void foo(int& z, int x, int y) {
  z = x + y;
}
void setup() {
  Serial.begin(115200);
  int z;
  foo(z, 3, 6);
  Serial.print("Sum is ");
  Serial.println(z);
}
void loop() {}

Without wishing to nitpick, your first example "fooReturn foo(int x, int y)" isn't a void function.

The other ones are not returning the value, that is a side-effect (they are modifying data pointed to by a pointer, or a reference passed into the function). To return a value you literally have to use the "return" statement.

void functions can certainly change things outside themselves. Your examples do that, plus they can simply modify a global variable.

Just to make sure...

#include

using std::cout;
using std::endl;

the stripped down C++ used by Arduino doesn't have "iostream" or "std", right?

Thanks again for the replies.
Fubar... hehe sounds like most of the code I write :slight_smile:

So here:

int main ()
  {
  foo (1, 2);  // call foo, there is no return value

  bar (4, 5);  // call bar, discard the return value

  int fubar = bar (6, 7);  // call bar, get its return value

  } // end of main

In the function "void foo(int a, int b)", you're assigning the number 1 and 2 to "int a" and "int b" respectively.
In the function "int bar(int a, int b)", you're assigning the number 4 and 5 to "int a" and "int b" respectively, resulting in a value of int a + int b (4 + 5) which equals 9, but discarding the return value.
Then using the variable "int fubar", int fubar = bar(6, 7) to get a return of "13" ?

t

That's correct.

westfw:
Just to make sure...

#include

using std::cout;
using std::endl;

the stripped down C++ used by Arduino doesn't have "iostream" or "std", right?

To be precise, the C++ isn't stripped down particularly. However if you compile the above you get:

sketch_dec21a.cpp:1:20: warning: iostream: No such file or directory

You can use the Streaming library from here to implement something similar:

http://arduiniana.org/libraries/streaming/

It doesn't particularly make sense for the Arduino IDE to support stdin and stdout (or stderr) as they don't have any real meaning in the environment.

However if you like to "stream" output to, say, Serial, then you can use the Streaming library to get similar effects.

Just as a curiosity, I saw a bit of code from maniacbug in an example sketch that configured stdout to use Serial. I suppose it would have been possible to hook up the stdin and stderr file descriptors in the same way, but I've never tried it. I also haven't tested to see whether the standard i/o streams followed the same path. Anyway, I thought it was a neat technique.

/*
 Copyright (C) 2011 James Coliz, Jr. <maniacbug@ymail.com>
 
 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 version 2 as published by the Free Software Foundation.
 */
 
/**
 * @file printf.h
 *
 * Setup necessary to direct stdout to the Arduino Serial library, which
 * enables 'printf'
 */

#ifndef __PRINTF_H__
#define __PRINTF_H__

int serial_putc( char c, FILE * ) 
{
  Serial.write( c );

  return c;
} 

void printf_begin(void)
{
  fdevopen( &serial_putc, 0 );
}

#endif // __PRINTF_H__

PeterH:

[quote author=Nick Gammon link=topic=138443.msg1040972#msg1040972 date=1356140884]
It doesn't particularly make sense for the Arduino IDE to support stdin and stdout (or stderr) as they don't have any real meaning in the environment.

Just as a curiosity, I saw a bit of code from maniacbug in an example sketch that configured stdout to use Serial. I suppose it would have been possible to hook up the stdin and stderr file descriptors in the same way, but I've never tried it. I also haven't tested to see whether the standard i/o streams followed the same path. Anyway, I thought it was a neat technique.
[/quote]
http://arduino.cc/forum/index.php/topic,120440.0.html
http://www.nongnu.org/avr-libc/user-manual/group__avr__stdio.html