HOWTO - C/C++
Céčko není složité :o)
// Pole nespecifikované velikosti s ukazateli na funkce, // které vrací ukazatele na funkce, které vrací void void (*(*f[])())()
Debug výpisy
#define DEBUG(x) cerr << "DEBUG: " << __FILE__ << ":" << __LINE__ << " " \ << __FUNCTION__ << "() " << #x << " = " << (x) << endl
OpenGL obdélník
glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex3i(-50, -50, -100); glTexCoord2f(1.0f, 0.0f); glVertex3i( 50, -50, -100); glTexCoord2f(1.0f, 1.0f); glVertex3i( 50, 50, -100); glTexCoord2f(0.0f, 1.0f); glVertex3i(-50, 50, -100); glEnd();
Přetížení vstupu/výstupu
friend ostream& operator<<(ostream& o, const CList& l); ostream& operator<<(ostream& o, CList& l) { CList* tmp = &l; while(tmp->next != NULL)// Vsechny prvky o << tmp->i << " "; return o; } /////////////////////////////////////////////////////////////////////////// //// I/O support istream& operator>>(istream& is, CColor& color); ostream& operator<<(ostream& os, CColor& color); /////////////////////////////////////////////////////////////////////////// //// I/O support istream& operator>>(istream& is, CColor& color) { Uint8 tmp; is >> tmp; color.SetR(tmp); is >> tmp; color.SetG(tmp); is >> tmp; color.SetB(tmp); is >> tmp; color.SetA(tmp); return is; } ostream& operator<<(ostream& os, CColor& color) { os << color.GetR() << " " << color.GetG() << " " << color.GetB() << " " << color.GetA(); return os; }
Jednoduchý makefile
TARGET = prg CC = g++ CFLAGS = -Wall LDFLAGS = -lm $(TARGET): src.cpp $(CC) -o $(TARGET) src.cpp $(CFLAGS) $(LDFLAGS) clean: rm -f $(TARGET) core
Makefile pro větší projekty
# With SDL and OpenGL support TARGET = prg CC = g++ CFLAGS = -Wall $(shell sdl-config --cflags) LDFLAGS = -L/usr/X11R6/lib $(shell sdl-config --libs) -lSDL_image -lSDL_ttf -lGL -lGLU -lm OBJECTS = $(shell ls *.cpp | sed 's/.cpp/.o/') .PHONY: depend .PHONY: run .PHONY: clean %.o: %.cpp $(CC) -c $< $(CFLAGS) $(TARGET): $(OBJECTS) $(CC) -o $(TARGET) $(OBJECTS) $(LDFLAGS) # Mozna bude nadavat kvuliva STL a SDL hlavickam, ale je to OK depend: makedepend $(shell ls *.cpp) run: ./$(TARGET) clean: rm -f $(TARGET) *.o core # DO NOT DELETE
Pythonovské skripty spouštěné z Céčka
http://www.linuxjournal.com/article/8497 ///// Makefile ///// TARGET = prg CC = g++ CFLAGS = -Wall -I/usr/include/python2.4 LDFLAGS = -lpython2.4 -lm -L/usr/lib/python2.4/config $(TARGET): python_v_cecku.cpp $(CC) -o $(TARGET) python_v_cecku.cpp $(CFLAGS) $(LDFLAGS) clean: rm -f $(TARGET) core ///// source.cpp ///// #include <Python.h> #include <stdio.h> void exec_pycode(const char* code) { Py_Initialize(); PyRun_SimpleString(code); Py_Finalize(); } int main(int argc, char *argv[]) { FILE *fp; long len; char *buf; fp=fopen("script.py", "rb"); fseek(fp, 0, SEEK_END); len=ftell(fp); fseek(fp, 0, SEEK_SET); buf = (char *)malloc(len); fread(buf, len, 1, fp); fclose(fp); exec_pycode(buf); free(buf); return 0; } ///// script.py ///// print 'Program vypise nejvyssi zadane cislo, pri zaporne hodnote se ukonci' act = 5 max = None while act > -1: try: act = int(raw_input()) except ValueError: print 'Invalid Number' continue if act > max: max = act print 'Nejvyssi zadane cislo:', max
Přátelské objekty a funkce
class NejakaTrida { friend class CTrida; friend ostream& operator<<(ostream&, const CTrida&); };
Zákaz kopírování objektů
class CTrida { // Metody se nemusí definovat (asi) private: CTrida::CTrida(const CTrida&); CTrida& operator=(const CTrida&); };
Zákaz implicitních koverzí u tříd
class CCislo { public: // Nikdy se nepoužije pro implicitní konverzi explicit CCislo(int cis); private: int cislo; };
Šablona auto_ptr
#include <memory> auto_ptr<CTrida> uk(new CTrida(parametr)); // Paměť se uvolňuje automaticky
Zjištění jména třídy
#include <typeinfo>// ??? CTrida obj; cout << type_id(obj).name() << endl;
Načtení celého souboru do paměti
ifstream infile(file_src, ios::in | ios::binary); if(!infile) { cerr << "Cannot open " << file_src << endl; return; } infile.seekg(0, ios::end); long file_size = infile.tellg(); infile.seekg(0, ios::beg); char* file_content = new char[file_size]; infile.read(file_content, file_size); infile.close();
Barevný výstup textu (musí být podpora v shellu)
#include <stdio.h> /* Attributes */ #define RESET 0 #define BRIGHT 1 #define DIM 2 #define UNDERLINE 3 #define BLINK 4 #define REVERSE 7 #define HIDDEN 8 /* Colors */ #define BLACK 0 #define RED 1 #define GREEN 2 #define YELLOW 3 #define BLUE 4 #define MAGENTA 5 #define CYAN 6 #define WHITE 7 void textcolor(int attr, int fg, int bg) { printf("%c[%d;%d;%dm", 0x1B, attr, fg + 30, bg + 40); } int main(int argc, char* argv[]) { textcolor(BRIGHT, RED, BLACK); printf("In color\n"); textcolor(RESET, WHITE, BLACK); return 0; } /* // Bright, fg red, bg black cerr << (char)0x1B << "[" << 1 << ";" << 31 << ";" << 40 << "m"; cerr << "[error] Something bad :-(" << endl; cerr << (char)0x1B << "[" << 0 << ";" << 37 << ";" << 40 << "m"; // Reset, fg white, bg black */ http://www.linuxjournal.com/article/8603
Zřetězení stringu s charem
const string operator+(const string& str, const char ch) { char tmp[2] = { ch, '\0' }; return str + tmp; }
Přesměrování streamu
#include <iostream> #include <fstream> using namespace std; int main () { streambuf *psbuf; ofstream filestr; filestr.open ("test.txt"); psbuf = filestr.rdbuf(); cout.rdbuf(psbuf); cout << "This is written to the file" << endl; filestr.close(); return 0; } http://www.cplusplus.com/ref/iostream/ios/rdbuf.html
Převody čísel mezi soustavami
#include <cstdlib> strtoul()
stringstream
#include <sstream> string GetString(void) { stringstream ss; ss << "Klasicky" << "vystup" << " do " << "streamu"; return ss.str(); }
Spuštění preprocesoru nad zdrojovým kódem
g++ -E soubor.cpp -std=c++98 -pedantic -Wall > preprocesovany.cpp
Formátování data a času v C++
#include <ctime> string GenerateFilename() { time_t rawtime; struct tm* timeinfo; char buffer[80]; time(&rawtime); timeinfo = localtime(&rawtime); // transfered_YYYY-MM-DD_HH-MM-SS.dat strftime(buffer, 80, "transfered_%Y-%m-%d_%H-%M-%S.dat", timeinfo); return buffer; }
Mapování signálů
#include <signal.h> void sigint_handler(int param) { cout << "ctrl+c pressed." << endl; } int main(int argc, char* argv[]) { signal(SIGINT, sigint_handler); while(true) ; }
Přeložení projektu z příkazové řádky (VC 2500)
"C:\Program Files\Microsoft Visual Studio 8\VC\bin\vcvars32.bat" devenv solution.sln /Rebuild debug devenv solution.sln /Rebuild release
Převedení řetězce na malá písmena
#include <string> #include <algorithm> string str = "Ahoj"; transform(str.begin(), str.end(), str.begin(), (int(*)(int))tolower);
Seřazení pole
#include <vector> #include <algorithm> bool CompareImages(const CImage& img1, const CImage& img2) { return img1.GetPath() < img2.GetPath(); } vector<CImage> v; sort(v.begin(), v.end(), CompareImages);
Výpis souborů v adresáři
#include <dirent.h> void ListDirectory(const string& path) { DIR* handle = NULL; dirent* entry = NULL; if((handle = opendir(path.c_str())) == NULL) throw runtime_error(_("Couldn't open directory: ") + path); while((entry = readdir(handle)) != NULL) cout << entry->d_name << endl; closedir(handle); }
Knihovny používané programem
[woq@woq sbkview]$ ldd sbkview linux-gate.so.1 => (0xffffe000) libSDL-1.2.so.0 => /usr/lib/libSDL-1.2.so.0 (0xb7ed1000) libSDL_image-1.2.so.0 => /usr/lib/libSDL_image-1.2.so.0 (0xb7eb6000) libSDL_ttf-2.0.so.0 => /usr/lib/libSDL_ttf-2.0.so.0 (0xb7eb1000) libSDL_gfx.so.4 => /usr/lib/libSDL_gfx.so.4 (0xb7e9f000) libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xb7dba000) libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0xb7d94000) libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb7d89000) libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7c58000) libasound.so.2 => /usr/lib/libasound.so.2 (0xb7b97000) libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7b93000) libdirectfb-0.9.so.25 => /usr/lib/libdirectfb-0.9.so.25 (0xb7b3c000) libfusion-0.9.so.25 => /usr/lib/libfusion-0.9.so.25 (0xb7b35000) libdirect-0.9.so.25 => /usr/lib/libdirect-0.9.so.25 (0xb7b26000) libvga.so.1 => /usr/lib/libvga.so.1 (0xb7ac6000) libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0xb7ab4000) libpng12.so.0 => /usr/lib/libpng12.so.0 (0xb7a91000) libz.so.1 => /usr/lib/libz.so.1 (0xb7a7d000) libfreetype.so.6 => /usr/lib/libfreetype.so.6 (0xb7a12000) /lib/ld-linux.so.2 (0xb7f9f000) [woq@woq sbkview]$
Tabulka symbolů programu
[woq@woq serialkas]$ nm kas U __assert_fail@@GLIBC_2.0 0804db08 A __bss_start 08049014 t call_gmon_start 0804dd00 b completed.5621 0804d96c d __CTOR_END__ 0804d95c d __CTOR_LIST__ U __cxa_atexit@@GLIBC_2.1.3 U __cxa_begin_catch@@CXXABI_1.3 U __cxa_call_unexpected@@CXXABI_1.3 U __cxa_end_catch@@CXXABI_1.3 U __cxa_rethrow@@CXXABI_1.3 0804dafc W data_start 0804dafc D __data_start 0804bd30 t __do_global_ctors_aux 08049040 t __do_global_dtors_aux 0804db00 D __dso_handle 0804d974 d __DTOR_END__ 0804d970 d __DTOR_LIST__ 0804d97c d _DYNAMIC 0804db08 A _edata ...
Memory leaks indicator
// Enable-disable the checking #define CHECK_MEMORY_LEAKS #ifdef CHECK_MEMORY_LEAKS #include <set> #include <typeinfo> #endif // CHECK_MEMORY_LEAKS // Base class of the class hierarchy class BaseObject { public: BaseObject(); virtual ~BaseObject(); virtual string toString(void) const = 0; uint getID(void) const { return m_id; } static uint getMaxID(void) { return m_max_id; } private: static uint m_max_id; uint m_id; #ifdef CHECK_MEMORY_LEAKS static set<BaseObject*> m_allocated_objects; public: static void printMemoryLeaks(void); #endif // CHECK_MEMORY_LEAKS }; ///////////////////////////////////////////////////////////////////////////// //// uint BaseObject::m_max_id = 0; #ifdef CHECK_MEMORY_LEAKS set<BaseObject*> BaseObject::m_allocated_objects = set<BaseObject*>(); #endif // CHECK_MEMORY_LEAKS ///////////////////////////////////////////////////////////////////////////// //// BaseObject::BaseObject() : m_id(m_max_id++) { #ifdef CHECK_MEMORY_LEAKS m_allocated_objects.insert(this); #endif // CHECK_MEMORY_LEAKS } BaseObject::~BaseObject() { #ifdef CHECK_MEMORY_LEAKS m_allocated_objects.erase(this); #endif // CHECK_MEMORY_LEAKS } ///////////////////////////////////////////////////////////////////////////// //// #ifdef CHECK_MEMORY_LEAKS void BaseObject::printMemoryLeaks(void) { cerr << "================== BaseObject::printMemoryLeaks(void) ==================" << endl; set<BaseObject*>::const_iterator it; for(it = m_allocated_objects.begin(); it != m_allocated_objects.end(); it++) cerr << "id = " << (*it)->getID() << ", type = " << typeid(**it).name() << ", tostring = " << (*it)->toString() << ", mem = " << *it << endl; cerr << endl; cerr << "Total number of memory leaks: " << m_allocated_objects.size() << endl; } #endif // CHECK_MEMORY_LEAKS int main(int argc, char** argv) { // ... #ifdef CHECK_MEMORY_LEAKS BaseObject::printMemoryLeaks(); #endif // CHECK_MEMORY_LEAKS cout << "Total number of created objects: " << BaseObject::getMaxID() << endl; return 0; }
Unit tests, verify macro
// TODO: check __STRING(expr) in non-Linux OS, see /usr/include/assert.h // TODO: Try to use VERIFY() from MFC in MS Windows // Verify macro, like assert but without exiting #define verify(expr) \ result = result && (expr); \ if(!(expr)) \ cerr << __FILE__ << ":" << __LINE__ \ << " " << __STRING(expr) << endl // Test template bool Tests::test(void) { bool result = true; // Add code here verify(true); return testResult(__FUNCTION__, result); } bool Tests::testResult(const string& testName, bool result) { if(result) cout << _("[ OK ] ") << testName << endl; else cerr << _("[ FAILED ] ") << testName << endl; return result; } void Tests::run(void) { uint failed = 0; failed += !test(); cout << _("Number of failed tests: ") << failed << endl; }
Paralelní build
# Dva procesory alias make='colormake -j2'
Trace makro
#define TRACE(arg) cout << #arg << endl; arg #define D(arg) cout << #arg " = [" << arg << "]" << endl; // Použití TRACE(for(int i = 0; i < 5; i++) cout << i << endl;); D(1 + 2); // Výstup programu for(int i = 0; i < 5; i++) cout << i << endl; 0 1 2 3 4 1 + 2 = [3] (Bruce Eckel: Thinking in C++ 2)
Doxygen
doxywizard http://www-scf.usc.edu/~peterchd/doxygen/
Vyčištění kontejneru ukazatelů
struct DeleteObject { template <typename T> void operator()(const T* ptr) const { delete ptr; ptr = NULL; } }; for_each(v.begin(), v.end(), DeleteObject()); http://www-staff.it.uts.edu.au/~ypisan/programming/stl50.html
Mazání prvků z kontejneru
// Remove přesune hledaný prvek na konec c.erase(remove(c.begin(), c.end(), 2004), c.end()); http://www-staff.it.uts.edu.au/~ypisan/programming/stl50.html
Kontejner ukazatelů s řazením
struct DereferenceLess { template <typename PtrType> bool operator()(PtrType pT1, PtrType pT2) const { return *pT1 < *pT2; } }; set<string*, DereferenceLess> ssp; http://www-staff.it.uts.edu.au/~ypisan/programming/stl50.html
Dešifrování STL chyb z kompilátoru
http://www.bdsoft.com/tools/stlfilt.html
Detekce úniků paměti
valgrind --leak-check=yes <program>
Inicializace random generátoru
#include <time.h> srand(time(NULL));
Copyright © 2001-2011 Michal Turek <WOQ (zavináč) seznam.cz>
Valid XHTML 1.0 Strict, Valid CSS