Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
CrusherEAGLE
Oct 28, 2007

Frosty Divine
What is the best book to buy to be able to learn how to program C++ from scratch?

I know some programming basics but I want to be able to master the language this summer.

Either a book or online tutorials, but I'm sure a book is better.

I'm mainly looking for a book that is easy to read and understand as well as teaching me the language comprehensively.

Adbot
ADBOT LOVES YOU

xgalaxy
Jan 27, 2004
i write code

CrusherEAGLE posted:

What is the best book to buy to be able to learn how to program C++ from scratch?

I know some programming basics but I want to be able to master the language this summer.

Either a book or online tutorials, but I'm sure a book is better.

I'm mainly looking for a book that is easy to read and understand as well as teaching me the language comprehensively.

http://www.amazon.com/Primer-5th-Edition-Stanley-Lippman/dp/0321714113
http://www.amazon.com/The-Programming-Language-4th-Edition/dp/0321563840

Both are good. Pick your poison.
And, not to discourage, but you aren't going to master the language from reading a book.

xgalaxy fucked around with this message at 17:15 on Mar 1, 2014

CrusherEAGLE
Oct 28, 2007

Frosty Divine

xgalaxy posted:

http://www.amazon.com/Primer-5th-Edition-Stanley-Lippman/dp/0321714113
http://www.amazon.com/The-Programming-Language-4th-Edition/dp/0321563840

Both are good. Pick your poison.
And, not to discourage, but you aren't going to master the language from reading a book.

Well I was hoping that the book would direct me in such a way that I would be creating my own programs so as to practice.

Or, how would you recommend I learn this?

Diametunim
Oct 26, 2010
Christ I've been asking a lot of questions lately. I finally got my dynamic array working and now I'm trying to read from my input file and place the values read into my dynamic array. For testing purposes my input file would look something like:

code:
 
00100
11001
01010
00000
00110
here's the for loop I'm attempting to use to read char by char and place the input read into the array.

code:
for (int i = 0; i < ROWS; i++)
{
    for (int j = 0; j < COLUMNS; j++)
    {
	c = initialState.get();
	mainArray[i][j] = c;
    }
}
and I believe I'm getting garbage because when I output my array I get:

code:
48 48 48 49 48
10 48 48 49 48
48 48 48 48 48 
49 49 49 48 49
48 48 48 49 48
What am I loving up? I'm awful with nested loops and 2d arrays.

Diametunim fucked around with this message at 23:16 on Mar 2, 2014

mobby_6kl
Aug 9, 2009

by Fluffdaddy
What's the value of char('0')?

Diametunim
Oct 26, 2010

mobby_6kl posted:

What's the value of char('0')?

I was hoping I could edit my post before someone got to it but oh well, I'm dumb. That's what I get for assigning char values into an int array.

e: finally finished with programming Conway's Game of Life, all that's left now is to optimize and clean up my code. Anyone else ever get depressed knowing what took you hours to program would take another person 30 minutes? :smith:

Diametunim fucked around with this message at 08:09 on Mar 3, 2014

FAT32 SHAMER
Aug 16, 2012



For a project I am to use a vector to store inputted data then find the min, max, median, and make a histogram of sorts displaying the percentage of elements of the vector in groups of 10. This is what I have so far:

C++ code:


#include <iostream>
#include <vector>
using namespace std;

void max( vector<double> input )
{
    auto max = max_element( begin( input ), end( input ) );
    cout << "Max is " << *max << "\n";
}

void min( vector<double> input )
{
    auto min = min_element( begin( input ), end( input ) );
    cout << "Min is " << *min << "\n";
}

void median( vector<double> input )
{
    double median;
    size_t size = input.size();
    
    sort( input.begin(), input.end() );
    
    if (size  % 2 == 0)
    {
        median = ( input[ size / 2 - 1 ] + input[ size / 2 ] ) / 2;
    }
    else
    {
        median = input[ size / 2 ];
    }
    cout << "Median is " << median << "\n";
}

double hist_obj( double number )
{
    double zero_ten = 0.0;
    double ten_twenty = 0.0;
    double twenty_thirty = 0.0;
    double thirty_forty = 0.0;
    double forty_fifty = 0.0;
    double fifty_sixty = 0.0;
    double sixty_seventy = 0.0;
    double seventy_eighty = 0.0;
    double eighty_ninety = 0.0;
    double ninety_hundred = 0.0;
    double elements[] = { zero_ten, ten_twenty, twenty_thirty, thirty_forty, forty_fifty, fifty_sixty, sixty_seventy, seventy_eighty, eighty_ninety, ninety_hundred };
    
    if( number >= 0 || number < 10 )
    {
        zero_ten++;
    }
    else if( number >= 10 || number < 20 )
    {
        ten_twenty++;
    }
    
    else if( number >= 20 || number < 30 )
    {
        twenty_thirty++;
    }
    
    else if( number >= 30 || number < 40 )
    {
        thirty_forty++;
    }
    
    else if( number >= 40 || number < 50 )
    {
        forty_fifty++;
    }
    
    else if( number >= 50 || number < 60 )
    {
        fifty_sixty++;
    }
    
    else if( number >= 60 || number < 70 )
    {
        sixty_seventy++;
    }
    
    else if( number >= 70 || number < 80 )
    {
        seventy_eighty++;
    }
    
    else if( number >= 80 || number < 90 )
    {
        eighty_ninety++;
    }
    else
    {
        ninety_hundred++;
    }
    return( zero_ten, ten_twenty, twenty_thirty, thirty_forty, forty_fifty, fifty_sixty, sixty_seventy, seventy_eighty, eighty_ninety, ninety_hundred );
    //return elements[] ;
}

void histogram( double one, double two, double three, double four, double five, double six, double seven, double eight, double nine, double ten )
//void histogram( double elements[] )
{
    printf( "[0, 10): %0.2f\n", one  );
    printf( "[10, 20): %0.2f\n", two );
    printf( "[20, 30): %0.2f\n", three  );
    printf( "[30, 40): %0.2f\n", four  );
    printf( "[40, 50): %0.2f\n", five );
    printf( "[50, 60): %0.2f\n", six );
    printf( "[60, 70): %0.2f\n", seven  );
    printf( "[70, 80): %0.2f\n", eight  );
    printf( "[80, 90): %0.2f\n", nine );
    printf( "[90, 100): %0.2f\n", ten  );
}

int main()
{
    vector<double> input;
    double number = 0.0;
    
    cout << "Please enter a value between 0 and 100, then press enter. Enter -999 when you are finished:\n";
    do
    {
        cin >> number;
        if( ( number < 0 || number > 100 ) && number != -999 )
        {
            cout << "entry invalid\n";
        }
        else
        {
            if( number == -999 )
            {
                cout << "Ending input\n";
            }
            else
            {
                input.push_back( number );
                sort( input.begin(), input.end() );
            }
            
        }
        //hist_obj( number );
    } while ( number != -999 );
    
    max( input );
    min( input );
    median( input );
    
}

Is there a way to scan through the completed vector to find if a number is, say, >= 0 || number < 10 etc instead of analysing the number just after input and determining if it is >=0||<10? I know that I'll need to divide the number by the vector<double> input.size() to get the correct percentage and I suspect that I can have the method histogram( double number ) do this for me by changing it to histogram( vector<double> input, double number ) but the only way I can think of implementing this would have it printing that part of the histogram too soon in the program instead of after printing the max, min, and median.

you can ignore double elements[] = {} since at first I thought that would be a good idea but now i'm pretty sure that it's not.

shodanjr_gr
Nov 20, 2007
I got a multiple-inheritance question but first here's some backstory. I'm using a rendering library which manages its own memory internally, with its own smart_pointer + ref count implementation. To accomplish this, all objects inherit from a base Object class. It also defines a Renderable class (that describes something that can be rendered) with a bunch of pure virtual function, which inherits from Object. Finally, it has two classes, one for Geometry and once for Text (both of which inherit from the Renderable class and implement its virtual methods).

In my code I wanted to augment the Renderable class by attaching some information to it, while still allowing it to be consumed at the regular places where the standard Renderable class would work.

code:

class MySexyRenderable : public TheGraphicsLibrary::Renderable
{
public:
int _someInfo;
}

Obviously this class would remain abstract since it inherits the pure virtual methods of Renderable. However, if I try to do something like:

code:
class MySexyText : public MySexyRenderable, public TheGraphicsLibrary::Text
{
	// nothing here
}
the compiler complains about no implementations for the virtual methods of TheGraphicsLibrary::Renderable, even though TheGraphicsLibrary::Text implements them...

If i add stub-implementations (that just call to the TheGraphicsLibrary::Text methods), then I get past this initial snag, but I hit a diamond-inheritance issue. The TheGraphicsLibrary::Object class defines methods for incrementing/decrementing the built-in reference counter and those methods are not virtual. Since the TheGraphicsLibrary::Object inheritance is pulled through both the Text and MySexyRenderable parent classes, any calls to those methods become ambiguous.

I tried virtual inheritance:

code:
class MySexyText : virtual public MySexyRenderable, public TheGraphicsLibrary::Text
{
	// nothing here
}
But it didn't work (I believe because the methods in TheGraphicsLibrary::Object are not virtual).

Is there a way to work around this while still using inheritance or am I stuck with coming up with some composition-based scheme?

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
MySexyRenderable and TheGraphicsLibrary::Text are the things that need to use virtual inheritance there.

If you really want to use inheritance here for some reason then making MySexyRenderable's base class a template parameter is likely to be easier than dealing with diamond inheritance.

hooah
Feb 6, 2006
WTF?

Tusen Takk posted:

For a project I am to use a vector to store inputted data then find the min, max, median, and make a histogram of sorts displaying the percentage of elements of the vector in groups of 10. This is what I have so far:

C++ code:


#include <iostream>
#include <vector>
using namespace std;

void max( vector<double> input )
{
    auto max = max_element( begin( input ), end( input ) );
    cout << "Max is " << *max << "\n";
}

void min( vector<double> input )
{
    auto min = min_element( begin( input ), end( input ) );
    cout << "Min is " << *min << "\n";
}

void median( vector<double> input )
{
    double median;
    size_t size = input.size();
    
    sort( input.begin(), input.end() );
    
    if (size  % 2 == 0)
    {
        median = ( input[ size / 2 - 1 ] + input[ size / 2 ] ) / 2;
    }
    else
    {
        median = input[ size / 2 ];
    }
    cout << "Median is " << median << "\n";
}

double hist_obj( double number )
{
    double zero_ten = 0.0;
    double ten_twenty = 0.0;
    double twenty_thirty = 0.0;
    double thirty_forty = 0.0;
    double forty_fifty = 0.0;
    double fifty_sixty = 0.0;
    double sixty_seventy = 0.0;
    double seventy_eighty = 0.0;
    double eighty_ninety = 0.0;
    double ninety_hundred = 0.0;
    double elements[] = { zero_ten, ten_twenty, twenty_thirty, thirty_forty, forty_fifty, fifty_sixty, sixty_seventy, seventy_eighty, eighty_ninety, ninety_hundred };
    
    if( number >= 0 || number < 10 )
    {
        zero_ten++;
    }
    else if( number >= 10 || number < 20 )
    {
        ten_twenty++;
    }
    
    else if( number >= 20 || number < 30 )
    {
        twenty_thirty++;
    }
    
    else if( number >= 30 || number < 40 )
    {
        thirty_forty++;
    }
    
    else if( number >= 40 || number < 50 )
    {
        forty_fifty++;
    }
    
    else if( number >= 50 || number < 60 )
    {
        fifty_sixty++;
    }
    
    else if( number >= 60 || number < 70 )
    {
        sixty_seventy++;
    }
    
    else if( number >= 70 || number < 80 )
    {
        seventy_eighty++;
    }
    
    else if( number >= 80 || number < 90 )
    {
        eighty_ninety++;
    }
    else
    {
        ninety_hundred++;
    }
    return( zero_ten, ten_twenty, twenty_thirty, thirty_forty, forty_fifty, fifty_sixty, sixty_seventy, seventy_eighty, eighty_ninety, ninety_hundred );
    //return elements[] ;
}

void histogram( double one, double two, double three, double four, double five, double six, double seven, double eight, double nine, double ten )
//void histogram( double elements[] )
{
    printf( "[0, 10): %0.2f\n", one  );
    printf( "[10, 20): %0.2f\n", two );
    printf( "[20, 30): %0.2f\n", three  );
    printf( "[30, 40): %0.2f\n", four  );
    printf( "[40, 50): %0.2f\n", five );
    printf( "[50, 60): %0.2f\n", six );
    printf( "[60, 70): %0.2f\n", seven  );
    printf( "[70, 80): %0.2f\n", eight  );
    printf( "[80, 90): %0.2f\n", nine );
    printf( "[90, 100): %0.2f\n", ten  );
}

int main()
{
    vector<double> input;
    double number = 0.0;
    
    cout << "Please enter a value between 0 and 100, then press enter. Enter -999 when you are finished:\n";
    do
    {
        cin >> number;
        if( ( number < 0 || number > 100 ) && number != -999 )
        {
            cout << "entry invalid\n";
        }
        else
        {
            if( number == -999 )
            {
                cout << "Ending input\n";
            }
            else
            {
                input.push_back( number );
                sort( input.begin(), input.end() );
            }
            
        }
        //hist_obj( number );
    } while ( number != -999 );
    
    max( input );
    min( input );
    median( input );
    
}

Is there a way to scan through the completed vector to find if a number is, say, >= 0 || number < 10 etc instead of analysing the number just after input and determining if it is >=0||<10?

Sure. Just use a for loop, if that's allowed for the project.

quote:

I know that I'll need to divide the number by the vector<double> input.size() to get the correct percentage and I suspect that I can have the method histogram( double number ) do this for me by changing it to histogram( vector<double> input, double number ) but the only way I can think of implementing this would have it printing that part of the histogram too soon in the program instead of after printing the max, min, and median.not.

You are correct that histogram( vector<double> input) can indeed do what you want. In fact, you don't even need to add another parameter, since vectors know their size, so you can just call input.size() within your histogram function.

A few other things I noticed that may or may not have been taught yet:
You're sorting a lot. If you just sort once after all the input is done, then the vector will stay sorted, since you're not doing anything to change it.

If you know about passing by reference, I would strongly suggest you do that, since passing a vector of unknown (and possibly quite large) size can be memory-intensive.

Your hist_obj function can't return what you want it to. It can only return one double, not 10 of them. You might consider using a vector here, too.

nielsm
Jun 1, 2009



Tusen Takk posted:

For a project I am to use a vector to store inputted data then find the min, max, median, and make a histogram of sorts displaying the percentage of elements of the vector in groups of 10.

Just so you know, this function:
C++ code:
double foo(double x)
{
  double a = x + 1;
  double b = x / 2;
  double c = x * x;
  return (a, b, c);
}
That function will return one value, and which will be the c variable. The values of a and b get ignored.
The comma has three functions in C and C++, one is separating declarations (such as in parameter lists and when declaring multiple variables in one line), another is in initializations (such as when declaring an array with static contents), and the last is as the sequencing operator. The last one is what you're invoking here.

The sequencing operator works on lists of expressions, evaluates all of them, and keeps the value of the last one. It's very rarely useful at all, but can be easy to accidentally invoke if you don't know about it.
So in this case there is an expression (a, b, c) which is enclosed in parentheses. The expression is a sequence of three sub-expressions, each consisting just of a single variable. The sub-expressions get evaluated in the order given, and the last one, c, becomes the result of the entire parenthesized expression.

Where is this useful? When you need to use functions with side effects in a place where only expressions are allowed, e.g. in the "step" part of a for loop.


And to return to the short function I wrote above, if you actually wanted it to return all three you would need to declare the function as returning e.g. a vector:
C++ code:
std::vector<double> foo(double x)
{
  double a, b, c;
  a = x + 1;
  b = x / 2;
  c = x * x;
  std::vector<double> result;
  result.push_back(a);
  result.push_back(b);
  result.push_back(c);
  return result;
}

xgalaxy
Jan 27, 2004
i write code
Use a tuple.

Dren
Jan 5, 2001

Pillbug

Diametunim posted:

e: finally finished with programming Conway's Game of Life, all that's left now is to optimize and clean up my code. Anyone else ever get depressed knowing what took you hours to program would take another person 30 minutes? :smith:

http://lakeshorepublicmedia.org/stories/daniel-tigers-neighborhood-keep-trying-youll-get-better/

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

shodanjr_gr posted:

the compiler complains about no implementations for the virtual methods of TheGraphicsLibrary::Renderable, even though TheGraphicsLibrary::Text implements them...

Yep, because nothing is overriding the implementations from the new base. You basically need to use virtual inheritance everywhere you inherit from something that needs to be shared, but that has its own problems.

shodanjr_gr posted:

If i add stub-implementations (that just call to the TheGraphicsLibrary::Text methods), then I get past this initial snag, but I hit a diamond-inheritance issue. The TheGraphicsLibrary::Object class defines methods for incrementing/decrementing the built-in reference counter and those methods are not virtual. Since the TheGraphicsLibrary::Object inheritance is pulled through both the Text and MySexyRenderable parent classes, any calls to those methods become ambiguous.

Which is good in this case, because you're also getting two copies of the refcount, which won't work. You need to virtually inherit from Object, everywhere.

shodanjr_gr posted:

I tried virtual inheritance:

Virtual bases of the same type all get coalesced so that there is only one virtual base subobject of that type. They do not, however, get coalesced win non-virtual bases of that type, so if you're going to use virtual inheritance, you need to use it everywhere you inherit from that class — i.e. you need to modify your existing class hierarchy to use it.

These sorts of things do make C++ inheritance remarkably annoying for modeling protocols and refinements thereof, yes.

Instead of using inheritance, consider using templates. You basically have two options:

1. Allow your main hierarchy classes to ascribe to more specific protocols by making the protocol a template parameter, e.g.:

C++ code:
template <class Base> class Text : public Base { // or SuperClass<Base> as necessary
This will, unfortunately, turn most of your code into templates with dependent base classes, which sucks on many levels at once.

2. Make your protocols extrinsic instead of using inheritance. That is, anywhere you would have a shared_ptr<Renderable>, use a Renderable, where instead of being a base class that's a std::function-like thing:

C++ code:
class Renderable {
  shared_ptr<Object> object;
  VTable *vtbl;
protected:
  struct VTable {
    // One of these per method in your protocol.
    void (*render)(Object *, Graphics *g);
  };
  template <class T> struct VTableImpl {
    static VTable vtable;
  };
  VTable *vtable() const { return vtbl; }
  Object *object() const { return object.get(); }

  Renderable(const shared_ptr<T> &object, VTable *vtable) : object(object), vtbl(vtable) {}
public:
  template <class T> Renderable(const shared_ptr<T> &object)
    : object(object), vtbl(&VTableImpl<T>::vtable) {}

  // One of these per method in your protocol.
  void render(Graphics *g) { vtable()->render(object(), g); }
};

template <class T> Renderable::VTable Renderable::VTableImpl<T>::vtable = {
  // One of these per method in your protocol.
  [](Object *object, Graphics *g) { static_cast<T*>(object)->render(g); }
};
It's a lot annoying boilerplate per protocol, granted, but you can x-macro that. Anyway, your protocol refinement looks something like this:

C++ code:
class MySexyRenderable : public Renderable {
protected:
  struct VTable {
    Renderable::VTable renderable;
    void (*sexyRender)(Graphics *g);
  };
  template <class T> struct VTableImpl {
    static VTable vtable;
  };
  VTable *vtable() const {
    // Yes, this is legal.
    return reinterpret_cast<VTable*>(Renderable::vtable());
  }

  MySexyRenderable(const shared_ptr<T> &object, VTable *vtable)
    : Renderable(object, &vtbl->renderable) {}
public:
  template <class T> MySexyRenderable(const shared_ptr<T> &object)
    : Renderable(object, &VTableImpl<T>::vtable.renderable) {}

  void sexyRender(Graphics *g) { vtable()->sexyRender(object(), g); }
};

template <class T> MySexyRenderable::VTable MySexyRenderable::VTableImpl<T>::vtable = {
  {
    // Unfortunately, you need an entry for each method in Renderable here.
    // x-macros will make everything better.
    [](Object *object, Graphics *g) { static_cast<T*>(object)->render(g); },
  },
  [](Object *object, Graphics *g) { static_cast<T*>(object)->sexyRender(g); }
};
The only thing you can't do with this directly is dynamic_cast, and if that's important, it's also doable (with some extra boilerplate v-table functions).

EDIT: messed up the subclass slightly.

rjmccall fucked around with this message at 21:57 on Mar 3, 2014

FAT32 SHAMER
Aug 16, 2012



nielsm posted:

Just so you know, this function:
C++ code:
double foo(double x)
{
  double a = x + 1;
  double b = x / 2;
  double c = x * x;
  return (a, b, c);
}
That function will return one value, and which will be the c variable. The values of a and b get ignored.
The comma has three functions in C and C++, one is separating declarations (such as in parameter lists and when declaring multiple variables in one line), another is in initializations (such as when declaring an array with static contents), and the last is as the sequencing operator. The last one is what you're invoking here.

The sequencing operator works on lists of expressions, evaluates all of them, and keeps the value of the last one. It's very rarely useful at all, but can be easy to accidentally invoke if you don't know about it.
So in this case there is an expression (a, b, c) which is enclosed in parentheses. The expression is a sequence of three sub-expressions, each consisting just of a single variable. The sub-expressions get evaluated in the order given, and the last one, c, becomes the result of the entire parenthesized expression.

Where is this useful? When you need to use functions with side effects in a place where only expressions are allowed, e.g. in the "step" part of a for loop.


And to return to the short function I wrote above, if you actually wanted it to return all three you would need to declare the function as returning e.g. a vector:
C++ code:
std::vector<double> foo(double x)
{
  double a, b, c;
  a = x + 1;
  b = x / 2;
  c = x * x;
  std::vector<double> result;
  result.push_back(a);
  result.push_back(b);
  result.push_back(c);
  return result;
}
Sweet, cheers for this, much appreciated haha

Diametunim
Oct 26, 2010
If I'm printing out a 2D array char by char using two for loops is there a way to only show the output once the for loops have finished running?

IE:

code:

for(int i = 0; i < rows; i++)
    for(int j = 0; j < columns; j++)
        cout << array[i][j] << endl;

I'm trying to make my output between generations on my implementation of Conway's game of life look half way decent. When I start with a smaller grid 5x5 for instance the output is so fast you don't notice it's printing char by char but with a larger grid, 61x71 for example you've gotta watch the output trail down the screen and it's ugly. So I was hoping I could display the output only after it's finished running through the loops.

hooah
Feb 6, 2006
WTF?

Diametunim posted:

If I'm printing out a 2D array char by char using two for loops is there a way to only show the output once the for loops have finished running?

IE:

code:

for(int i = 0; i < rows; i++)
    for(int j = 0; j < columns; j++)
        cout << array[i][j] << endl;

I'm trying to make my output between generations on my implementation of Conway's game of life look half way decent. When I start with a smaller grid 5x5 for instance the output is so fast you don't notice it's printing char by char but with a larger grid, 61x71 for example you've gotta watch the output trail down the screen and it's ugly. So I was hoping I could display the output only after it's finished running through the loops.

Use \n instead of endl, since endl flushes the buffer. At least, I think that'll work; I've never been a fan of delaying buffer flushing, since it can make it difficult to debug.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
I think what you probably want is to just not do an endl on every column; do it after each row instead.

FAT32 SHAMER
Aug 16, 2012



So, I finished my project by grossly simplifying it instead of trying to use fancy pantsy functions/methods/whatever they're called. The code is working 100% correctly in Xcode, but when I FTP it to my university's unix server then use ssh in terminal, I'm getting a shitload of errors.

C++ code:
//
//

#include <iostream>
#include <vector>
using namespace std;

void max( vector<double> input )
{
    auto max = max_element( begin( input ), end( input ) );
    cout << "Max is " << *max << "\n";
}

void min( vector<double> input )
{
    auto min = min_element( begin( input ), end( input ) );
    cout << "Min is " << *min << "\n";
}

void median( vector<double> input )
{
    double median;
    size_t size = input.size();
    
    sort( input.begin(), input.end() );
    
    if (size  % 2 == 0)
    {
        median = ( input[ size / 2 - 1 ] + input[ size / 2 ] ) / 2;
    }
    else
    {
        median = input[ size / 2 ];
    }
    cout << "Median is " << median << "\n";
}


int main()
{
    vector<double> input;
    double number = 0.0;
    double zero_ten = 0.0;
    double ten_twenty = 0.0;
    double twenty_thirty = 0.0;
    double thirty_forty = 0.0;
    double forty_fifty = 0.0;
    double fifty_sixty = 0.0;
    double sixty_seventy = 0.0;
    double seventy_eighty = 0.0;
    double eighty_ninety = 0.0;
    double ninety_hundred = 0.0;
    
    
    cout << "Please enter a value between 0 and 100, then press enter. Enter -999 when you are finished:\n";
    do
    {
        cin >> number;
        if( ( number < 0 || number > 100 ) && number != -999 )
        {
            cout << "invalid entry\n";
        }
        else
        {
            if( number == -999 )
            {
                cout << "Ending input\n";
            }
            else
            {
                if( number >= 0 && number < 10 )
                {
                    zero_ten++;
                    input.push_back( number );
                    sort( input.begin(), input.end() );
                }
                if( number >= 10 && number < 20 )
                {
                    ten_twenty++;
                    input.push_back( number );
                    sort( input.begin(), input.end() );
                }
                
                else if( number >= 20 && number < 30 )
                {
                    twenty_thirty++;
                    input.push_back( number );
                    sort( input.begin(), input.end() );
                }
                
                else if( number >= 30 && number < 40 )
                {
                    thirty_forty++;
                    input.push_back( number );
                    sort( input.begin(), input.end() );
                }
                
                else if( number >= 40 && number < 50 )
                {
                    forty_fifty++;
                    input.push_back( number );
                    sort( input.begin(), input.end() );
                }
                
                else if( number >= 50 && number < 60 )
                {
                    fifty_sixty++;
                    input.push_back( number );
                    sort( input.begin(), input.end() );
                }
                
                else if( number >= 60 && number < 70 )
                {
                    sixty_seventy++;
                    input.push_back( number );
                    sort( input.begin(), input.end() );
                }
                
                else if( number >= 70 && number < 80 )
                {
                    seventy_eighty++;
                    input.push_back( number );
                    sort( input.begin(), input.end() );
                }
                
                else if( number >= 80 && number < 90 )
                {
                    eighty_ninety++;
                    input.push_back( number );
                    sort( input.begin(), input.end() );
                }
                else
                {
                    ninety_hundred++;
                    input.push_back( number );
                    sort( input.begin(), input.end() );
                }
                
            }
        }
        
    } while ( number != -999 );
    
    max( input );
    min( input );
    median( input );
    
    double size = input.size();
    printf( "[0, 10): %0.2f\n", zero_ten / size );
    printf( "[10, 20): %0.2f\n", ten_twenty /size );
    printf( "[20, 30): %0.2f\n", twenty_thirty / size );
    printf( "[30, 40): %0.2f\n", thirty_forty /size );
    printf( "[40, 50): %0.2f\n", forty_fifty /size );
    printf( "[50, 60): %0.2f\n", fifty_sixty /size );
    printf( "[60, 70): %0.2f\n", sixty_seventy / size );
    printf( "[70, 80): %0.2f\n", seventy_eighty / size );
    printf( "[80, 90): %0.2f\n", eighty_ninety / size );
    printf( "[90, 100): %0.2f\n", ninety_hundred / size );
    
    return 0;
}

University Unix Server posted:

me@janus:~$ g++ DistributionCalc.cpp
DistributionCalc.cpp: In function ‘void max(std::vector<double, std::allocator<double> >)’:
DistributionCalc.cpp:15: error: ISO C++ forbids declaration of ‘max’ with no type
DistributionCalc.cpp:15: error: ‘begin’ was not declared in this scope
DistributionCalc.cpp:15: error: ‘end’ was not declared in this scope
DistributionCalc.cpp:15: error: ‘max_element’ was not declared in this scope
DistributionCalc.cpp:16: error: invalid type argument of ‘unary *’
DistributionCalc.cpp: In function ‘void min(std::vector<double, std::allocator<double> >)’:
DistributionCalc.cpp:21: error: ISO C++ forbids declaration of ‘min’ with no type
DistributionCalc.cpp:21: error: ‘begin’ was not declared in this scope
DistributionCalc.cpp:21: error: ‘end’ was not declared in this scope
DistributionCalc.cpp:21: error: ‘min_element’ was not declared in this scope
DistributionCalc.cpp:22: error: invalid type argument of ‘unary *’
DistributionCalc.cpp: In function ‘void median(std::vector<double, std::allocator<double> >)’:
DistributionCalc.cpp:30: error: ‘sort’ was not declared in this scope
DistributionCalc.cpp: In function ‘int main()’:
DistributionCalc.cpp:80: error: ‘sort’ was not declared in this scope
DistributionCalc.cpp:86: error: ‘sort’ was not declared in this scope
DistributionCalc.cpp:93: error: ‘sort’ was not declared in this scope
DistributionCalc.cpp:100: error: ‘sort’ was not declared in this scope
DistributionCalc.cpp:107: error: ‘sort’ was not declared in this scope
DistributionCalc.cpp:114: error: ‘sort’ was not declared in this scope
DistributionCalc.cpp:121: error: ‘sort’ was not declared in this scope
DistributionCalc.cpp:128: error: ‘sort’ was not declared in this scope
DistributionCalc.cpp:135: error: ‘sort’ was not declared in this scope
DistributionCalc.cpp:141: error: ‘sort’ was not declared in this scope
DistributionCalc.cpp:154: error: ‘printf’ was not declared in this scope

Anyone know why?

hooah
Feb 6, 2006
WTF?
You need to include ...I believe it's <algorithm> for all the sort, max, etc. calls. printf is in <stdio.h>.

Edit: Also, you really should only need to call sort once, after all the input is done.

FAT32 SHAMER
Aug 16, 2012



hooah posted:

You need to include ...I believe it's <algorithm> for all the sort, max, etc. calls. printf is in <stdio.h>

Welp I am an idiot, thanks.

FAT32 SHAMER
Aug 16, 2012



Maybe not, now I'm just getting less errors:

quote:

DistributionCalc.cpp: In function ‘void max(std::vector<double, std::allocator<double> >)’:
DistributionCalc.cpp:17: error: ISO C++ forbids declaration of ‘max’ with no type
DistributionCalc.cpp:17: error: ‘begin’ was not declared in this scope
DistributionCalc.cpp:17: error: ‘end’ was not declared in this scope
DistributionCalc.cpp:18: error: invalid type argument of ‘unary *’
DistributionCalc.cpp: In function ‘void min(std::vector<double, std::allocator<double> >)’:
DistributionCalc.cpp:23: error: ISO C++ forbids declaration of ‘min’ with no type
DistributionCalc.cpp:23: error: ‘begin’ was not declared in this scope
DistributionCalc.cpp:23: error: ‘end’ was not declared in this scope
DistributionCalc.cpp:24: error: invalid type argument of ‘unary *’

astr0man
Feb 21, 2007

hollyeo deuroga
Does your compiler actually support c++11 "auto"?

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
You're using C++11 stuff, so you need to use C++11 when building it. g++ -std=c++11 DistributionCalc.cpp

FAT32 SHAMER
Aug 16, 2012



Aw poo poo the server doesn't loving support C++ 11.

gently caress sakes my university is useless.

b0lt
Apr 29, 2005

Tusen Takk posted:

Aw poo poo the server doesn't loving support C++ 11.

gently caress sakes my university is useless.

Try -std=c++0x?

FAT32 SHAMER
Aug 16, 2012



I ended up emailing the prof who said that he had a feeling it would start to be an issue and that he'll just grade it from VS.

Thanks for the help duders

leper khan
Dec 28, 2010
Honest to god thinks Half Life 2 is a bad game. But at least he likes Monster Hunter.

Tusen Takk posted:

I ended up emailing the prof who said that he had a feeling it would start to be an issue and that he'll just grade it from VS.

Thanks for the help duders

You should probably just write standard compliant code and not rely on anything implementation specific. And if your class doesn't support c++0x/c++11 just deal with it and write code that is supported. It shouldn't be too difficult to get your local compiler flags to match your course.

Or just remote in for all of your assignments.

duck monster
Dec 15, 2004

Does C++ have an equivilent to Javascript anonymous functions or Objective C blocks?

Like if I have something like (From the cocos2dx framework)
code:
    _charactersprite->runAction( Sequence::create(
                                          MoveTo::create(duration,putGuy),
                                          CallFuncN::create(CC_CALLBACK_1(Character::cancelGuy,this)),
                                          NULL)

and replace it with something that replaces Character::cancelGuy with function() { blah blah blah } as I would in Javascript?

Because that would be super good. I could make my code look like spastic jumblesstructured node.js code! (or alternatively just save some keystrokes)

b0lt
Apr 29, 2005

duck monster posted:

Does C++ have an equivilent to Javascript anonymous functions or Objective C blocks?

Like if I have something like (From the cocos2dx framework)
code:
    _charactersprite->runAction( Sequence::create(
                                          MoveTo::create(duration,putGuy),
                                          CallFuncN::create(CC_CALLBACK_1(Character::cancelGuy,this)),
                                          NULL)

and replace it with something that replaces Character::cancelGuy with function() { blah blah blah } as I would in Javascript?

Because that would be super good. I could make my code look like spastic jumblesstructured node.js code! (or alternatively just save some keystrokes)
C++11:
C++ code:
    _charactersprite->runAction( Sequence::create(
                                          MoveTo::create(duration,putGuy),
                                          CallFuncN::create(CC_CALLBACK_1(
                                              [](Character *character) {
                                                  character->do_whatever();
                                              },this)),
                                          NULL)

duck monster
Dec 15, 2004

Whats the [] square brackets do? (Excuse the dumb questions, I'm reteaching myself C++ after nearly a couple of decades away from the language, and C++11 seems to introduce quite a few new ideas. (I'm in love with the iiterator based for syntax!)

code:
/Users/duckmonster/Documents/work/platform/platformgame/Classes/Character.cpp:114:69:
 Taking the address of a temporary object of type '<lambda at /Users/duckmonster/Documents/work/platform/platformgame/Classes/Character.cpp:114:69>'
Motherfucker!

I guess the CC_CALLBACK_1 macro dont like lambdas.

duck monster fucked around with this message at 06:46 on Mar 6, 2014

shrughes
Oct 11, 2008

(call/cc call/cc)
They're used to provide lists of which variables the closure captures. If it's empty, the closure captures all the variables or all the ones it uses or something (e: turns out it's "something" -- it captures nothing). You can also specify to capture by reference or by value.

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

duck monster posted:

Whats the [] square brackets do? (Excuse the dumb questions, I'm reteaching myself C++ after nearly a couple of decades away from the language, and C++11 seems to introduce quite a few new ideas. (I'm in love with the iiterator based for syntax!)

The square brackets indicate what variables are captured by the lambda, and whether by value or reference. Wikipedia with examples.

I found the Wikipedia C++11 page to be a great summary of stuff that changed since I last rode that bike.

That Turkey Story
Mar 30, 2003

shrughes posted:

If it's empty, the closure captures all the variables or all the ones it uses or something (e: turns out it's "something" -- it captures nothing). You can also specify to capture by reference or by value.
If empty it actually captures nothing, not everything. You need to specify = to capture all by default or & to capture all by reference. Alternatively you can capture things individually. C++14 makes capturing better by having user-specified initialized captures, so you can do things like capture-by-move, etc.

duck monster
Dec 15, 2004

God drat it, this loving language. C++ is like a hot crazy girlfriend. Shes fast, she's sexy, she can do wild things without breaking a sweat, but shes loving demanding and if you screw up and put something in the wrong box she'll segfault and try to murder you. Finally , her complaints are indecipherable and numerous.

I really need a better IDE than loving xcode.

xgalaxy
Jan 27, 2004
i write code
JetBrains is coming out with a C/C++ IDE that I'm really looking forward to. Also Resharper is being made to work with C++ as well.

FamDav
Mar 29, 2008

duck monster posted:

God drat it, this loving language. C++ is like a hot crazy girlfriend. Shes fast, she's sexy, she can do wild things without breaking a sweat, but shes loving demanding and if you screw up and put something in the wrong box she'll segfault and try to murder you. Finally , her complaints are indecipherable and numerous.

I really need a better IDE than loving xcode.

Awesome post. You should write for an MRA newsletter.

Hughlander
May 11, 2005

b0lt posted:

C++11:
C++ code:
    _charactersprite->runAction( Sequence::create(
                                          MoveTo::create(duration,putGuy),
                                          CallFuncN::create(CC_CALLBACK_1(
                                              [](Character *character) {
                                                  character->do_whatever();
                                              },this)),
                                          NULL)

http://www.cocos2d-x.org/docs/manual/framework/native/input/event-dispatcher/en implies that they support C++11 lambdas just not with the CC_CALLBACK_N macros. If a CC_CALLBACK_1 is able to take a block and you're using a recentish clang it should still work though.

raminasi
Jan 25, 2005

a last drink with no ice
My preferred analogy for C++ is that it's a rocket-powered wheelchair with lasers and poo poo. Yeah, it's incredibly powerful, and has an astonishing flexibility, but sometimes you just want to walk down some dang stairs without having to use Boost.Hover and three layers of template definitions.

Adbot
ADBOT LOVES YOU

mobby_6kl
Aug 9, 2009

by Fluffdaddy

GrumpyDoctor posted:

My preferred analogy for C++ is that it's a rocket-powered wheelchair with lasers and poo poo. Yeah, it's incredibly powerful, and has an astonishing flexibility, but sometimes you just want to walk down some dang stairs without having to use Boost.Hover and three layers of template definitions.

Awesome post. Make sure you kick a few cripples in the head on you way home :downs:

Edit: C++ in action:

mobby_6kl fucked around with this message at 18:30 on Mar 6, 2014

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply