Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
| Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
|
becki:linux:c [2010-11-08 14:21] becki |
becki:linux:c [2017-12-07 14:19] (aktuell) becki [Definition of constant Strings] |
||
|---|---|---|---|
| Zeile 2: | Zeile 2: | ||
| This is about ISO C and its standard library. POSIX/Linux enhancements and features are described in [[:becki:my:linux:linux programming]]. How to build applications is described in [[build tools]]. | This is about ISO C and its standard library. POSIX/Linux enhancements and features are described in [[:becki:my:linux:linux programming]]. How to build applications is described in [[build tools]]. | ||
| + | |||
| + | ===== CLI args and main() == | ||
| + | |||
| + | <code c> | ||
| + | int main(int argc, char **argv){ | ||
| + | char * progName= argv[0]; // Filename of programm itself | ||
| + | if (argc >= 2) char * firstArg= argv[1]; // First Argument | ||
| + | } | ||
| + | |||
| + | int main(void){} | ||
| + | // is also possible (Carm p.416) | ||
| + | // don't omit void! (Carm p.278) | ||
| + | </code> | ||
| + | |||
| + | ===== C Program Structure == | ||
| + | |||
| + | {{page>becki/my/linux/design_blog/2017-01-20_c_program_structure&noheader}} | ||
| + | |||
| + | ===== Position of Pointer Sign ====== | ||
| + | |||
| + | Some investigations: | ||
| + | <code c> | ||
| + | int main(int argc, char* argv[]) // Stroustrup p.126 | ||
| + | int main(int argc, char* argv[]) // Josuttis p.21 | ||
| + | int main(int argc, char* argv[], char *env[]) // (!) Breymann p.216 | ||
| + | int main(int argc, char *argv[]) // glibc reference | ||
| + | int main(int argc, char *argv[]) // Kernighan / Ritchie | ||
| + | int main(int argc, char *argv[]) // Harbison / Steele | ||
| + | int main(int argc, char **argv) // gtk reference | ||
| + | int main(int argc, char **argv) // qt reference | ||
| + | int main(int argc, char **argv) // fluxbox source | ||
| + | </code> | ||
| + | |||
| + | -> I use | ||
| + | <code c>char *cp</code> | ||
| + | because | ||
| + | - it seems to be more common | ||
| + | - declarations like "int a, *ap;" are possible | ||
| ===== Loops == | ===== Loops == | ||
| Zeile 38: | Zeile 76: | ||
| } | } | ||
| </code> | </code> | ||
| - | |||
| - | ===== CLI args and main() == | ||
| - | |||
| - | <code c> | ||
| - | int main(int argc, char **argv){ | ||
| - | char * progName= argv[0]; // Filename of programm itself | ||
| - | if (argc >= 2) char * firstArg= argv[1]; // First Argument | ||
| - | } | ||
| - | |||
| - | int main(void){} | ||
| - | // is also possible (Carm p.416) | ||
| - | // don't omit void! (Carm p.278) | ||
| - | </code> | ||
| - | |||
| - | ===== Position of Pointer Sign ====== | ||
| - | Some investigations: | ||
| - | <code c> | ||
| - | int main(int argc, char* argv[]) // Stroustrup p.126 | ||
| - | int main(int argc, char* argv[]) // Josuttis p.21 | ||
| - | int main(int argc, char* argv[], char *env[]) // (!) Breymann p.216 | ||
| - | int main(int argc, char *argv[]) // glibc reference | ||
| - | int main(int argc, char *argv[]) // Kernighan / Ritchie | ||
| - | int main(int argc, char *argv[]) // Harbison / Steele | ||
| - | int main(int argc, char **argv) // gtk reference | ||
| - | int main(int argc, char **argv) // qt reference | ||
| - | int main(int argc, char **argv) // fluxbox source | ||
| - | </code> | ||
| - | |||
| - | -> I use | ||
| - | <code c>char *cp</code> | ||
| - | because | ||
| - | - it seems to be more common | ||
| - | - declarations like "int a, *ap;" are possible | ||
| ===== Standard In- and Output == | ===== Standard In- and Output == | ||
| Zeile 85: | Zeile 90: | ||
| while (fgets(lin, MAX_LINE_LEN, stdin)) {/* do some thing */} | while (fgets(lin, MAX_LINE_LEN, stdin)) {/* do some thing */} | ||
| </code> | </code> | ||
| + | |||
| + | <note tip>If input line lenght is unknown, use ''getline()'' instead of ''fgets()''! | ||
| + | (See ''freesigs/io_modbus'')</note> | ||
| ''scanf'' can also be used for reading from ''stdin''. | ''scanf'' can also be used for reading from ''stdin''. | ||
| Zeile 103: | Zeile 111: | ||
| </code> | </code> | ||
| - | Writing to ''stderr'' is unbuffered, writing to ''stdout'' is buffered ((CARM p.351)) => Always use ''stderr'' for debugging messages ((RRUSP p.68)) | + | Writing to ''stderr'' is unbuffered, writing to ''stdout'' is buffered ((CARM p.351)) |
| + | ⇒ Always use ''stderr'' for debugging messages ((RRUSP p.68)) | ||
| ===== Constants ====== | ===== Constants ====== | ||
| Zeile 212: | Zeile 221: | ||
| [static] const char *mystring= "String" // false, needs 6 Bytes + Pointer | [static] const char *mystring= "String" // false, needs 6 Bytes + Pointer | ||
| </code> | </code> | ||
| + | |||
| * ''static'' to limit the scope for global strings. Not necessary inside a code block. | * ''static'' to limit the scope for global strings. Not necessary inside a code block. | ||
| * see also [[http://www.dclc-faq.de/kap2.htm|de.comp.lang.c FAQ]] -> Frage 2.2 / K&R p.101 / Carm p.124 | * see also [[http://www.dclc-faq.de/kap2.htm|de.comp.lang.c FAQ]] -> Frage 2.2 / K&R p.101 / Carm p.124 | ||
| + | * //Writable// strings must be declared as array (eg ''char a[]= "aff";'') not as pointer. See Carm p 32 | ||
| === Detailed Description == | === Detailed Description == | ||
| Zeile 374: | Zeile 385: | ||
| - Use another, smaller type when space is relevant (eg in ''struct'' definitions or large arrays) | - Use another, smaller type when space is relevant (eg in ''struct'' definitions or large arrays) | ||
| - Use a bigger type when the space in ''int'' is not sufficient | - Use a bigger type when the space in ''int'' is not sufficient | ||
| + | |||
| + | ===== Private Members in structs == | ||
| + | |||
| + | Any pointer type may be an incomplete type. This can be used to get private members in an object: | ||
| + | |||
| + | ==== Library Code == | ||
| + | |||
| + | <code c> | ||
| + | /* file: point-private.h */ | ||
| + | |||
| + | struct point { | ||
| + | int x; | ||
| + | int y; | ||
| + | }; | ||
| + | </code> | ||
| + | |||
| + | <code c> | ||
| + | /* file: point.c */ | ||
| + | #include <stdlib.h> | ||
| + | #include "point-private.h" | ||
| + | |||
| + | struct point * point_new(int x, int y) { | ||
| + | struct point *p= malloc(sizeof(struct point)); | ||
| + | p->x= x; | ||
| + | p->y= y; | ||
| + | return p; | ||
| + | } | ||
| + | |||
| + | int point_get_x(struct point *this) { | ||
| + | return this->x; | ||
| + | } | ||
| + | </code> | ||
| + | |||
| + | <code c> | ||
| + | /* file: point.h */ | ||
| + | |||
| + | struct point * point_new(int x, int y); | ||
| + | |||
| + | int point_get_x(struct point *this); | ||
| + | </code> | ||
| + | |||
| + | ==== Client Code == | ||
| + | |||
| + | <code c> | ||
| + | #include <stdio.h> | ||
| + | #include "point.h" | ||
| + | |||
| + | int main(void) { | ||
| + | struct point *p = point_new(7,4); | ||
| + | |||
| + | printf("x=%d\n", point_get_x(p)); | ||
| + | //printf("x=%d\n", p->x); // Error: incomplete type | ||
| + | |||
| + | return 0; | ||
| + | } | ||
| + | </code> | ||
| ===== Unsorted Tips == | ===== Unsorted Tips == | ||