Ściągawka C++

Użyteczne konstrukcje w C++

Jak powtórzyć jakiś kod podaną przez użytkownika ilość razy?

int n;
// Najpierw wczytujemy żądaną ilość razy
cin >> n;
// Teraz tworzymy pętlę
for (int i = 0; i < n; ++i) {
  // Kod do powtarzania
}

Jak odczytać wszystkie liiczby na wejściu, nie wiedząc z góry ile ich jest?

int i;
while (cin >> i) {
  // Kod do wykonania dla każdej liczby
}

Jak odczytać wszystkie linijki tekstu na wejściu, nie wiedząc z góry ile ich jest?

string s;
while (getline(cin, s)) {
  // Kod do wykonania dla każdej linijki tekstu
}

Jak pozbyć się niepotrzebnego znaku nowej linii na wejściu?

Jeżeli wejście do programu wygląda następująco:

2
Linijka 1
Linijka 2

To instrukcje

int n;
cin >> n;
string s;
getline(cin, s);

spowodują, że s będzie puste. Powodem tego jest znak nowej linii po cyfrze 2 na wejściu. Aby w s dostać "Linijka 1" należy napisać w programie:

int n;
cin >> n;
// Każemy zignorować następne 10 znaków, ale przerwać
// ignorowanie po napotkaniu znaku nowej linii.
cin.ignore(10, '\n');
string s;
getline(cin, s);

Jak stworzyć tablicę nieznanego rozmiaru?

Wiele osób na początku próbuje:

int n;
cin >> n;
int t[n];

I to często działa, ale jest z tym kilka problemów. W razie braku pamięci program wyłączy się i nie będzie szans dojść dlaczego, ani temu zapobiec. Poza tym taka tablica zabiera cenne miejsce na stosie.

Powinniśmy używać jednego z dwóch sposobów. Albo tworzmy tablicę używając metod przeznaczonych do dynamicznego alokowania pamięci (rozwiązanie rodem z C):

int n;
cin >> n;
// Tworzymy nową tablicę, ale na stercie.\
// W razie braku pamięci, zostanie rzucony wyjątek
// std::bad_alloc, który potem nauczymy się przechwycić.
int *t = new int[n];
//
// Kod korzystający z tablicy t.
// Co prawda t jest wskaźnikiem, ale można pisać normalnie:
// t[0], t[1], ..., t[n-1]
//
//
// Samodzielnie przydzieloną pamięć
// należy samemu zwolnić.
delete[] t;

W C++ jednak raczej powinniśmy korzystać z biblioteki standardowej pozwalającej na tworzenie tablicy rosnącej w razie potrzeby. Dzieki temu nie ryzykujemy, że zapomnimy o zwolnieniu pamięci.

// Poniższe v potrafi przechowywać
// wartości typu int.
// Oczywiście w razie potrzeby zmieniamy int na coś innego
vector<int> v;

// Nowe wartości dodajemy na koniec wektora pisząc:
v.push_back(1);

// Do liczb w wektorze można dostać się podobnie jak
// do tablicy, należy jednak uważać, aby nie odwołać się do
// nieistniejących obiektów (indeks w [] nie jest sprawdzany):
cout << v[0];

// Długość wektora:
v.size();

//Zrobienie czegoś dla wszystkich elementów na dwa sposoby: przez []:
for (int i = 0; i < v.size(); ++i) {
    cout << v[i];
}
// i przez iterator:
for (vector<int>::iterator it = v.begin(); it != v.end(); ++it) {
    cout << *it;
}

Jak wypisać liczbę zmiennoprzecinkową z dwoma miejscami po przecinku?

#include <iomanip>
// x to wypisywana liczba
cout << fixed << setprecision(2) << x;

Jak posortować tablicę liczb rosnąco?

Poniższe sortowanie jest w miejscu, tzn. zmieniamy porządek tablicy, bez tworzenia kopii.

// Funkcja std::sort znajduje się w nagłowku
// algorithms
// Niech tablica t ma n elementów
std::sort(t, t+n);

Nie jest istotne, że w tabeli są liczby, ważne jest, że obiekty z tabeli możemy sensownie porównać.

Jak posortować wektor rosnąco?

// Funkcja std::sort znajduje się w nagłowku
// algorithms
// v to wektor do posortowania
std::sort(v.begin(), v.end());

Jak posortować wektor malejąco?

// Funkcja std::sort znajduje się w nagłowku
// algorithms
// v to wektor do posortowania
std::sort(v.rbegin(), v.rend());

Jak posortować tablicę/wektor z własną funkcją porównującą?

// Przjmuje parę obiektów z tablicy i odpowiada na pytanie:
// Czy a jest mniejsze od b?
// A co znaczy "mniejsze" to już algorytmu nie interesuje...
bool porownaj(int a, int b) {
    return a < b;
}

// Funkcja std::sort znajduje się w nagłowku
// algorithms
// t to tabela o n elementach
// v to wektor do posortowania
std::sort(t, t+n, porownaj);
std::sort(v.begin(), v.end(), porownaj);

Jak wypisać 15000 cyfr liczby π?

Program może służyć za przykład jak nie należy pisać w języku C/C++. Mimo to robi spore wrażenie… Kod pochodzi z książki π Unleashed (Jörg Arndt, Christoph Haenel).

Najpierw w troszkę niestandardowym C:

a[52514],b,c=52514,d,e,f=1e4,g,h;
main(){for(;b=c-=14;h=printf("%04d",e+d/f))
for (e=d%=f;g=--b*2;d/=g)d=d*b+f*(h?a[b]:f/5),a[b]=d%--g;}

A teraz w bardziej standardowym C++:

#include <cstdio>
using std::printf;

int a[52514], b, c = 52514, d, e, f = 1e4, g, h;

int main() {
    for (; b = c -= 14; h = printf("%04d", e + d/f))
        for (e = d %= f; g = --b*2; d /= g) {
            d = d*b + f*(h ? a[b] : f/5);
            a[b] = d%--g;
        }
    return 0;
}