Yao Lirong's Blog

C Manual

2021/08/31

大概是写这么多年 C(++) 以来第一次正式学 C (虽然其实在康奈尔学过一遍C++)

Compiling C Program

1
2
3
4
5
# compile hello.c and name the executable as default (a.out)
gcc hello.c

# compile hello.c and name the output executable "sayhello"
gcc hello.c -o sayhello

We usually write return 0, this exit code 0 means EXIT_SUCCESS.

Prototype Definition
prototype - declare a function (write down its name) definition - define a function (write down its content)
.h stand for “header” and it contains prototype of function .c stand for “code” and it contains definition of function

Complex & Custom Data Types

struct

1
2
3
4
5
struct rect_t {
int left;
... };

struct rect_t myRect;

typedef

The keyword typedef allows a programmer to create a new type.

1
2
struct _rect_t { ... };
typedef struct _rect_t rect_t;

Now we can create instance of the new type: (Note how this is different from a struct instance declaration)

1
2
3
rect_t myRect;
myRect.left = 1;
...

Strings

  • char *strstr(const char *haystack, const char *needle): finds the first occurrence of the substring needle in the string haystack.
  • sprintf(char *str, const char *format, ...): “prints out” formatted output to a string str, but instead of really printing them out, sprintf buffers the output to the string.(sprintf(str, "Pi = %f", 3.14); will set str to be Pi = 3.14)

Dynamic Memory Allocation

Consider the following program:

1
2
3
4
int * initArray(int howLarge) {
int myArray[howLarge];
for (int i = 0; i < howLarge; i++) myArray[i] = i;
return myArray; }

We cannot do this because the space allocated to myArray is only inside the scope of initArray and will be freed once we exit this function. So what we want is dynamic memory allocation so the memory will be allocated at a dynamic heap instead of the call stack.

1
2
3
int *p = malloc(6 * sizeof(int)); // memory allocation
p = realloc(p, 12 * sizeof(int)); // re-allocation
free(p);

We can then rewrite the above function as:

1
2
3
4
int * initArray(int howLarge) {
int *myArray = malloc(howLarge * sizeof(int));
for (int i = 0; i < howLarge; i++) myArray[i] = i;
return myArray; }

Note the following when you use free:

1
2
3
4
5
6
7
8
// you cannot free something on the stack
int x = 3; int *p = &x;
free(p); // early termination

// free can only be used to free address returned by malloc
int *p = malloc(4*sizeof(int));
p++;
free(p); // early termination

Debugging C in VSCode

  1. Install the extension “GDB Debugger - Beyond”

  2. Replace what’s in launch.json - configurations with the following codes:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    "configurations": [
    {
    "type": "by-gdb",
    "request": "launch",
    "name": "Launch(gdb)",
    "program": "${fileDirname}/${fileBasenameNoExtension}",
    "cwd": "${workspaceRoot}"
    }
    ]
CATALOG
  1. 1. Compiling C Program
  2. 2. Complex & Custom Data Types
    1. 2.1. struct
    2. 2.2. typedef
  3. 3. Strings
  4. 4. Dynamic Memory Allocation
  5. 5. Debugging C in VSCode