d2jsp
Log InRegister
d2jsp Forums > Off-Topic > Computers & IT > Programming & Development > Make Me A Better Programmer - From Step 1
Prev15678956Next
Add Reply New Topic New Poll
Member
Posts: 13,425
Joined: Sep 29 2007
Gold: 0.00
Warn: 20%
Jul 21 2012 01:02pm
Quote (PumblesMumbles @ Jul 21 2012 11:54am)


this. although i always expand my brackets such as.

Code
if (whatever)
{
   return true;
}
else
{
   return false;
}


dont ask me why its just a bad habbit. i think they both look alright besides the 1 extra line that is not needed and if you use an IDE that supports the function of collapsible statements you can collapse the code and it wont bother you in either style lol.

uncollapsed http://i.imgur.com/Qzh7b.png
collapsed certian functions/if statements http://i.imgur.com/BBmE1.png

as for your your confusion about the const there are two was to pass variables to a function. pass by reference and pass by value.

passing by value simply transfers the current value held in the local variable of the calling function and "sends a copy" to the function. the function would then have a copy of the variable that it can change at will and no matter what the local variable of the calling function will not change.

passing by reference on the other hand passes the memory address of the variable for which the function can change for itself and the original function that called it.

a simply analogy would be if i gave you a url to a website this would be passing as reference. if the website changes both you and i would see the change (both the original calling function and the function you called will see the change to the variable)

on the other hand if i print out a copy of the webpage and gave it to you, you would only have a copy and if i changed the website in any way you wouldnt see a difference nor if you changed the paper i wouldnt see it (if the calling function changes the variable the function that called it would not see the changes.)

a code example would be like so.

Code
#include <stdio.h>
#include <stdlib.h>

int pass_by_value(int x);
int pass_by_ref(int *x);

void main()
{
int test = 5;
int pbvalue = 0;
int pbref = 0;

printf("\n our starting number is: %d", test);

pbvalue = pass_by_value(test);
printf("\n\n our original variable test: %d \n our returned variable: %d", test, pbvalue);

pbref = pass_by_ref(&test);
printf("\n\n our original variable test: %d \n our returned variable: %d\n", test, pbref);
}

int pass_by_value(int x)
{
x += x;
return x;
}

int pass_by_ref(int *x)
{
*x += *x;
return *x;
}


the output is

Code
our starting number is: 5

our original variable test: 5
our returned variable: 10

our original variable test: 10
our returned variable: 10

Process returned 62 (0x3E)   execution time : 0.014 s
Press any key to continue.


as you can see when we pass a variable by value our original is unchanged but since i passed a pointer (reference) to our variable our original changed as well.

This post was edited by AbDuCt on Jul 21 2012 01:03pm
Member
Posts: 13,425
Joined: Sep 29 2007
Gold: 0.00
Warn: 20%
Jul 21 2012 01:15pm
Quote (Reynaldo @ Jul 21 2012 02:39pm)
hey, i program on c, python, you could make an infinte loop when you ask for information, and ONLY IF the information introduced was right, then you proceed to close the loop and then the program keeps going

an example in c

....

int inf=0, num1;

while (inf==0)
{
printf("\nIntroduce me one number between 1-1000");
scanf("%i", &num1);

if (num1>1 && num1<1000)
{
inf=1;
}
}


sorry for the double post but this code is horrid >.>

could do away with 1 whole variable and make the logic flow better by using a do while loop and putting your conditions in the while brackets. (using a do..while loop guarantees that 1 loop will execute before the conditions are checked while, a while loop will check conditions before a single iteration has been preformed)
Member
Posts: 23,862
Joined: Aug 16 2006
Gold: 20.00
Jul 22 2012 12:30am
Thanks for the posts! Let me see if I can respond to some. (prepare for edits)

Quote (PumblesMumbles @ Jul 21 2012 10:54am)
The only "bug" I see is that you are counting 0 as a positive number.

As far as style, there are four things I'd call out. First, I always use brackets in if/else statements, even if the block is only one line. It makes all programs look the same and makes it easier to add more to the block later. Second, whenever you have an expression like

Code
if (whatever) {
   return true;
}
else {
   return false;
}


you can always just shorten that to return (whatever);. If you'd return false in the if case and true in the else case, it can be return !(whatever);. Third, I recommend camel case for function names (isInOrder, printResults, etc) since it makes them easier to read. Fourth, I recommend spaces between function arguments (inorder(x, y, z) vs inorder(x,y,z)) again because it makes the program easier to read.

It sounds like the last two might be decisions the professor has made for you. More important than any style preference is working in the same style as the rest of your team.


Ahhh, good point about the zero. I forgot the prof. did mention to take care of that as well.

About the if else, THANKS. I have been waiting for someone to tell me that it is a good idea to do that. I have absolutely NO PROBLEM doing the brackets even if there is only one line. I just had no idea whether doing that was good writing or not.

Will do the other things you mentioned too (spaces, and camel case)

Quote (Reynaldo @ Jul 21 2012 01:39pm)
hey, i program on c, python, you could make an infinte loop when you ask for information, and ONLY IF the information introduced was right, then you proceed to close the loop and then the program keeps going

an example in c

....

int inf=0, num1;

while (inf==0)
{
printf("\nIntroduce me one number between 1-1000");
scanf("%i", &num1);

if (num1>1 && num1<1000)
{
inf=1;
}
}


I am still searching for the best way to do something like checking a value while getting it. The prof. used do-whiles, but I am not sure what is the best way yet.

Quote (AbDuCt @ Jul 21 2012 02:15pm)
sorry for the double post but this code is horrid >.>

could do away with 1 whole variable and make the logic flow better by using a do while loop and putting your conditions in the while brackets. (using a do..while loop guarantees that 1 loop will execute before the conditions are checked while, a while loop will check conditions before a single iteration has been preformed)


Thanks for your posts. I have not learned about pointers yet in the class but probably will soon.

Can you offer a better way for me to do that cin function?

You said a while loop would work better?

This post was edited by Eep on Jul 22 2012 12:45am
Member
Posts: 279
Joined: Apr 11 2010
Gold: 1,486.00
Jul 22 2012 08:29am
Quote (Eep @ Jul 22 2012 02:30am)
Can you offer a better way for me to do that cin function?

I see two problems with your written getdouble() function. The first is that you have some duplication in it. The duplication is in your check for the do-while and your check for printing the re-prompt (both check d < 0). In general, you should avoid duplication like this, even when it is relatively small. Here's how I would write that (I've also included a fix for the 0-is-positive bug):

Code
double getDouble() {
   double d;
   
   do {
       cin >> d;
       
       if (isNotPositive(d)) {
           cout << "Please enter a positive number." << endl;
       }
   }
   while (isNotPositive(d));
   
   return d;
}

bool isNotPositive(double d) {
   return (d <= 0);
}


The second problem that I have with it is that it includes a do-while loop. I think do-while loops are confusing. I don't think I've ever had the need to write one in my entire career. If you step back for a second, getDouble() just:

1) takes in a number
2) checks if that number is valid
3) returns that number if it is
4) loops if it isn't

Here's a much more straightforward way of writing that code, in my opinion:

Code
double getDouble() {
   double d;
   
   while (true) {
       cin >> d;
       
       if (d > 0) {
           return d;
       }
       else {
           cout << "Please enter a positive number." << endl;
       }
   }
}


As you read through this version of the function, it's clear from the top of the while (true) that we are going to be looping until something happens (in this case, until if (d > 0) is satisfied). It is then clear that we are taking in a number and behaving in one of two ways depending on what the value of that number is.

Hope this helps.

edit: converted tabs to spaces in the code blocks

This post was edited by PumblesMumbles on Jul 22 2012 08:30am
Member
Posts: 13,425
Joined: Sep 29 2007
Gold: 0.00
Warn: 20%
Jul 22 2012 11:50am
Quote (PumblesMumbles @ Jul 22 2012 10:29am)

Here's a much more straightforward way of writing that code, in my opinion:

Code
double getDouble() {
   double d;
   
   while (true) {
       cin >> d;
       
       if (d > 0) {
           return d;
       }
       else {
           cout << "Please enter a positive number." << endl;
       }
   }
}


^this. returning at any point in a function will terminate the loop and pass control back to the function that called it along with the variable included with return (in this case d).
not only is it cleaner, its less code and makes a bit more sense to someone else who may read your code. either way they both do the same thing and would both work.
Member
Posts: 23,862
Joined: Aug 16 2006
Gold: 20.00
Jul 22 2012 12:29pm
Quote (AbDuCt @ Jul 22 2012 12:50pm)
^this. returning at any point in a function will terminate the loop and pass control back to the function that called it along with the variable included with return (in this case d).
not only is it cleaner, its less code and makes a bit more sense to someone else who may read your code. either way they both do the same thing and would both work.


Quote
Here's a much more straightforward way of writing that code, in my opinion:

Code
double getDouble() {
   double d;
   
   while (true) {
       cin >> d;
       
       if (d > 0) {
           return d;
       }
       else {
           cout << "Please enter a positive number." << endl;
       }
   }
}


As you read through this version of the function, it's clear from the top of the while (true) that we are going to be looping until something happens (in this case, until if (d > 0) is satisfied). It is then clear that we are taking in a number and behaving in one of two ways depending on what the value of that number is.

Hope this helps.

edit: converted tabs to spaces in the code blocks



I never thought about using a while with condition 'true. That is pretty neat. Thanks a bunch for the help guys.

This post was edited by Eep on Jul 22 2012 12:30pm
Member
Posts: 23,862
Joined: Aug 16 2006
Gold: 20.00
Jul 22 2012 08:49pm
Code
#include <iostream>
using namespace std;

const int N = 3;
double getdouble();
bool isinorder(double x, double y, double z);
void printresults(string x, double y);
void instructions(int n);
double total(double x, double y, double z);

int main()
{
   instructions(N);  //prompts the user for 3 pos numbers (doubles)

   double x=getdouble();
   double y=getdouble();
   double z=getdouble();

   if (isinorder(x,y,z))
   {
       cout <<"Theyre in order.\n";
   }
   else
   {
       cout <<"Theyre not in order.\n";
   }

   double sum = total(x,y,z);
   double avg = sum/N;

   printresults("total: ",sum);
   printresults("avg: ",avg);

   return 0;
}

void instructions(int n)
{
   if (n == 1)
   {
       cout<<"Please type in a positive double";
   }
   else
   {
       cout<<"Please type in "<<n<<" positive doubles";
       cout <<".\n";
   }
}

bool isinorder(double x, double y, double z)
{
   if (x <= y && y <= z)
   {
       return true;
   }
   return false;
}

double getdouble()
{
   double d;

   while (true)
   {
       cin >> d;

       if (d > 0)
       {
           return d;
       }
       else
       {
           cout << "Please enter a positive number." << endl;
       }
   }
}


double total(double x, double y, double z)
{
   return x + y + z;
}

void printresults(string x, double y)
{
   cout << x << y << endl;
}


re-posted
Member
Posts: 279
Joined: Apr 11 2010
Gold: 1,486.00
Jul 23 2012 06:39am
Looking better but you could still change isInOrder() to just be

return (x <= y && y <= z);
Member
Posts: 30,712
Joined: Sep 19 2007
Gold: 340.00
Jul 23 2012 10:21am
use more descriptive variable names, it's not a contest to have the smallest code. Concise code may often be small, but small code is not necessarily concise. Also, use arrays. There's no good reason not to, and your program could be way more adaptable to change if you did.

You don't need an extra line for
cout <<".\n";
that \n should be included in the above cout

N should be a define statement instead of cons int;

array-ify the following:
isinorder
total
*new method that gets an array of double as user input

if you're going to have a method for instructions, you may as well make one for displaying if the results are in order or not. Personally I think those are small enough snippets and they're too localized to be made into functions, aka you're not going to be reusing them so why extract them.
instructions could be incorporated into the new user input method

print results is useless

and I'm not sure but I think using namespace std is discouraged.

so here's my suggested program (wire-frame)

I have not used C++ in a long time

Code
#include <iostream>
using namespace std;

#define N = 3;

int main()
{

  int inputs[N];
  getInputs(&inputs, N);

  if (sorted(&inputs, N))
  {
      cout <<"Theyre in order.\n";
  }
  else
  {
      cout <<"Theyre not in order.\n";
  }

  double sum = sum(&inputs, N);
  double avg = sum/N;

  cout << "total:" << sum << endl;
  cout << "average:" << avg << endl;

  return 0;
}

void getInputs(int * results, int count)
{
  if (n == 1)
  {
      cout<<"Please type in a positive double";
  }
  else
  {
      cout<<"Please type in "<<n<<" positive doubles\n";
  }

 for(int index = 0; index < count; index++)
   results[index] = getDouble();
}

bool sorted(int * list, int length)
{
  int prev = list[0];
  for(int index = 1; index < length; index++)
  {
     if (prev > list[index])
       return false;
     prev = list[index];
  }
 
  return true;
}

int sum(int * list, int length)
{
  int total;
  for(int index = 0; index < length; index++)
     total += list[index];
 
  return total;

}

double getdouble()
{
  double d;

  while (true)
  {
      cin >> d;

      if (d > 0)
      {
          return d;
      }
      else
      {
          cout << "Please enter a positive number." << endl;
      }
  }
}


This post was edited by J_B on Jul 23 2012 10:34am
Member
Posts: 13,425
Joined: Sep 29 2007
Gold: 0.00
Warn: 20%
Jul 23 2012 11:55pm
Quote (J_B @ Jul 23 2012 12:21pm)

[CODE][/CODE]


iirc you dont need to use the & operator to pass an pointer of an array to a function. the label already points to the start of the address block.

fake edit:: yea as a matter of fact i just tested it you you get an "incompatible pointer type" error. reason being that the label for the array is already a pointer to the starting memory address.

i agree with everything else about his code though.
Go Back To Programming & Development Topic List
Prev15678956Next
Add Reply New Topic New Poll