functions

Pages: 12
hi,
I have the following code, and I'd like to put the if statements in a function, which will return the value of variables 'flag' (can have values U or D for now, and I intend to add more),'dn' and 'up'...how do I do that?
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
#include <iostream>
using namespace std;

int main()
{
  double up=0;
  double dn=0;
 
  char flag='U';

 int arrsize=7;
  double s[]={24,24.2,23.8,23.9,23.5,23.95,24.1};

  for(int i=0;i<arrsize;i++){

  if(flag=='U')
    {  
      if(s[i]>s[i-1])
	{
	  up=s[i];
	  flag='U';
	}
      else
	{
	  dn=s[i];
	  flag='D';
	 }
    }
  else
    {
      if(s[i]<s[i-1]){
	dn=s[i];
      flag='D';}
      else
	{
	     up=s[i];
	    flag='U';
	}
    }
  }
  return 0;
}
closed account (zb0S216C)
Do you mean something like this (?):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
char FunctionIdentifier( char &Target, double &Up, double &Dn )
{
    if( Flag == 'U' )
    {  
        // ...
    }

    else
    {
        // ...
    }
}

int main( )
{
    // ...
    // To call your function:
    FunctionIdentifier( flag, up, dn );
}

Wazzak
Last edited on
well, i thought I would need one function for upmove and one for downmove, so,

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
char upmove( double *, char, double);
char dnmove(double *, char, double);
int main()
{
if(flag=='U')
{
upmove(&(s[i]), flag,up); 
}
else
{
dnmove(&(s[i], flag, dn);
}
return 0;
}

char upmove(double *sptr, char uflag, double ut)
{
ut=*sptr; //basically, I want to assign 'ut' the value of s[i] - is this even a correct way of doing it?
uflag='U';//I want to update uflag to 'U'
return ??? I want to return the uflag and ut back to the main function, how do I do that? 
}

char dnmove(double *sptr, char dflag, double dt)
{
dt=*sptr; //basically, I want to assign 'dt' the value of s[i] - is this even a correct way of doing it?
dflag='D';//I want to update dflag to 'D'
return ??? here, I want to return the dflag and dt back to the main function, just like in upmove?? 
}
closed account (zb0S216C)
itcplpl wrote:
//basically, I want to assign 'ut' the value of s[i] - is this even a correct way of doing it?

Yes. When you want to see the value pointed to by a pointer, you dereference it; like you've done here.

itcplpl wrote:
I want to return the uflag and ut back to the main function, how do I do that?

You cannot return two values at the same time. There is an alternative, however. The alternative involves a basic structure. The structure may look like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
struct ReturnValues
{
    ReturnValues( void ) : Flag( 'A' ), Ut( 0.0 )
    { }

    ReturnValues( const char NewFlag, const double NewUt ) : Flag( NewFlag ), Ut( NewUt ) 
    { }

    char Flag;
    double Ut;
};

// To use the structure:
ReturnValues upmove( double *sptr, char uflag, double ut )
{
    // ...
    return ReturnValues( uflag, ut );
}

Wazzak
Last edited on
cool, thx.
let me try that out
ok, so I put this in as my entire code and I get errors that Flag, Ut, upmove was not declared in this scope...did I write this correct...

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
#include <iostream>
using namespace std;

struct Trend
{
   Trend(void): Flag('U'), Ut(0.0) {}
  //Trend(const NewFlag, const double NewUt):Flag(NewFlag),Ut(NewUt){}
  char Flag;
  double Ut;
};

int main()
{
 int arrsize=7;
  double s[]={24,24.2,23.8,23.91,23.55,23.9,24.1};

  for (int i=0;i<arrsize;i++)
    {
      upmove(&(s[i]),Flag, Ut);
      cout<<"for loop"<<Flag<<' '<<Ut;
    }
  return 0;
}

Trend upmove (double *sptr, char uflag, double ut)
{
  ut=*sptr;
  uflag='U';
  cout<<"ut is"<<ut<<' '<<uflag<<endl;
  return Trend(uflag, ut);
}
closed account (zb0S216C)
First, you never defined upmove( ) until after main( ). Second, since you commented out the second constructor of Trend, you've broken the return statement of upmove( ).

Before you can access members of a structure, you must instantiate it[1]. For example:

1
2
3
4
5
6
7
8
9
10
11
12
struct Trend
{
  char Flag;
  double Ut;
};

int main( )
{
    Trent trend;
    trend.Flag = 'U';
    trend.Ut = 0.0;
}

If a function returns a structure, you can access the member of the returned structure, like this:

1
2
3
4
5
6
7
8
9
Trent Function( void )
{
    // ...
    return Trent( 'A', 0.0 );
}

// Accessing the members of the returned structure:
Function( ).Flag = 'A';
Function( ).Ut = 0.0;

References:
[1]http://www.cplusplus.com/doc/tutorial/structures/


Wazzak
Last edited on
so why do we need a second constructor?
also, I am passing 3 parameters to upmove, but in the constructor, or in the body of main, the first one ,i.e., s[i] is not instantiated....

but, I have now instantiated the members of the structure, and this is the code again:
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
#include <iostream>
using namespace std;

struct Trend
{
  Trend(void): Flag('U'), Ut(0.0) {}
  Trend(const NewFlag, const double NewUt):Flag(NewFlag),Ut(NewUt){}
  char Flag;
  double Ut;
};

int main()
{
  Trend trend;
  trend.Flag='U';
  trend.Ut=0.0;
 int arrsize=7;
  double s[]={24,24.2,23.8,23.91,23.55,23.9,24.1};

  for (int i=0;i<arrsize;i++)
    {
      upmove(&(s[i]),Flag, Ut);
      cout<<"for loop"<<upmove().Flag<<' '<<upmove().Ut;
    }
return 0;
}

Trend upmove (double *sptr, char uflag, double ut)
{
  ut=*sptr;
  uflag='U';
  cout<<"ut is"<<ut<<' '<<uflag<<endl;
  return Trend(uflag, ut);
}


when I run it, this is the error i get:
1
2
3
4
5
6
7
8
9
testd1.cpp:7:15: error: ‘NewFlag’ does not name a type
testd1.cpp:7:15: error: ISO C++ forbids declaration of ‘parameter’ with no type
testd1.cpp: In constructor ‘Trend::Trend(int, double)’:
testd1.cpp:7:49: error: ‘NewFlag’ was not declared in this scope
testd1.cpp: In function ‘int main()’:
testd1.cpp:22:22: error: ‘Flag’ was not declared in this scope
testd1.cpp:22:28: error: ‘Ut’ was not declared in this scope
testd1.cpp:22:30: error: ‘upmove’ was not declared in this scope
make: *** [testd1] Error 1

closed account (zb0S216C)
Your code should look like this:

Before:
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
#include <iostream>
using namespace std;

struct Trend
{
  Trend(void): Flag('U'), Ut(0.0) {}
  Trend(const NewFlag, const double NewUt):Flag(NewFlag),Ut(NewUt){}
  char Flag;
  double Ut;
};

int main()
{
  Trend trend;
  trend.Flag='U';
  trend.Ut=0.0;
 int arrsize=7;
  double s[]={24,24.2,23.8,23.91,23.55,23.9,24.1};

  for (int i=0;i<arrsize;i++)
    {
      upmove(&(s[i]),Flag, Ut);
      cout<<"for loop"<<upmove().Flag<<' '<<upmove().Ut;
    }
return 0;
}

Trend upmove (double *sptr, char uflag, double ut)
{
  ut=*sptr;
  uflag='U';
  cout<<"ut is"<<ut<<' '<<uflag<<endl;
  return Trend(uflag, ut);
}


After:
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
#include <iostream>
using namespace std;

struct Trend
{
  Trend( void ): Flag( 'U' ), Ut( 0.0 ) { }
  Trend( const char NewFlag, const double NewUt ) : Flag( NewFlag ), Ut( NewUt ){ }
  char Flag;
  double Ut;
};

Trend upmove( double *, char, double );

int main( )
{
	Trend trend;
	Trend ReturnTrend;

	trend.Flag='U';
	trend.Ut=0.0;
	double s[]={24,24.2,23.8,23.91,23.55,23.9,24.1};

	int arrsize( sizeof( s ) / sizeof( s[ 0 ] ) );

	for( int i( 0 ); i < arrsize; i++ )
	{
		ReturnTrend = upmove( &s[ i ], trend.Flag, trend.Ut );
		cout << "for loop: " << ReturnTrend.Flag << ' ' << ReturnTrend.Ut;
	}

	std::cin.get( );
	return 0;
}

Trend upmove( double *sptr, char uflag, double ut )
{
	ut = *sptr;
	uflag = 'U';
	cout << "Ut is: " << ut << ' ' << uflag << endl;
	return Trend( uflag, ut );
}

Wazzak
thanks....it worked....
is class also similar to struct...and would this also be possible by defining class or is that more complicated
Classes, structs, and unions are all exactly the same, except that classes by default start with an invisible private: at the start, structs and unions start off public, and union data members use the same memory space.
cool, ok....I should try my hand at classes also then...
ok, I don't understand how the constructors are working, but using Framework's struct code, it works.....I've only read about standard constructor where the code would be:

1
2
3
4
5
6
7
8
class Trend
{
public:
Trend();
...
}
Trend::Trend(char, double): Flag('U'), Ut(0.0)
{}


but that doesn't seem to work in this case....if you can provide me a reference that explains the concept of these 2 constructors, that would help to know....

also, when I declare Flag and Ut as private, it doesn't compile....why?
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
#include <iostream>
using namespace std;

class Trend
{
public:
  Trend(void): Flag('U'),Ut(0.0){}
  Trend(char Nflag, double Nut):Flag(Nflag), Ut(Nut){}
Trend upmove(double *, char, double);
  char Flag;
  double Ut;
};

Trend Trend::upmove(double *sptr, char flag, double ut)
{
  ut=*sptr;
  flag='U';
   return Trend(flag,ut);
}

int main()
{
  Trend trend;
  Trend retrend;
 
  double s[]={24,24.2,23.8,23.91,23.55,23.9,24.1};
 int arrsize=sizeof(s)/sizeof(s[0]);

  for (int i=0;i<arrsize;i++)
    {
      retrend=trend.upmove(&(s[i]),trend.Flag,trend.Ut);
     cout<<"flag"<<retrend.Flag<<retrend.Ut;
    }
  cout<<endl;
return 0;
}


Last edited on
closed account (zb0S216C)
itcplpl wrote:
Trend::Trend(char, double): Flag('U'), Ut(0.0) {}

This constructor was never declared within the Trend class. Also, since you never gave the arguments identifiers, those arguments become useless.

itcplpl wrote:
when I declare Flag and Ut as private, it doesn't compile....why?

when a constructor is declared as private, the compiler cannot call that constructor because you told the compiler that you don't want any external classes, functions, or objects to access it (including the compiler). This is the same for members of a class. Here's how it goes: A member that's declared as private can only be accessed by the members of the same class. Declaring a member as public will allow all internal and external functions, classes, and objects to access it.

Wazzak
so, if I declare the variables, Flag and Ut as private, then upmove, which is a member function of class Trend, should be able to access it, right. why doesn't it?

1
2
3
4
5
6
7
8
9
10
class Trend
{
public:
  Trend(void): Flag('U'),Ut(0.0){}
  Trend(char Nflag, double Nut):Flag(Nflag), Ut(Nut){}
Trend upmove(double *, char, double);
private:
  char Flag;
  double Ut;
};
closed account (zb0S216C)
itcplpl wrote:
why doesn't it?

in your code, upmode( ) is declared as public, so it should work. Can you post the definition of upmove( )? Also, are you receiving any errors at all?

When members such as Flag and Ut are declared private, only members of the same class can access them. For example:

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
#include <iostream>

class Example
{
    public:
        Example( void ) : Member( 0 )
        { }

        const int &GetMember( void ) const;
        const int &SetMember( const int NewInt ); 

    private:
        int Member;
};

const int &Example::GetMember( void ) const
{
    return this->Member; // this-> isn't required.
}

const int &Example::SetMember( const int NewInt )
{
    this->Member = NewInt;
    return this->GetMember( );
}

int main( )
{
    Example example;

    example.Member = 10;      // Error! Member is private.
    example.SetMember( 40 );  // OK. SetMember( ) is public.
    
    std::cout << "example.Member is holding: " << example.GetMember( ) << std::endl;

    std::cin.get( );
    return 0;
}

Referrals:
Classes (video tutorial): http://www.youtube.com/watch?v=r1ZkiJ4BgWM


Wazzak
Last edited on
this is what I have for upmove()
1
2
3
4
5
6
Trend Trend::upmove(double *sptr, char flag, double ut)
{
  ut=*sptr;
  flag='U';
   return Trend(flag,ut);
}


and the error message I get is:
1
2
3
4
5
6
7
8
9
10
framework.cpp: In function ‘int main()’:
framework.cpp:11:8: error: ‘char Trend::Flag’ is private
framework.cpp:32:42: error: within this context
framework.cpp:12:10: error: ‘double Trend::Ut’ is private
framework.cpp:32:53: error: within this context
framework.cpp:11:8: error: ‘char Trend::Flag’ is private
framework.cpp:33:28: error: within this context
framework.cpp:12:10: error: ‘double Trend::Ut’ is private
framework.cpp:33:42: error: within this context
make: *** [framework] Error 1


this is the full program:
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
#include <iostream>
using namespace std;

class Trend
{
public:
  Trend(void): Flag('U'),Ut(0.0){}
  Trend(char Nflag, double Nut):Flag(Nflag), Ut(Nut){}
Trend upmove(double *, char, double);
private:
  char Flag;
  double Ut;
};

Trend Trend::upmove(double *sptr, char flag, double ut)
{
  ut=*sptr;
  flag='U';
   return Trend(flag,ut);
}

int main()
{
  Trend trend;
  Trend retrend;
 
  double s[]={24,24.2,23.8,23.91,23.55,23.9,24.1};
 int arrsize=sizeof(s)/sizeof(s[0]);

  for (int i=0;i<arrsize;i++)
    {
      retrend=trend.upmove(&(s[i]),trend.Flag,trend.Ut);
     cout<<"flag"<<retrend.Flag<<retrend.Ut;
    }
  cout<<endl;
return 0;
}


If I am not mistaken, the error is due to the assignment to retrend ....if so, other than making Flag and Ut public, is there a workaround so I can leave them private....
closed account (zb0S216C)
As I said in my previous post, only members of the same class can access private members. I'll modify your code so that it works. I'll point out the changes I made and you can study them.

OK. Here's your new code. Notice how I've added two methods to Trend. Also note how I used both new methods within main( ). Look at how they're defined and called.

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>
using namespace std;

class Trend
{
	public:
		Trend(void): Flag('U'),Ut(0.0){}
		Trend(char Nflag, double Nut):Flag(Nflag), Ut(Nut){}
		Trend upmove(double *, char, double);

		//-----------------------------------------------------------
		// Name: GetFlag( )
		// Desc: Returns 'Flag' to the caller.
		//-----------------------------------------------------------
		char &GetFlag( void );

		//-----------------------------------------------------------
		// Name: GetUt( )
		// Desc: Returns 'Ut' to the caller.
		//-----------------------------------------------------------
		double &GetUt( void );

	private:
		char Flag;
		double Ut;
};

//-------------------------------------------------------------------
// Trend Definition - upmove( )
//-------------------------------------------------------------------
Trend Trend::upmove(double *sptr, char flag, double ut)
{
	ut=*sptr;
	flag='U';
	return Trend(flag,ut);
}

//-------------------------------------------------------------------
// Trend Definition - GetFlag( )
//-------------------------------------------------------------------
char &Trend::GetFlag( void )
{
	return this->Flag;
}

//-------------------------------------------------------------------
// Trend Definition - GetUt( )
//-------------------------------------------------------------------
double &Trend::GetUt( void )
{
	return this->Ut;
}

int main( )
{
	Trend trend;
	Trend retrend;
 
	double s[]={24,24.2,23.8,23.91,23.55,23.9,24.1};
	int arrsize=sizeof(s)/sizeof(s[0]);

	for( int i = 0; i < arrsize; i++ )
        {
		retrend = trend.upmove( &(s[i]), trend.GetFlag( ), trend.GetUt( ) );
		cout<<"flag"<< retrend.GetFlag( ) << retrend.GetUt( );
        }

	cout<<endl;
	return 0;
}

When you call the new methods, it will return a non-constant reference to the corresponding member. The method identifier indicates which private member it returns.

Added Content:
Using the two new methods, you can modify the private members. For example:
retrend.GetFlag( ) = 'F';

To prevent assignments through these methods, you can add the const qualifier. For example:
const char &GetFlag( void ) const;

Here, the const before char indicates that the value returned by this method cannot be modified. The const after the argument list indicates that the method will not modify any member of the class. Ever.

Wazzak


Last edited on
thanks very much.....that is helpful.....I will study that...
I do need the program to modify Flag to other alphabets, after x iterations. so I understand I should not use const after the argument list, but since I don't want any other method to modify the value returned by this method, I should include const before char, is that correct?
Pages: 12