├── .gitignore ├── Chapter01 ├── array.c ├── array2.c ├── get_word.c ├── pointer.c └── pointer_calc.c ├── Chapter02 ├── alignmen.c ├── auto.c ├── byteorder.c ├── free.c ├── print_address.c ├── quick_sort.c ├── stackoverflow.c ├── tiny_printf.c └── vmtest.c ├── Chapter04 ├── array_argument.c ├── cat.c ├── output_argument.c ├── pass_2d_array.c ├── read_file.c ├── read_file_v2.c ├── read_line.c ├── read_line.h ├── read_line_v2.c ├── read_line_v2.h ├── read_slogan.c ├── realloc.c └── variable_array.c ├── Chapter05 ├── word_count_array │ ├── add_word.c │ ├── dump_word.c │ ├── finalize.c │ ├── get_word.c │ ├── get_word.h │ ├── initialize.c │ ├── main.c │ ├── word_manage.h │ └── word_manage_p.h ├── word_count_list │ ├── add_word.c │ ├── dump_word.c │ ├── finalize.c │ ├── get_word.c │ ├── get_word.h │ ├── initialize.c │ ├── main.c │ ├── word_manage.h │ └── word_manage_p.h └── x_draw │ ├── Shape.h │ └── draw_shape.c ├── Chapter06 ├── double.c └── float.c ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | modules.order 49 | Module.symvers 50 | Mkfile.old 51 | dkms.conf 52 | 53 | build 54 | -------------------------------------------------------------------------------- /Chapter01/array.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char *argv[]) { 4 | 5 | int array[5]; 6 | int i; 7 | 8 | /// 为数组 array 的各元素设值 9 | for (i = 0; i < 5; i++) { 10 | array[i] = i; 11 | } 12 | 13 | /// 输出数组各元素的值 14 | for (i = 0; i < 5; i++) { 15 | printf("%d\n", array[i]); 16 | } 17 | 18 | /// 输出数组各元素的值 19 | for (i = 0; i < 5; i++) { 20 | printf("&array[%d]... %p\n", i, &array[i]); 21 | } 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /Chapter01/array2.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char *argv[]) { 4 | 5 | int array[5]; 6 | int *p; 7 | int i; 8 | 9 | /// 为数组 array 的各元素设值 10 | for (i = 0; i < 5; i++) { 11 | array[i] = i; 12 | } 13 | 14 | /// 输出数组各元素的值(指针版) 15 | for (p = &array[0]; p != &array[5]; p++) { 16 | printf("%d\n", *p); 17 | } 18 | 19 | /// 利用指针输出数组各元素的值——改写版 20 | p = &array[0]; 21 | for (i = 0; i < 5; i++) { 22 | printf("%d\n", *(p + i)); 23 | } 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /Chapter01/get_word.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int get_word(char *buf, int buf_size, FILE *fp) { 6 | 7 | int len; 8 | int ch; 9 | 10 | /// 跳过读取空白字符 11 | while ((ch = getc(fp)) != EOF && !isalnum(ch)); 12 | 13 | if (ch == EOF) return EOF; 14 | 15 | /// 此时,ch 中保存了单词的初始字符。 16 | len = 0; 17 | do { 18 | buf[len] = ch; 19 | len++; 20 | if (len >= buf_size) { 21 | /// 由于单词太长,提示错误 22 | fprintf(stderr, "word too long.\n"); 23 | exit(1); 24 | } 25 | } while ((ch = getc(fp)) != EOF && isalnum(ch)); 26 | buf[len] = '\0'; 27 | 28 | return len; 29 | } 30 | 31 | int main(int argc, char *argv[]) { 32 | 33 | char buf[256]; 34 | 35 | while(get_word(buf, 256, stdin) != EOF) { 36 | printf("<<%s>>\n", buf); 37 | } 38 | 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /Chapter01/pointer.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char *argv[]) { 4 | 5 | int hoge = 5; 6 | int piyo = 10; 7 | int *hoge_p; 8 | 9 | /// 输出每个变量的地址 10 | printf("&hoge..%p\n", &hoge); 11 | printf("&piyo..%p\n", &piyo); 12 | printf("&hoge_p..%p\n", &hoge_p); 13 | 14 | /// 将 hoge 的地址赋予 hoge_p 15 | hoge_p = &hoge; 16 | printf("hoge_p..%p\n", hoge_p); 17 | 18 | /// 通过 hoge_p 输出 hoge 的内容 19 | printf("*hoge_p..%d\n", *hoge_p); 20 | 21 | /// 通过 hoge_p 修改 hoge 的内容 22 | *hoge_p = 10; 23 | printf("hoge..%d\n", hoge); 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /Chapter01/pointer_calc.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char *argv[]) { 4 | 5 | int hoge = 5; 6 | int *hoge_p; 7 | 8 | /// 将指向 hoge 的指针赋予 hoge_p 9 | hoge_p = & hoge; 10 | /// 输出 hoge_p 的值 11 | printf("hoge_p...%p\n", hoge_p); 12 | /// 给 hoge_p 加1 13 | hoge_p++; 14 | /// *输出 hoge_p 的值 15 | printf("hoge_p..%p\n", hoge_p); 16 | /// 输出 hoge_p 加3后的值 17 | printf("hoge_p..%p\n", hoge_p + 3); 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /Chapter02/alignmen.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef struct { 4 | int int1; 5 | double double1; 6 | char char1; 7 | double double2; 8 | } Hoge; 9 | 10 | int main(int argc, char *argv[]) { 11 | 12 | Hoge hoge; 13 | 14 | printf("hoge size..%lu\n", sizeof(Hoge)); 15 | printf("hoge ..%p\n", &hoge); 16 | printf("int1 ..%p\n", &hoge.int1); 17 | printf("double1..%p\n", &hoge.double1); 18 | printf("char1 ..%p\n", &hoge.char1); 19 | printf("double2..%p\n", &hoge.double2); 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /Chapter02/auto.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void func(int a, int b) { 4 | 5 | int c, d; 6 | 7 | printf("func:&a..%p &b..%p\n", &a, &b); 8 | printf("func:&c..%p &d..%p\n", &c, &d); 9 | } 10 | 11 | 12 | int main(int argc, char *argv[]) { 13 | 14 | int a, b; 15 | 16 | printf("main:&a..%p &b..%p\n", &a, &b); 17 | func(1, 2); 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /Chapter02/byteorder.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char *argv[]) { 4 | 5 | int hoge = 0x12345678; 6 | unsigned char *hoge_p = (unsigned char *)&hoge; 7 | printf("%x\n", hoge_p[0]); 8 | printf("%x\n", hoge_p[1]); 9 | printf("%x\n", hoge_p[2]); 10 | printf("%x\n", hoge_p[3]); 11 | 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter02/free.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | int main(int argc, char *argv[]) { 6 | 7 | int *int_p; 8 | 9 | int_p = malloc(sizeof(int)); 10 | 11 | *int_p = 12345; 12 | 13 | free(int_p); 14 | 15 | printf("*int_p..%d\n", *int_p); 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /Chapter02/print_address.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int global_variable; 5 | static int file_static_variable; 6 | 7 | void func1(void) { 8 | 9 | int func1_variable; 10 | static int func1_static_variable; 11 | 12 | printf("&func1_variable..%p\n", &func1_variable); 13 | printf("&func1_static_variable..%p\n", &func1_static_variable); 14 | 15 | } 16 | 17 | void func2(void) { 18 | 19 | int func2_variable; 20 | printf("&func2_variable..%p\n", &func2_variable); 21 | 22 | } 23 | 24 | int main(int argc, char *argv[]) { 25 | 26 | int *p; 27 | 28 | /// 输出指向函数的指针 29 | printf("&func1..%p\n", func1); 30 | printf("&func2..%p\n", func2); 31 | 32 | /// 输出字符串常量的地址 33 | printf("string literal..%p\n", "abc"); 34 | 35 | /// 输出全局变量 36 | printf("&global_variable..%p\n", &global_variable); 37 | 38 | /// 输出文件内的static变量的地址 39 | printf("&file_static_variable..%p\n", &file_static_variable); 40 | 41 | /// 输出局部变量 42 | func1(); 43 | func2(); 44 | 45 | /// 通过malloc申请的内存区域的地址 46 | p = malloc(sizeof(int)); 47 | printf("malloc address..%p\n", p); 48 | 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /Chapter02/quick_sort.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define SWAP(a, b) {int temp; temp = a; a = b; b = temp;} 4 | 5 | void quick_sort_sub(int *data, int left, int right) { 6 | 7 | int left_index = left; 8 | int right_index = right; 9 | int pivot = data[(left + right) / 2]; 10 | 11 | while (left_index <= right_index) { 12 | for (; data[left_index] < pivot; left_index++) ; 13 | for (; data[right_index] > pivot; right_index--) ; 14 | 15 | if (left_index <= right_index) { 16 | SWAP(data[left_index], data[right_index]); 17 | left_index++; 18 | right_index--; 19 | } 20 | } 21 | 22 | if (right_index > left) { 23 | quick_sort_sub(data, left, right_index); 24 | } 25 | if (left_index < right) { 26 | quick_sort_sub(data, left_index, right); 27 | } 28 | } 29 | 30 | void quick_sort(int *data, int data_size) { 31 | printf("befor: [ "); 32 | for (int i = 0; i < data_size; i++) { 33 | printf(" %d ", data[i]); 34 | } 35 | printf(" ]\n"); 36 | 37 | quick_sort_sub(data, 0, data_size - 1); 38 | 39 | printf("after: [ "); 40 | for (int i = 0; i < data_size; i++) { 41 | printf(" %d ", data[i]); 42 | } 43 | printf(" ]\n"); 44 | } 45 | 46 | int main(int argc, char *argv[]) { 47 | 48 | int data[] = { 10, 2, 23, 15, 15, 0, 4, 30, 20, 10 }; 49 | 50 | quick_sort(data, 10); 51 | 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /Chapter02/stackoverflow.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void hello(void) { 4 | 5 | fprintf(stderr, "hello!\n"); 6 | 7 | } 8 | 9 | void func(void) { 10 | 11 | void *buf[10]; 12 | static int i; 13 | 14 | for (i = 0; i < 100; i++) { 15 | buf[i] = hello; 16 | } 17 | } 18 | 19 | 20 | int main(int argc, char *argv[]) { 21 | 22 | int buf[1000]; 23 | 24 | func(); 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /Chapter02/tiny_printf.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void tiny_printf(char *format, ...) { 6 | 7 | int i; 8 | va_list ap; 9 | 10 | va_start(ap, format); 11 | for (i = 0; format[i] != '\0'; i++) { 12 | switch (format[i]) { 13 | case 's': 14 | printf("%s ", va_arg(ap, char *)); 15 | break; 16 | case 'd': 17 | printf("%d ", va_arg(ap, int)); 18 | break; 19 | default: 20 | assert(0); 21 | } 22 | } 23 | va_end(ap); 24 | putchar('\n'); 25 | } 26 | 27 | int main(int argc, char *argv[]) { 28 | 29 | tiny_printf("sdd", "result..", 3, 5); 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /Chapter02/vmtest.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char *argv[]) { 4 | 5 | int hoge; 6 | char buf[256]; 7 | 8 | printf("&hoge..%p\n", &hoge); 9 | 10 | printf("Input initial value.\n"); 11 | fgets(buf, sizeof(buf), stdin); 12 | sscanf(buf, "%d", &hoge); 13 | 14 | for (;;) { 15 | printf("hoge..%d\n", hoge); 16 | /* 17 | * getchar()让控制台处于等待输入的状态 18 | * 每次敲入回车键,增加hoge的值 19 | */ 20 | getchar(); 21 | hoge++; 22 | } 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /Chapter04/array_argument.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void func(int *array, int size) { 4 | 5 | int i; 6 | 7 | for (i = 0; i < size; i++) { 8 | printf("array[%d]..%d\n", i, array[i]); 9 | } 10 | } 11 | 12 | int main(int argc, char *argv[]) { 13 | 14 | int array[] = {1, 2, 3, 4 , 5}; 15 | 16 | func(array, sizeof(array) / sizeof(int)); 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /Chapter04/cat.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void type_one_file(FILE *fp) 5 | { 6 | int ch; 7 | while ((ch = getc(fp)) != EOF) { 8 | putchar(ch); 9 | } 10 | } 11 | 12 | int main(int argc, char *argv[]) 13 | { 14 | if (argc == 1) { 15 | type_one_file(stdin); 16 | } else { 17 | int i; 18 | FILE *fp; 19 | 20 | for (i = 1; i < argc; i++) { 21 | fp = fopen(argv[i], "rb"); 22 | if (fp == NULL) { 23 | fprintf(stderr, "%s:%s can not open\n", argv[0], argv[i]); 24 | exit(1); 25 | } 26 | type_one_file(fp); 27 | fclose(fp); 28 | } 29 | } 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /Chapter04/output_argument.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void func(int *a, double *b) 4 | { 5 | *a = 5; 6 | *b = 3.5; 7 | } 8 | 9 | int main(int argc, char *argv[]) 10 | { 11 | int a; 12 | double b; 13 | 14 | func(&a, &b); 15 | 16 | printf("a..%d b..%f\n", a, b); 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /Chapter04/pass_2d_array.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void func(int (*hoge)[3]) 4 | { 5 | int i, j; 6 | 7 | for (i = 0; i < 4; i++) { 8 | for (j = 0; j < 3; j++) { 9 | printf("%d, ", hoge[i][j]); 10 | } 11 | putchar('\n'); 12 | } 13 | } 14 | 15 | int main(int argc, char *argv[]) 16 | { 17 | int hoge[][3] = { 18 | {1, 2, 3}, 19 | {4, 5, 6}, 20 | {7, 8, 9}, 21 | {10, 11, 12}, 22 | }; 23 | 24 | func(hoge); 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /Chapter04/read_file.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define ALLOC_SIZE (256) 6 | #include "read_line.h" 7 | 8 | char **add_line(char **text_data, char *line, int *line_alloc_num, int *line_num) 9 | { 10 | assert(*line_alloc_num >= *line_num); 11 | if (*line_alloc_num >= *line_num) { 12 | text_data = realloc(text_data, (*line_alloc_num + ALLOC_SIZE) * sizeof(char*)); 13 | *line_alloc_num += ALLOC_SIZE; 14 | } 15 | text_data[*line_num] = line; 16 | (*line_num)++; 17 | 18 | return text_data; 19 | } 20 | 21 | char **read_file(FILE *fp, int *line_num_p) 22 | { 23 | char **text_data = NULL; 24 | int line_num = 0; 25 | int line_alloc_num = 0; 26 | char *line; 27 | 28 | while ((line = read_line(fp)) != NULL) { 29 | text_data = add_line(text_data, line, &line_alloc_num, &line_num); 30 | } 31 | 32 | /// 将 text_data 缩小到实际需要的大小 33 | text_data = realloc(text_data, line_num * sizeof(char*)); 34 | *line_num_p = line_num; 35 | 36 | return text_data; 37 | } 38 | 39 | int main(int argc, char *argv[]) 40 | { 41 | char **text_data; 42 | int line_num; 43 | int i; 44 | 45 | text_data = read_file(stdin, &line_num); 46 | 47 | for (i = 0; i < line_num; i++) { 48 | printf("%s\n", text_data[i]); 49 | } 50 | 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /Chapter04/read_file_v2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define ALLOC_SIZE (256) 6 | #include "read_line_v2.h" 7 | 8 | char **add_line(char **text_data, char *line, int *line_alloc_num, int *line_num) 9 | { 10 | assert(*line_alloc_num >= *line_num); 11 | if (*line_alloc_num >= *line_num) { 12 | text_data = realloc(text_data, (*line_alloc_num + ALLOC_SIZE) * sizeof(char*)); 13 | *line_alloc_num += ALLOC_SIZE; 14 | } 15 | text_data[*line_num] = line; 16 | (*line_num)++; 17 | 18 | return text_data; 19 | } 20 | 21 | char **read_file(FILE *fp, int *line_num_p) 22 | { 23 | char **text_data = NULL; 24 | int line_num = 0; 25 | int line_alloc_num = 0; 26 | char *line; 27 | 28 | while (read_line(fp, &line) != READ_LINE_EOF) { 29 | text_data = add_line(text_data, line, &line_alloc_num, &line_num); 30 | } 31 | 32 | /// 将 text_data 缩小到实际需要的大小 33 | text_data = realloc(text_data, line_num * sizeof(char*)); 34 | *line_num_p = line_num; 35 | 36 | return text_data; 37 | } 38 | 39 | int main(int argc, char *argv[]) 40 | { 41 | char **text_data; 42 | int line_num; 43 | int i; 44 | 45 | text_data = read_file(stdin, &line_num); 46 | 47 | printf("read_file_v2: \n"); 48 | 49 | for (i = 0; i < line_num; i++) { 50 | printf("%s\n", text_data[i]); 51 | } 52 | 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /Chapter04/read_line.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #define ALLOC_SIZE (256) 6 | 7 | /// 读取行的缓冲,必要时进行扩展。但是区域不会被缩小。调用 free_buffer() 释放。 8 | static char *st_line_buffer = NULL; 9 | 10 | /// 在 st_line_buffer 前方被分配的内存区域的大小。 11 | static int st_current_buffer_size = 0; 12 | 13 | /// st_line_buffer 中现在保存的字符的大小。 14 | static int st_current_used_size = 0; 15 | 16 | /* 17 | * 如有必要,扩展 st_line_buffer 前方的内存区域。 18 | * 在 st_line_buffer 末尾追加一个字符。 19 | */ 20 | static void add_character(int ch) 21 | { 22 | /// 此函数每次被调用,st_current_used_size都必定会增加1,正常的情况下,下面的断言肯定不会出错。 23 | assert(st_current_buffer_size >= st_current_used_size); 24 | 25 | /// st_current_used_size达到st_current_buffer_size的时候,扩展缓冲区的内存区域。 26 | if (st_current_buffer_size == st_current_used_size) { 27 | st_line_buffer = realloc(st_line_buffer, (st_current_buffer_size + ALLOC_SIZE) * sizeof(char)); 28 | st_current_buffer_size += ALLOC_SIZE; 29 | } 30 | /// 在缓冲区末尾追加一个字符 31 | st_line_buffer[st_current_used_size] = ch; 32 | st_current_used_size++; 33 | } 34 | 35 | /* 36 | * 从fp读取一行字符,一旦读到文件末尾,就返回NULL。 37 | */ 38 | char *read_line(FILE *fp) 39 | { 40 | int ch; 41 | char *ret; 42 | 43 | st_current_used_size = 0; 44 | while ((ch = getc(fp)) != EOF) { 45 | if (ch == '\n') { 46 | add_character('\0'); 47 | break; 48 | } 49 | add_character(ch); 50 | } 51 | if (ch == EOF) { 52 | if (st_current_used_size > 0) { 53 | add_character('\0'); 54 | } else { 55 | return NULL; 56 | } 57 | } 58 | 59 | ret = malloc(sizeof(char) * st_current_used_size); 60 | strcpy(ret, st_line_buffer); 61 | 62 | return ret; 63 | } 64 | 65 | /* 66 | * 释放缓冲区内存。其实即使不调用这个函数也不会有什么问题, 67 | * 但对于那些抱有“程序结束时,最好使用free()释放掉malloc()分配的内存区域”这种想法的人, 68 | * 可以调用这个函数。 69 | */ 70 | 71 | void free_buffer(void) 72 | { 73 | free(st_line_buffer); 74 | st_line_buffer = NULL; 75 | st_current_buffer_size = 0; 76 | st_current_used_size = 0; 77 | } 78 | -------------------------------------------------------------------------------- /Chapter04/read_line.h: -------------------------------------------------------------------------------- 1 | #ifndef READ_LINE_H_INCLUDED 2 | #define READ_LINE_H_INCLUDED 3 | 4 | #include 5 | 6 | char *read_line(FILE *fp); 7 | void free_buffer(void); 8 | 9 | #endif /* READ_LINE_H_INCLUDED */ 10 | -------------------------------------------------------------------------------- /Chapter04/read_line_v2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "read_line_v2.h" 6 | #define ALLOC_SIZE (256) 7 | 8 | /// 读取行的缓冲,必要时进行扩展。但是区域不会被缩小。调用 free_buffer() 释放。 9 | static char *st_line_buffer = NULL; 10 | 11 | /// 在 st_line_buffer 前方被分配的内存区域的大小。 12 | static int st_current_buffer_size = 0; 13 | 14 | /// st_line_buffer 中现在保存的字符的大小。 15 | static int st_current_used_size = 0; 16 | 17 | /* 18 | * 如有必要,扩展 st_line_buffer 前方的内存区域。 19 | * 在 st_line_buffer 末尾追加一个字符。 20 | */ 21 | static ReadLineStatus add_character(int ch) 22 | { 23 | /// 此函数每次被调用,st_current_used_size都必定会增加1,正常的情况下,下面的断言肯定不会出错。 24 | assert(st_current_buffer_size >= st_current_used_size); 25 | 26 | /// st_current_used_size达到st_current_buffer_size的时候,扩展缓冲区的内存区域。 27 | if (st_current_buffer_size == st_current_used_size) { 28 | char *temp; 29 | temp = realloc(st_line_buffer, (st_current_buffer_size + ALLOC_SIZE) * sizeof(char)); 30 | if (temp == NULL) { 31 | return READ_LINE_OUT_OF_MEMORY; 32 | } 33 | st_line_buffer = temp; 34 | st_current_buffer_size += ALLOC_SIZE; 35 | } 36 | /// 在缓冲区末尾追加一个字符 37 | st_line_buffer[st_current_used_size] = ch; 38 | st_current_used_size++; 39 | 40 | return READ_LINE_SUCCESS; 41 | } 42 | 43 | /* 44 | * 从fp读取一行字符,一旦读到文件末尾,就返回NULL。 45 | */ 46 | ReadLineStatus read_line(FILE *fp, char **line) 47 | { 48 | int ch; 49 | ReadLineStatus status = READ_LINE_SUCCESS; 50 | 51 | st_current_used_size = 0; 52 | while ((ch = getc(fp)) != EOF) { 53 | if (ch == '\n') { 54 | add_character('\0'); 55 | if (status != READ_LINE_SUCCESS) { 56 | goto FUNC_END; 57 | } 58 | break; 59 | } 60 | add_character(ch); 61 | if (status != READ_LINE_SUCCESS) { 62 | goto FUNC_END; 63 | } 64 | } 65 | if (ch == EOF) { 66 | if (st_current_used_size > 0) { 67 | status = add_character('\0'); 68 | if (status != READ_LINE_SUCCESS) { 69 | goto FUNC_END; 70 | } 71 | } else { 72 | status = READ_LINE_EOF; 73 | goto FUNC_END; 74 | } 75 | } 76 | 77 | *line = malloc(sizeof(char) * st_current_used_size); 78 | if (*line == NULL) { 79 | status = READ_LINE_OUT_OF_MEMORY; 80 | goto FUNC_END; 81 | } 82 | strcpy(*line, st_line_buffer); 83 | 84 | FUNC_END: 85 | if (status != READ_LINE_SUCCESS && status != READ_LINE_EOF) { 86 | free_buffer(); 87 | } 88 | return status; 89 | } 90 | 91 | /* 92 | * 释放缓冲区内存。其实即使不调用这个函数也不会有什么问题, 93 | * 但对于那些抱有“程序结束时,最好使用free()释放掉malloc()分配的内存区域”这种想法的人, 94 | * 可以调用这个函数。 95 | */ 96 | 97 | void free_buffer(void) 98 | { 99 | free(st_line_buffer); 100 | st_line_buffer = NULL; 101 | st_current_buffer_size = 0; 102 | st_current_used_size = 0; 103 | } 104 | -------------------------------------------------------------------------------- /Chapter04/read_line_v2.h: -------------------------------------------------------------------------------- 1 | #ifndef READ_LINE_H_INCLUDED 2 | #define READ_LINE_H_INCLUDED 3 | 4 | #include 5 | 6 | typedef enum { 7 | READ_LINE_SUCCESS, /// 正常地读取了1行 8 | READ_LINE_EOF, /// 读到了文件的末尾 9 | READ_LINE_OUT_OF_MEMORY /// 内存不足导致处理失败 10 | } ReadLineStatus; 11 | 12 | ReadLineStatus read_line(FILE *fp, char **line); 13 | void free_buffer(void); 14 | 15 | #endif /* READ_LINE_H_INCLUDED */ 16 | -------------------------------------------------------------------------------- /Chapter04/read_slogan.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void read_slogan(FILE *fp, char **slogan) 6 | { 7 | char buf[1024]; 8 | int i; 9 | 10 | for (i = 0; i < 7; i++) { 11 | fgets(buf, 1024, fp); 12 | 13 | /// 删除换行字符 14 | buf[strlen(buf)-1] = '\0'; 15 | 16 | /// 分配保存一个标语的内存空间 17 | slogan[i] = malloc(sizeof(char) * (strlen(buf)+1)); 18 | 19 | /// 复制标语的内容 20 | strcpy(slogan[i], buf); 21 | } 22 | } 23 | 24 | int main(int argc, char *argv[]) 25 | { 26 | char *slogan[7]; 27 | int i; 28 | 29 | read_slogan(stdin, slogan); 30 | 31 | /// 输出读取的标语 32 | for(i = 0; i < 7; i++) { 33 | printf("%s\n", slogan[i]); 34 | } 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /Chapter04/realloc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | int *variable_array = NULL; 7 | int size = 0; 8 | char buf[256]; 9 | int i; 10 | 11 | while (fgets(buf, 256, stdin) != NULL) { 12 | size++; 13 | variable_array = realloc(variable_array, sizeof(int) * size); 14 | sscanf(buf, "%d", &variable_array[size-1]); 15 | } 16 | 17 | for (i = 0; i < size; i++) { 18 | printf("variable_array[%d]..%d\n", i, variable_array[i]); 19 | } 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /Chapter04/variable_array.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | char buf[256]; 7 | int size; 8 | int *variable_array; 9 | int i; 10 | 11 | printf("Input array size>"); 12 | fgets(buf, 256, stdin); 13 | sscanf(buf, "%d", &size); 14 | 15 | variable_array = malloc(sizeof(int) * size); 16 | 17 | for (i = 0; i < size; i++) { 18 | variable_array[i] = i; 19 | } 20 | for (i = 0; i < size; i++) { 21 | printf("variable_array[%d]..%d\n", i, variable_array[i]); 22 | } 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /Chapter05/word_count_array/add_word.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "word_manage_p.h" 5 | 6 | /// 将index后面的元素(包括index)依次向后方移动 7 | static void shift_array(int index) 8 | { 9 | int src; /// 被复制元素的索引 10 | 11 | for (src = num_of_word - 1; src >= index; src--) { 12 | word_array[src+1] = word_array[src]; 13 | } 14 | num_of_word++; 15 | } 16 | 17 | /// 复制字符串 18 | static char *my_strdup(char *src) 19 | { 20 | char *dest; 21 | 22 | dest = malloc(sizeof(char) * (strlen(src) + 1)); 23 | strcpy(dest, src); 24 | 25 | return dest; 26 | } 27 | 28 | /********************************************************* 29 | * 追加单词 30 | *********************************************************/ 31 | void add_word(char *word) 32 | { 33 | int i; 34 | int result; 35 | 36 | for(i = 0; i < num_of_word; i++) { 37 | result = strcmp(word_array[i].name, word); 38 | if (result >= 0) { 39 | break; 40 | } 41 | } 42 | 43 | if (num_of_word != 0 && result == 0) { 44 | /// 发现相同的单词 45 | word_array[i].count++; 46 | } else { 47 | shift_array(i); 48 | word_array[i].name = my_strdup(word); 49 | word_array[i].count = 1; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Chapter05/word_count_array/dump_word.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "word_manage_p.h" 3 | 4 | /********************************************************* 5 | * 输出单词的出现频率 6 | *********************************************************/ 7 | 8 | void dump_word(FILE *fp) 9 | { 10 | int i; 11 | 12 | for (i = 0; i < num_of_word; i++) { 13 | fprintf(fp, "%-20s%5d\n", word_array[i].name, word_array[i].count); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /Chapter05/word_count_array/finalize.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "word_manage_p.h" 3 | 4 | /********************************************************* 5 | * 管理单词部分的结束处理 6 | *********************************************************/ 7 | 8 | void word_finalize(void) 9 | { 10 | int i; 11 | 12 | /// 释放单词部分的内存区域 13 | for (i = 0; i < num_of_word; i++) { 14 | free(word_array[i].name); 15 | } 16 | 17 | num_of_word = 0; 18 | } 19 | -------------------------------------------------------------------------------- /Chapter05/word_count_array/get_word.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int get_word(char *buf, int size, FILE *stream) { 6 | 7 | int len; 8 | int ch; 9 | 10 | /// 跳过读取空白字符 11 | while ((ch = getc(stream)) != EOF && !isalnum(ch)); 12 | 13 | if (ch == EOF) return EOF; 14 | 15 | /// 此时,ch 中保存了单词的初始字符。 16 | len = 0; 17 | do { 18 | buf[len] = ch; 19 | len++; 20 | if (len >= size) { 21 | /// 由于单词太长,提示错误 22 | fprintf(stderr, "word too long.\n"); 23 | exit(1); 24 | } 25 | } while ((ch = getc(stream)) != EOF && isalnum(ch)); 26 | buf[len] = '\0'; 27 | 28 | return len; 29 | } 30 | -------------------------------------------------------------------------------- /Chapter05/word_count_array/get_word.h: -------------------------------------------------------------------------------- 1 | #ifndef GET_WORD_H_INCLUDED 2 | #define GET_WORD_H_INCLUDED 3 | #include 4 | 5 | int get_word(char *buf, int size, FILE *stream); 6 | 7 | #endif /* GET_WORD_H_INCLUDED */ 8 | -------------------------------------------------------------------------------- /Chapter05/word_count_array/initialize.c: -------------------------------------------------------------------------------- 1 | #include "word_manage_p.h" 2 | 3 | Word word_array[WORD_NUM_MAX]; 4 | int num_of_word; 5 | 6 | /************************************************************ 7 | * 初始化管理单词部分 8 | ************************************************************/ 9 | 10 | void word_initialize(void) 11 | { 12 | num_of_word = 0; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter05/word_count_array/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "get_word.h" 4 | #include "word_manage.h" 5 | 6 | #define WORD_LEN_MAX (1024) 7 | 8 | int main(int argc, char *argv[]) 9 | { 10 | char buf[WORD_LEN_MAX]; 11 | FILE *fp; 12 | 13 | if (argc == 1) { 14 | fp = stdin; 15 | } else { 16 | fp = fopen(argv[1], "r"); 17 | if (fp == NULL) { 18 | fprintf(stderr, "%s:%s can not open.\n",argv[0], argv[1]); 19 | exit(1); 20 | } 21 | } 22 | 23 | /// 初始化“管理单词部分” 24 | word_initialize(); 25 | 26 | /// 边读取文件,边加入单词 27 | while (get_word(buf, WORD_LEN_MAX, fp) != EOF) { 28 | add_word(buf); 29 | } 30 | 31 | /// 输出单词的出现频率 32 | dump_word(stdout); 33 | 34 | /// “管理单词部分”的结束处理 35 | word_finalize(); 36 | 37 | return 0; 38 | } -------------------------------------------------------------------------------- /Chapter05/word_count_array/word_manage.h: -------------------------------------------------------------------------------- 1 | #ifndef WORD_MANAGE_H_INCLUDED 2 | #define WORD_MANAGE_H_INCLUDED 3 | #include 4 | 5 | void word_initialize(void); 6 | void add_word(char *word); 7 | void dump_word(FILE *fp); 8 | void word_finalize(void); 9 | 10 | #endif /* WORD_MANAGE_H_INCLUDED */ 11 | -------------------------------------------------------------------------------- /Chapter05/word_count_array/word_manage_p.h: -------------------------------------------------------------------------------- 1 | #ifndef WORD_MANAGE_P_H_INCLUDED 2 | #define WORD_MANAGE_P_H_INCLUDED 3 | #include "word_manage.h" 4 | 5 | typedef struct { 6 | char *name; 7 | int count; 8 | } Word; 9 | 10 | #define WORD_NUM_MAX (1000) 11 | 12 | extern Word word_array[]; 13 | extern int num_of_word; 14 | 15 | #endif /* WORD_MANAGE_P_H_INCLUDED */ 16 | -------------------------------------------------------------------------------- /Chapter05/word_count_list/add_word.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "word_manage_p.h" 5 | 6 | /// 复制字符串 7 | static char *my_strdup(char *src) 8 | { 9 | char *dest; 10 | 11 | dest = malloc(sizeof(char) * (strlen(src) + 1)); 12 | strcpy(dest, src); 13 | 14 | return dest; 15 | } 16 | 17 | /// 生成新的Word结构体 18 | static Word *create_word(char *name) 19 | { 20 | Word *new_word; 21 | 22 | new_word = malloc(sizeof(Word)); 23 | 24 | new_word->name = my_strdup(name); 25 | new_word->count = 1; 26 | new_word->next = NULL; 27 | 28 | return new_word; 29 | } 30 | 31 | /********************************************************* 32 | * 追加单词 33 | *********************************************************/ 34 | void add_word(char *word) 35 | { 36 | Word *pos; 37 | Word *prev; /// 指向pos前一个Word元素的指针 38 | Word *new_word; 39 | int result; 40 | 41 | prev = NULL; 42 | for (pos = word_header; pos != NULL; pos = pos->next) { 43 | result = strcmp(pos->name, word); 44 | if (result >= 0) { 45 | break; 46 | } 47 | prev = pos; 48 | } 49 | if (word_header != NULL && result == 0) { 50 | /// 发现相同的单词 51 | pos->count++; 52 | } else { 53 | new_word = create_word(word); 54 | if(prev == NULL) { 55 | new_word->next = word_header; 56 | word_header = new_word; 57 | } else { 58 | new_word->next = pos; 59 | prev->next = new_word; 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Chapter05/word_count_list/dump_word.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "word_manage_p.h" 3 | 4 | /********************************************************* 5 | * 输出单词的出现频率 6 | *********************************************************/ 7 | 8 | void dump_word(FILE *fp) 9 | { 10 | Word *pos; 11 | 12 | for (pos = word_header; pos; pos = pos->next) { 13 | fprintf(fp, "%-20s%5d\n", pos->name, pos->count); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /Chapter05/word_count_list/finalize.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "word_manage_p.h" 3 | 4 | /********************************************************* 5 | * 管理单词部分的结束处理 6 | *********************************************************/ 7 | 8 | void word_finalize(void) 9 | { 10 | Word *temp; 11 | 12 | /// 释放单词部分的内存区域 13 | while(word_header != NULL) { 14 | temp = word_header; 15 | word_header = word_header->next; 16 | 17 | free(temp->name); 18 | free(temp); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /Chapter05/word_count_list/get_word.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int get_word(char *buf, int size, FILE *stream) { 6 | 7 | int len; 8 | int ch; 9 | 10 | /// 跳过读取空白字符 11 | while ((ch = getc(stream)) != EOF && !isalnum(ch)); 12 | 13 | if (ch == EOF) return EOF; 14 | 15 | /// 此时,ch 中保存了单词的初始字符。 16 | len = 0; 17 | do { 18 | buf[len] = ch; 19 | len++; 20 | if (len >= size) { 21 | /// 由于单词太长,提示错误 22 | fprintf(stderr, "word too long.\n"); 23 | exit(1); 24 | } 25 | } while ((ch = getc(stream)) != EOF && isalnum(ch)); 26 | buf[len] = '\0'; 27 | 28 | return len; 29 | } 30 | -------------------------------------------------------------------------------- /Chapter05/word_count_list/get_word.h: -------------------------------------------------------------------------------- 1 | #ifndef GET_WORD_H_INCLUDED 2 | #define GET_WORD_H_INCLUDED 3 | #include 4 | 5 | int get_word(char *buf, int size, FILE *stream); 6 | 7 | #endif /* GET_WORD_H_INCLUDED */ 8 | -------------------------------------------------------------------------------- /Chapter05/word_count_list/initialize.c: -------------------------------------------------------------------------------- 1 | #include "word_manage_p.h" 2 | 3 | Word *word_header = NULL; 4 | 5 | /************************************************************ 6 | * 初始化管理单词部分 7 | ************************************************************/ 8 | 9 | void word_initialize(void) 10 | { 11 | word_header = NULL; 12 | } 13 | -------------------------------------------------------------------------------- /Chapter05/word_count_list/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "get_word.h" 4 | #include "word_manage.h" 5 | 6 | #define WORD_LEN_MAX (1024) 7 | 8 | int main(int argc, char *argv[]) 9 | { 10 | char buf[WORD_LEN_MAX]; 11 | FILE *fp; 12 | 13 | if (argc == 1) { 14 | fp = stdin; 15 | } else { 16 | fp = fopen(argv[1], "r"); 17 | if (fp == NULL) { 18 | fprintf(stderr, "%s:%s can not open.\n",argv[0], argv[1]); 19 | exit(1); 20 | } 21 | } 22 | 23 | /// 初始化“管理单词部分” 24 | word_initialize(); 25 | 26 | /// 边读取文件,边加入单词 27 | while (get_word(buf, WORD_LEN_MAX, fp) != EOF) { 28 | add_word(buf); 29 | } 30 | 31 | /// 输出单词的出现频率 32 | dump_word(stdout); 33 | 34 | /// “管理单词部分”的结束处理 35 | word_finalize(); 36 | 37 | return 0; 38 | } -------------------------------------------------------------------------------- /Chapter05/word_count_list/word_manage.h: -------------------------------------------------------------------------------- 1 | #ifndef WORD_MANAGE_H_INCLUDED 2 | #define WORD_MANAGE_H_INCLUDED 3 | #include 4 | 5 | void word_initialize(void); 6 | void add_word(char *word); 7 | void dump_word(FILE *fp); 8 | void word_finalize(void); 9 | 10 | #endif /* WORD_MANAGE_H_INCLUDED */ 11 | -------------------------------------------------------------------------------- /Chapter05/word_count_list/word_manage_p.h: -------------------------------------------------------------------------------- 1 | #ifndef WORD_MANAGE_P_H_INCLUDED 2 | #define WORD_MANAGE_P_H_INCLUDED 3 | #include "word_manage.h" 4 | 5 | typedef struct Word_tag { 6 | char *name; 7 | int count; 8 | struct Word_tag *next; 9 | } Word; 10 | 11 | #define WORD_NUM_MAX (1000) 12 | 13 | extern Word *word_header; 14 | 15 | #endif /* WORD_MANAGE_P_H_INCLUDED */ 16 | -------------------------------------------------------------------------------- /Chapter05/x_draw/Shape.h: -------------------------------------------------------------------------------- 1 | #ifndef SHAPE_H_INCLUDED 2 | #define SHAPE_H_INCLUDED 3 | 4 | typedef enum { 5 | COLOR_BLACK, /* 黑 */ 6 | COLOR_BLUE, /* 蓝 */ 7 | COLOR_RED, /* 红 */ 8 | COLOR_MAGENTA, /* 品红 */ 9 | COLOR_GREEN, /* 绿 */ 10 | COLOR_CYAN, /* 青 */ 11 | COLOR_YELLOW, /* 黄 */ 12 | COLOR_WHITE /* 白 */ 13 | } Color; 14 | 15 | typedef enum { 16 | FILL_NONE, /* 不填充 */ 17 | FILL_SOLID, /* 实心填充 */ 18 | FILL_HATCH, /* 填充斜线图案 */ 19 | FILL_CROSSHATCH /* 填充交叉阴影线 */ 20 | } FillPattern; 21 | 22 | typedef enum { 23 | POLYLINE_PRIMITIVE, 24 | RECTANGLE_PRIMITIVE, 25 | CIRCLE_PRIMITIVE 26 | } PrimitiveType; 27 | 28 | typedef struct { 29 | double x; 30 | double y; 31 | } Point; 32 | 33 | typedef struct { 34 | int npoints; 35 | Point *point; 36 | } Polyline; 37 | 38 | typedef struct { 39 | Point minPoint; /* 左下的坐标 */ 40 | Point maxPoint; /* 右上的坐标 */ 41 | } Rectangle; 42 | 43 | typedef struct { 44 | Point center; /* 圆心 */ 45 | double radius; /* 半径 */ 46 | } Circle; 47 | 48 | typedef struct { 49 | /* 画笔(轮廓)的颜色 */ 50 | Color pen_color; 51 | /* 填充样式,FILL_NONE的时候不填充 */ 52 | FillPattern fill_pattern; 53 | /* 填充的颜色 */ 54 | Color fill_color; 55 | /* 图形的种类 */ 56 | PrimitiveType type; 57 | union { 58 | Polyline polyline; 59 | Rectangle rectangle; 60 | Circle circle; 61 | } u; 62 | } Primitive; 63 | 64 | typedef struct Shape_tag Shape; 65 | 66 | typedef struct { 67 | Shape *head; 68 | Shape *tail; 69 | } Group; 70 | 71 | typedef enum { 72 | PRIMITIVE_SHAPE, 73 | GROUP_SHAPE 74 | } ShapeType; 75 | 76 | struct Shape_tag { 77 | ShapeType type; 78 | union { 79 | Primitive primitive; 80 | Group group; 81 | } u; 82 | struct Shape_tag *prev; 83 | struct Shape_tag *next; 84 | }; 85 | 86 | #endif /* SHAPE_H_INCLUDED */ -------------------------------------------------------------------------------- /Chapter05/x_draw/draw_shape.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "Shape.h" 4 | 5 | void draw_polyline(Shape *shape); 6 | void draw_rectangle(Shape *shape); 7 | void draw_circle(Shape *shape); 8 | 9 | void draw_primitive(Shape *shape) 10 | { 11 | switch (shape->u.primitive.type) { 12 | case POLYLINE_PRIMITIVE: 13 | /// 调用绘制折线的函数 14 | draw_polyline(shape); 15 | break; 16 | case RECTANGLE_PRIMITIVE: 17 | /// 调用绘制长方形的函数 18 | draw_rectangle(shape); 19 | break; 20 | case CIRCLE_PRIMITIVE: 21 | /// 调用绘制圆的函数 22 | draw_polyline(shape); 23 | break; 24 | default: 25 | assert(0); 26 | } 27 | } 28 | 29 | void draw_all_shapes(Shape *head) 30 | { 31 | Shape *pos; 32 | 33 | for (pos = head; pos != NULL; pos = pos->next) { 34 | switch (pos->type) { 35 | case PRIMITIVE_SHAPE: 36 | draw_primitive(pos); 37 | break; 38 | case GROUP_SHAPE: 39 | draw_all_shapes(pos->u.group.head); 40 | break; 41 | default: 42 | assert(0); 43 | } 44 | } 45 | } 46 | 47 | int main(int argc, char *argv[]) { 48 | 49 | } -------------------------------------------------------------------------------- /Chapter06/double.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void sub_func(); 4 | 5 | void func(d) 6 | double d; 7 | { 8 | sub_func(&d); 9 | } 10 | -------------------------------------------------------------------------------- /Chapter06/float.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void sub_func(); 4 | 5 | void func(f) 6 | float f; 7 | { 8 | sub_func(&f); 9 | } 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 郭宇翔 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LearningCPoniter 2 | 3 | 《征服C指针》源码整理 4 | --------------------------------------------------------------------------------