expression

I studied in reference book that Any arrangement of variables, constants, and operators that specifies a computation is called an expression. I also studied that Even single variables and constants, like alpha and 37, are considered to be expressions.

 
  cout << "the result is" << number;

In the above statement the variable number is the expression?
number is an expression. See:
https://en.cppreference.com/w/cpp/language/expressions

"the result is" is also an expression and perhaps maybe surprising:

cout << "the result is" << number

is also an expression as it returns a type/value (type std::ostream) - not used here.
Last edited on
Basically anything that gives you a value that you can use or print is an expression. Function calls are always expressions even if the return type is void.
> cout << "the result is" << number;

cout - id-expression (primary expression)

"the result is" - literal (primary expression)

cout << "the result is" - subexpression

number - id-expression (primary expression)

cout << "the result is" << number - full-expression (discarded-value expression)

cout << "the result is" << number; - expression statement
JLBorges wrote:
cout << "the result is" - subexpression

A subexpression is essentially an expression that is part of another expression so cout, "the result is" and number are also subexpressions.
Last edited on
What is the difference between statements and expressions?
hassan236 wrote:
What is the difference between statements and expressions?

The most important difference is that an expression has a type and will give you a value of that type unless the type is void. A statement does not have a type and does not result in a value.

Examples of expressions:
 
x+9
 
std::gcd(1, 100)
 
foo()


Any expression can be turned into a statement by putting a semicolon after it.

This is an expression:
 
foo()

This is a statement (that contains an expression):
 
foo();


There are also other kind of statements, some of which does not end in a semicolon.

If statements:
1
2
3
4
if (cond)
{
	doSomething();
}

Loop statements:
1
2
3
4
while (x < 100)
{
	std::cout << ++x << "\n";
}

Variable declaration statements:
 
int x = 5;

Note that some of these statements contain other statements and/or expressions.


In some places you are expected to use statements and in other places you are expected to use expressions.

The body of a function contains a list of statements. If you instead write a list of expressions (without semicolons) you would get a compilation error.
1
2
3
4
5
6
void bar()
{
	5+9
	std::gcd(1, 100)    // ERROR! 
	foo()
}

The arguments that you pass to functions should be expressions. You cannot write statements instead. That won't work.
1
2
// This is an error no matter how someFunction is defined:
someFunction(foo();, if(cond){doSomething();});


Last edited on
Statements are fragments of the C++ program that are executed in sequence. An expression statement is an expression followed by a semicolon. See:
https://en.cppreference.com/w/cpp/language/statements
cout is also the expression? how?
Last edited on
As in mine and others previous posts,

 
cout << "the result is" << number


is an expression - as cout returns a type and a value.

 
cout << "the result is" << number;


is a statement (with the ;) where the returned value from cout expression is not used. Only the expression side-effects are utilised here (output to the console).
Let's say you using a C++ container like a std::vector, you can overload the insertion operator (<<) so writing an output statement for a container is as simple as outputting a built-in C++ type like an int.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
#include <vector>

// 1D
template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& v)
{
   for ( auto const& x : v ) { os << x << ' '; }
   return os;
}

// 2D, which ends up calling the 1D overload as well
template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<std::vector<T>>& v)
{
   for ( auto const& x : v ) { os << x << '\n'; }
   return os;
}

int main()
{
   std::vector vec1D { 1, 2, 3, 4, 5 };

   std::cout << vec1D << "\n\n";

   std::vector<std::vector<int>> vec2D { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };

   std::cout << vec2D << '\n';
}

Returning the std::ostream object in the overload functions chains up the output for proper functioning of the insertion operator.

How the 2 container objects at lines 22 & 26 are instantiated requires C++17 or later, the rest of the code is C++11.

A 3D container will use the 1D and 2D overloads, no need to write an overload for 3D unless it requires different output handling (C++11 or later):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <iostream>
#include <vector>

template <typename T>
std::ostream& operator<<(std::ostream&, const std::vector<T>&);
template <typename T>
std::ostream& operator<<(std::ostream&, const std::vector<std::vector<T>>&);

int main()
{
   std::cout << "Creating a 3-dimensional vector, enter depth size: ";
   int depth;
   std::cin >> depth;

   std::cout << "Enter row size: ";
   int row;
   std::cin >> row;

   std::cout << "Enter column size: ";
   int col;
   std::cin >> col;

   std::cout << "\n";

   // create a 3 dimensional int vector with known dimensions
   using std::vector;
   vector<vector<vector<int>>> aVector(depth, vector<vector<int>>(row, vector<int>(col, 0)));

   // let's display the initial 3D vector
   std::cout << aVector << '\n';

   // initialize the vector with some values
   for (int depth_loop = 0; depth_loop < depth; depth_loop++)
   {
      for (int row_loop = 0; row_loop < row; row_loop++)
      {
         for (int col_loop = 0; col_loop < col; col_loop++)
         {
            aVector[depth_loop][row_loop][col_loop] = (((depth_loop + 1) * 100)
                                                       + ((row_loop + 1) * 10)
                                                       + col_loop + 1);
         }
      }
   }

   // let's display the filled 3D vector
   std::cout << aVector << '\n';
}

template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& v)
{
   for (auto const& x : v)
   {
      os << x << ' ';
   }

   return os;
}

template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<std::vector<T>>& v)
{
   for (auto const& x : v)
   {
      os << x << '\n';
   }

   return os;
}

You can overload the extraction operator (>>) as well.

Dealing with a custom class is another use for writing I/O stream overloads.

https://www.geeksforgeeks.org/overloading-stream-insertion-operators-c/
IMO it's easier when dealing with things like vector<vector<... to have using statements for new type defs. Consider:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <iostream>
#include <vector>

template <typename T = int>
using Arr1d = std::vector<T>;

template <typename T = int>
using Arr2d = std::vector<Arr1d<T>>;

template <typename T = int>
using Arr3d = std::vector<Arr2d<T>> ;

template <typename T>
std::ostream& operator<<(std::ostream&, const Arr1d<T>&);

template <typename T>
std::ostream& operator<<(std::ostream&, const Arr2d<T>&);

int main() {
	std::cout << "Creating a 3-dimensional vector, enter depth size: ";
	int depth;
	std::cin >> depth;

	std::cout << "Enter row size: ";
	int row;
	std::cin >> row;

	std::cout << "Enter column size: ";
	int col;
	std::cin >> col;

	// create a 3 dimensional int vector with known dimensions
	Arr3d aVector(depth, Arr2d(row, Arr1d(col)));

	// let's display the initial 3D vector
	std::cout << '\n' << aVector;

	// initialize the vector with some values
	for (int rc {}; auto& rw : aVector) {
		rc += 100;
		for (int cc {}; auto& cl : rw) {
			cc += 10;
			for (int ec {}; auto& elem : cl)
				elem = rc + cc + ++ec;
		}
	}

	// let's display the filled 3D vector
	std::cout << aVector;
}

template <typename T>
std::ostream& operator<<(std::ostream& os, const Arr1d<T>& v) {
	for (auto const& x : v)
		os << x << ' ';

	return os;
}

template <typename T>
std::ostream& operator<<(std::ostream& os, const Arr2d<T>& v) {
	for (auto const& x : v)
		os << x << '\n';

	return os;
}

Last edited on
cout is also the expression? how?

In addition to what @seeplus mentions about cout having a type and a value, note that cout is not "built in" to the compiler, it is simply a variable that is defined by the standard library.
Last edited on
Topic archived. No new replies allowed.