/**********************************************
 *                                            *
 *                     C                      *
 *                                            *  
 **********************************************/



A C programozási nyelv


Dennis M Ritchie (1941 - 2011)

At&T 1969 - 1973



/* simple hello in C */
#include <stdio.h>

int main()
{
    fprintf( stdout, "Hello world\n");
    return 0;
}



/* converts from Fahrenheit to Celsius 
 * 1st try
 *
 * */
#include <stdio.h>


int main()
{
    int fahr;

    for ( fahr = 0; fahr <= 200; fahr += 40 )
    {
        fprintf( stdout, "F = %d\tC = %d\n", fahr, 5/9*(fahr-32));
    }
    return 0;
}



/* converts from Fahrenheit to Celsius 
 * 1st try
 *
 */
#include <stdio.h>

#define LOWER   0
#define UPPER   200
#define STEP    40

int main()
{
    int fahr;

    for ( fahr = LOWER; fahr <= UPPER; fahr += STEP )
    {
        fprintf( stdout, "F = %d\tC = %d\n", fahr, 5/9*(fahr-32));
    }
    return 0;
}



/* converts from Fahrenheit to Celsius 
 * 2nd try
 *
 */
#include <stdio.h>

#define LOWER   0
#define UPPER   200
#define STEP    40

int main()
{
    int fahr;

    for ( fahr = LOWER; fahr <= UPPER; fahr += STEP )
    {
        fprintf( stdout, "F = %d\tC = %d\n", fahr, 5./9*(fahr-32));
    }
    return 0;
}



/* converts from Fahrenheit to Celsius 
 * 3rd try
 *
 */
#include <stdio.h>

#define LOWER   0
#define UPPER   200
#define STEP    40

int main()
{
    int fahr;

    for ( fahr = LOWER; fahr <= UPPER; fahr += STEP )
    {
        fprintf( stdout, "F = %d\tC = %f\n", fahr, 5./9*(fahr-32));
    }
    return 0;
}



/* copying stdin to stdout */
#include <stdio.h>

int main()
{
    int ch; /* this is important */

    while ( (ch = getchar()) != EOF)
    {
        putchar(ch);
    }
    return 0;
}





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

/* stack implementacio */

struct stack
{
    int    capacity;   /* lefoglalt tárterület mérete */
    int    sp;         /* aktuális elemek száma */
    double *v;         /* pointer a tárterületre */
};


struct stack *make_stack(int init_size)
{
    struct stack *s = (struct stack*) malloc(sizeof(struct stack));
    s->capacity = init_size;
    s->sp = 0;
    s->v = (double *) malloc(init_size*sizeof(double));
    return s;
}

void push(struct stack *s, double d)
{
    s->v[s->sp] = d;
    ++s->sp;
}

double pop(struct stack *s)
{
    return s->v[--s->sp];
}

int size(struct stack *s)
{
    return s->sp;
}

void print(struct stack *s)
{
    int i;
    printf("[ ");
    for(i = 0; i < s->sp; ++i)
    {
        printf("%f ", s->v[i]);
    }
    printf("]\n");
}


int main()
{
    struct stack *d1 = make_stack(10);
    push(d1, 3.14);   push(d1, 4.14);   push(d1, 5.14);

    print(d1);
    struct stack *d2 = d1; // hopp, ez gyanús!
    print(d2);

    while ( size(d1) > 0 )
        printf("pop: %f\n", pop(d1));

    print(d1);
  /*  print(d2); */
    return 0;
}

/* output:

[ 3.14 4.14 5.14 ]
pop: 5.14
pop: 4.14
pop: 3.14
[ ]

*/



/* output:

[ 3.14 4.14 5.14 ]
pop: 5.14
pop: 4.14
pop: 3.14
[ ]
[ ]

*/



struct stack *copy_stack(struct stack *rhs)
{
    int i;
    struct stack *s = make_stack(rhs->capacity);
    s->sp = rhs->sp;
    for(i = 0; i < s->sp; ++i)
      s->v[i] = rhs->v[i];
    return s;
}

int main()
{
    struct stack *d1 = make_stack(10);
    push(d1, 3.14);   push(d1, 4.14);   push(d1, 5.14);

    print(d1);
    struct stack *d2 = copy_stack(d1);
    print(d2);

    while ( size(d1) > 0 )
        printf("pop: %f\n", pop(d1));

    print(d1);
    print(d2);
    return 0;
}

/* output:

[ 3.14 4.14 5.14 ]
pop: 5.14
pop: 4.14
pop: 3.14
[ ]
[ 3.14 4.14 5.14 ]

*/



////////////////////////////////////////////////////
//                                                //
//                      C++                       //
//                                                //
////////////////////////////////////////////////////


Bjarne Stroustrup (1950 - )





// nagyjából helyes C++ dstack definíció

#ifndef DSTACK_H
#define DSTACK_H

#include <iostream>

class dstack
{
    friend std::ostream &operator<<( std::ostream &os, dstack ds);
public:
      dstack( int size = 128);
      dstack( const dstack &other);     // ver2: másoló konstruktor 
      ~dstack();                        // ver2: destruktor         
    dstack& operator=( const dstack &other); // ver2: értékadó operátor  

    void   push( double d);
    double pop();

    bool is_empty() const;
    bool is_full()  const;
private:
    int    capacity;
    int    sp;
    double *v;

    void copy( const dstack &other);  // ver2: inicializálás és másolás  
};
std::ostream &operator<<( std::ostream &os, dstack ds);

#endif /* DSTACK_H */



#include <iostream>
#include "dstack2.h"

dstack::dstack( int size)
{
    v = new double[capacity = size];
    sp = 0;
}
dstack::dstack( const dstack &other)    /* ver2 */
{
    copy(other);
}
dstack::~dstack()                       /* ver2 */
{
    delete [] v;
}
dstack& dstack::operator=( const dstack &other) /* ver2 */
{
    if ( this != &other )   // x = x
    {
        // nem igazán kivétel-biztos
        delete [] v;
        copy(other);
    }
    return *this;
}
void dstack::copy( const dstack &other)
{
    v = new double[capacity = other.capacity];
    sp = other.sp;

    for ( int i = 0 ; i < sp; ++i)
        v[i] = other.v[i];
}
void dstack::push( double d)
{
    // TODO?: hibakezelés
    if ( ! is_full() )
        v[sp++] = d;
}
double dstack::pop()
{
    // TODO?: hibakezelés
    return is_empty() ? 0.0 : v[--sp];
}
bool dstack::is_empty() const
{
    return 0 == sp;
}
bool dstack::is_full() const
{
    return capacity == sp;
}
std::ostream &operator<<( std::ostream &os, dstack ds)
{
    os << "[ ";
    for ( int i = 0; i < ds.sp-1; ++i )
        os << ds.v[i] << ", ";
    if ( ds.sp > 0 )
        os << ds.v[ds.sp-1];
    os << " ]";

    return os;
}




#include <iostream>
#include "dstack2.h"

using namespace std;

int main()
{
    dstack d1(10);  // Konstruktor: d1.dstack(10)
    d1.push(3.14);    d1.push(4.14);    d1.push(5.14);
    cout << d1 << endl;
    dstack d2(d1);  // Másoló konstruktor: d2.dstack(d1)

    while ( ! d1.is_empty() )
        cout << "pop: " << d1.pop() << endl;

    d1.push(6.14);

    cout << d1 << endl;
    cout << d2 << endl;

    d1 = d2;   // Értékadás: d1.operator=(d2)
    cout << d1 << endl;
    return 0;
}   // Destruktor: d2.~dstack(); d1.~dstack()

/* Output:

[ 3.14, 4.14, 5.14 ]
pop: 5.14
pop: 4.14
pop: 3.14
[ 6.14 ]
[ 3.14, 4.14, 5.14 ]
[ 3.14, 4.14, 5.14 ]

*/


// simple hello in C++
#include <iostream>

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



// simple hello in C++
#include <iostream>

using namespace std;

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



// converts from Fahrenheit to Celsius 
#include <iostream>

using namespace std;

inline double fahr2cels( double f)
{
    return 5./9*(f-32);
}
int main()
{
    const int lower = 0;
    const int upper = 200;
    const int step  = 40;

    for ( int fahr = lower; fahr <= upper; fahr+=step )
    {
        cout << "F = " << fahr << '\t' << "C = " << fahr2cels(fahr) << endl;
    }
    return 0;
}



// copying cin to cout 
// 1st version

#include <iostream>

using namespace std;

int main()
{
    char ch;   // this is important

    // cin >> noskipws;
    // while ( cin >> ch )
    while ( cin.get(ch) )
    {
         cout.put(ch);  // or: cout << ch
    }
    return 0;
}


// copying cin to cout 
// 1st version

#include <iostream>

using namespace std;

int main()
{
    char ch;   // this is important

    while ( cin >> ch )
    {
         cout << ch;
    }
    return 0;
}



//////////////////////////////////////////////////////////
//                                                      //
//            Láthatóság és élettartam                  //
//                                                      //
//////////////////////////////////////////////////////////

// file1.cpp
#include <iostream>

int i;          // global, with external linkage
static int j;   // global, without external linkage
extern int n;   // global, defined somewhere else

namespace X
{
    int i;      // X::i

    int f() // X::f()
    {
        i = n;      // X::i = ::n; 
        return j;   // ::j
    }
    void g(); // X::g()
}

namespace
{
    int k;  // ::k
}

void f()
{
    int i;          // local i
    static int k;   // local k  
    {
        int j = i;  // local j
        int i = j;  // local i

        std::cout << i << j << k << X::i << ::k << ::i;
    }
}

static void g()
{
    ++k;    // ::k
}

void X::g() // X::g()
{
    ++i;    // X::i
}



A C++ objektumok az alábbi módon jöhetnek létre:

- globális, névtérbeli változó vagy statikus adattag
    C - program eleje
    D - program vége

- automatikus objektum (névvel rendelkezik)
    C - deklaráció kiértékelődik
    D - vezérlés elhagyja a deklaráló blokkot

- dinamikus objektum (szabad memória, free store)
    C - new
    D - delete

- nemstatikus adattag
    C - tartalmazó objektum létrejön
    D - tartalmazó objektum megsemmisül

- tömbelem
    C - tömb létrejön
    D - tömb megsemmisül

- lokális statikus objektum
    C - deklaráció első alkalommal kiértékelődik
    D - program vége

- temporális objektum
    C - (rész)kifejezés kiértékelése
    D - teljes kifejezés kiértékelése után

- union tag
    nem lehet statikus adattag
    nem lehet konstruktora ill. destruktora




// automatikus élettartam

void f()
{
    int i = 2;  // initializáció: i 
    ....
}               // megsemmisül: i





//  statikus élettartam

date d(2003,3,13);  // inicializáció: d
static int i;       // inicializáció: i

int main()
{
    while ( ... )
    {
        if ( ... )
        {
            static int j = 6;   // inicializáció: j
        }
    }
} // megsemmisülés: j, i, d




// dinamikus élettartam:

    date *p = new date;
    date *q = new date(*p);
    date *s = new date[10];
    //...
    delete p;
    delete p;   // !! runtime error
    delete s;   // !! runtime error
    delete [] s;// ez a helyes




// C-ben:

    date *p = (date*) malloc(sizeof(date));
    //...
    free(p);






#include <iostream>

using namespace std;

char *answer( char *question);

int main()
{
    cout << answer( "How are you? ") << endl;
    return 0;
}

// very bad code!!
char *answer( char *question)
{
    cout << question;
    char buffer[80];
    cin >> buffer;      // buffer overrun!!
    return buffer;      // never do this!
}


#include <iostream>

using namespace std;

char *answer( char *question);
char buffer[80];

int main()
{
    cout << answer( "How are you? ") << endl;
    return 0;
}

char *answer( char *question)
{
    cout << question;
//  char buffer[80];
    cin.getline(buffer,80);
    return buffer;
}



#include <iostream>

using namespace std;

char *answer( char *question);

int main()
{
    cout << answer( "How are you? ") << endl;
    return 0;
}

char *answer( char *question)
{
    cout << question;
    static char buffer[80];
    cin.getline(buffer,80);
    return buffer;
}



#include <iostream>

using namespace std;

char *answer( char *question);

int main()
{
    cout << answer("Sure? ") << answer( "How are you? ") << endl;
    return 0;
}

char *answer( char *question)
{
    cout << question;
    static char buffer[80];
    cin.getline(buffer,80);
    return buffer;
}



#include <iostream>

using namespace std;

char *answer( char *question);

int main()
{
    cout << answer("Sure? ") << answer( "How are you? ") << endl;
    return 0;
}

// very bad code!!
char *answer( char *question)
{
    cout << question;
    char *buffer = new char[80];
    cin.getline(buffer,80);
    return buffer;
}




#include <iostream>

using namespace std;

char *answer( const char *question, char *buffer, int size);

int main()
{
    const int bufsize = 80;
    char buffer1[bufsize], buffer2[bufsize];
    cout << answer("Sure? ", buffer1, bufsize)
         << answer( "How are you? ", buffer2, bufsize) << endl;
    return 0;
}

char *answer( const char *question, char *buffer, int size)
{
    cout << question;
    cin.getline(buffer,size);
    return buffer;
}




#include <iostream>
#include <string>

using namespace std;

string answer( string question);

int main()
{
    cout << answer("Sure? ") << answer( "How are you? ") << endl;
    return 0;
}

string answer( string question)
{
    cout << question;
    string s;
    getline(cin,s);
    return s;
}




#include <iostream>
#include <string>

using namespace std;

string answer( string question);

int main()
{
    cout << answer( "How are you? ") << endl;
    cout << answer( "Sure? ") << endl;
    return 0;
}

string answer( string question)
{
    cout << question;
    string s;
    getline(cin,s);
    return s;
}





#include <iostream>
#include <sstream>
#include <string>

using namespace std;

string answer( string question);

int main()
{
    ostringstream os;
    os << answer( "How are you? ");
    os << ", ";
    os << answer( "Sure? ");
    cout << os.str() << endl;
    return 0;
}

string answer( string question)
{
    cout << question;
    string s;
    getline(cin,s);
    return s;
}




////////////////////////////////////////////////////////
//                                                    //  
//            Template-ek és az STL                   //
//                                                    //
////////////////////////////////////////////////////////


#ifndef STACK_H
#define STACK_H

#include <iostream>

template <class T>
class stack
{
    // template friend: speciális jelölés. 
    // a stack<T> osztály friendje a stack<S> -et kiíró operátor
    // akkor és csak akkor, ha T==S
    friend std::ostream &operator<< <> ( std::ostream &os, stack s);
public:
        stack( int size = 128);
        stack( const stack &rhs);
        ~stack();
    stack& operator=( const stack &rhs);

    void  push( T d);
    T     pop();

    bool is_empty() const;
    bool is_full()  const;
private:
    int    capacity;
    int    sp;
    T      *v;

    void copy( const stack &other);
};

// itt jönnek a függvény megvalósítások: nincsen .cpp fájl!
template <class T>
stack<T>::stack( int size)
{
    v = new T[capacity = size];
    sp = 0;
}
template <class T>
stack<T>::stack( const stack &other)
{
    copy(other);
}
template <class T>
stack<T>::~stack()
{
    delete [] v;
}
template <class T>
stack<T>& stack<T>::operator=( const stack &other)
{
    if ( this != &other )
    {
        delete [] v;
        copy(other);
    }
    return *this;
}
template <class T>
void stack<T>::copy( const stack &other)
{
    v = new T[capacity = other.capacity];
    sp = other.sp;

    // ezt a ciklust nem lehet helyettesíteni memcpy()-al!
    for ( int i = 0 ; i < sp; ++i)
        v[i] = other.v[i];  // a T típus operator=() -a
}

// üres, vagy teli? ellenőrizze a felhasználó!
template <class T>
void stack<T>::push( T d)
{
    v[sp++] = d;
}
template <class T>
T stack<T>::pop()
{
    v[--sp];
}

// ezek a függvények is template-ek, hiszen specializálhatóak
template <class T>
bool stack<T>::is_empty() const
{
    return 0 == sp;
}
template <class T>
bool stack<T>::is_full() const
{
    return capacity == sp;
}

// ez egy "közönséges" template függvény, stack<T> -re specializálva
template <class T>
std::ostream &operator<<( std::ostream &os, stack<T> ds)
{
    os << "[ ";
    for ( int i = 0; i < ds.sp-1; ++i )
        os << ds.v[i] << ", ";
    if ( ds.sp > 0 )
        os << ds.v[ds.sp-1];
    os << " ]";
    return os;
}

#endif /* STACK_H */




#ifndef STACK_BOOL_H
#define STACK_BOOL_H

#include <iostream>

template <>
class stack<bool>
{
    // egészen más implementáció
    // ...
};

template <>
void stack<bool>::copy( const stack &other)
{
    v = new T[capacity = other.capacity];
    sp = other.sp;

    memcpy(v, other.v, sizeof(T)*sp);
}

#endif /* STACK_BOOL_H */



#include <iostream>

#include "stack.h"
#include "stack_bool.h"

#include "date.h"

using namespace std;

int main()
{
    stack<int> d1(10);
    d1.push(3);
    d1.push(4);
    d1.push(5);
    cout << d1 << endl;

    date d;
    stack<date> d2(5);
    d2.push(date(2000,6,23));
    d2.push(d);

    stack<bool> d3(2000);
    //...

    cout << d1 << endl;
    cout << d2 << endl;
    cout << d3 << endl;
    return 0;
}



  // Feladat: keressük az első előfordulást...


    int t[] = { 1, 3, 5, ... };

    int *pi = find( t, t+sizeof(t)/sizeof(t[0]), 55);

    if ( pi )
    {
        *pi = 56;
    }



    // Egy nagyon specifikus find():


    int *find( int *begin, int *end, int x)
    {
        while ( begin != end )
        {
            if ( *begin == x )
            {
                return begin;
            }
            ++begin;
        }
        return 0;
    }



    // Általánosítsunk a típuson: int -> T


    template <typename T>
    T *find( T *begin, T *end, const T& x)
    {
        while ( begin != end )
        {
            if ( *begin == x )
            {
                return begin;
            }
            ++begin;
        }
        return 0;
    }



    // Általánosítsunk az adatszerkezeten: ++, *


    template <typename It, typename T>
    It find( It begin, It end, const T& x)
    {
        while ( begin != end )
        {
            if ( *begin == x )
            {
                return begin;
            }
            ++begin;
        }
        return end;
    }



    // Egységes használat: 


    int t[] = { 1, 3, 5, ... };


    int t[] = { 1, 3, 5, ... };

    int *pi = find( t, t+sizeof(t)/sizeof(t[0]), 55);

    if ( pi )
    {
        *pi = 56;
    }

    vector<int> v;
    v.push_back(1); v.push_back(3); v.push_back(5); ...

    vector<int>::iterator vi = find( v.begin(), v.end(), 55);

    if ( vi != v.end() )
    {
        *vi = 56;
    }

    list<double> l;
    l.push_back(1.1); l.push_back(3.3); l.push_back(5.5); ...

    list<double>::iterator li = find( l.begin(), l.end(), 55.55);

    if ( li != l.end() )
    {
        *li = 56.66;
    }



    // Konstans-biztosság:


    const int t[] = { 1, 3, 5, ... };

    const int *pi = find( t, t+sizeof(t)/sizeof(t[0]), 55);

    if ( pi )
    {
        // *pi = 56;    Syntax error
        cout << *pi;
    }

    vector<int> v;
    v.push_back(1); v.push_back(3); v.push_back(5); ...

    const list<double> cl( v.begin(), v.end());

    list<double>::const_iterator cli = find( cl.begin(), cl.end(), 55.55);

    if ( cli != cl.end() )
    {
        // *cli = 56.66;    Syntax error
        cout << *cli;
    }



    // Keressük meg a harmadik előfordulást:


    list<double> l; ...
    list<double>::iterator li;

    li = find( l.begin(), l.end(), 3.14);
    li = find( li, l.end(), 3.14);
    li = find( li, l.end(), 3.14);

    // vagy: 

    li = find(find(find(l.begin(),l.end(),3.14),l.end(),3.14),l.end(),3.14);



    // Keressük meg a harmadik elemet, amelyik kisebb 55-nél:


    template <typename It, typename Pred>
    It find_if( It begin, It end, Pred p)
    {
        while ( begin != end )
        {
            if ( p(*begin) )
            {
                return begin;
            }
            ++begin;
        }
        return end;
    }



    // Predikátum I. (nem túl jó):

    bool less55_3rd( int x)
    {
        static int cnt = 0;
        if ( x < 55 )
            ++cnt;
        return 3 == cnt;
    }


    // Használat:

    vector<int> v; ...

    vector<int>::iterator = find_if( v.begin(), v.end(), less55_3rd);



    // Predikátum II:

    struct less55_3rd
    {
        less55_3rd() : cnt(0) { }
        bool operator()(int x)
        {
            if ( x < 55 )
               ++cnt;
            return 3 == cnt;
        }
    private:
        int cnt;
    };


    // Használat:


    vector<int> v; ...

    less55_3rd  pp;
    vector<int>::iterator = find_if( v.begin(), v.end(), pp);

    // vagy:

    vector<int>::iterator = find_if( v.begin(), v.end(), less55_3rd());



    // Predikátum III.: általánosabban

    template <typename T>
    struct less_nth
    {
        less_nth( const T& t, int n) : t_(t), n_(n), cnt_(0) { }
        bool operator()(const T& t)
        {
            if ( t < t_ )
               ++cnt;
            return n_ == cnt;
        }
    private:
        T   t_;
        int n_;
        int cnt_;
    };


    // Használat:


    vector<int> v; ...

    vector<int>::iterator = find_if(v.begin(),v.end(),less_nth<int>(55,3));








http://aszt.inf.elte.hu/~gsd/pny2/html