#7 Kit
Samozrejme C môže vracať štruktúry. Problém je kde alokuješ dáta na ten string. C nemá templaty ako C++, D a iné jazyky takže to rieši tak že ako parameter funkcie je pointer na dopredu alokované dáta.
Příspěvky odeslané z IP adresy 195.28.77.–
#34 ondrej39
Problém je že chce zdielať 1 objekt typu B medzi viacerými objektami typu A. Tam je nutné použiť určitú formu pointera/referencie a podľa mňa je lepšie použiť pointer s vlastníctvom a nie čistý pointer/referenciu prípadne GC. Kým je všetko na stacku tak to môže byť OK ale stačí aby začal využívať kontajnery a inú dynamickú alokáciu pamäte a skončí pri tom že sa bude učiť ako narábať s valgrind-om (čo môže byť nakoniec aj prospešné )
Podľa mňa by bolo lepšie pre začiatočníka aby trieda A vlastnila objekt shromazdovac (napr cez shared_ptr) alebo aby bol shromazdovac globalna/staticka premenná kde nemôže nastať situácia že životnosť objektu A je vyššia ako životnosť shromazdovac-a...
Zabudol si vynulovať wert na začiatku cyklu.
Premenne môžeš deklarovať aj v cykloch:
#include <iostream>
using namespace std;
int main()
{
do{
char wiederholung = 'j';
int n, wert = 0;
cout << "Bitte, geben Sie eine Zahl: " << endl;
cin >> n;
for (int i = 1; i <= n; i++){
wert = wert +(i*i);
}
cout << wert << endl;
cout << "Wollen sie weitergehen? ";
cin >> wiederholung;
if (wiederholung != 'j')
return 0;
}
while(1);
return 0;
}
Skús niečo takéto:
char str[50], op[50];
fgets(str, 50, stdin); //nacitaj si vstup do stringu neh ho mozes pouzit viacej krat
if(sscanf(str, "%f%c%f",&x,&oper,&y)==3){
///tvoj switch...
}
else if(sscanf(str, "%s%f",&op,&x)==2){
if(strcmp(op, "odm")){
///...
}
else if(strcmp(op, "moc")){
///...
}
}
Ak to budeš neskôr rozširovať o zátvorky, komplikovanejšiu aritmetiku a priority operátorov tak sa to rieši cez vlastný parser
#18 BDS
Načo to robiť jednoducho keď to ide spraviť zložito...
static class Eviduj2
{
public:
static bool metodaKdeChciZjistitHodnotuPromenne(Zpracuj * instanceZpracuj)
{
return instanceZpracuj->getStavNeceho();
}
};
Jednoduchá verzia:
bool metodaKdeChciZjistitHodnotuPromenne(Zpracuj* instanceZpracuj){
return instanceZpracuj->getStavNeceho();
}
//alebo rovno použiť:
instanceZpracuj->getStavNeceho();
Celý ten návrh je dosť divný, Možno by úplne stačila jedna trieda kde budú dáta, prípadne primitívna štruktúra a k tomu 2 funkcie/metódy na serializáciu a deserializáciu...
#2 Longin
Ta kniha ma 15 rokov, odvety sa schvalili 3 nove standrdy jazyka C++, konkretne c++03, c++11 a c++14.
Doporucujem aby si si nasiel novsiu knihu. V dnesnej dobe vobec nepotrebujes zadavat Iterator aj parameter T:
template <class Iterator>
auto median(Iterator begin, Iterator end)->decltype(*begin){
//...
}
void log( Type t, std::string& msg ) noexcept override{} //kompilator ti vypise chybu lebo ti tam chyba const
#14 xxx7691
TABULKA_PARANETROV x;
if(x.BEZPECNOST > 3.14){
//...
}
TABULKA_PARANETROV* y = &x; //cez pointer
if(y->BEZPECNOST > 3.14){
//...
}
najjednoduhsie bude asi spravyt si pole pointrov na TABULKA_PARANETROV a to zoradit bodla parameta BEZPECNOST.
#10 ondrej39
Naco nasobenie?
#include <stdio.h>
#include <stdint.h>
uint32_t init_ip(uint8_t a, uint8_t b, uint8_t c, uint8_t d){
uint8_t tmp[4] = {a, b, c, d};
return *(uint32_t*)tmp;
}
void print_ip(uint32_t ip){
uint8_t tmp[4];
*(uint32_t*)tmp = ip;
printf("%d.%d.%d.%d", (int)tmp[0], (int)tmp[1], (int)tmp[2], (int)tmp[3]);
}
int main(){
uint32_t ip = init_ip(123, 255, 32, 14);
print_ip(ip);
}
template<int m1, int l1, int t1, int m2, int l2, int t2> //template parametre
Fyzikalni<m1+m2, l1+l2, t1+t2> //navratovy typ
operator* //meno funkcie
(
Fyzikalni<m1, l1, t1> lhs, //parameter funkcie 1
Fyzikalni<m2, l2, t2> rhs //parameter funkcie 2
)
{
return Fyzikalni<m1+m2, l1+l2, t1+t2>::unit * lhs.value() * rhs.value(); //daky exprssion, na pochopenie by trebalo deklaraciu triedy Fyzikalni
}
#1 Jan Tržický
Knihy mas tu: http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list (niektore su aj na torrentoch/uloz.to/...)
Treba si uvedomit ze C++ nie je C#. Aj ked sa velmi podobaju, tak sa v nich programuje uplne inak.
Len tak zo zaujimavost. Dajme tomu ze mas naprogramovany ten revolucny stavkovy system. Samotne patentovanie je drahe a patentovani softweru v EU bude problematicke (mozno aj nemozne). V USA zas patentovanie trva niekolko rokov a ak by si aj mal daky uspech tak sa na teba moze obratit patentovy trol a sudit sa s nim je velmi nakladne.
#1 Heina
Je to nieco ako if:
condition_expression ? then_expression : else_expression
scale = (580)/((bottom_interval == top_interval) ? 0 : (top_interval - bottom_interval));
//eqvivalentom je:
if(bottom_interval == top_interval)scale = 580/0; //delis nulov
else scale = 580 / (top_interval - bottom_interval)
#9 ondrej39
inspiruj sa sa tu: http://en.cppreference.com/w/cpp/container/list
#4 Jmeno
1. Vytvoris anonymnu strukturu a nasledne pomocou typedefu vytvoris identifikator pre tuto strukturu:
typedef struct{}nazev;
2. Vytvoris strukturu s identifikatorom "nazev":
struct nazev{};
V c++ je viac menej rozdiel len v tom ze 1. priklade nemozes spravyt nieco taketo:
typedef struct{
nazev* ptr; //error: identifikator "nazev" este nebol deklarovany.
}nazev;
V C je uz vecsi rozdiel. C na rozdiel od C++ ma viacej kategorii identifikatorov:
struct nazov{}; //#1
typedef struct{}nazov; //#2
int main(){
struct nazov s1; //pouzie typ #1
nazov s2; //pouzie typ #2
}
Vypisovat pred kazdu premennu 'struct' je otravne tak sa pouziva verzia s typedef. Ale len v C, v C++ je to zbytocne.
Skus spravne odsadzovat bloky a hned najdes niektore chyby:
enum TypPredmetu {
Mec=0,
Stit=1,
Helma=2
};
class Predmety {
int m_bonusObrana;
string m_nazev;
int m_typ;
public:
Predmety (int obrana, string nazev, int typ){
m_bonusObrana=obrana;
m_nazev=nazev;
m_typ=typ;
}
int getBonusObrana(){
return m_bonusObrana;
}
string getNazev(){
return m_nazev;
}
class Hrdina{
private:
array <Predmety*,10> m_predmety;
int m_penize;
int m_obrana;
Predmety** m_comaNaSobe;
public:
Hrdina(int penize, int obrana){
m_penize = penize;
m_obrana = obrana;
for(int i = 0; i<(int)m_predmety.size(); i++){
m_predmety.at(i)=0;
}
}
int getPenize(){
return m_penize;
}
int getObrana(){
return m_obrana;
}
int i=0;
void seberPredmet(Predmety*stit){
m_predmety.at(i)=stit;
i=i+1;
}
void pouzijPredmet(int ktery){
m_comaNaSobe[TypPredmetu::Stit] = m_predmety.at(ktery);
m_obrana=m_obrana+m_comaNaSobe[TypPredmetu::Stit]->getBonusObrana();
}
void printInfo(){
cout<<"Pocet zlataku: "<<m_penize<<endl;
}
~ Hrdina (){
#3 lukas.balaz
FP aritmetika je zlozitejsia ako sa na prvy pohlad moze zdat, skus sa napr pozret sem: http://dlang.org/d-floating-point.html
#2 Tomáš
chybu mas asi tu:
FILE *f;
predaj = fopen("subor.txt", "r");
/// f je neinicializvane
edit:
//miesto:
if ((udaje = malloc(30 * sizeof(char *))) == NULL);
//pouzi:
char* udaje[30];
//alebo:
char udaje[30][52];
inak 0xCDCDCDCD znamena ze je hodnta neinicializvana (plati len v debug mde u msvc kmpilatru)
edit2:
zabudes uzatvarat subor a zabudes uvalnvat pamet pri niektorych chybach
#1 začátečník
Pre std je dobra tato referencia: http://en.cppreference.com/w/
Pouzivanie goto vedie k neprehladnemu kodu v ktorom sa blbo orientuje. Ja som to zatial vyuzil len pri vyskakovani zo zanoreneho switchu/cyklu a pri tvorbe stavovych automatov kde treba skakat v switchi medzi roznymi case. V C sa goto vyuziva na uvolnovanie zdrojov pri chybach lebo nema RAII.
#1 matus
Visual C++ je kompilator pre C++ od microsoftu, nie je to jazyk. C++ je jazyk a mozes pouzit aj ine kompilatory ako gcc, clang,...
Mozes skusit QT ktore funguje na Wine, OSX, Linuxe a ciastocne aj na androide a ios-e. Tento framework je na rozdiel od win api napisany v C++ a nie v C.
Instancivanie templatov funguje nasledovne:
//mas template funkcie:
template<typename T>
void zobraz(const T& );
template<typename T>
void zobraz(const T* );
//Ak zavolas funkciu zobraz s mutable value premennou:
int i;
fnc(i);
//tak sa vygeneruju nasledovne funkcie:
void zobraz(const int&); //1
void zobraz(/*error*/); //2: tato funkica sa zahodi vdaka SFINAE
//zavola sa funkcia 1.
//Ak zavolas funkciu zobraz z mutable pointerom:
int i;
zobraz(&i);
//vygeneruju sa tieto 2 funkcie:
void zobraz(const int*&); //1
void zobraz(const int* ); //2
//obe funkcie akceptuju typ int* po pretypovani na const int*, ale funkcia 1 ho bere ako refrenciu, cize ma vyzsiu prioritu pri overloadingu.
//Ak zavolas funkciu s const pointrom:
const int i;
zobraz(&i);
//vygeneruju sa nasledovne funkcie:
zobraz(const int*&); //1
zobraz(const int*); //2
//obe funkcie sa mozu pouzit, ale funkcia 2. akceptuje parameter &i typu const int* BEZ PRETYPOVANIA, cize ma vyzsiu prioritu ako funkcia 1.
Ak chces aby sa pre pointre vzdy volala 1 funkcia a pre ostatne hodnoty druha, tak potrebujes parametre bez const:
template<typename T>
void zobraz(T*);
template<typename T>
void zobraz(T&&); //akceptuje referencie a rvalue referencie (vyzaduje c++11/c++14)
//obe funkcie akceptuju aj const parametre!
//pripadne mozes spravyt overloading vsetkych 4 verzii:
template<typename T>
void zobraz(T*);
template<typename T>
void zobraz(const T*);
template<typename T>
void zobraz(T&);
template<typename T>
void zobraz(const T&);
Snazis sa deklarovat funkciu vo funkcii a to C nepodporuje.
Celkovo, na konci programu asi nieco chyba... :
// kozolovina.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "kozolovina.h"
#include <windows.h>
#include <gl.h>
#include <glu.h>
#include <glaux.h>
HDC hDC = NULL;// Privátní GDI Device Context
HGLRC hRC = NULL;// Trvalý Rendering Context
HWND hWnd = NULL;// Obsahuje Handle našeho okna
HINSTANCE hInstance;// Obsahuje instanci aplikace
bool keys[256];// Pole pro ukládání vstupu z klávesnice
bool active = TRUE;// Ponese informaci o tom, zda je okno aktivní
bool fullscreen = TRUE;// Ponese informaci o tom, zda je program ve fullscreenu
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);// Deklarace procedury okna
GLvoid ReSizeGLScene(GLsizei width, GLsizei height)// Změna velikosti a inicializace
{
if (height==0)// Zabezpečení proti dělení nulou
{
height=1;// Nastaví výšku na jedna
}
glViewport(0,0,width,height);// Resetuje aktuální nastavení
glMatrixMode(GL_PROJECTION);// Zvolí projekční matici
glLoadIdentity();// Reset matice
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);// Výpočet perspektivy
glMatrixMode(GL_MODELVIEW);// Zvolí matici Modelview
glLoadIdentity();// Reset matice
}
int InitGL(GLvoid)// Všechno nastavení OpenGL
{
glShadeModel(GL_SMOOTH);// Povolí jemné stínování Nastavíme barvu pozadí prázdné obrazovky. Rozsah barev se určuje ve stupnici
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);// Černé pozadí
glClearDepth(1.0f);// Nastavení hloubkového bufferu
glEnable(GL_DEPTH_TEST);// Povolí hloubkové testování
glDepthFunc(GL_LEQUAL);// Typ hloubkového testování
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);// Nejlepší perspektivní korekce
return TRUE;// Inicializace proběhla v pořádku
}
int DrawGLScene(GLvoid)// Vykreslování
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// Smaže obrazovku a hloubkový buffer
glLoadIdentity();// Reset matice
// Sem můžete kreslit
return TRUE;// Vykreslení proběhlo v pořádku
}
#define MAX_LOADSTRING 100
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_KOZOLOVINA, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_KOZOLOVINA));
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_KOZOLOVINA));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_KOZOLOVINA);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&wcex);
}
//
// FUNCTION: InitInstance(HINSTANCE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
GLvoid KillGLWindow(GLvoid)// Zavírání okna
{
if (fullscreen)// Jsme ve fullscreenu?
{ChangeDisplaySettings(NULL,0);// Přepnutí do systému
ShowCursor(TRUE);// Zobrazí kurzor myši
}
if (hRC)// Máme rendering kontext?
{
if (!wglMakeCurrent(NULL,NULL))// Jsme schopni oddělit kontexty?
{MessageBox(NULL,"Release Of DC And RC Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
}
return (INT_PTR)FALSE;
}
// ????
V c++11 (QT5 by malo fungovat) mozes pridat inicialiaciu priamo do deklaracie atributu (musi to byt ale konstanta znama pri kompilacii)
class BADA_3_LOADER{
QUERY_TYPE* query = nullptr; //alebo "= NULL;" alebo "= 0;"
DB_TYPE* db = nullptr; //alebo "= NULL;" alebo "= 0;"
//...
}
BADA_3_LOADER::BADA_3_LOADER(const QString &dbPath){}
#1 Pavelv
Podobny efekt sa da docielit s template funkciami, bohuzial nejde pretazit operator= v globalnom scope.
#include <iostream>
#include <initializer_list>
#include <cassert>
#include <algorithm>
#include <iterator>
template <class T, size_t N>
auto set(T (&array)[N], std::initializer_list<T>&& x)->decltype(array)&{
std::copy_n(
std::begin(x),
std::min(sizeof(array), x.size()),
std::begin(array)
);
return array;
}
template <class T, size_t N, size_t M>
void print(T (&array)[N][M]){
for(auto &x : array){
std::cout << "{";
for(int i : x)std::cout << i << ", ";
std::cout << "}\n";
}
std::cout << "\n";
}
int main(){
int array[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8 ,9}
};
print(array);
set(array[1], {1, 1, 1});
print(array);
return 0;
}
#16 Ceyn
Unreal engin podporuje android aj ios.
Pri vybere enginu musis zvazit vela vec: chces tvorit komercne hry,free alebo open sorce(nebodaj GPL)?, Chces mat pristup k zdrojakom enginu?, Aky typ hry to bude?, v com to chces programovat?, na ake platformy?,...
Herny engin je len dalsia vrstva. Pri pouzivani herneho enginu sa s OpenGL/Direct3D ani nemusis stretnut. Mas jednoducho modely a textury v subore a enginu cez dake funkcie poviez ze ich ma zobrazit a dalej sa nestaras. V OpenGL/Direct3D pracujes hlavne zo shadermi(ked pouzies nove OpenGL/Direct3D). Robis tam transformacie medzi priestormi, vypocitavas a zobrazuje tiene/svetla a podobne veci...
#1 .
Mas tam nasledovnu chybu:
void cihla::nakreslit() {
//cihla nie je premenna ale typ, nemozes pouzit '.' na pristup k metode
int a = cihla.jetam();
//pouzi jedno z nasledovnych volani metody:
int a = cihla::jetam();
int a = this->jetam();
int a = jetam();
std::cout << a;
}
#1 Kenvelo
pouzi map/unordered_map
#include <iostream>
#include <unordered_map>
#include <string>
#include <cstdlib>
struct A{
int b = rand()%10;
};
int main(){
std::string retazec;
std::unordered_map<std::string, A> db;
for(std::getline(std::cin, retazec); retazec.size(); std::getline(std::cin, retazec)){
db[retazec] = A{};
}
for(auto& i : db){
std::cout << i.first << ":\t" << i.second.b << '\n';
}
}
#1 Cesar
Skus prejst na C11, je tam podpora threadov priamo v standarde: http://en.cppreference.com/w/c/thread
#1 tomas_prokop
Skus si vybrat podla tohto:http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list.
#1 Sefiros
vector ma specializaciu na typ 'bool'. Vtedy sa zrejme pouziva allocator inak ako v standartnom pripade. Akonahle zmenis typ bool za nieco ine tak ti to bude fungovat.
Ak mas c++11 kompilator tak mozes pouzit nieco taketo aby to bolo viac prehladne:
template <class T>
using dbg_vector = std::vector<T, debugAllocator<T>>;
int main()
{
dbg_vector<dbg_vector<int>> vect(
0,
dbg_vector<int>{},
debugAllocator<dbg_vector<int>>{}
);
return 0;
}
#1 Fičak
Zaujímavá úloha, keď ju spravíš tak môžeš skúsiť aj tieto:
#7 Swixi
Skus tuto stranku: http://en.cppreference.com/w/c/string/byte/memmove
Dokonca tam máš príklady.
Napriklad:github.com a code.google.com
#1 NotBeginner
Eclipse je len vyvojove prostredie, zalezi aj na tom aky mas kompilator. #pragma prikazy su rozdielne pre rozne prekladace, tusim ten tvoj na prilinkvanie statickej kniznice bude fungovat len v vc++ . Ak mas mingw, tak to budes musiet pridat ako parameter pri spustani prekladaca, eclipse by na to malo mat niekde klikatko.
#1 .
Slo by to takto:
//obycajne polia
#include <iostream>
#include <initializer_list>
#include <cassert>
#include <algorithm>
template<class T, size_t S>
auto arrayInit(T (&array)[S], std::initializer_list<T>&& ini)->decltype(array)&{
assert(S >= ini.size());
std::copy(ini.begin(), ini.end(), std::begin(array));
return array;
}
int main(){
int array[4];
arrayInit(array, {1, 2, 3, 4});
for(int i : array)std::cout << i << '\n';
return 0;
}
alebo cez std::array:
#include <iostream>
#include <initializer_list>
#include <cassert>
#include <algorithm>
#include <array>
template<class T, size_t S>
std::array<T, S>& operator|=(std::array<T, S>& array, std::initializer_list<T>&& ini){
assert(S >= ini.size());
std::copy(ini.begin(), ini.end(), std::begin(array));
return array;
}
int main(){
std::array<int, 4> array;
array |= {1, 2, 3, 4};
for(int i : array)std::cout << i << '\n';
return 0;
}
#7 Deril
Mozes pouzit nieco taketo:
#include <string>
#include <iostream>
using namespace std;
struct Kniha
{
string nazevKnihy;
string autorJmeno;
string autorPrijmeni;
int pocetStran;
int rokVydani;
void serialize(std::ostream& out)const;
void deserialize(std::istream& in);
void print(std::ostream& out)const{
out << "Kniha[" << nazevKnihy << ", " << autorJmeno << ", " << autorPrijmeni << ", " << pocetStran << ", " << rokVydani << "]\n";
}
};
template<class T>
void binSerialize(std::ostream& out, const T& data){
out.write(reinterpret_cast<const char*>(&data), sizeof(T));
}
template<class T>
void binDeserialize(std::istream& in, T& data){
in.read(reinterpret_cast<char*>(&data), sizeof(T));
}
//specializacia pre string
template<>
void binSerialize<std::string>(std::ostream& out, const std::string& str){
binSerialize(out, str.size());
out << str;
}
//specializacia pre string
template<>
void binDeserialize<std::string>(std::istream& in, std::string& str){
size_t s;
binDeserialize(in, s);
if(s){
str = std::string(s, '\0');
in.read(&str[0], s);
}
}
void Kniha::serialize(std::ostream& out)const{
binSerialize(out, nazevKnihy);
binSerialize(out, autorJmeno);
binSerialize(out, autorPrijmeni);
binSerialize(out, pocetStran);
binSerialize(out, rokVydani);
}
void Kniha::deserialize(std::istream& in){
binDeserialize(in, nazevKnihy);
binDeserialize(in, autorJmeno);
binDeserialize(in, autorPrijmeni);
binDeserialize(in, pocetStran);
binDeserialize(in, rokVydani);
}
#include <fstream>
int main(){
{
std::ofstream file("test.dat", std::ios::binary);
Kniha{"a", "bb", "ccc", 6314, 2000}.serialize(file);
Kniha{"eee", "", "gggg", 123, 1500}.serialize(file);
}
std::ifstream file("test.dat", std::ios::binary);
Kniha kniha[2];
kniha[0].deserialize(file);
kniha[1].deserialize(file);
kniha[0].print(std::cout);
kniha[1].print(std::cout);
return 0;
}
#5 Deril
Zalezi od toho ci obsahuje typ 'Kniha' dake pointre. Nezabudaj ze std::string, std::vector a ine kontainery su implementovane cez pointre, takze tie sa neulozia do suboru (std::string moze niekedy fungovat ak tvoj prekladac podporuje SSO, ale to plati len pre male stringy, tusim do 15 znakov). Ak ma typ 'Kniha' virtualne metody, tak ma aj vptr(pointer do tabulky virtualnych metod) a ten sa moze menit ak prekompilujes program.
#1 Kowalsky95
Mozes skusit tuto:
http://www.amazon.com/C-Concurrency-Action-Practical-Multithreading/dp/1933988770
#1 Doomista
Metody sa od funkci lisia tym ze maju skryty parameter(pointer na objekt):
struct A{
void f(){}
static void g(){}
};
//Metoda A::f prebera 1 parameter, nie 0 ako by sa mohlo zdat. Funkcia g prebera 0 parametrov.
//prototym funkcie f si mozes predstavyt takto:
void f(A* this);
Predpokladam ze funkcia Mix_HookMusicFinished ocakava ako parameter pointer na funkciu bez parametrov co metoda A::f nie je (ma 1 skryty parameter this).
#1 Jana
Da sa pouzit aj stringstream:
#include <iostream>
#include <sstream>
#include <vector>
#include <string>
#include <stdexcept>
using year_t = unsigned;
std::vector<year_t> parseYears(const std::string& str){
std::istringstream iss(str);
std::string tmp[3];
std::vector<year_t> years;
while(iss >> tmp[0]){
if(iss >> tmp[1]){
if(tmp[1] == "-"){
if(iss >> tmp[2]){
year_t a = std::stoul(tmp[0]);
year_t b = std::stoul(tmp[2]);
for(; a <= b; ++a)years.push_back(a);
}
else throw std::logic_error("parseYears error");
}
else if(tmp[1] == ","){
years.push_back(std::stoul(tmp[0]));
}
else throw std::logic_error("parseYears error2: " + tmp[1]);
}
else{
years.push_back(std::stoul(tmp[0]));
return years;
}
}
return years;
}
int main(){
for(year_t y : parseYears( " 2006 , 2008 , 2009 - 2011 "))
std::cout << y << '\n';
}
#5 paya
Úplne štandardné veci: http://cppquiz.org/quiz/question/15.
EXIT_SUCCESS je makro ktoré preprocesor nahradí za 0. Takže return 0; a return EXIT_SUCCESS; su viac menej totožné statementy.
Veľmi zaujímavý quiz obsahujúci temné zákutia c++ :)
Napada ma takyto sposob:
//policko reprezentujuce cislo:
struct Filed{
int x; //0 ak na policku nie je ziadne cislo alebo cislo <1, 9>
bool poss_map[9];//mapa cisiel ktore mozu byt umiestnene na toto policko (index 0 reprezentuje cislo 1, index 1 reprezentuje cislo 2, ...)
}
//herna plocha:
struct GameField{
Filed fields[9][9]; //vsetky policka
}
- Najprv na zaklade existujucich policok ktore maju definovany atribut @x naplnis @poss_map-y (podla pravidiel sudoku X).
- Potom vyplnis @x pre vsetky policka kde @poss_map obsahuje len 1 hodnotu.
- Ak neexistuje taka situacia, tak si najdes policko kde je co najmenej moznosti (idealne 2) a pre kazdu moznost vygenerujes novu hernu plochu (GameField), pre kazdu tuto plochu spravis bod (2).
- Vynulujes vsetky @poss_map zo vsetkych fieldoch vo vsetkych hernych plochach
- vrat sa na bod (1) a opakuj dokym mas volne policka.
#4 Martin
stringstream je stream tak ako cin, cout...
Rozdiel je v tom ze data vybera/vklada z/do stringu.
#include <sstream>
#include <iostream>
int main(){
using namespace std;
std::stringstream ss("slovo slovo 456 12.5");
string str1, str2;
int i;
double d;
ss >> str1 >> str2 >> i >> d;
cout
<< str1 << endl
<< str2 << endl
<< i << endl
<< d << endl;
}
#1 ulikk
dynamicky alokovat mozes pomocou new[] a odalokovat delete[].
Funguje to tak ze alokujes N prvkove pole a uchovavas si o nom nasledovne vlastnosti:
- pointer na 0. prvok
- velkost alokovanej pamete (kapacita = N)
- pocet prvkov v poly (pocet prvkov ktore si do pola vlozil)
Do pola mozes vkaladat prvky dovtedy dokym pocet prvkov < kapacita.
Potom musis alokovat nove pole ktore bude vecsie (napr 2 nasobok predchadazajucej kapacity) a prekopirovat donho vsetky prvky z predchadzajuceho pola a potom dealokovat stare pole (mozes pouzivat aj malloc, realoc a free, vtedy musis ale rucne volat konstruktory/destructory objektov lebo C funkcie ich nevolaju).
#4 Martin
#include <iostream>
#include <string>
int main(){
using namespace std;
string str = "str strstr str";
string x = "str";
size_t count = 0;
size_t pos = str.find(x, 0); //vyhladas v stringu @str substring @x od 0 pozicie a vrati jeho poziciu
while(pos != string::npos){ //string::npos je konstanta co reprezentuje neplatnu poziciu v stringu
++count;
pos=str.find(x, pos+x.size());
};
cout << "pocet vyskytov \"" << x << "\" v stringu \"" << str << "\" == " << count << '\n';
return 0;
}