├── .gitignore ├── Chapter-1 Getting Started ├── README.md ├── example │ ├── example1-1.c │ └── example1-2.c ├── images │ ├── 1-compiler-and-linker.png │ └── 2-prepare-c.png └── review-questions │ └── Answers.md ├── Chapter-10 Arrays and Pointers ├── README.md ├── example │ ├── 10.1-day_mon1.c │ ├── 10.10-sum_arr1.c │ ├── 10.11-sum_arr2.c │ ├── 10.12-order.c │ ├── 10.13-prt_ops.c │ ├── 10.14-arf.c │ ├── 10.15-zippo1.c │ ├── 10.16-zippo2.c │ ├── 10.17-array2d.c │ ├── 10.18-vararr2d.c │ ├── 10.19-flc.c │ ├── 10.2-no_data.c │ ├── 10.3-somedata.c │ ├── 10.4-day_mon2.c │ ├── 10.5-designate.c │ ├── 10.6-bounds.c │ ├── 10.7-rain.c │ ├── 10.8-pnt_add.c │ └── 10.9-day_mon3.c ├── exercise │ ├── 10-1.c │ ├── 10-10.c │ ├── 10-11.c │ ├── 10-12.c │ ├── 10-13.c │ ├── 10-14.c │ ├── 10-2.c │ ├── 10-3.c │ ├── 10-4.c │ ├── 10-5.c │ ├── 10-6.c │ ├── 10-7.c │ ├── 10-8.c │ └── 10-9.c └── review-questions │ └── Answers.md ├── Chapter-11 Character Strings and String Functions ├── README.md ├── example │ ├── 11.1-strings1.c │ ├── 11.10-s_gets.c │ ├── 11.11-scan_str.c │ ├── 11.12-put_out.c │ ├── 11.13-nono.c │ ├── 11.14-put1.c │ ├── 11.15-put2.c │ ├── 11.16-put_put.c │ ├── 11.17-test_fit.c │ ├── 11.18-str_cat.c │ ├── 11.19-join_chk.c │ ├── 11.2-strptr.c │ ├── 11.20-nogo.c │ ├── 11.21-compare.c │ ├── 11.22-compback.c │ ├── 11.23-quit_chk.c │ ├── 11.24-starsrch.c │ ├── 11.25-copy1.c │ ├── 11.26-copy2.c │ ├── 11.27-copy3.c │ ├── 11.28-format.c │ ├── 11.29-sort_str.c │ ├── 11.3-addresses.c │ ├── 11.30-mod_str.c │ ├── 11.31-repeat.c │ ├── 11.32-hello.c │ ├── 11.33-strcnvt.c │ ├── 11.4-arrchar.c │ ├── 11.5-p_and_s.c │ ├── 11.6-getsputs.c │ ├── 11.7-fgets1.c │ ├── 11.8-fgets2.c │ └── 11.9-fgets3.c ├── exercise │ ├── 11-1.c │ ├── 11-10.c │ ├── 11-11.c │ ├── 11-12.c │ ├── 11-13.c │ ├── 11-14.c │ ├── 11-15.c │ ├── 11-16.c │ ├── 11-2.c │ ├── 11-3.c │ ├── 11-4.c │ ├── 11-5.c │ ├── 11-6.c │ ├── 11-7.c │ ├── 11-8.c │ └── 11-9.c └── review-questions │ └── Answers.md ├── Chapter-12 Storage Classes, Linkage, and Memory Management ├── README.md ├── example │ ├── 12.1-hiding.c │ ├── 12.10-r_drive1.c │ ├── 12.11-diceroll.c │ ├── 12.12-diceroll.h │ ├── 12.13-manydice.c │ ├── 12.14-dyn_arr.c │ ├── 12.15-where.c │ ├── 12.2-forc99.c │ ├── 12.3-loc_stat.c │ ├── 12.4-global.c │ ├── 12.5-parta.c │ ├── 12.6-partb.c │ ├── 12.7-rand0.c │ ├── 12.8-r_drive0.c │ └── 12.9-s_and_r.c ├── exercise │ ├── 12-1.c │ ├── 12-4.c │ ├── 12-5.c │ ├── 12-6.c │ └── 12-7.c └── review-questions │ └── Answers.md ├── Chapter-13 File Input-Output ├── README.md ├── example │ ├── 13.1-count.c │ ├── 13.2-reducto.c │ ├── 13.3-addaword.c │ ├── 13.4-reverse.c │ ├── 13.5-append.c │ └── 13.6-randbin.c ├── exercise │ ├── 13-1.c │ ├── 13-10.c │ ├── 13-11.c │ ├── 13-12.c │ ├── 13-2.c │ ├── 13-3.c │ ├── 13-4.c │ ├── 13-5.c │ ├── 13-6.c │ ├── 13-7-a.c │ ├── 13-7-b.c │ ├── 13-8.c │ ├── 13-9.c │ ├── numbers │ └── pic └── review-questions │ └── Answers.md ├── Chapter-14 Structures and Other Data Forms ├── README.md ├── example │ ├── 14.1-book.c │ ├── 14.10-names3.c │ ├── 14.11-complit.c │ ├── 14.12-flexmemb.c │ ├── 14.13-funds4.c │ ├── 14.14-booksave.c │ ├── 14.15-enum.c │ ├── 14.16-func_ptr.c │ ├── 14.2-manybook.c │ ├── 14.3-friend.c │ ├── 14.4-friends.c │ ├── 14.5-funds1.c │ ├── 14.6-funds2.c │ ├── 14.7-funds3.c │ ├── 14.8-names1.c │ └── 14.9-names2.c └── review-questions │ └── Answers.md ├── Chapter-15 Bit Fiddling ├── README.md └── example │ ├── 15.1-binbit.c │ ├── 15.2-invert4.c │ ├── 15.3-fields.c │ └── 15.4-dualview.c ├── Chapter-16 The C Preprocessor and the C Library ├── example │ ├── 16.1-preproc.c │ ├── 16.10-names.h │ ├── 16.11-doubincl.c │ ├── 16.12-predef.c │ ├── 16.13-mytype.c │ ├── 16.14-rect_pol.c │ ├── 16.15-generic.c │ ├── 16.16-byebye.c │ ├── 16.17-qsorter.c │ ├── 16.18-assert.c │ ├── 16.19-statasrt.c │ ├── 16.2-mac_arg.c │ ├── 16.20-mems.c │ ├── 16.21-varargs.c │ ├── 16.3-subst.c │ ├── 16.4-glue.c │ ├── 16.5-variadic.c │ ├── 16.6-names_st.h │ ├── 16.7-name_st.c │ ├── 16.8-useheader.c │ └── 16.9-ifdef.c └── review-questions │ └── Answers.md ├── Chapter-17 Advanced Data Representation ├── example │ ├── 17.1-films1.c │ ├── 17.10-tree.h │ ├── 17.11-tree.c │ ├── 17.12-petclub.c │ ├── 17.2-films2.c │ ├── 17.3-list.h │ ├── 17.4-films3.c │ ├── 17.5-list.c │ ├── 17.6-queue.h │ ├── 17.7-queue.c │ ├── 17.8-use_q.c │ └── 17.9-mall.c └── review-questions │ └── Answers.md ├── Chapter-2 Introducing C ├── README.md ├── example │ ├── 2.1-first.c │ ├── 2.2-fathm_ft.c │ └── 2.3-two_func.c ├── exercise │ ├── 2-1.c │ ├── 2-2.c │ ├── 2-3.c │ ├── 2-4.c │ ├── 2-5.c │ ├── 2-6.c │ ├── 2-7.c │ └── 2-8.c ├── images │ ├── 1-c-program-structure.png │ ├── 2-keywords-1.png │ └── 2-keywords-2.png └── review-questions │ └── Answers.md ├── Chapter-3 Data and C ├── .DS_Store ├── README.md ├── example │ ├── 3.1-platinum.c │ ├── 3.2-print1.c │ ├── 3.3-bases.c │ ├── 3.4-print2.c │ ├── 3.5-charcode.c │ ├── 3.7-showf_pt.c │ ├── 3.8-typesize.c │ ├── 3.9-badcount.c │ └── floaterr.c ├── exercise │ ├── 3-1.c │ ├── 3-2.c │ ├── 3-3.c │ ├── 3-4.c │ ├── 3-5.c │ ├── 3-6.c │ ├── 3-7.c │ └── 3-8.c ├── images │ ├── 1-datatype-key-word.png │ ├── 2-escape-squence.png │ ├── 3-data-show-and-storage.png │ ├── 4-decimal.png │ ├── 5-review-question-6.png │ └── 6-review-question-7.png └── review-questions │ └── Answers.md ├── Chapter-4 Character Strings and Formatted Input-Output ├── README.md ├── example │ ├── 4.1-talkback.c │ ├── 4.10-stringf.c │ ├── 4.11-intconv.c │ ├── 4.12-floatcnv.c │ ├── 4.13-prntval.c │ ├── 4.14-longstrg.c │ ├── 4.15-input.c │ ├── 4.16-varwid.c │ ├── 4.17-skip2.c │ ├── 4.2-praise1.c │ ├── 4.3-praise2.c │ ├── 4.4-pizza.c │ ├── 4.5-defines.c │ ├── 4.6-printout.c │ ├── 4.7-width.c │ ├── 4.8-floats.c │ └── 4.9-flags.c ├── exercise │ ├── 4-1.c │ ├── 4-2.c │ ├── 4-3.c │ ├── 4-4.c │ ├── 4-5.c │ ├── 4-6.c │ ├── 4-7.c │ └── 4-8.c ├── images │ ├── 1-manifest-constants-limits.png │ ├── 2-manifest-constants-float.png │ ├── 3-printf-conversion-specification.png │ ├── 4-printf-modifier.png │ ├── 5-printf-flags.png │ ├── 6-scanf-modifier.png │ ├── 7-scanf-flags-2.png │ └── 7-scanf-flags.png └── review-questions │ └── Answers.md ├── Chapter-5 Operators, Expressions, and Statements ├── README.md ├── example │ ├── 5.1-shoes1.c │ ├── 5.10-add_one.c │ ├── 5.11-post_pre.c │ ├── 5.12-bottles.c │ ├── 5.13-addemup.c │ ├── 5.14-convert.c │ ├── 5.15-pound.c │ ├── 5.16-running.c │ ├── 5.2-shoes2.c │ ├── 5.3-golf.c │ ├── 5.4-squares.c │ ├── 5.5-wheat.c │ ├── 5.6-divide.c │ ├── 5.7-rules.c │ ├── 5.8-sizeof.c │ └── 5.9-min_sec.c ├── exercise │ ├── 5-1.c │ ├── 5-2.c │ ├── 5-3.c │ ├── 5-4.c │ ├── 5-5.c │ ├── 5-6.c │ ├── 5-7.c │ ├── 5-8.c │ └── 5-9.c └── review-questions │ └── Answers.md ├── Chapter-6 C Control Statements: Looping ├── README.md ├── example │ ├── 6.1-summing.c │ ├── 6.10-sweetie1.c │ ├── 6.11-sweetie2.c │ ├── 6.12-for_cube.c │ ├── 6.13-postage.c │ ├── 6.14-zeno.c │ ├── 6.15-do_while.c │ ├── 6.16-entry.c │ ├── 6.17-rows1.c │ ├── 6.18-rows2.c │ ├── 6.19-scores_in.c │ ├── 6.2-when.c │ ├── 6.20-power.c │ ├── 6.3-while1.c │ ├── 6.4-while2.c │ ├── 6.5-cmpflt.c │ ├── 6.6-t_and_f.c │ ├── 6.7-truth.c │ ├── 6.8-trouble.c │ └── 6.9-boolean.c ├── exercise │ ├── 6-1.c │ ├── 6-10.c │ ├── 6-11.c │ ├── 6-12.c │ ├── 6-13.c │ ├── 6-14.c │ ├── 6-15.c │ ├── 6-16.c │ ├── 6-17.c │ ├── 6-18.c │ ├── 6-2.c │ ├── 6-3.c │ ├── 6-4.c │ ├── 6-5.c │ ├── 6-6.c │ ├── 6-7.c │ ├── 6-8.c │ └── 6-9.c └── review-questions │ └── Answers.md ├── Chapter-7 C Control Statements: Branching and Jumps ├── README.md ├── example │ ├── 7.1-colddays.c │ ├── 7.11-animales.c │ ├── 7.2-cypher1.c │ └── 7.3-cypher2.c └── review-questions │ └── Answers.md ├── Chapter-8 Character Input-Output and Input Validation ├── README.md ├── example │ ├── 8.2-echo_eof.c │ ├── 8.3-file_eof.c │ └── 8.7-checking.c └── review-questions │ └── Answers.md ├── Chapter-9 Functions ├── README.md ├── example │ ├── 9.1-lethead1.c │ ├── 9.10-hotel.c │ ├── 9.11-hotel.h │ ├── 9.12-loccheck.c │ ├── 9.13-swap1.c │ ├── 9.14-swap2.c │ ├── 9.15-swap3.c │ ├── 9.2-lethead2.c │ ├── 9.3-lesser.c │ ├── 9.4-misuse.c │ ├── 9.5-proto.c │ ├── 9.6-recur.c │ ├── 9.7-factor.c │ ├── 9.8-binary.c │ └── 9.9-usehotel.c ├── exercise │ ├── 9-1.c │ ├── 9-10.c │ ├── 9-11.c │ ├── 9-2.c │ ├── 9-3.c │ ├── 9-4.c │ ├── 9-7.c │ ├── 9-8.c │ └── 9-9.c └── review-questions │ └── Answers.md ├── README.md ├── build ├── constant.js ├── index.js ├── ready-to-learn-next-chapter.js └── utils.js ├── cover.jpg └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | # c编译的可执行文件 2 | *.out 3 | # c编译的中间文件 4 | *.o -------------------------------------------------------------------------------- /Chapter-1 Getting Started/example/example1-1.c: -------------------------------------------------------------------------------- 1 | #include  2 | 3 | int main(void) 4 | { 5 | int dogs; 6 | printf("How many dogs do you have?\n"); 7 | scanf("%d", &dogs); 8 | printf("So you have %d dog(s)!\n", dogs); 9 | return 0; 10 | } -------------------------------------------------------------------------------- /Chapter-1 Getting Started/example/example1-2.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | printf("Concrete contains gravel and cement.\n"); 6 | return 0; 7 | } -------------------------------------------------------------------------------- /Chapter-1 Getting Started/images/1-compiler-and-linker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/logan70/C-Primer-Plus-6th-Notes-CN/6d4beffefdbf6ebe4893974a274d0cfb112605b6/Chapter-1 Getting Started/images/1-compiler-and-linker.png -------------------------------------------------------------------------------- /Chapter-1 Getting Started/images/2-prepare-c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/logan70/C-Primer-Plus-6th-Notes-CN/6d4beffefdbf6ebe4893974a274d0cfb112605b6/Chapter-1 Getting Started/images/2-prepare-c.png -------------------------------------------------------------------------------- /Chapter-1 Getting Started/review-questions/Answers.md: -------------------------------------------------------------------------------- 1 | ## 对编程而言,可移植性意味着什么? 2 | 3 | 完美的可移植程序是,其源代码无需修改就能在不同计算机系统中成功编译的程序。 4 | 5 | ## 解释源代码文件、目标代码文件和可执行文件有什么区别? 6 | 7 | 源代码文件包含程序员使用的任何编程语言编写的代码。目标代码文件包含机器语言代码,它不必是完整的程序代码。可执行文件包含组成可执行程序的完整机器语言代码。 8 | 9 | ## 编程的7个主要步骤是什么? 10 | 11 | (1)定义程序目标;(2)设计程序;(3)编写程序;(4)编译程 序;(5)运行程序;(6)测试和调试程序;(7)维护和修改程序。 12 | 13 | ## 编译器的任务是什么? 14 | 15 | 编译器把源代码(如用C语言编写的代码)翻译成等价的机器语言代码(也叫作目标代码)。 16 | 17 | ## 链接器的任务是什么? 18 | 19 | 链接器把编译器翻译好的目标代码以及库代码和启动代码组合起来,生成一个可执行程序。 -------------------------------------------------------------------------------- /Chapter-10 Arrays and Pointers/example/10.1-day_mon1.c: -------------------------------------------------------------------------------- 1 | // day_mon1.c - 打印每个月的天数 2 | #include 3 | #define MONTHS 12 4 | 5 | int main(void) 6 | { 7 | int days[MONTHS] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 8 | int index; 9 | for (index = 0; index < MONTHS; index++) 10 | printf("Month %2d has %2d days.\n", index + 1, days[index]); 11 | return 0; 12 | } -------------------------------------------------------------------------------- /Chapter-10 Arrays and Pointers/example/10.10-sum_arr1.c: -------------------------------------------------------------------------------- 1 | // sum_arr1.c - 数组元素之和 2 | // 如果编译器不支持%zd,用%u或%lu替换它 3 | #include 4 | #define SIZE 10 5 | int sum(int ar[], int n); 6 | int main(void) 7 | { 8 | int marbles[SIZE] = { 20, 10, 5, 39, 4, 16, 19, 26, 31, 20 }; 9 | long answer; 10 | answer = sum(marbles, SIZE); 11 | printf("The total number of marbles is %ld.\n", answer); 12 | printf("The size of marbles is %zd bytes.\n", sizeof marbles); 13 | return 0; 14 | } 15 | 16 | int sum(int ar[], int n) 17 | { 18 | int i; 19 | int total = 0; 20 | for (i = 0; i < n; i++) 21 | total += ar[i]; 22 | printf("The size of ar is %zd btyes.\n", sizeof ar); 23 | return total; 24 | } -------------------------------------------------------------------------------- /Chapter-10 Arrays and Pointers/example/10.11-sum_arr2.c: -------------------------------------------------------------------------------- 1 | // sum_arr2.c - 数组元素之和 2 | #include 3 | #define SIZE 10 4 | int sum(int * start, int * end); 5 | int main(void) 6 | { 7 | int marbles[SIZE] = { 20, 10, 5, 39, 4, 16, 19, 26, 31, 20 }; 8 | long answer; 9 | answer = sum(marbles, marbles + SIZE); 10 | printf("The total number of marbles is %ld.\n", answer); 11 | printf("The size of marbles is %zd bytes.\n", sizeof marbles); 12 | return 0; 13 | } 14 | 15 | int sum(int * start, int * end) 16 | { 17 | int total = 0; 18 | while (start < end) 19 | { 20 | total += *start; 21 | start++; 22 | } 23 | return total; 24 | } -------------------------------------------------------------------------------- /Chapter-10 Arrays and Pointers/example/10.12-order.c: -------------------------------------------------------------------------------- 1 | // order.c - 指针运算中的优先级 2 | #include 3 | 4 | int data[2] = { 100, 200 }; 5 | int moredata[2] = { 300, 400 }; 6 | int main(void) 7 | { 8 | int * p1, * p2, * p3; 9 | p1 = p2 = data; 10 | p3 = moredata; 11 | printf(" *p1 = %d, *p2 = %d, *p3 = %d\n", *p1, *p2, *p3); 12 | printf("*p1++ = %d, *++p2 = %d, (*p3)++ = %d\n", *p1++, *++p2, (*p3)++); 13 | printf(" *p1 = %d, *p2 = %d, *p3 = %d\n", *p1, *p2, *p3); 14 | return 0; 15 | } -------------------------------------------------------------------------------- /Chapter-10 Arrays and Pointers/example/10.13-prt_ops.c: -------------------------------------------------------------------------------- 1 | // ptr_ops.c - 指针操作 2 | #include 3 | 4 | int main(void) 5 | { 6 | int urn[5] = { 100, 200, 300, 400, 500 }; 7 | int * ptr1, * ptr2, * ptr3; 8 | ptr1 = urn; // 把一个地址赋给指针 9 | ptr2 = &urn[2]; // 把一个地址赋给指针 10 | // 解引用指针,以及获得指针的地址 11 | printf("poiter value, dereferenced pointer, pointer adderess:\n"); 12 | printf("ptr1 = %p, *ptr1 = %d, &ptr1 = %p\n", ptr1, *ptr1, &ptr1); 13 | // 指针加法 14 | ptr3 = ptr1 + 4; 15 | printf("\nadding an int to a pointer:\n"); 16 | printf("ptr1 + 4 = %p, *(ptr1 + 4) = %d\n", ptr1 + 4, *(ptr1 + 4)); 17 | ptr1++; // 递增指针 18 | printf("\nvalues after ptr1++: \n"); 19 | printf("ptr1 = %p, *ptr1 = %d, &ptr1 = %p\n", ptr1, *ptr1, &ptr1); 20 | ptr2--; // 递减指针 21 | printf("\nvalues after --ptr2:\n"); 22 | printf("ptr2 = %p, *ptr2 = %d, &ptr2 = %p\n", ptr2, *ptr2, &ptr2); 23 | --ptr1; // 恢复为初始值 24 | ++ptr2; // 恢复为初始值 25 | printf("\nPointers reset to original values:\n"); 26 | printf("ptr1 = %p, ptr2 = %p\n", ptr1, ptr2); 27 | // 一个指针减去另一个指针 28 | printf("\nsubtracting one pointer from another:\n"); 29 | printf("ptr2 = %p, ptr1 = %p, ptr2 - ptr1 = %td\n", ptr2, ptr1, ptr2 - ptr1); 30 | // 一个指针减去一个整数 31 | printf("\nsubstraction an int from a pointer:\n"); 32 | printf("ptr3 = %p, ptr3 - 2 = %p\n", ptr3, ptr3 - 2); 33 | return 0; 34 | } -------------------------------------------------------------------------------- /Chapter-10 Arrays and Pointers/example/10.14-arf.c: -------------------------------------------------------------------------------- 1 | // arf.c - 处理数组的函数 2 | #include 3 | #define SIZE 5 4 | void show_array(const double ar[], int n ); 5 | void mult_array(double ar[], int n, double mult); 6 | 7 | int main(void) 8 | { 9 | double dip[SIZE] = { 20.0, 17.66, 8.2, 15.3, 22.22 }; 10 | printf("The original dip array:\n"); 11 | show_array(dip, SIZE); 12 | mult_array(dip, SIZE, 2.5); 13 | printf("The dip array after calling mult_array():\n"); 14 | show_array(dip, SIZE); 15 | return 0; 16 | } 17 | 18 | // 显示数组的内容 19 | void show_array(const double ar[], int n) 20 | { 21 | int i; 22 | for (i = 0; i < n; i++) 23 | printf("%8.3f ", ar[i]); 24 | putchar('\n'); 25 | } 26 | 27 | // 把数组的每个元素都乘以相同的值 28 | void mult_array(double ar[], int n, double mult) 29 | { 30 | int i; 31 | for (i = 0; i < n; i++) 32 | ar[i] *= mult; 33 | } -------------------------------------------------------------------------------- /Chapter-10 Arrays and Pointers/example/10.15-zippo1.c: -------------------------------------------------------------------------------- 1 | // zippo1.c - zippo的相关信息 2 | #include 3 | 4 | int main(void) 5 | { 6 | int zippo[4][2] = { { 2, 4 }, { 6, 8 }, { 1, 3 }, { 5, 7 } }; 7 | printf(" zippo = %p, zippo + 1 = %p\n", zippo, zippo + 1); 8 | printf("zippo[0] = %p, zippo[0] + 1 = %p\n", zippo[0], zippo[0] + 1); 9 | printf(" *zippo = %p, *zippo + 1 = %p\n", *zippo, *zippo + 1); 10 | printf("zippo[0][0] = %d\n", zippo[0][0]); 11 | printf(" *zippo[0] = %d\n", *zippo[0]); 12 | printf(" **zippo = %d\n", **zippo); 13 | printf(" zippo[2][1] = %d\n", zippo[2][1]); 14 | printf("*(*(zippo + 2) + 1) = %d\n", *(*(zippo + 2) + 1)); 15 | return 0; 16 | } -------------------------------------------------------------------------------- /Chapter-10 Arrays and Pointers/example/10.16-zippo2.c: -------------------------------------------------------------------------------- 1 | // zippo2.c - 通过指针获取zippo的信息 2 | #include 3 | 4 | int main(void) 5 | { 6 | int zippo[4][2] = { { 2, 4 }, { 6, 8 }, { 1, 3 }, { 5, 7 } }; 7 | int (* pz)[2]; 8 | pz = zippo; 9 | printf(" pz = %p, pz + 1 = %p\n", pz, pz + 1); 10 | printf("pz[0] = %p, pz[0] + 1 = %p\n", pz[0], pz[0] + 1); 11 | printf(" *pz = %p, *pz + 1 = %p\n", *pz, *pz + 1); 12 | printf("pz[0][0] = %d\n", pz[0][0]); 13 | printf(" *pz[0] = %d\n", *pz[0]); 14 | printf(" **pz = %d\n", **pz); 15 | printf(" pz[2][1] = %d\n", pz[2][1]); 16 | printf("*(*(pz+2) + 1) = %d\n", *(*(pz + 2) + 1)); 17 | return 0; 18 | } -------------------------------------------------------------------------------- /Chapter-10 Arrays and Pointers/example/10.17-array2d.c: -------------------------------------------------------------------------------- 1 | // array2d.c - 处理二维数组的函数 2 | #include 3 | #define ROWS 3 4 | #define COLS 4 5 | void sum_rows(int ar[][COLS], int rows); 6 | void sum_cols(int [][COLS], int); // 省略形参名,没问题 7 | int sum2d(int (* ar)[COLS], int rows); // 另一种语法 8 | 9 | int main(void) 10 | { 11 | int junk[ROWS][COLS] = { 12 | { 2, 4, 6, 8 }, 13 | { 3, 5, 7, 9 }, 14 | { 12, 10, 8, 6 } 15 | }; 16 | sum_rows(junk, ROWS); 17 | sum_cols(junk, ROWS); 18 | printf("Sum of all elements = %d\n", sum2d(junk, ROWS)); 19 | return 0; 20 | } 21 | 22 | void sum_rows(int ar[][COLS], int rows) 23 | { 24 | int r, c, tot; 25 | for (r = 0; r < rows; r++) 26 | { 27 | tot = 0; 28 | for (c = 0; c < COLS; c++) 29 | tot += ar[r][c]; 30 | printf("row %d: sum = %d\n", r, tot); 31 | } 32 | } 33 | 34 | void sum_cols(int ar[][COLS], int rows) 35 | { 36 | int r, c, tot; 37 | for (c = 0; c < COLS; c++) 38 | { 39 | tot = 0; 40 | for (r = 0; r < rows; r++) 41 | tot += ar[r][c]; 42 | printf("col %d: sum = %d\n", c, tot); 43 | } 44 | } 45 | 46 | int sum2d(int ar[][COLS], int rows) 47 | { 48 | int r, c, tot = 0; 49 | for (r = 0; r < rows; r++) 50 | { 51 | for (c = 0; c < COLS; c++) 52 | tot += ar[r][c]; 53 | } 54 | return tot; 55 | } 56 | -------------------------------------------------------------------------------- /Chapter-10 Arrays and Pointers/example/10.18-vararr2d.c: -------------------------------------------------------------------------------- 1 | // vararr2d.c - 使用变长数组的函数 2 | #include 3 | #define ROWS 3 4 | #define COLS 5 5 | int sum2d(int rows, int cols, int ar[rows][cols]); 6 | int main(void) 7 | { 8 | int i, j; 9 | int rs = 3; 10 | int cs = 10; 11 | int junk[ROWS][COLS] = { 12 | { 2, 4, 6, 8 }, 13 | { 3, 5, 7, 9 }, 14 | { 12, 10, 8, 6 } 15 | }; 16 | int morejunk[ROWS - 1][COLS + 2] = { 17 | { 20, 30, 40, 50, 60, 70 }, 18 | { 5, 6, 7, 8, 9, 10 } 19 | }; 20 | int varr[rs][cs]; // 变长数组VLA 21 | for (i = 0; i < rs; i++) 22 | for (j = 0; j < cs; j++) 23 | varr[i][j] = i * j + j; 24 | printf("3x5 array\n"); 25 | printf("Sum of all elements = %d\n", sum2d(ROWS, COLS, junk)); 26 | printf("2x6 array\n"); 27 | printf("Sum of all elements = %d\n", sum2d(ROWS - 1, COLS + 2, morejunk)); 28 | printf("3x10 VLA\n"); 29 | printf("Sum of all elements = %d\n", sum2d(rs, cs, varr)); 30 | return 0; 31 | } 32 | 33 | // 带变长数组形参的函数 34 | int sum2d(int rows, int cols, int ar[rows][cols]) 35 | { 36 | int r, c, tot = 0; 37 | for (r = 0; r < rows; r++) 38 | for (c = 0; c < cols; c++) 39 | tot += ar[r][c]; 40 | return tot; 41 | } -------------------------------------------------------------------------------- /Chapter-10 Arrays and Pointers/example/10.19-flc.c: -------------------------------------------------------------------------------- 1 | // flc.c - 有趣的常量 2 | #include 3 | #define COLS 4 4 | int sum2d(const int ar[][COLS], int rows); 5 | int sum(const int ar[], int n); 6 | int main(void) 7 | { 8 | int total1, total2, total3; 9 | int * pt1; 10 | int (*pt2)[COLS]; 11 | pt1 = (int[2]){ 10, 20 }; 12 | pt2 = (int[2][COLS]) { { 1, 2, 3, -9 }, { 4, 5, 6, -8 } }; 13 | total1 = sum(pt1, 2); 14 | total2 = sum2d(pt2, 2); 15 | total3 = sum((int []){ 4, 4, 4, 5, 5, 5 }, 6); 16 | printf("total1 = %d\n", total1); 17 | printf("total2 = %d\n", total2); 18 | printf("total3 = %d\n", total3); 19 | return 0; 20 | } 21 | 22 | int sum(const int ar[], int n) 23 | { 24 | int i, total = 0; 25 | for (i = 0; i < n; i++) 26 | total += ar[i]; 27 | return total; 28 | } 29 | 30 | int sum2d(const int ar[][COLS], int rows) 31 | { 32 | int r, c, tot = 0; 33 | for (r = 0; r < rows; r++) 34 | for (c = 0; c < COLS; c++) 35 | tot += ar[r][c]; 36 | return tot; 37 | } -------------------------------------------------------------------------------- /Chapter-10 Arrays and Pointers/example/10.2-no_data.c: -------------------------------------------------------------------------------- 1 | // no_data.c - 未初始化数组 2 | #include 3 | #define SIZE 4 4 | 5 | int main(void) 6 | { 7 | int no_data[SIZE]; 8 | int i; 9 | printf("%2s%14s\n", "i", "no_data[i]"); 10 | for (i = 0; i < SIZE; i++) 11 | printf("%2d%14d\n", i, no_data[i]); 12 | return 0; 13 | } -------------------------------------------------------------------------------- /Chapter-10 Arrays and Pointers/example/10.3-somedata.c: -------------------------------------------------------------------------------- 1 | // somedata.c - 部分初始化的数组 2 | #include 3 | #define SIZE 4 4 | 5 | int main(void) 6 | { 7 | int some_data[SIZE] = { 1492, 1066 }; 8 | int i; 9 | printf("%2s%14s\n", "i", "some_data[i]"); 10 | for (i = 0; i < SIZE; i++) 11 | printf("%2d%14d\n", i, some_data[i]); 12 | return 0; 13 | } -------------------------------------------------------------------------------- /Chapter-10 Arrays and Pointers/example/10.4-day_mon2.c: -------------------------------------------------------------------------------- 1 | // day_mon2.c - 让编译器计算元素个数 2 | #include 3 | 4 | int main(void) 5 | { 6 | int days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 7 | int index; 8 | for (index = 0; index < sizeof days / sizeof days[0]; index++) 9 | printf("Month %2d has %2d days.\n", index + 1, days[index]); 10 | return 0; 11 | } -------------------------------------------------------------------------------- /Chapter-10 Arrays and Pointers/example/10.5-designate.c: -------------------------------------------------------------------------------- 1 | // designate.c - 使用指定初始化器 2 | #include 3 | #define MONTHS 12 4 | 5 | int main(void) 6 | { 7 | int days[MONTHS] = { 31, 28, [4] = 31, 30, 31, [1] = 29 }; 8 | int i; 9 | for (i = 0; i < MONTHS; i++) 10 | printf("%2d %d\n", i + 1, days[i]); 11 | return 0; 12 | } -------------------------------------------------------------------------------- /Chapter-10 Arrays and Pointers/example/10.6-bounds.c: -------------------------------------------------------------------------------- 1 | // bounds.c - 数组下标越界 2 | #include 3 | #define SIZE 4 4 | int main(void) 5 | { 6 | int value1 = 44; 7 | int arr[SIZE]; 8 | int value2 = 88; 9 | int i; 10 | printf("value1 = %d, value2 = %d\n", value1, value2); 11 | for (i = -1; i <= SIZE; i++) 12 | arr[i] = 2 * i + 1; 13 | for (i = -1; i < 7; i++) 14 | printf("%2d %d\n", i, arr[i]); 15 | printf("value1 = %d, value2 = %d\n", value1, value2); 16 | printf("address of arr[-1]: %p\n", &arr[-1]); 17 | printf("address of arr[4]: %p\n", &arr[4]); 18 | printf("address of value1: %p\n", &value1); 19 | printf("address of value2: %p\n", &value2); 20 | return 0; 21 | } -------------------------------------------------------------------------------- /Chapter-10 Arrays and Pointers/example/10.8-pnt_add.c: -------------------------------------------------------------------------------- 1 | // pnt_add.c - 指针地址 2 | #include 3 | #define SIZE 4 4 | 5 | int main(void) 6 | { 7 | short dates[SIZE]; 8 | short * pti; 9 | short index; 10 | double bills[SIZE]; 11 | double * ptf; 12 | pti = dates; 13 | ptf = bills; 14 | printf("%23s %15s\n", "short", "double"); 15 | for (index = 0; index < SIZE; index++) 16 | printf("pointers + %d: %10p %10p\n", index, pti + index, ptf + index); 17 | return 0; 18 | } -------------------------------------------------------------------------------- /Chapter-10 Arrays and Pointers/example/10.9-day_mon3.c: -------------------------------------------------------------------------------- 1 | // day_mon3.c - uses pointer notation 2 | #include 3 | #define MONTHS 12 4 | int main(void) 5 | { 6 | int days[MONTHS] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 7 | int index; 8 | for (index = 0; index < MONTHS; index++) 9 | printf("Month %2d has %d days.\n", index + 1, 10 | *(days + index)); // 与 days[index]相同 11 | return 0; 12 | } -------------------------------------------------------------------------------- /Chapter-10 Arrays and Pointers/exercise/10-10.c: -------------------------------------------------------------------------------- 1 | // 10. 编写一个函数,把两个数组中相对应的元素相加,然后把结果储存到第3个数组中。 2 | // 也就是说,如果数组1中包含的值是2、4、5、8,数组2中包含的值是1、0、4、6, 3 | // 那么该函数把3、4、9、14赋给第3个数组。函数接受3个数组名和一个数组大小。 4 | // 在一个简单的程序中测试该函数。 5 | #include 6 | void sum_arr(int ar1[], int ar2[], int sumar[], int n); 7 | void print_arr(int ar[], int n); 8 | 9 | int main(void) 10 | { 11 | int ar1[] = { 2, 4, 5, 8 }; 12 | int ar2[] = { 1, 0, 4, 6 }; 13 | int sumar[4]; 14 | sum_arr(ar1, ar2, sumar, 4); 15 | printf("ar1: \n"); 16 | print_arr(ar1, 4); 17 | printf("ar2: \n"); 18 | print_arr(ar2, 4); 19 | printf("sumar: \n"); 20 | print_arr(sumar, 4); 21 | return 0; 22 | } 23 | 24 | void sum_arr(int ar1[], int ar2[], int sumar[], int n) 25 | { 26 | int i; 27 | for (i = 0; i < n; i++) 28 | sumar[i] = ar1[i] + ar2[i]; 29 | } 30 | void print_arr(int ar[], int n) 31 | { 32 | int i; 33 | printf("[ "); 34 | for (i = 0; i < n; i++) 35 | printf("%d ", ar[i]); 36 | printf("]\n"); 37 | } -------------------------------------------------------------------------------- /Chapter-10 Arrays and Pointers/exercise/10-11.c: -------------------------------------------------------------------------------- 1 | // 11. 编写一个程序,声明一个int类型的3×COLS二维数组,并用合适的值初始化它。 2 | // 该程序打印数组中的值,然后各值翻倍(即是原值的2倍),并显示出各元素的新值。 3 | // 编写一个函数显示数组的内容,再编写一个函数把各元素的值翻倍。 4 | // 这两个函数都以函数名和行数作为参数。 5 | #include 6 | #define COLS 5 7 | void print_arr2d(int ar[][COLS], int rows); 8 | void double_arr2d(int ar[][COLS], int rows); 9 | 10 | int main(void) 11 | { 12 | int ar[][COLS] = { 13 | { 1, 2, 3, 4, 5 }, 14 | { 6, 7, 8, 9, 10 }, 15 | { 11, 12, 13, 14, 15 } 16 | }; 17 | printf("arr before doubled: \n"); 18 | print_arr2d(ar, 3); 19 | double_arr2d(ar, 3); 20 | printf("arr after doubled: \n"); 21 | print_arr2d(ar, 3); 22 | return 0; 23 | } 24 | 25 | void double_arr2d(int ar[][COLS], int rows) 26 | { 27 | int r, c; 28 | for (r = 0; r < rows; r++) 29 | for (c = 0; c < COLS; c++) 30 | ar[r][c] *= 2; 31 | } 32 | void print_arr2d(int ar[][COLS], int rows) 33 | { 34 | int r, c; 35 | printf("[\n"); 36 | for (r = 0; r < rows; r++) 37 | { 38 | printf(" [ "); 39 | for (c = 0; c < COLS; c++) 40 | { 41 | printf("%d ", ar[r][c]); 42 | } 43 | printf("]\n"); 44 | } 45 | printf("]\n"); 46 | } -------------------------------------------------------------------------------- /Chapter-10 Arrays and Pointers/exercise/10-3.c: -------------------------------------------------------------------------------- 1 | // 3. 编写一个函数,返回储存在int类型数组中的最大值,并在一个简单的程序中测试该函数。 2 | #include 3 | int get_max(int ar[], int n); 4 | 5 | int main(void) 6 | { 7 | printf("The max in [5, 10, 15, 20] is %d\n", 8 | get_max((int []){ 5, 10, 15, 20 }, 4)); 9 | return 0; 10 | } 11 | 12 | int get_max(int ar[], int n) 13 | { 14 | int i, max; 15 | for (max = 0, i = 0; i < n; i++) 16 | if (ar[i] > max) 17 | max = ar[i]; 18 | return max; 19 | } -------------------------------------------------------------------------------- /Chapter-10 Arrays and Pointers/exercise/10-4.c: -------------------------------------------------------------------------------- 1 | // 4. 编写一个函数,返回储存在double类型数组中最大值的下标, 2 | // 并在一个简单的程序中测试该函数。 3 | #include 4 | int get_max_index(double ar[], int n); 5 | 6 | int main(void) 7 | { 8 | printf("The index of the biggest value in [2.3, 1.8, 3.5] is: %d\n", 9 | get_max_index((double []){ 2.3, 1.8, 3.5 }, 3)); 10 | return 0; 11 | } 12 | 13 | int get_max_index(double ar[], int n) 14 | { 15 | int i, max_idx; 16 | double max; 17 | for (i = 0, max = ar[i]; i < n; i++) 18 | { 19 | if (ar[i] > max) 20 | { 21 | max = ar[i]; 22 | max_idx = i; 23 | } 24 | } 25 | return max_idx; 26 | } -------------------------------------------------------------------------------- /Chapter-10 Arrays and Pointers/exercise/10-5.c: -------------------------------------------------------------------------------- 1 | // 5. 编写一个函数,返回储存在double类型数组中最大值和最小值的差值, 2 | // 并在一个简单的程序中测试该函数。 3 | #include 4 | double get_diff(double ar[], int n); 5 | 6 | int main(void) 7 | { 8 | printf("The biggest value in [2.3, 1.8, 3.5] minus the smallest one," 9 | " the result is: %.1f\n", 10 | get_diff((double []){ 2.3, 1.8, 3.5 }, 3)); 11 | return 0; 12 | } 13 | 14 | double get_diff(double ar[], int n) 15 | { 16 | int i; 17 | double max, min; 18 | for (i = 0, max = ar[i], min = ar[i]; i < n; i++) 19 | { 20 | if (ar[i] > max) 21 | max = ar[i]; 22 | if (ar[i] < min) 23 | min = ar[i]; 24 | } 25 | return max - min; 26 | } -------------------------------------------------------------------------------- /Chapter-10 Arrays and Pointers/exercise/10-6.c: -------------------------------------------------------------------------------- 1 | // 6. 编写一个函数,把double类型数组中的数据倒序排列, 2 | // 并在一个简单的程序中测试该函数。 3 | #include 4 | void printArr(double ar[], int n); 5 | void reverseArr(double source[], double target[], int n); 6 | 7 | int main(void) 8 | { 9 | double ar[5] = {1.1, 2.2, 3.3, 4.4, 5.5}; 10 | double target[5]; 11 | reverseArr(ar, target, 5); 12 | printf("source: "); 13 | printArr(ar, 5); 14 | printf("after reversed: "); 15 | printArr(target, 5); 16 | return 0; 17 | } 18 | 19 | void reverseArr(double source[], double target[], int n) 20 | { 21 | int i; 22 | for (i = 0; i < n; i++) 23 | target[n - 1 - i] = source[i]; 24 | } 25 | 26 | void printArr(double ar[], int n) 27 | { 28 | int i; 29 | for (i = 0; i < n; i++) 30 | printf("%.1f ", ar[i]); 31 | putchar('\n'); 32 | } 33 | -------------------------------------------------------------------------------- /Chapter-10 Arrays and Pointers/exercise/10-7.c: -------------------------------------------------------------------------------- 1 | // 7. 编写一个程序,初始化一个double类型的二维数组, 2 | // 使用编程练习2中的一个拷贝函数把该数组中的数据拷贝至另一个二维数组中 3 | // (因为二维数组是数组的数组,所以可以使用处理一维数组的拷贝函数来处理数组中的 4 | // 每个子数组)。 5 | #include 6 | void copy_arr2d(int rows, int cols, double source[rows][cols], double target[rows][cols]); 7 | void print_arr2d(int rows, int cols, double ar[rows][cols]); 8 | 9 | int main(void) 10 | { 11 | double source[2][2] = { { 1.1, 2.2 }, { 3.3, 4.4 } }; 12 | double target[2][2]; 13 | copy_arr2d(2, 2, source, target); 14 | printf("source: \n"); 15 | print_arr2d(2, 2, source); 16 | printf("target: \n"); 17 | print_arr2d(2, 2, target); 18 | return 0; 19 | } 20 | 21 | void copy_arr2d(int rows, int cols, double source[rows][cols], double target[rows][cols]) 22 | { 23 | int r, c; 24 | for (r = 0; r < rows; r++) 25 | for (c = 0; c < cols; c++) 26 | target[r][c] = source[r][c]; 27 | } 28 | 29 | void print_arr2d(int rows, int cols, double ar[rows][cols]) 30 | { 31 | int r, c; 32 | for (r = 0; r < rows; r++) 33 | { 34 | for (c = 0; c < cols; c++) 35 | printf("%.1f ", ar[r][c]); 36 | putchar('\n'); 37 | } 38 | } -------------------------------------------------------------------------------- /Chapter-10 Arrays and Pointers/exercise/10-8.c: -------------------------------------------------------------------------------- 1 | // 8. 使用编程练习2中的拷贝函数,把一个内含7个元素的数组中第3~第5个元素拷贝 2 | // 至内含3个元素的数组中。该函数本身不需要修改,只需要选择合适的实际参数 3 | // (实际参数不需要是数组名和数组大小,只需要是数组元素的地址和待处理元素的个数)。 4 | #include 5 | void copy_ptrs(double * target, double *start, double *end); 6 | void print_arr(double ar[], int n); 7 | 8 | int main(void) 9 | { 10 | double source[] = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7 }; 11 | double target[3]; 12 | copy_ptrs(target, source + 2, source + 5); 13 | printf("source: "); 14 | print_arr(source, 7); 15 | printf("target: "); 16 | print_arr(target, 3); 17 | return 0; 18 | } 19 | void copy_ptrs(double * target, double *start, double *end) 20 | { 21 | while (start < end) 22 | { 23 | *target = *start; 24 | start++; 25 | target++; 26 | } 27 | } 28 | 29 | 30 | void print_arr(double ar[], int n) 31 | { 32 | int i; 33 | for (i = 0; i < n; i++) 34 | printf("%.1f ", ar[i]); 35 | putchar('\n'); 36 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/README.md: -------------------------------------------------------------------------------- 1 | # 第十一章 字符串和字符串函数 2 | 3 | C字符串是一系列char类型的字符,以空字符('\0')结尾。字符串可以储存在字符数组中。字符串还可以用字符串常量来表示,里面都是字符,括在双引号中(空字符除外)。编译器提供空字符。因此,"joy"被储存为4个字符j、o、y和\0。strlen()函数可以统计字符串的长度,空字符不计算在内。 4 | 5 | 字符串常量也叫作字符串——字面量,可用于初始化字符数组。为了容纳末尾的空字符,数组大小应该至少比容纳的数组长度多1。也可以用字符串常量初始化指向char的指针。 6 | 7 | 函数使用指向字符串首字符的指针来表示待处理的字符串。通常,对应的实际参数是数组名、指针变量或用双引号括起来的字符串。无论是哪种情况,传递的都是首字符的地址。一般而言,没必要传递字符串的长度,因为函数可以通过末尾的空字符确定字符串的结束。 8 | 9 | fgets()函数获取一行输入,puts()和fputs()函数显示一行输出。它们都是stdio.h头文件中的函数,用于代替已被弃用的gets()。 10 | 11 | C库中有多个字符串处理函数。在ANSIC中,这些函数都声明在string.h文件中。C库中还有许多字符处理函数,声明在ctype.h文件中。 12 | 13 | 给main()函数提供两个合适的形式参数,可以让程序访问命令行参数。第1个参数通常是int类型的argc,其值是命令行的单词数量。第2个参数通常是一个指向数组的指针argv,数组内含指向char的指针。每个指向char的指针都指向一个命令行参数字符串,argv[0]指向命令名称,argv[1]指向第1个命令行参数,以此类推。 14 | 15 | atoi()、atol()和atof()函数把字符串形式的数字分别转换成int、long和double类型的数字。strtol()、strtoul()和strtod()函数把字符串形式的数字分别转换成long、unsignedlong和double类型的数字。 -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/example/11.1-strings1.c: -------------------------------------------------------------------------------- 1 | // strings1.c 2 | #include 3 | #define MSG "I am a symbolic string constant." 4 | #define MAXLENGTH 81 5 | int main(void) 6 | { 7 | char words[MAXLENGTH] = "I am a string in an array."; 8 | const char * pt1 = "Something is pointing at me."; 9 | puts("Here are some strings:"); 10 | puts(MSG); 11 | puts(words); 12 | puts(pt1); 13 | words[8] = 'p'; 14 | puts(words); 15 | return 0; 16 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/example/11.10-s_gets.c: -------------------------------------------------------------------------------- 1 | // s_gets.c 2 | #include 3 | 4 | char * s_gets(char * st, int n) 5 | { 6 | char * ret_val; 7 | int i = 0; 8 | ret_val = fgets(st, n, stdin); 9 | if (ret_val) // 即,ret_val != NULL 10 | { 11 | while (st[i] != '\n' && st[i] != '\0') 12 | { 13 | i++; 14 | if (st[i] == '\n') 15 | st[i] = '\0'; 16 | else 17 | while (getchar() != '\n') 18 | continue; 19 | } 20 | return ret_val; 21 | } 22 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/example/11.11-scan_str.c: -------------------------------------------------------------------------------- 1 | // scan_str.c - 使用scanf() 2 | #include 3 | 4 | int main(void) 5 | { 6 | char name1[11], name2[11]; 7 | int count; 8 | printf("Please enter 2 names.\n"); 9 | count = scanf("%5s %10s", name1, name2); 10 | printf("Iread the %d names %s and %s.\n", count, name1, name2); 11 | return 0; 12 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/example/11.12-put_out.c: -------------------------------------------------------------------------------- 1 | // put_out.c - 使用puts() 2 | #include 3 | #define DEF "I am a #defined string." 4 | int main(void) 5 | { 6 | char str1[80] = "An array was initialized to me."; 7 | const char * str2 = "A pointer was initialized to me."; 8 | puts("I'm an argument to puts()."); 9 | puts(DEF); 10 | puts(str1); 11 | puts(str2); 12 | puts(&str1[5]); 13 | puts(str2 + 4); 14 | return 0; 15 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/example/11.13-nono.c: -------------------------------------------------------------------------------- 1 | // nono.c - 千万不要模仿 2 | #include 3 | 4 | int main(void) 5 | { 6 | char side_a[] = "Side A"; 7 | char dont[] = { 'W', 'O', 'W', '!' }; 8 | char side_b[] = "Side B"; 9 | puts(dont); // dont 不是一个字符串 10 | return 0; 11 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/example/11.14-put1.c: -------------------------------------------------------------------------------- 1 | // put1.c - 打印字符串,不添加\n 2 | #include 3 | 4 | void put1(const char * string) 5 | { 6 | while (*string != '\0') 7 | putchar(*string++); 8 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/example/11.15-put2.c: -------------------------------------------------------------------------------- 1 | // put2.c - 打印一个字符串,并统计打印的字符数 2 | #include 3 | 4 | int put2(const char * string) 5 | { 6 | int count = 0; 7 | while (*string) 8 | { 9 | putchar(*string++); 10 | count ++; 11 | } 12 | putchar('\n'); 13 | return count; 14 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/example/11.16-put_put.c: -------------------------------------------------------------------------------- 1 | // put_put.c - 用户自定义输出函数 2 | #include 3 | void put1(const char *); 4 | int put2(const char *); 5 | 6 | int main(void) 7 | { 8 | put1("If I'd as much money"); 9 | put1(" as I could spend,\n"); 10 | printf("I count %d characters.\n", 11 | put2("I never would cry old chairs to mend.")); 12 | return 0; 13 | } 14 | 15 | void put1(const char * string) 16 | { 17 | while (*string) 18 | putchar(*string++); 19 | } 20 | 21 | int put2(const char * string) 22 | { 23 | int count = 0; 24 | while (*string) 25 | { 26 | putchar(*string++); 27 | count++; 28 | } 29 | putchar('\n'); 30 | return count; 31 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/example/11.17-test_fit.c: -------------------------------------------------------------------------------- 1 | // test_fit.c - 使用缩短字符串长度的函数 2 | #include 3 | #include 4 | 5 | void fit(char *, unsigned int); 6 | int main(void) 7 | { 8 | char mesg[] = "Things should be as simple as possible, but not simpler."; 9 | puts(mesg); 10 | fit(mesg, 38); 11 | puts(mesg); 12 | puts("Let's look at some more of the string."); 13 | puts(mesg + 39); 14 | return 0; 15 | } 16 | 17 | void fit(char * string, unsigned int size) 18 | { 19 | if (strlen(string) > size) 20 | string[size] = '\0'; 21 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/example/11.18-str_cat.c: -------------------------------------------------------------------------------- 1 | // str_cat.c - 拼接两个字符串 2 | #include 3 | #include 4 | #define SIZE 80 5 | char * s_gets(char * st, int n); 6 | 7 | int main(void) 8 | { 9 | char flower[SIZE]; 10 | char addon [] = "s smell like old shoes."; 11 | puts("What is your favorite flower?"); 12 | if (s_gets(flower, SIZE)) 13 | { 14 | strcat(flower, addon); 15 | puts(flower); 16 | puts(addon); 17 | } 18 | else 19 | puts("End of file encountered!"); 20 | puts("bye"); 21 | return 0; 22 | } 23 | 24 | char * s_gets(char * st, int n) 25 | { 26 | char * ret_val; 27 | int i = 0; 28 | ret_val = fgets(st, n, stdin); 29 | if (ret_val) 30 | { 31 | while (st[i] != '\n' && st[i] != '\0') 32 | i++; 33 | if (st[i] == '\n') 34 | st[i] = '\0'; 35 | else 36 | while (getchar() != '\n') 37 | continue; 38 | } 39 | return ret_val; 40 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/example/11.19-join_chk.c: -------------------------------------------------------------------------------- 1 | // join_chk.c - 拼接两个字符串,检查第一个数组的大小 2 | #include 3 | #include 4 | #define SIZE 30 5 | #define BUGSIZE 13 6 | char * s_gets(char * st, int n); 7 | 8 | int main(void) 9 | { 10 | char flower[SIZE]; 11 | char addon [] = "s smell like old shoes."; 12 | char bug[BUGSIZE]; 13 | int available; 14 | puts("What is your favorite flower?"); 15 | s_gets(flower, SIZE); 16 | if ((strlen(addon) + strlen(flower) + 1) <= SIZE) 17 | strcat(flower, addon); 18 | puts(flower); 19 | puts("What is your favorite bug?"); 20 | s_gets(bug, BUGSIZE); 21 | available = BUGSIZE - strlen(bug) - 1; 22 | strncat(bug, addon, available); 23 | puts(bug); 24 | return 0; 25 | } 26 | 27 | char * s_gets(char * st, int n) 28 | { 29 | char * ret_val; 30 | int i = 0; 31 | ret_val = fgets(st, n, stdin); 32 | if (ret_val) 33 | { 34 | while (st[i] != '\n' && st[i] != '\0') 35 | i++; 36 | if (st[i] == '\n') 37 | st[i] = '\0'; 38 | else 39 | while (getchar() != '\n') 40 | continue; 41 | } 42 | return ret_val; 43 | } 44 | 45 | -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/example/11.2-strptr.c: -------------------------------------------------------------------------------- 1 | // strptr.c - 把字符串看作指针 2 | #include 3 | int main(void) 4 | { 5 | printf("%s, %p, %c\n", "We", "are", *"space farers"); 6 | return 0; 7 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/example/11.20-nogo.c: -------------------------------------------------------------------------------- 1 | // nogo.c - 该程序是否能正常运行? 2 | #include 3 | #define ANSWER "Grant" 4 | #define SIZE 40 5 | char * s_gets(char *st, int n); 6 | int main(void) 7 | { 8 | char try[SIZE]; 9 | puts("Who is buried in Grant's tomb?"); 10 | s_gets(try, SIZE); 11 | while (try != ANSWER) 12 | { 13 | puts("No, that's wrong, Try again."); 14 | s_gets(try, SIZE); 15 | } 16 | puts("That's right!"); 17 | return 0; 18 | } 19 | 20 | char * s_gets(char * st, int n) 21 | { 22 | char * ret_val; 23 | int i = 0; 24 | ret_val = fgets(st, n, stdin); 25 | if (ret_val) 26 | { 27 | while (st[i] != '\n' && st[i] != '\0') 28 | i++; 29 | if (st[i] == '\n') 30 | st[i] = '\0'; 31 | else 32 | while (getchar() != '\n') 33 | continue; 34 | } 35 | return ret_val; 36 | } 37 | -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/example/11.21-compare.c: -------------------------------------------------------------------------------- 1 | // compare.c - 该程序能正常运行 2 | #include 3 | #include 4 | #define ANSWER "Grant" 5 | #define SIZE 40 6 | char * s_gets(char *st, int n); 7 | int main(void) 8 | { 9 | char try[SIZE]; 10 | puts("Who is buried in Grant's tomb?"); 11 | s_gets(try, SIZE); 12 | while (strcmp(try, ANSWER) != 0) 13 | { 14 | puts("No, that's wrong, Try again."); 15 | s_gets(try, SIZE); 16 | } 17 | puts("That's right!"); 18 | return 0; 19 | } 20 | 21 | char * s_gets(char * st, int n) 22 | { 23 | char * ret_val; 24 | int i = 0; 25 | ret_val = fgets(st, n, stdin); 26 | if (ret_val) 27 | { 28 | while (st[i] != '\n' && st[i] != '\0') 29 | i++; 30 | if (st[i] == '\n') 31 | st[i] = '\0'; 32 | else 33 | while (getchar() != '\n') 34 | continue; 35 | } 36 | return ret_val; 37 | } 38 | -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/example/11.22-compback.c: -------------------------------------------------------------------------------- 1 | // compback.c - strcmp()的返回值 2 | #include 3 | #include 4 | int main(void) 5 | { 6 | printf("strcmp(\"A\", \"A\") is "); 7 | printf("%d\n", strcmp("A", "A")); 8 | printf("strcmp(\"A\", \"B\") is "); 9 | printf("%d\n", strcmp("A", "B")); 10 | printf("strcmp(\"B\", \"A\") is "); 11 | printf("%d\n", strcmp("B", "A")); 12 | printf("strcmp(\"C\", \"A\") is "); 13 | printf("%d\n", strcmp("C", "A")); 14 | printf("strcmp(\"Z\", \"a\") is "); 15 | printf("%d\n", strcmp("Z", "a")); 16 | printf("strcmp(\"apples\", \"apple\") is "); 17 | printf("%d\n", strcmp("apples", "apple")); 18 | return 0; 19 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/example/11.23-quit_chk.c: -------------------------------------------------------------------------------- 1 | // quit_chk.c - 某程序的开始部分 2 | #include 3 | #include 4 | #define SIZE 80 5 | #define LIM 10 6 | #define STOP "quit" 7 | char * s_gets(char * st, int n); 8 | 9 | int main(void) 10 | { 11 | char input[LIM][SIZE]; 12 | int ct = 0; 13 | printf("Enter up to %d lines (type quit to quit):\n", LIM); 14 | while (ct < LIM && s_gets(input[ct], SIZE) != NULL && strcmp(input[ct], STOP) != 0) 15 | { 16 | ct++; 17 | } 18 | printf("%d strings entered\n", ct); 19 | return 0; 20 | } 21 | 22 | char * s_gets(char * st, int n) 23 | { 24 | char * ret_val; 25 | int i = 0; 26 | ret_val = fgets(st, n, stdin); 27 | if (ret_val) 28 | { 29 | while (st[i] != '\n' && st[i] != '\0') 30 | i++; 31 | if (st[i] == '\n') 32 | st[i] = '\0'; 33 | else 34 | while (getchar() != '\n') 35 | continue; 36 | } 37 | return ret_val; 38 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/example/11.24-starsrch.c: -------------------------------------------------------------------------------- 1 | // starsrch.c - 使用strncmp() 2 | #include 3 | #include 4 | #define LISTSIZE 6 5 | 6 | int main() 7 | { 8 | const char * list[LISTSIZE] = { 9 | "astronomy", "astounding", 10 | "astrophysics", "ostracize", 11 | "asterism", "astrophobia" 12 | }; 13 | int count = 0; 14 | int i; 15 | for (i = 0; i < LISTSIZE; i++) 16 | if (strncmp(list[i], "astro", 5) == 0) 17 | { 18 | printf("Found: %s\n", list[i]); 19 | count++; 20 | } 21 | printf("The list contained %d words" 22 | " beginning with astro.\n", count); 23 | return 0; 24 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/example/11.25-copy1.c: -------------------------------------------------------------------------------- 1 | // copy1.c - 演示strcpy() 2 | #include 3 | #include 4 | #define SIZE 40 5 | #define LIM 5 6 | char * s_gets(char * st, int n); 7 | 8 | int main(void) 9 | { 10 | char qwords[LIM][SIZE]; 11 | char temp[SIZE]; 12 | int i = 0; 13 | printf("Enter %d words beginning with q:\n", LIM); 14 | while (i < LIM && s_gets(temp, SIZE)) 15 | { 16 | if (temp[0] != 'q') 17 | printf("%s doesn't begin with q!\n", temp); 18 | else 19 | { 20 | strcpy(qwords[i], temp); 21 | i++; 22 | } 23 | } 24 | puts("Here are the words accepted:"); 25 | for (i = 0; i < LIM; i++) 26 | puts(qwords[i]); 27 | return 0; 28 | } 29 | 30 | char * s_gets(char * st, int n) 31 | { 32 | char * ret_val; 33 | int i = 0; 34 | ret_val = fgets(st, n, stdin); 35 | if (ret_val) 36 | { 37 | while (st[i] != '\n' && st[i] != '\0') 38 | i++; 39 | if (st[i] == '\n') 40 | st[i] = '\0'; 41 | else 42 | while (getchar() != '\n') 43 | continue; 44 | } 45 | return ret_val; 46 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/example/11.26-copy2.c: -------------------------------------------------------------------------------- 1 | // copy2.c - 使用strcpy() 2 | #include 3 | #include 4 | #define WORDS "beast" 5 | #define SIZE 40 6 | int main(void) 7 | { 8 | const char * orig = WORDS; 9 | char copy[SIZE] = "Be the best that you can be."; 10 | char * ps; 11 | puts(orig); 12 | puts(copy); 13 | ps = strcpy(copy + 7, orig); 14 | puts(copy); 15 | puts(ps); 16 | return 0; 17 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/example/11.27-copy3.c: -------------------------------------------------------------------------------- 1 | // copy3.c - 使用strncpy() 2 | #include 3 | #include 4 | #define SIZE 40 5 | #define TARGSIZE 7 6 | #define LIM 5 7 | char * s_gets(char * st, int n); 8 | 9 | int main(void) 10 | { 11 | char qwords[LIM][TARGSIZE]; 12 | char temp[SIZE]; 13 | int i = 0; 14 | printf("Enter %d words beginning with q:\n", LIM); 15 | while (i < LIM && s_gets(temp, SIZE)) 16 | { 17 | if (temp[0] != 'q') 18 | printf("%s doesn't begin with q!\n", temp); 19 | else 20 | { 21 | strncpy(qwords[i], temp, TARGSIZE - 1); 22 | qwords[i][TARGSIZE - 1] = '\0'; 23 | i++; 24 | } 25 | } 26 | puts("Here are the words accepted:"); 27 | for (i = 0; i < LIM; i++) 28 | puts(qwords[i]); 29 | return 0; 30 | } 31 | 32 | char * s_gets(char * st, int n) 33 | { 34 | char * ret_val; 35 | int i = 0; 36 | ret_val = fgets(st, n, stdin); 37 | if (ret_val) 38 | { 39 | while (st[i] != '\n' && st[i] != '\0') 40 | i++; 41 | if (st[i] == '\n') 42 | st[i] = '\0'; 43 | else 44 | while (getchar() != '\n') 45 | continue; 46 | } 47 | return ret_val; 48 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/example/11.28-format.c: -------------------------------------------------------------------------------- 1 | // format.c - 格式化字符串 2 | #include 3 | #define MAX 20 4 | char * s_gets(char * st, int n); 5 | int main(void) 6 | { 7 | char first[MAX]; 8 | char last[MAX]; 9 | char formal[2 * MAX + 10]; 10 | double prize; 11 | puts("Enter your first name:"); 12 | s_gets(first, MAX); 13 | puts("Enter your last name:"); 14 | s_gets(last, MAX); 15 | puts("Enter your prize money;"); 16 | scanf("%lf", &prize); 17 | sprintf(formal, "%s, %-19s: $%6.2f\n", last, first, prize); 18 | puts(formal); 19 | return 0; 20 | } 21 | 22 | char * s_gets(char * st, int n) 23 | { 24 | char * ret_val; 25 | int i = 0; 26 | ret_val = fgets(st, n, stdin); 27 | if (ret_val) 28 | { 29 | while (st[i] != '\n' && st[i] != '\0') 30 | i++; 31 | if (st[i] == '\n') 32 | st[i] = '\0'; 33 | else 34 | while (getchar() != '\n') 35 | continue; 36 | } 37 | return ret_val; 38 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/example/11.3-addresses.c: -------------------------------------------------------------------------------- 1 | // addresses.c - 字符串的地址 2 | #define MSG "I'm special" 3 | #include 4 | 5 | int main(void) 6 | { 7 | char ar[] = MSG; 8 | const char *pt = MSG; 9 | printf("address of \"I'm special\": %p \n", "I'm special"); 10 | printf(" address ar: %p\n", ar); 11 | printf(" address pt: %p\n", pt); 12 | printf(" address of MSG: %p\n", MSG); 13 | printf("address of \"I'm special\": %p \n", "I'm special"); 14 | return 0; 15 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/example/11.30-mod_str.c: -------------------------------------------------------------------------------- 1 | // mod_str.c - 修改字符串 2 | #include 3 | #include 4 | #include 5 | #define LIMIT 81 6 | void ToUpper(char *); 7 | int PunctCount(const char *); 8 | int main(void) 9 | { 10 | char line[LIMIT]; 11 | char * find; 12 | puts("Please enter a line:"); 13 | fgets(line, LIMIT, stdin); 14 | find = strchr(line, '\n'); 15 | if (find) 16 | *find = '\0'; 17 | ToUpper(line); 18 | puts(line); 19 | printf("That line has %d punctuation characters.\n", PunctCount(line)); 20 | return 0; 21 | } 22 | 23 | void ToUpper(char * str) 24 | { 25 | while (*str) 26 | { 27 | *str = toupper(*str); 28 | str++; 29 | } 30 | } 31 | 32 | int PunctCount(const char * str) 33 | { 34 | int ct = 0; 35 | while (*str) 36 | { 37 | if (ispunct(*str)) 38 | ct++; 39 | str++; 40 | } 41 | return ct; 42 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/example/11.31-repeat.c: -------------------------------------------------------------------------------- 1 | // repeat.c - 带参数的main() 2 | #include 3 | int main(int argc, char * argv[]) 4 | { 5 | int count; 6 | printf("The command line has %d arguments:\n", argc - 1); 7 | for (count = 1; count < argc; count++) 8 | printf("%d: %s\n", count, argv[count]); 9 | printf("\n"); 10 | return 0; 11 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/example/11.32-hello.c: -------------------------------------------------------------------------------- 1 | // hello.c - 把命令行参数转换为数字 2 | #include 3 | #include 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | int i, times; 8 | if (argc < 2 || (times = atoi(argv[1])) < 1) 9 | printf("Usage: %s positive-number\n", argv[0]); 10 | else 11 | for (i = 0; i < times; i++) 12 | puts("Hello, good looking!"); 13 | return 0; 14 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/example/11.33-strcnvt.c: -------------------------------------------------------------------------------- 1 | // strcnvt.c - 使用strtol() 2 | #include 3 | #include 4 | #define LIM 30 5 | char * s_gets(char * st, int n); 6 | int main() 7 | { 8 | char number[LIM]; 9 | char * end; 10 | long value; 11 | puts("Enter a number (empty line to quit):"); 12 | while (s_gets(number, LIM) && number[0] != '\0') 13 | { 14 | value = strtol(number, &end, 10); 15 | printf("base 10 input, base 10 output: %ld, stopped at %s(%d)\n", 16 | value, end, *end); 17 | value = strtol(number, &end, 16); 18 | printf("base 16 input, base 10 output: %ld, stopped at %s(%d)\n", 19 | value, end, *end); 20 | puts("Next number:"); 21 | } 22 | puts("Bye!"); 23 | return 0; 24 | } 25 | 26 | char * s_gets(char * st, int n) 27 | { 28 | char * ret_val; 29 | int i = 0; 30 | ret_val = fgets(st, n, stdin); 31 | if (ret_val) 32 | { 33 | while (st[i] != '\n' && st[i] != '\0') 34 | i++; 35 | if (st[i] == '\n') 36 | st[i] = '\0'; 37 | else 38 | while (getchar() != '\n') 39 | continue; 40 | } 41 | return ret_val; 42 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/example/11.4-arrchar.c: -------------------------------------------------------------------------------- 1 | // arrchar.c - 指针数组,字符串数组 2 | #include 3 | #define SLEN 40 4 | #define LIM 5 5 | 6 | int main(void) 7 | { 8 | const char *mytalents[LIM] = { 9 | "Adding numbers swiftly", 10 | "Multiplying accurately", 11 | "Stashing data", 12 | "Following instructions to the letter", 13 | "Understanding the C language" 14 | }; 15 | char yourtalents[LIM][SLEN] = { 16 | "Walking in a straight line", 17 | "Sleeping", 18 | "Watching television", 19 | "Mailing letters", 20 | "Reading email" 21 | }; 22 | int i; 23 | puts("Let's compare talents."); 24 | printf("%-36s %-25s\n", "My Talents", "Your Talents"); 25 | for (i = 0; i < LIM; i++) 26 | printf("%-36s %-25s\n", mytalents[i], yourtalents[i]); 27 | printf("\nsizeof mytalents: %zd, sizeof yourtalents: %zd\n", 28 | sizeof(mytalents), sizeof(yourtalents)); 29 | return 0; 30 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/example/11.5-p_and_s.c: -------------------------------------------------------------------------------- 1 | // p_and_s.c - 指针和字符串 2 | #include 3 | int main(void) 4 | { 5 | const char * mesg = "Don't be a fool!"; 6 | const char * copy; 7 | copy = mesg; 8 | printf("%s\n", copy); 9 | printf("mesg = %s; &mesg = %p; value = %p\n", mesg, &mesg, mesg); 10 | printf("copy = %s; © = %p; value = %p\n", copy, ©, copy); 11 | return 0; 12 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/example/11.6-getsputs.c: -------------------------------------------------------------------------------- 1 | // getsputs.c - 使用gets()和puts() 2 | #include 3 | #define STLEN 81 4 | int main(void) 5 | { 6 | char words[STLEN]; 7 | puts("Enter a string, please."); 8 | gets(words); 9 | printf("Your string twice:\n"); 10 | printf("%s\n", words); 11 | puts(words); 12 | puts("Done."); 13 | return 0; 14 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/example/11.7-fgets1.c: -------------------------------------------------------------------------------- 1 | // fgets1.c - 使用fgets()和fputs() 2 | #include 3 | #define STLEN 14 4 | 5 | int main(void) 6 | { 7 | char words[STLEN]; 8 | puts("Enter a string, please."); 9 | fgets(words, STLEN, stdin); 10 | printf("Yourt string twice (puts(), then fputs()):\n"); 11 | puts(words); 12 | fputs(words, stdout); 13 | puts("Enter another string, please."); 14 | fgets(words, STLEN, stdin); 15 | printf("Yourt string twice (puts(), then fputs()):\n"); 16 | puts(words); 17 | fputs(words, stdout); 18 | puts("Done."); 19 | return 0; 20 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/example/11.8-fgets2.c: -------------------------------------------------------------------------------- 1 | // fgets2.c - 使用fgets()和fputs() 2 | #include 3 | #define STLEN 10 4 | int main(void) 5 | { 6 | char words[STLEN]; 7 | puts("Enter strings (empty line to quit):"); 8 | while (fgets(words, STLEN, stdin) != NULL && words[0] != '\n') 9 | fputs(words, stdout); 10 | puts("Done."); 11 | return 0; 12 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/example/11.9-fgets3.c: -------------------------------------------------------------------------------- 1 | // fgets3.c - 使用fgets() 2 | #include 3 | #define STLEN 10 4 | int main(void) 5 | { 6 | char words[STLEN]; 7 | int i; 8 | puts("Enter string (empty line to quit):"); 9 | while (fgets(words, STLEN, stdin) != NULL && words[0] != '\n') 10 | { 11 | i = 0; 12 | while (words[i] != '\n' && words[i] != '\0') 13 | i++; 14 | if (words[i] == '\n') 15 | words[i] = '\0'; 16 | else 17 | while (getchar() != '\n') 18 | continue; 19 | puts(words); 20 | } 21 | puts("done"); 22 | return 0; 23 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/exercise/11-1.c: -------------------------------------------------------------------------------- 1 | // 1. 设计并测试一个函数,从输入中获取下n个字符(包括空白、制表 符、换行符), 2 | // 把结果储存在一个数组里,它的地址被传递作为一个参数。 3 | #include 4 | #define LIM 40 5 | char * get_chars(char * st, int n); 6 | 7 | int main(void) 8 | { 9 | char string[LIM]; 10 | char * check; 11 | printf("Enter %d characters, please:\n", LIM - 1); 12 | check = get_chars(string, LIM - 1); 13 | if (check) 14 | printf("Your input is:\n %s\n", string); 15 | else 16 | puts("Input error!"); 17 | return 0; 18 | } 19 | 20 | char * get_chars(char * st, int n){ 21 | int i, ch; 22 | for (i = 0; i < n; i++) 23 | { 24 | ch = getchar(); 25 | if (ch == EOF) 26 | break; 27 | else 28 | *(st + i) = ch; 29 | } 30 | return (ch == EOF && i == 0) ? NULL : st; 31 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/exercise/11-10.c: -------------------------------------------------------------------------------- 1 | // 10. 编写一个函数接受一个字符串作为参数,并删除字符串中的空格。 2 | // 在一个程序中测试该函数,使用循环读取输入行,直到用户输入一行空行。 3 | // 该程序应该应用该函数只每个输入的字符串,并显示处理后的字符串。 4 | #include 5 | #define LIM 40 6 | char * s_gets(char * st, int n); 7 | void del_blank(char *st); 8 | 9 | int main(void) 10 | { 11 | char st[LIM]; 12 | printf("Enter a string: "); 13 | while (s_gets(st, LIM -1) && st[0] != '\0') 14 | { 15 | printf("Before delete blank: \n %s\n", st); 16 | del_blank(st); 17 | printf("After delete blank: \n %s\n", st); 18 | printf("Enter next string(blank line to quit): "); 19 | } 20 | puts("Done."); 21 | return 0; 22 | } 23 | 24 | char * s_gets(char * st, int n) 25 | { 26 | char * ret_val; 27 | int i = 0; 28 | ret_val = fgets(st, n, stdin); 29 | if (ret_val) 30 | { 31 | while (st[i] != '\n' && st[i] != '\0') 32 | i++; 33 | if (st[i] == '\n') 34 | st[i] = '\0'; 35 | else 36 | while (getchar() != '\n') 37 | continue; 38 | } 39 | return ret_val; 40 | } 41 | 42 | void del_blank(char * st) 43 | { 44 | char * pt; 45 | while (*st) { 46 | if (*st == ' ') 47 | { 48 | pt = st; 49 | do 50 | { 51 | *pt = *(pt + 1); 52 | } while (*++pt); 53 | } 54 | else 55 | st++; 56 | } 57 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/exercise/11-12.c: -------------------------------------------------------------------------------- 1 | // 12. 编写一个程序,读取输入,直至读到EOF, 2 | // 报告读入的单词数、大写字母数、小写字母数、标点符号数和数字字符数。 3 | // 使用ctype.h头文件中的函数。 4 | #include 5 | #include 6 | #include 7 | 8 | int main(void) 9 | { 10 | char ch; 11 | int words_ct = 0; 12 | int upper_ct = 0; 13 | int lower_ct = 0; 14 | int punct_ct = 0; 15 | int num_ct = 0; 16 | bool is_in_word = false; 17 | puts("Enter text to be analyzed(EOF to quit):"); 18 | while ((ch = getchar()) != EOF) 19 | { 20 | if (!isspace(ch) && !is_in_word) 21 | { 22 | is_in_word = true; 23 | words_ct++; 24 | } 25 | if (isspace(ch) && is_in_word) 26 | is_in_word = false; 27 | if (isalpha(ch)) 28 | { 29 | if (isupper(ch)) 30 | upper_ct++; 31 | if (islower(ch)) 32 | lower_ct++; 33 | } 34 | if (ispunct(ch)) 35 | punct_ct++; 36 | if (isnumber(ch)) 37 | num_ct++; 38 | } 39 | puts(""); 40 | printf("You entered %d words, %d uppers, %d lowers, %d puncts, %d numbers\n", 41 | words_ct, upper_ct, lower_ct, punct_ct, num_ct); 42 | return 0; 43 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/exercise/11-13.c: -------------------------------------------------------------------------------- 1 | // 13. 编写一个程序,反序显示命令行参数的单词。 2 | // 例如,命令行参数是 see you later,该程序应打印later you see。 3 | #include 4 | 5 | int main(int argc, char * argv[]) 6 | { 7 | int i; 8 | for (i = 0; i < argc - 1; i++) 9 | { 10 | printf("%s",argv[argc - 1 - i]); 11 | if (i < argc - 2) 12 | printf(" "); 13 | else 14 | printf("\n"); 15 | } 16 | return 0; 17 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/exercise/11-14.c: -------------------------------------------------------------------------------- 1 | // 14. 编写一个通过命令行运行的程序计算幂。第1个命令行参数是double类型的数, 2 | // 作为幂的底数,第2个参数是整数,作为幂的指数。 3 | #include 4 | #include 5 | #include 6 | 7 | int main(int argc, char * argv[]) 8 | { 9 | double num; 10 | int exp; 11 | if (argc < 3) 12 | puts("Usage: "); 13 | else 14 | { 15 | num = atof(argv[1]); 16 | exp = atoi(argv[2]); 17 | printf("%.2f ^ %d = %.2f\n", num, exp, pow(num, (double)exp)); 18 | } 19 | return 0; 20 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/exercise/11-15.c: -------------------------------------------------------------------------------- 1 | // 15. 使用字符分类函数实现atoi()函数。如果输入的字符串不是纯数字, 2 | // 该函数返回0。 3 | #include 4 | #include 5 | 6 | int my_atoi(char * st); 7 | int get_num(char ch); 8 | 9 | int main(void) 10 | { 11 | printf("my_atoi(\"123\") = %d\n", my_atoi("123")); 12 | printf("my_atoi(\"123a\") = %d\n", my_atoi("123a")); 13 | return 0; 14 | } 15 | 16 | int my_atoi(char * st) 17 | { 18 | int num; 19 | while (*st) 20 | { 21 | if (isnumber(*st)) 22 | { 23 | num = num * 10 + get_num(*st); 24 | st++; 25 | } 26 | else 27 | return 0; 28 | } 29 | return num; 30 | } 31 | 32 | int get_num(char ch) 33 | { 34 | int num; 35 | switch (ch) 36 | { 37 | case '0': 38 | num = 0; 39 | break; 40 | case '1': 41 | num = 1; 42 | break; 43 | case '2': 44 | num = 2; 45 | break; 46 | case '3': 47 | num = 3; 48 | break; 49 | case '4': 50 | num = 4; 51 | break; 52 | case '5': 53 | num = 5; 54 | break; 55 | case '6': 56 | num = 6; 57 | break; 58 | case '7': 59 | num = 7; 60 | break; 61 | case '8': 62 | num = 8; 63 | break; 64 | case '9': 65 | num = 9; 66 | break; 67 | default: 68 | num = 0; 69 | break; 70 | } 71 | return num; 72 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/exercise/11-16.c: -------------------------------------------------------------------------------- 1 | // 16. 编写一个程序读取输入,直至读到文件结尾,然后把字符串打印出来。 2 | // 该程序识别和实现下面的命令行参数: 3 | // -p 按原样打印 4 | // -u 把输入全部转换成大写 5 | // -l 把输入全部转换成小写 6 | // 如果没有命令行参数,则让程序像是使用了-p参数那样运行。 7 | #include 8 | #include 9 | 10 | int main(int argc, char * argv[]) 11 | { 12 | char mode, ch; 13 | int valid = 0; 14 | if (argc > 2) 15 | printf("Usage: %s [-p | -u | -l]\n", argv[0]); 16 | else if (argc == 2) 17 | { 18 | if (argv[1][0] == '-') 19 | { 20 | mode = argv[1][1]; 21 | if (mode == 'p' || mode == 'u' || mode == 'l') 22 | valid = 1; 23 | } 24 | else 25 | { 26 | printf("Usage: %s [-p | -u | -l]\n", argv[0]); 27 | } 28 | } 29 | else 30 | { 31 | mode = 'p'; 32 | valid = 1; 33 | } 34 | 35 | if (!valid) 36 | return 0; 37 | while ((ch = getchar()) != EOF) 38 | { 39 | switch (mode) 40 | { 41 | case 'p': 42 | putchar(ch); 43 | break; 44 | case 'u': 45 | putchar(toupper(ch)); 46 | break; 47 | case 'l': 48 | putchar(tolower(ch)); 49 | break; 50 | default: 51 | break; 52 | } 53 | } 54 | printf("\n"); 55 | return 0; 56 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/exercise/11-2.c: -------------------------------------------------------------------------------- 1 | // 2. 修改并编程练习1的函数,在n个字符后停止,或在读到第1个空白、制表符或换行符时停止, 2 | // 哪个先遇到哪个停止。不能只使用scanf()。 3 | #include 4 | #include 5 | #define LIM 40 6 | char * get_chars(char * st, int n); 7 | 8 | int main(void) 9 | { 10 | char string[LIM]; 11 | char * check; 12 | printf("Enter %d characters, please:\n", LIM - 1); 13 | check = get_chars(string, LIM - 1); 14 | if (check) 15 | printf("Your input is:\n %s\n", string); 16 | else 17 | puts("No input!"); 18 | return 0; 19 | } 20 | 21 | char * get_chars(char * st, int n){ 22 | int i, ch; 23 | for (i = 0; i < n; i++) 24 | { 25 | ch = getchar(); 26 | if (ch == EOF || isspace(ch)) 27 | break; 28 | else 29 | *(st + i) = ch; 30 | } 31 | return (i == 0) ? NULL : st; 32 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/exercise/11-3.c: -------------------------------------------------------------------------------- 1 | // 3. 设计并测试一个函数,从一行输入中把一个单词读入一个数组中, 2 | // 并丢弃输入行中的其余字符。该函数应该跳过第1个非空白字符前面的所有空白。 3 | // 将一个单词定义为没有空白、制表符或换行符的字符序列。 4 | #include 5 | #include 6 | char * get_word(char * st); 7 | 8 | int main(void) 9 | { 10 | char word[40]; 11 | char * check; 12 | printf("Please enter a word: "); 13 | check = get_word(word); 14 | if (check) 15 | printf("The word you input is: \"%s\"\n", word); 16 | else 17 | puts("No input."); 18 | return 0; 19 | } 20 | 21 | char * get_word(char * st) 22 | { 23 | int count; 24 | char ch; 25 | char * cp = st; 26 | while (isspace(ch = getchar())) 27 | continue; 28 | if (ch == EOF) 29 | return NULL; 30 | else 31 | *st++ = ch; 32 | while ((ch = getchar()) != EOF && !isspace(ch)) 33 | *st++ = ch; 34 | *st = '\0'; 35 | if (ch == EOF) 36 | return st; 37 | else 38 | while (ch != '\n') 39 | ch = getchar(); 40 | return cp; 41 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/exercise/11-4.c: -------------------------------------------------------------------------------- 1 | // 4.设计并测试一个函数,它类似编程练习3的描述, 2 | // 只不过它接受第2个参数指明可读取的最大字符数。 3 | #include 4 | #include 5 | char * get_word(char * st, int n); 6 | 7 | int main(void) 8 | { 9 | char word[10]; 10 | char * check; 11 | printf("Please enter a word: "); 12 | check = get_word(word, 9); 13 | if (check) 14 | printf("The word you input is: \"%s\"\n", word); 15 | else 16 | puts("No input."); 17 | return 0; 18 | } 19 | 20 | char * get_word(char * st, int n) 21 | { 22 | int count = 0; 23 | char ch; 24 | char * cp = st; 25 | while (isspace(ch = getchar())) 26 | continue; 27 | if (ch == EOF) 28 | return NULL; 29 | else 30 | { 31 | *st++ = ch; 32 | count++; 33 | } 34 | while (count < n && (ch = getchar()) != EOF && !isspace(ch)) 35 | { 36 | *st++ = ch; 37 | count++; 38 | } 39 | *st = '\0'; 40 | if (ch == EOF) 41 | return st; 42 | else 43 | while (ch != '\n') 44 | ch = getchar(); 45 | return cp; 46 | } -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/exercise/11-5.c: -------------------------------------------------------------------------------- 1 | // 5.设计并测试一个函数,搜索第1个函数形参指定的字符串, 2 | // 在其中查找第2个函数形参指定的字符首次出现的位置。 3 | // 如果成功,该函数返指向该字符的指针,如果在字符串中未找到指定字符, 4 | // 则返回空指针(该函数的功能与strchr()函数相同)。 5 | // 在一个完整的程序中测试该函数,使用一个循环给函数提供输入值。 6 | #include 7 | #define MESSAGE "Be the best you can be" 8 | char * strchr(char * st, char ch); 9 | 10 | int main(void) 11 | { 12 | char * start = MESSAGE; 13 | char * pt = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 14 | char * chp; 15 | 16 | printf("MESSAGE = \"%s\"\n", MESSAGE); 17 | while (*pt) 18 | { 19 | chp = strchr(MESSAGE, *pt); 20 | if (chp) 21 | printf("char = %c, address = %p\n", *chp, chp); 22 | else 23 | printf("'%c' not found in MESSAGE.\n", *pt); 24 | pt++; 25 | } 26 | return 0; 27 | } 28 | 29 | char * strchr(char * st, char ch) 30 | { 31 | char * pt; 32 | while (*st && ch != *st) 33 | st++; 34 | return *st ? st : NULL; 35 | } 36 | -------------------------------------------------------------------------------- /Chapter-11 Character Strings and String Functions/exercise/11-9.c: -------------------------------------------------------------------------------- 1 | // 9. 编写一个函数,把字符串中的内容用其反序字符串代替。 2 | // 在一个完整的程序中测试该函数,使用一个循环给函数提供输入值。 3 | #include 4 | #include 5 | #define LEN 81 6 | 7 | void reverse_str(char * str); 8 | char * s_gets(char * st, int n); 9 | 10 | int main (void) 11 | { 12 | char string[LEN]; 13 | 14 | puts("Enter the string to reverse: "); 15 | while(s_gets(string,LEN) != NULL && string[0] != '\0') 16 | { 17 | reverse_str(string); 18 | puts(string); 19 | puts("Enter the string to reverse(enter a new line to quit): "); 20 | } 21 | puts("Done."); 22 | return 0; 23 | } 24 | 25 | void reverse_str(char * str) 26 | { 27 | char temp; 28 | int len = strlen(str); 29 | int i; 30 | for (i = 0; i < len / 2; i++) 31 | { 32 | temp = str[i]; 33 | str[i] = str[len - 1 - i]; 34 | str[len - 1 - i] = temp; 35 | } 36 | } 37 | 38 | char * s_gets(char * st, int n) 39 | { 40 | char * ret_val; 41 | int i = 0; 42 | 43 | ret_val = fgets(st, n, stdin); 44 | if (ret_val) 45 | { 46 | while (st[i] != '\n' && st[i] != '\0') 47 | i++; 48 | if (st[i] == '\n') 49 | st[i] = '\0'; 50 | else 51 | while (getchar() != '\n') 52 | continue; 53 | } 54 | return ret_val; 55 | } -------------------------------------------------------------------------------- /Chapter-12 Storage Classes, Linkage, and Memory Management/example/12.1-hiding.c: -------------------------------------------------------------------------------- 1 | // hiding.c - 块中的变量 2 | #include 3 | int main() 4 | { 5 | int x = 30; 6 | printf("x in outer block: %d at %p\n", x, &x); 7 | { 8 | int x = 77; 9 | printf("x in inner block: %d at %p\n", x, &x); 10 | } 11 | printf("x in outer block: %d at %p\n", x, &x); 12 | while (x++ < 33) 13 | { 14 | int x = 100; 15 | x++; 16 | printf("x in while loop: %d at %p\n", x, &x); 17 | } 18 | printf("x in outer block: %d at %p\n", x, &x); 19 | return 0; 20 | } -------------------------------------------------------------------------------- /Chapter-12 Storage Classes, Linkage, and Memory Management/example/12.10-r_drive1.c: -------------------------------------------------------------------------------- 1 | // r_drive1.c - 测试rand1和srand1() 2 | // 与s_and_r.c一起编译 3 | #include 4 | #include 5 | extern void srand1(unsigned int x); 6 | extern int rand1(void); 7 | 8 | int main(void) 9 | { 10 | int count; 11 | unsigned seed; 12 | printf("Please enter your choice for seed.\n"); 13 | while (scanf("%u", &seed) == 1) 14 | { 15 | srand1(seed); // 重置种子 16 | for (count = 0; count < 5; count++) 17 | printf("%d\n", rand1()); 18 | printf("Please enter next seed(q to quit):\n"); 19 | } 20 | printf("Done\n"); 21 | return 0; 22 | } -------------------------------------------------------------------------------- /Chapter-12 Storage Classes, Linkage, and Memory Management/example/12.11-diceroll.c: -------------------------------------------------------------------------------- 1 | // diceroll.c - 掷骰子模拟程序 2 | // 与12.13-mandydice.c 一起编译 3 | #include "12.12-diceroll.h" 4 | #include 5 | #include // 提供库函数rand()的原型 6 | int roll_count = 0; // 外部链接 7 | static int rollem(int sides) // 该函数属于该文件私有 8 | { 9 | int roll; 10 | roll = rand() % sides + 1; 11 | ++roll_count; // 计算函数调用次数 12 | return roll; 13 | } 14 | 15 | int roll_n_dice(int dice, int sides) 16 | { 17 | int d; 18 | int total = 0; 19 | if (sides < 2) 20 | { 21 | printf("Need at least 2 sides.\n"); 22 | return -2; 23 | } 24 | if (dice < 1) 25 | { 26 | printf("Need at least 1 die.\n"); 27 | return -1; 28 | } 29 | for (d = 0; d < dice; d++) 30 | total += rollem(sides); 31 | return total; 32 | } -------------------------------------------------------------------------------- /Chapter-12 Storage Classes, Linkage, and Memory Management/example/12.12-diceroll.h: -------------------------------------------------------------------------------- 1 | // diceroll.h 2 | extern int roll_count; 3 | int roll_n_dice(int dice, int sides); -------------------------------------------------------------------------------- /Chapter-12 Storage Classes, Linkage, and Memory Management/example/12.13-manydice.c: -------------------------------------------------------------------------------- 1 | // manydice.c - 多次掷骰子的模拟程序 2 | // 与12.11-diceroll.c一起编译 3 | #include 4 | #include 5 | #include 6 | #include "12.12-diceroll.h" 7 | 8 | int main(void) 9 | { 10 | int dice, roll; 11 | int sides; 12 | int status; 13 | srand((unsigned int) time(0)); // 随机种子 14 | printf("Enter the number of sides per die, 0 to stop.\n"); 15 | while (scanf("%d", &sides) == 1 && sides > 0) 16 | { 17 | printf("How many dice?\n"); 18 | if ((status = scanf("%d", &dice)) != 1) 19 | { 20 | if (status == EOF) 21 | break; 22 | else 23 | { 24 | printf("You should have entered an integer."); 25 | printf(" Let's begin again.\n"); 26 | while (getchar() != '\n') 27 | continue; 28 | printf("How many sides? Enter 0 to stop.\n"); 29 | continue; 30 | } 31 | } 32 | roll = roll_n_dice(dice, sides); 33 | printf("You have rolled a %d using %d %d-sided dice.\n", 34 | roll, dice, sides); 35 | printf("How mang sides? Enter 0 to stop.\n"); 36 | } 37 | printf("The rollem() function was called %d times.\n", roll_count); 38 | printf("GOOD FORTUNE TO YOU!\n"); 39 | return 0; 40 | } -------------------------------------------------------------------------------- /Chapter-12 Storage Classes, Linkage, and Memory Management/example/12.14-dyn_arr.c: -------------------------------------------------------------------------------- 1 | // dyn_arr.c - 动态分配数组 2 | #include 3 | #include // 为malloc()、free()提供原型 4 | 5 | int main(void) 6 | { 7 | double * ptd; 8 | int max; 9 | int number; 10 | int i = 0; 11 | puts("What is the maximum number of type double entries?"); 12 | if (scanf("%d", &max) != 1) 13 | { 14 | puts("Number not correctly entered -- bye."); 15 | exit(EXIT_FAILURE); 16 | } 17 | ptd = (double *)malloc(max * sizeof(double)); 18 | if (ptd == NULL) 19 | { 20 | puts("Memory allocation failed. Goodbye."); 21 | exit(EXIT_FAILURE); 22 | } 23 | // ptd现在指向有max个元素的数组 24 | puts("Enter the valuew (q to quit):"); 25 | while (i < max && scanf("%lf", &ptd[i]) == 1) 26 | ++i; 27 | printf("Here are your %d entries:\n", number = i); 28 | for (i = 0; i < number; i++) 29 | { 30 | printf("%7.2f ", ptd[i]); 31 | if (i % 7 == 6) 32 | putchar('\n'); 33 | } 34 | if (i % 7 != 0) 35 | putchar('\n'); 36 | puts("Done."); 37 | free(ptd); 38 | return 0; 39 | } -------------------------------------------------------------------------------- /Chapter-12 Storage Classes, Linkage, and Memory Management/example/12.15-where.c: -------------------------------------------------------------------------------- 1 | // where.c - 数据被储存在何处? 2 | #include 3 | #include 4 | #include 5 | int static_store = 30; 6 | const char * pcg = "String Literal"; 7 | int main() 8 | { 9 | int auto_store = 40; 10 | char auto_string[] = "Auto char Array"; 11 | int * pi; 12 | char * pcl; 13 | pi = (int *)malloc(sizeof(int)); 14 | *pi = 35; 15 | pcl = (char *)malloc(strlen("Dynamic String") + 1); 16 | strcpy(pcl, "Dynamic String"); 17 | printf("static_store, %d at %p\n", static_store, &static_store); 18 | printf("auto_store, %d at %p\n", auto_store, &auto_store); 19 | printf(" *pi, %d at %p\n", *pi, pi); 20 | printf(" %s at %p\n", pcg, pcg); 21 | printf(" %s at %p\n", auto_string, auto_string); 22 | printf(" %s at %p\n", pcl, pcl); 23 | printf(" %s at %p\n", "Quoted String", "Quoted String"); 24 | free(pi); 25 | free(pcl); 26 | return 0; 27 | } -------------------------------------------------------------------------------- /Chapter-12 Storage Classes, Linkage, and Memory Management/example/12.2-forc99.c: -------------------------------------------------------------------------------- 1 | // forc99.c - 新的C99块规则 2 | #include 3 | 4 | int main() 5 | { 6 | int n = 8; 7 | printf(" Intially, n = %d at %p\n", n, &n); 8 | for (int n = 1; n < 3; n++) 9 | printf(" loop 1, n = %d at %p\n", n, &n); 10 | printf("After loop1, n = %d at %p\n", n, &n); 11 | for (int n = 1; n < 3; n++) 12 | { 13 | printf(" loop 2 index n = %d at %p\n", n, &n); 14 | int n = 6; 15 | printf(" loop 2: n = %d at %p\n", n, &n); 16 | n++; 17 | } 18 | printf("After loop 2, n = %d at %p\n", n, &n); 19 | return 0; 20 | } -------------------------------------------------------------------------------- /Chapter-12 Storage Classes, Linkage, and Memory Management/example/12.3-loc_stat.c: -------------------------------------------------------------------------------- 1 | // loc_stat.c - 使用局部静态变量 2 | #include 3 | void trystat(void); 4 | 5 | int main(void) 6 | { 7 | int count; 8 | for (count = 1; count <= 3; count++) 9 | { 10 | printf("Here comes iteration %d:\n", count); 11 | trystat(); 12 | 13 | } 14 | return 0; 15 | } 16 | 17 | void trystat(void) 18 | { 19 | int fade = 1; 20 | static int stay = 1; 21 | printf("fade = %d and stay = %d\n", fade++, stay++); 22 | } -------------------------------------------------------------------------------- /Chapter-12 Storage Classes, Linkage, and Memory Management/example/12.4-global.c: -------------------------------------------------------------------------------- 1 | // global.c - 使用外部变量 2 | #include 3 | int units = 0; // 外部变量 4 | void critic(void); 5 | 6 | int main(void) 7 | { 8 | extern int units;// 可选的重复声明 9 | printf("How many pounds to a firkin of butter?\n"); 10 | scanf("%d", &units); 11 | while (units != 56) 12 | critic(); 13 | printf("You must have looked it up!\n"); 14 | return 0; 15 | } 16 | 17 | void critic(void) 18 | { 19 | // 删除了可选的重复声明 20 | printf("No luck, my friend, Try again.\n"); 21 | scanf("%d", &units); 22 | } -------------------------------------------------------------------------------- /Chapter-12 Storage Classes, Linkage, and Memory Management/example/12.5-parta.c: -------------------------------------------------------------------------------- 1 | // parta.c - 不同的存储类别 2 | // 与12.6-partb.c 一起编译 3 | #include 4 | void report_count(); 5 | void accumulate(int k); 6 | int count = 0; // 文件作用域,外部链接 7 | int main(void) 8 | { 9 | int value; // 自动变量 10 | register int i; // 寄存器变量 11 | printf("Enter a positive integer(0 to quit): "); 12 | while (scanf("%d", &value) == 1 && value > 0) 13 | { 14 | ++count; // 使用文件作用域变量 15 | for (i = value; i >= 0; i--) 16 | accumulate(i); 17 | printf("Enter a positive integer (0 to quit): "); 18 | } 19 | report_count(); 20 | return 0; 21 | } 22 | 23 | void report_count() 24 | { 25 | printf("Loop executed %d times\n", count); 26 | } -------------------------------------------------------------------------------- /Chapter-12 Storage Classes, Linkage, and Memory Management/example/12.6-partb.c: -------------------------------------------------------------------------------- 1 | // partb.c - 程序的其余部分 2 | // 与12.5-parta.c 一起编译 3 | #include 4 | extern int count; // 引用式声明,外部链接 5 | static int total = 0; // 静态定义,内部链接 6 | void accumulate(int k); // 函数原型 7 | void accumulate(int k) // k具有块作用域,无链接 8 | { 9 | static int subtotal = 0; // 静态,无链接 10 | if (k <= 0) 11 | { 12 | printf("loop cycle: %d\n", count); 13 | printf("subtotal: %d; total: %d\n", subtotal, total); 14 | subtotal = 0; 15 | } 16 | else 17 | { 18 | subtotal += k; 19 | total += k; 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter-12 Storage Classes, Linkage, and Memory Management/example/12.7-rand0.c: -------------------------------------------------------------------------------- 1 | // rand0.c - 生成随机数 2 | // 使用 ANSI C 可移植算法 3 | static unsigned long int next = 1; // 种子 4 | unsigned int rand0(void) 5 | { 6 | // 生成伪随机数的魔术公式 7 | next = next * 1103515245 + 12345; 8 | return (unsigned int) (next / 65536) % 32768; 9 | } 10 | -------------------------------------------------------------------------------- /Chapter-12 Storage Classes, Linkage, and Memory Management/example/12.8-r_drive0.c: -------------------------------------------------------------------------------- 1 | // r_drive0.c - 测试rand0()函数 2 | // 与 rand0.c 一起编译 3 | #include 4 | extern unsigned int rand0(void); 5 | int main(void) 6 | { 7 | int count; 8 | for (count = 0; count < 5; count++) 9 | printf("%d\n", rand0()); 10 | return 0; 11 | } -------------------------------------------------------------------------------- /Chapter-12 Storage Classes, Linkage, and Memory Management/example/12.9-s_and_r.c: -------------------------------------------------------------------------------- 1 | // s_and_r.c - 包含rand1()和srand1()的文件 2 | // 使用 ANSI C 可移植算法 3 | static unsigned long int next = 1; // 种子 4 | int rand1(void) 5 | { 6 | // 生成伪随机数的魔术公式 7 | next = next * 1103515245 + 12345; 8 | return (unsigned int) (next / 65536) % 32768; 9 | } 10 | 11 | void srand1(unsigned int seed) 12 | { 13 | next = seed; 14 | } -------------------------------------------------------------------------------- /Chapter-12 Storage Classes, Linkage, and Memory Management/exercise/12-1.c: -------------------------------------------------------------------------------- 1 | // 1. 不使用全局变量,重写程序清单12.4 2 | #include 3 | void critic(int * pt); 4 | 5 | int main(void) 6 | { 7 | int units = 0; // 外部变量 8 | printf("How many pounds to a firkin of butter?\n"); 9 | scanf("%d", &units); 10 | while (units != 56) 11 | critic(&units); 12 | printf("You must have looked it up!\n"); 13 | return 0; 14 | } 15 | 16 | void critic(int * pt) 17 | { 18 | // 删除了可选的重复声明 19 | printf("No luck, my friend, Try again.\n"); 20 | scanf("%d", pt); 21 | } -------------------------------------------------------------------------------- /Chapter-12 Storage Classes, Linkage, and Memory Management/exercise/12-4.c: -------------------------------------------------------------------------------- 1 | // 4. 在一个循环中编写并测试一个函数,该函数返回它被调用的次数。 2 | #include 3 | 4 | void my_fun(void); 5 | 6 | int main(void) 7 | { 8 | for (int i = 0; i < 10; i++) 9 | my_fun(); 10 | return 0; 11 | } 12 | 13 | void my_fun(void) 14 | { 15 | static int times = 0; 16 | printf("This function has been called for %d times.\n", ++times); 17 | } -------------------------------------------------------------------------------- /Chapter-12 Storage Classes, Linkage, and Memory Management/exercise/12-5.c: -------------------------------------------------------------------------------- 1 | // 编写一个程序,生成100个1~10范围内的随机数,并以降序排列 2 | // (可以把第11章的排序算法稍加改动,便可用于整数排序,这里仅对整数排序)。 3 | #include 4 | #include 5 | #define LIM 100 6 | 7 | void sort_desc(int * ar, int n); 8 | 9 | int main(void) 10 | { 11 | int ar[LIM]; 12 | int i; 13 | for (i = 0; i < LIM; i++) 14 | ar[i] = (int)rand() % 10 + 1; 15 | sort_desc(ar, LIM); 16 | for (i = 0; i < LIM; i++) 17 | { 18 | printf("%2d ", ar[i]); 19 | if (i % 10 == 9) 20 | putchar('\n'); 21 | } 22 | } 23 | 24 | void sort_desc(int * ar, int n) 25 | { 26 | int i, j, temp; 27 | for (i = 0; i < n - 1; i++) 28 | for (j = i; j < n; j++) 29 | if (ar[i] < ar[j]) 30 | { 31 | temp = ar[i]; 32 | ar[i] = ar[j]; 33 | ar[j] = temp; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Chapter-12 Storage Classes, Linkage, and Memory Management/exercise/12-6.c: -------------------------------------------------------------------------------- 1 | // 6. 编写一个程序,生成1000个1~10范围内的随机数。 2 | // 不用保存或打印这些数字,仅打印每个数出现的次数。 3 | // 用10个不同的种子值运行,生成的数字出现的次数是否相同? 4 | // 可以使用本章自定义的函数或ANSI C的rand()和srand()函数,它们的格式相同。 5 | // 这是一个测试特定随机数生成器随机性的方法。 6 | #include 7 | #include 8 | #include 9 | #define LIM 1000 10 | void anaylize(int * ar, int n); 11 | 12 | int main(void) 13 | { 14 | int ar[LIM]; 15 | int seed, i; 16 | for (seed = 1; seed <= 10; seed++) 17 | { 18 | srand(seed); 19 | for (i = 0; i < LIM; i++) 20 | ar[i] = rand() % 10 + 1; 21 | anaylize(ar, LIM); 22 | } 23 | } 24 | 25 | void anaylize(int * ar, int n) 26 | { 27 | static int times = 0; 28 | int i; 29 | int * pr; 30 | pr = (int *) calloc(10, sizeof(int)); 31 | for (i = 0; i < n; i++) 32 | pr[ar[i] - 1]++; 33 | printf("Anaylize %d time(s): \n", ++times); 34 | for (i = 0; i < 10; i++) 35 | printf("%d: %d times\n", i + 1, *(pr + i)); 36 | free(pr); 37 | } 38 | -------------------------------------------------------------------------------- /Chapter-12 Storage Classes, Linkage, and Memory Management/exercise/12-7.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/logan70/C-Primer-Plus-6th-Notes-CN/6d4beffefdbf6ebe4893974a274d0cfb112605b6/Chapter-12 Storage Classes, Linkage, and Memory Management/exercise/12-7.c -------------------------------------------------------------------------------- /Chapter-13 File Input-Output/README.md: -------------------------------------------------------------------------------- 1 | # 第十三章 文件输入/输出 2 | 3 | 对于大多数C程序而言,写入文件和读取文件必不可少。为此,绝大对数C实现都提供底层I/O和标准高级I/O。因为ANSIC库考虑到可移植性,包含了标准I/O包,但是未提供底层I/O。 4 | 5 | 标准I/O包自动创建输入和输出缓冲区以加快数据传输。fopen()函数为标准I/O打开一个文件,并创建一个用于存储文件和缓冲区信息的结构。fopen()函数返回指向该结构的指针,其他函数可以使用该指针指定待处理的文件。feof()和ferror()函数报告I/O操作失败的原因。 6 | 7 | C把输入视为字节流。如果使用fread()函数,C把输入看作是二进制值并将其储存在指定存储位置。如果使用fscanf()、getc()、fgets()或其他相关函数,C则将每个字节看作是字符码。然后fscanf()和scanf()函数尝试把字符码翻译成转换说明指定的其他类型。例如,输入一个值23,%f转换说明会把23翻译成一个浮点值,%d转换说明会把23翻译成一个整数值,%s转换说明则会把23储存为字符串。getc()和fgetc()系列函数把输入作为字符码储存,将其作为单独的字符保存在字符变量中或作为字符串储存在字符数组中。类似地,fwrite()将二进制数据直接放入输出流,而其他输出函数把非字符数据转换成用字符表示后才将其放入输出流。 8 | 9 | ANSIC提供两种文件打开模式:二进制和文本。以二进制模式打开文件时,可以逐字节读取文件;以文本模式打开文件时,会把文件内容从文本的系统表示法映射为C表示法。对于UNIX和Linux系统,这两种模式完全相同。 10 | 11 | 通常,输入函数getc()、fgets()、fscanf()和fread()都从文件开始处按顺序读取文件。然而,fseek()和ftell()函数让程序可以随机访问文件中的任意位置。fgetpos()和fsetpos()把类似的功能扩展至更大的文件。与文本模式相比,二进制模式更容易进行随机访问。 -------------------------------------------------------------------------------- /Chapter-13 File Input-Output/example/13.1-count.c: -------------------------------------------------------------------------------- 1 | // count.c - 使用标准I;O 2 | #include 3 | #include 4 | int main(int argc, char * argv[]) 5 | { 6 | int ch; // 读取文件时,储存每个字符的地方 7 | FILE *fp; // 文件指针 8 | unsigned long count = 0; 9 | if (argc != 2) 10 | { 11 | printf("Usage: %s filename\n", argv[0]); 12 | exit(EXIT_FAILURE); 13 | } 14 | if ((fp = fopen(argv[1], "r")) == NULL) 15 | { 16 | printf("Can't open %s\n", argv[1]); 17 | exit(EXIT_FAILURE); 18 | } 19 | while ((ch = getc(fp)) != EOF) 20 | { 21 | putc(ch, stdout); // 与putchar(ch);相同 22 | count++; 23 | } 24 | fclose(fp); 25 | printf("File %s has %lu characters\n", argv[1], count); 26 | return 0; 27 | } -------------------------------------------------------------------------------- /Chapter-13 File Input-Output/example/13.2-reducto.c: -------------------------------------------------------------------------------- 1 | // reducto.c - 把文件压缩成原来的1/3 2 | #include 3 | #include 4 | #include 5 | #define LEN 40 6 | int main(int argc, char *argv[]) 7 | { 8 | FILE *in, *out; 9 | int ch; 10 | char name[LEN]; 11 | int count = 0; 12 | // 检查命令行参数 13 | if (argc < 2) 14 | { 15 | fprintf(stderr, "Usage: %s filename\n", argv[0]); 16 | exit(EXIT_FAILURE); 17 | } 18 | // 设置输入 19 | if ((in = fopen(argv[1], "r")) == NULL) 20 | { 21 | fprintf(stderr, "I couldn't open the file\"%s\"\n", argv[1]); 22 | exit(EXIT_FAILURE); 23 | } 24 | // 设置输出 25 | strncpy(name, argv[1], LEN - 5); 26 | name[LEN - 5] = '\0'; 27 | strcat(name, ".red"); 28 | if ((out = fopen(name, "w")) == NULL) 29 | { 30 | fprintf(stderr, "Can't create output file.\n"); 31 | exit(3); 32 | } 33 | // 拷贝数据 34 | while ((ch = getc(in)) != EOF) 35 | if(count++ % 3 == 0) 36 | putc(ch, out); // 打印3个字符中的第一个 37 | // 收尾工作 38 | if(fclose(in) != 0 || fclose(out) != 0) 39 | fprintf(stderr, "Error in closing files\n"); 40 | return 0; 41 | } -------------------------------------------------------------------------------- /Chapter-13 File Input-Output/example/13.3-addaword.c: -------------------------------------------------------------------------------- 1 | // addaword.c - 使用fprintf()、fscanf()和rewind() 2 | #include 3 | #include 4 | #include 5 | #define MAX 41 6 | 7 | int main(void) 8 | { 9 | FILE *fp; 10 | char words[MAX]; 11 | if ((fp = fopen("wordy", "a+")) == NULL) 12 | { 13 | fprintf(stdout, "Can't open \"wordy\" file.\n"); 14 | exit(EXIT_FAILURE); 15 | } 16 | puts("Enter words to add to the file; press the #"); 17 | puts("key at the beginning of a line to terminate."); 18 | while ((fscanf(stdin, "%40s", words) == 1) && (words[0] != '#')) 19 | fprintf(fp, "%s\n", words); 20 | puts("File contents:"); 21 | rewind(fp); // 返回到文件开始处 22 | while (fscanf(fp, "%s", words) == 1) 23 | puts(words); 24 | puts("Done!"); 25 | if (fclose(fp) != 0) 26 | fprintf(stderr, "Error closing file\n"); 27 | return 0; 28 | } -------------------------------------------------------------------------------- /Chapter-13 File Input-Output/example/13.4-reverse.c: -------------------------------------------------------------------------------- 1 | // reverse.c - 倒序显示文件的内容 2 | #include 3 | #include 4 | #define CNTL_Z '\032' // DOS文本文件中的文件结尾标记 5 | #define SLEN 81 6 | int main(void) 7 | { 8 | char file[SLEN];; 9 | char ch; 10 | FILE *fp; 11 | long count, last; 12 | puts("Enter the name of the file to be processed:"); 13 | scanf("%80s", file); 14 | if ((fp = fopen(file, "rb")) == NULL) 15 | { 16 | printf("reverse can't open %s\n", file); 17 | exit(EXIT_FAILURE); 18 | } 19 | fseek(fp, 0L, SEEK_END); // 定位到文件末尾 20 | last = ftell(fp); 21 | for (count = 1L; count <= last; count++) 22 | { 23 | fseek(fp, -count, SEEK_END); // 回退 24 | ch = getc(fp); 25 | if (ch != CNTL_Z && ch != '\r') // MS-DOS文件 26 | putchar(ch); 27 | } 28 | putchar('\n'); 29 | fclose(fp); 30 | return 0; 31 | } -------------------------------------------------------------------------------- /Chapter-13 File Input-Output/exercise/13-1.c: -------------------------------------------------------------------------------- 1 | // 1. 修改程序清单13.1中的程序,要求提示用户输入文件名, 2 | // 并读取用户输入的信息,不使用命令行参数。 3 | #include 4 | #include 5 | #include 6 | #define LIM 81 7 | char * s_gets(char * st, int n); 8 | 9 | int main(int argc, char * argv[]) 10 | { 11 | int ch; // 读取文件时,储存每个字符的地方 12 | FILE *fp; // 文件指针 13 | unsigned long count = 0; 14 | char filename[LIM]; 15 | printf("Enter the name of file: "); 16 | while ((s_gets(filename, LIM)) && filename[0] != '\0') 17 | { 18 | if ((fp = fopen(filename, "r")) == NULL) 19 | { 20 | printf("Can't open %s\n", filename); 21 | exit(EXIT_FAILURE); 22 | } 23 | while ((ch = getc(fp)) != EOF) 24 | { 25 | putc(ch, stdout); // 与putchar(ch);相同 26 | count++; 27 | } 28 | fclose(fp); 29 | printf("\nFile %s has %lu characters\n", filename, count); 30 | fputs("Enter the name of file: (new line to quit)\n", stdout); 31 | } 32 | puts("Done"); 33 | return 0; 34 | } 35 | 36 | char * s_gets(char * st, int n) 37 | { 38 | char * ret_val; 39 | char * find; 40 | ret_val = fgets(st, n, stdin); 41 | if (ret_val) 42 | { 43 | if ((find = strchr(ret_val, '\n'))) 44 | *find = '\0'; 45 | else 46 | while (getchar() != '\n') 47 | continue; 48 | } 49 | return ret_val; 50 | } 51 | -------------------------------------------------------------------------------- /Chapter-13 File Input-Output/exercise/13-11.c: -------------------------------------------------------------------------------- 1 | // 11. 编写一个程序,接受两个命令行参数。第1个参数是一个字符串, 2 | // 第2个参数是一个文件名。然后该程序查找该文件,打印文件中包含该字符串的 3 | // 所有行。因为该任务是面向行而不是面向字符的,所以要使用fgets()而不是getc()。 4 | // 使用标准C库函数strstr()(11.5.7节简要介绍过)在每一行中查找指定字符串。 5 | // 假设文件中的所有行都不超过255个字符。 6 | #include 7 | #include 8 | #include 9 | #define SIZE 256 10 | 11 | int main(int argc, char * argv[]) 12 | { 13 | FILE *fp; 14 | char buf[SIZE]; 15 | if (argc != 3) 16 | { 17 | fprintf(stderr, "Usage: %s string filename.\n", argv[0]); 18 | exit(EXIT_FAILURE); 19 | } 20 | if ((fp = fopen(argv[2], "r")) == NULL) 21 | { 22 | fprintf(stderr, "Could not open %s\n", argv[2]); 23 | exit(EXIT_FAILURE); 24 | } 25 | while (fgets(buf, SIZE, fp)) 26 | { 27 | if (strstr(buf, argv[1]) != NULL) 28 | fputs(buf, stdout); 29 | } 30 | puts("\nDone."); 31 | return 0; 32 | } -------------------------------------------------------------------------------- /Chapter-13 File Input-Output/exercise/13-2.c: -------------------------------------------------------------------------------- 1 | // 2. 编写一个文件拷贝程序,该程序通过命令行获取原始文件名和拷贝文件名。 2 | // 尽量使用标准I/O和二进制模式。 3 | #include 4 | #include 5 | #define BUFSIZE 256 6 | 7 | void copy_file(FILE *source, FILE *dest); 8 | 9 | int main(int argc, char * argv[]) 10 | { 11 | FILE *fp1; 12 | FILE *fp2; 13 | if (argc != 3) 14 | { 15 | fprintf(stderr, "Usage: %s sourcefile destinationfile\n", argv[0]); 16 | exit(EXIT_FAILURE); 17 | } 18 | if ((fp1 = fopen(argv[1], "r")) == NULL) 19 | { 20 | fprintf(stderr, "Could not open %s.\n", argv[1]); 21 | exit(EXIT_FAILURE); 22 | } 23 | if ((fp2 = fopen(argv[2], "w")) == NULL) 24 | { 25 | fprintf(stderr, "Could not open %s.\n", argv[2]); 26 | exit(EXIT_FAILURE); 27 | } 28 | copy_file(fp1, fp2); 29 | // 收尾工作 30 | if(fclose(fp1) != 0 || fclose(fp2) != 0) 31 | fprintf(stderr, "Error in closing files\n"); 32 | return 0; 33 | } 34 | 35 | void copy_file(FILE *source, FILE *dest) 36 | { 37 | static char temp[BUFSIZE]; 38 | size_t bytes; 39 | while ((bytes = fread(temp, sizeof(char), BUFSIZE, source)) > 0) 40 | fwrite(temp, sizeof(char), bytes, dest); 41 | } -------------------------------------------------------------------------------- /Chapter-13 File Input-Output/exercise/13-3.c: -------------------------------------------------------------------------------- 1 | // 3. 编写一个文件拷贝程序,提示用户输入文本文件名,并以该文件名作为原始文件名 2 | // 和输出文件名。该程序要使用ctype.h中的 toupper()函数,在写入到输出文件时 3 | // 把所有文本转换成大写。使用标准I/O和文本模式。 4 | #include 5 | #include 6 | #include 7 | #include 8 | #define LIM 80 9 | char * s_gets(char * st, int n); 10 | 11 | int main(void) 12 | { 13 | FILE *fp; 14 | char file[LIM]; 15 | char ch; 16 | printf("Enter file name: "); 17 | while (s_gets(file, LIM) && file[0] != '\0') 18 | { 19 | if ((fp = fopen(file, "r+")) == NULL) 20 | { 21 | fprintf(stderr, "Could not open %s.\n", file); 22 | exit(EXIT_FAILURE); 23 | } 24 | while((ch = getc(fp)) != EOF) 25 | { 26 | fseek(fp, -1L, SEEK_CUR); 27 | putc(toupper(ch), fp); 28 | } 29 | rewind(fp); 30 | printf("file content:\n"); 31 | while ((ch = getc(fp)) != EOF) 32 | putchar(ch); 33 | printf("\nEnter file name(new line to quit): "); 34 | } 35 | puts("Done."); 36 | return 0; 37 | } 38 | 39 | char * s_gets(char * st, int n) 40 | { 41 | char * ret_val; 42 | char * find; 43 | ret_val = fgets(st, n, stdin); 44 | if (ret_val) 45 | { 46 | if ((find = strchr(ret_val, '\n'))) 47 | *find = '\0'; 48 | else 49 | while (getchar() != '\n') 50 | continue; 51 | } 52 | return ret_val; 53 | } -------------------------------------------------------------------------------- /Chapter-13 File Input-Output/exercise/13-4.c: -------------------------------------------------------------------------------- 1 | // 4. 编写一个程序,按顺序在屏幕上显示命令行中列出的所有文件。 2 | // 使用argc控制循环。 3 | #include 4 | #include 5 | 6 | int main(int argc, char * argv[]) 7 | { 8 | FILE *fp; 9 | int i; 10 | char ch; 11 | for (i = 1; i < argc; i++) 12 | { 13 | if ((fp = fopen(argv[i], "r")) == NULL) 14 | { 15 | fprintf(stderr, "Could not open %s.\n", argv[i]); 16 | exit(EXIT_FAILURE); 17 | } 18 | printf("File \"%s\" content:\n", argv[i]); 19 | while ((ch = getc(fp)) != EOF) 20 | putc(ch, stdout); 21 | putchar('\n'); 22 | } 23 | return 0; 24 | } -------------------------------------------------------------------------------- /Chapter-13 File Input-Output/exercise/13-7-a.c: -------------------------------------------------------------------------------- 1 | // 7. 编写一个程序打开两个文件。可以使用命令行参数或提示用户输入文 件名。 2 | #include 3 | #include 4 | 5 | int main(int argc, char * argv[]) 6 | { 7 | FILE *fp1, *fp2; 8 | char ch; 9 | if (argc != 3) 10 | { 11 | fprintf(stderr, "Usage: %s filename1 filename2\n", argv[0]); 12 | exit(EXIT_FAILURE); 13 | } 14 | if ((fp1 = fopen(argv[1], "r")) == NULL) 15 | { 16 | fprintf(stderr, "Could open %s.\n", argv[1]); 17 | exit(EXIT_FAILURE); 18 | } 19 | if ((fp2 = fopen(argv[2], "r")) == NULL) 20 | { 21 | fprintf(stderr, "Could open %s.\n", argv[2]); 22 | exit(EXIT_FAILURE); 23 | } 24 | while (!feof(fp1) || !feof(fp2)) 25 | { 26 | while (!feof(fp1) && (ch = getc(fp1))) 27 | { 28 | if (ch == '\n' || ch == EOF) 29 | { 30 | putc('\n', stdout); 31 | break; 32 | } 33 | else 34 | putc(ch, stdout); 35 | } 36 | while (!feof(fp2) && (ch = getc(fp2))) 37 | { 38 | if (ch == '\n' || ch == EOF) 39 | { 40 | putc('\n', stdout); 41 | break; 42 | } 43 | else 44 | putc(ch, stdout); 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /Chapter-13 File Input-Output/exercise/13-7-b.c: -------------------------------------------------------------------------------- 1 | // 7. 编写一个程序打开两个文件。可以使用命令行参数或提示用户输入文 件名。 2 | #include 3 | #include 4 | 5 | int main(int argc, char * argv[]) 6 | { 7 | FILE *fp1, *fp2; 8 | char ch; 9 | if (argc != 3) 10 | { 11 | fprintf(stderr, "Usage: %s filename1 filename2\n", argv[0]); 12 | exit(EXIT_FAILURE); 13 | } 14 | if ((fp1 = fopen(argv[1], "r")) == NULL) 15 | { 16 | fprintf(stderr, "Could open %s.\n", argv[1]); 17 | exit(EXIT_FAILURE); 18 | } 19 | if ((fp2 = fopen(argv[2], "r")) == NULL) 20 | { 21 | fprintf(stderr, "Could open %s.\n", argv[2]); 22 | exit(EXIT_FAILURE); 23 | } 24 | while (!feof(fp1) || !feof(fp2)) 25 | { 26 | while (!feof(fp1) && (ch = getc(fp1))) 27 | { 28 | if (ch == '\n' || ch == EOF) 29 | break; 30 | else 31 | putc(ch, stdout); 32 | } 33 | while (!feof(fp2) && (ch = getc(fp2))) 34 | { 35 | if (ch == '\n' || ch == EOF) 36 | break; 37 | else 38 | putc(ch, stdout); 39 | } 40 | putchar('\n'); 41 | } 42 | } -------------------------------------------------------------------------------- /Chapter-13 File Input-Output/exercise/13-9.c: -------------------------------------------------------------------------------- 1 | // 9. 修改程序清单 13.3 中的程序,从 1 开始,根据加入列表的顺序为每个单词 2 | // 编号。当程序下次运行时,确保新的单词编号接着上次的编号开始。 3 | #include 4 | #include 5 | #include 6 | #define MAX 41 7 | 8 | int main(void) 9 | { 10 | FILE *fp; 11 | char words[MAX]; 12 | int index = 0; 13 | if ((fp = fopen("wordy", "a+")) == NULL) 14 | { 15 | fprintf(stdout, "Can't open \"wordy\" file.\n"); 16 | exit(EXIT_FAILURE); 17 | } 18 | rewind(fp); // 返回到文件开始处 19 | while (fscanf(fp, "%*d %s", words) == 1) 20 | index++; 21 | fseek(fp, 0L, SEEK_END); 22 | puts("Enter words to add to the file; press the #"); 23 | puts("key at the beginning of a line to terminate."); 24 | while ((fscanf(stdin, "%40s", words) == 1) && (words[0] != '#')) 25 | fprintf(fp, "%d %s\n", ++index, words); 26 | puts("File contents:"); 27 | rewind(fp); // 返回到文件开始处 28 | while (fscanf(fp, "%*d %s", words) == 1) 29 | puts(words); 30 | puts("Done!"); 31 | if (fclose(fp) != 0) 32 | fprintf(stderr, "Error closing file\n"); 33 | return 0; 34 | } -------------------------------------------------------------------------------- /Chapter-13 File Input-Output/exercise/numbers: -------------------------------------------------------------------------------- 1 | 009000000000589985200000000000 2 | 000090000000589985520000000000 3 | 000000000000581985452000000000 4 | 000090000000589985045200000000 5 | 009000000000589985004520000000 6 | 000000000000589185000452000000 7 | 000000000000589985000045200000 8 | 555555555555589985555555555555 9 | 888888888888589985888888888888 10 | 999909999999999999999939999999 11 | 888888888888589985888888888888 12 | 555555555555589985555555555555 13 | 000000000000589985000000000000 14 | 000000000000589985000066000000 15 | 000022000000589985005600650000 16 | 000033000000589985056111165000 17 | 000044000000589985005600650000 18 | 000055000000589985000066000000 19 | 000000000000589985000000000000 20 | 000000000000589985000000000000 -------------------------------------------------------------------------------- /Chapter-13 File Input-Output/exercise/pic: -------------------------------------------------------------------------------- 1 | ) %())(%" 2 | ) %())(%%" 3 | %(!)(%$%" 4 | ) %())(% $%" 5 | ) %())(% $%" 6 | %()!(% $%" 7 | %())(% $%" 8 | %%%%%%%%%%%%%())(%%%%%%%%%%%%% 9 | ((((((((((((%())(%(((((((((((( 10 | )))) )))))))))))))))))#))))))) 11 | ((((((((((((%())(%(((((((((((( 12 | %%%%%%%%%%%%%())(%%%%%%%%%%%%% 13 | %())(% 14 | %())(% && 15 | "" %())(% %& &% 16 | ## %())(% %&!!!!&% 17 | $$ %())(% %& &% 18 | %% %())(% && 19 | %())(% 20 | %())(% 21 | -------------------------------------------------------------------------------- /Chapter-14 Structures and Other Data Forms/README.md: -------------------------------------------------------------------------------- 1 | # 第十四章 结构和其他数据形式 2 | 3 | C 结构提供在相同的数据对象中储存多个不同类型数据项的方法。可以使用标记来标识一个具体的结构模板,并声明该类型的变量。通过成员点运算符 `.` 可以使用结构模版中的标签来访问结构的各个成员。 4 | 5 | 如果有一个指向结构的指针,可以用该指针和间接成员运算符 `->` 代替结构名和点运算符来访问结构的各成员。和数组不同,结构名不是结构的地址,要在结构名前使用&运算符才能获得结构的地址。 6 | 7 | 一贯以来,与结构相关的函数都使用指向结构的指针作为参数。现在的C允许把结构作为参数传递,作为返回值和同类型结构之间赋值。然而,传递结构的地址通常更有效。 8 | 9 | 联合使用与结构相同的语法。然而,联合的成员共享一个共同的存储空间。联合同一时间内只能储存一个单独的数据项,不像结构那样同时储存多种数据类型。也就是说,结构可以同时储存一个int类型数据、一个double类 型数据和一个char类型数据,而相应的联合只能保存一个int类型数据,或者 一个double类型数据,或者一个char类型数据。 10 | 11 | 通过枚举可以创建一系列代表整型常量(枚举常量)的符号和定义相关联的枚举类型。 12 | 13 | typedef工具可用于建立C标准类型的别名或缩写。 14 | 15 | 函数名代表函数的地址,可以把函数的地址作为参数传递给其他函数,然后这些函数就可以使用被指向的函数。如果把特定函数的地址赋给一个名为pf的函数指针,可以通过以下两种方式调用该函数: 16 | 17 | ```c 18 | #include /* 提供sin()函数的原型:double sin(double) */ 19 | // ... 20 | 21 | double (*pdf)(double); 22 | double x; 23 | pdf = sin; 24 | x = (*pdf)(1.2); // 调用sin(1.2) 25 | x = pdf(1.2);   // 同样调用 sin(1.2) 26 | ``` -------------------------------------------------------------------------------- /Chapter-14 Structures and Other Data Forms/example/14.1-book.c: -------------------------------------------------------------------------------- 1 | // book.c - 一本书的图书目录 2 | #include 3 | #include 4 | char * s_gets(char * st, int n); 5 | #define MAXTITL 41 // 书名的最大长度+1 6 | #define MAXAUTL 31 // 作者姓名的最大长度 7 | struct book { // 结构模板,标记是book 8 | char title[MAXTITL]; 9 | char author[MAXAUTL]; 10 | float value; 11 | }; // 结构模板结束 12 | 13 | int main(void) 14 | { 15 | struct book library; // 把library声明为一个book类型的变量 16 | printf("Please enter eht book title.\n"); 17 | s_gets(library.title, MAXTITL); // 访问title部分 18 | printf("Now enter the author.\n"); 19 | s_gets(library.author, MAXAUTL); 20 | printf("Now enter the value.\n"); 21 | scanf("%f", &library.value); 22 | printf("%s by %s: $%.2f\n", library.title, library.author, library.value); 23 | printf("%s: \"%s\"(%.2f)\n", library.author, library.title, library.value); 24 | printf("Done.\n"); 25 | return 0; 26 | } 27 | 28 | char * s_gets(char * st, int n) 29 | { 30 | char * ret_val; 31 | char * find; 32 | ret_val = fgets(st, n, stdin); 33 | if (ret_val) 34 | { 35 | find = strchr(st, '\n'); 36 | if (find) 37 | *find = '\0'; 38 | else 39 | while (getchar() != '\n') 40 | continue; 41 | } 42 | return ret_val; 43 | } -------------------------------------------------------------------------------- /Chapter-14 Structures and Other Data Forms/example/14.11-complit.c: -------------------------------------------------------------------------------- 1 | // complit.c - 复合字面量 2 | #include 3 | #define MAXTITL 41 4 | #define MAXAUTL 31 5 | struct book { 6 | char title[MAXTITL]; 7 | char author[MAXAUTL]; 8 | float value; 9 | }; 10 | 11 | int main(void) 12 | { 13 | struct book readfirst; 14 | int score; 15 | printf("Enter test score: "); 16 | scanf("%d", &score); 17 | if (score >= 84) 18 | readfirst = (struct book) { 19 | "Crime and Punishment", 20 | "Fyodor Dostoyevsky", 21 | 11.25 22 | }; 23 | else 24 | readfirst = (struct book) { 25 | "Mr.Bouncy's Nice Hat", 26 | "Fred Winsome", 27 | 5.99 28 | }; 29 | printf("Your assigned reading:\n"); 30 | printf("%s by %s: $.2f\n", readfirst.title, 31 | readfirst.author, readfirst.value); 32 | return 0; 33 | } -------------------------------------------------------------------------------- /Chapter-14 Structures and Other Data Forms/example/14.12-flexmemb.c: -------------------------------------------------------------------------------- 1 | // flexmemb.c - 伸缩性数组成员(C99新增特性) 2 | #include 3 | #include 4 | struct flex 5 | { 6 | size_t count; 7 | double average; 8 | double scores[]; // 伸缩型数组成员 9 | }; 10 | void showFlex(const struct flex * p); 11 | 12 | int main(void) 13 | { 14 | struct flex *pf1, *pf2; 15 | int n = 5; 16 | int i; 17 | int tot = 0; 18 | // 为结构和数组分配存储空间 19 | pf1 = malloc(sizeof(struct flex) + n * sizeof(double)); 20 | pf1->count = n; 21 | for (i = 0; i < n; i++) 22 | { 23 | pf1->scores[i] = 20.0 - i; 24 | tot += pf1->scores[i]; 25 | } 26 | pf1->average = tot / n; 27 | showFlex(pf1); 28 | n = 9; 29 | tot = 0; 30 | pf2 = malloc(sizeof(struct flex) + n * sizeof(double)); 31 | pf2->count = n; 32 | for (i = 0; i < n; i++) 33 | { 34 | pf2->scores[i] = 20.0 - i / 2.0; 35 | tot += pf2->scores[i]; 36 | } 37 | pf2->average = tot / n; 38 | showFlex(pf2); 39 | free(pf1); 40 | free(pf2); 41 | return 0; 42 | } 43 | 44 | void showFlex(const struct flex * p) 45 | { 46 | int i; 47 | printf("Scores: "); 48 | for (i = 0; i < p->count; i++) 49 | printf("%g ", p->scores[i]); 50 | printf("\nAverage: %g\n", p->average); 51 | } -------------------------------------------------------------------------------- /Chapter-14 Structures and Other Data Forms/example/14.13-funds4.c: -------------------------------------------------------------------------------- 1 | // funds1.c - 把结构成员作为参数传递 2 | #include 3 | #define FUNDLEN 50 4 | #define N 2 5 | struct funds { 6 | char bank[FUNDLEN]; 7 | double bankfund; 8 | char save[FUNDLEN]; 9 | double savefund; 10 | }; 11 | double sum(const struct funds money[], int n); 12 | 13 | int main(void) 14 | { 15 | struct funds jones[N] = { 16 | { 17 | "Garlic-Melon Bank", 18 | 4032.27, 19 | "Lucky's Savings and Loan", 20 | 8543.94 21 | }, 22 | { 23 | "Honest Jack's Bank", 24 | 3620.88, 25 | "Party Time Savings", 26 | 3802.91 27 | } 28 | }; 29 | printf("The Joneses have a total of $%.2f.\n", sum(jones, N)); 30 | return 0; 31 | } 32 | // 两个double 类型的数相加 33 | double sum(const struct funds money[], int n) 34 | { 35 | double total; 36 | int i; 37 | for (i = 0, total = 0; i < n; i++) 38 | total += money[i].bankfund + money[i].savefund; 39 | return total; 40 | } -------------------------------------------------------------------------------- /Chapter-14 Structures and Other Data Forms/example/14.3-friend.c: -------------------------------------------------------------------------------- 1 | // friend.c - 嵌套结构示例 2 | #include 3 | #define LEN 20 4 | const char * msgs[5] = 5 | { 6 | " Thank you for the wonderful evening,", 7 | "You certainly prove that a ", 8 | "is a special kind of guy. We must get together", 9 | "over a delicious", 10 | " and have a few laughs" 11 | }; 12 | struct names { 13 | char first[LEN]; 14 | char last[LEN]; 15 | }; 16 | struct guy { 17 | struct names handle; 18 | char favfood[LEN]; 19 | char job[LEN]; 20 | float income; 21 | }; 22 | 23 | int main(void) 24 | { 25 | struct guy fellow = { 26 | { "Ewen", "Villard" }, 27 | "grilled salmon", 28 | "personality coach", 29 | 68112.00 30 | }; 31 | printf("Dear %s, \n\n", fellow.handle.first); 32 | printf("%s%s.\n", msgs[0], fellow.handle.first); 33 | printf("%s%s\n", msgs[1], fellow.job); 34 | printf("%s\n", msgs[2]); 35 | printf("%s%s%s", msgs[3], fellow.favfood, msgs[4]); 36 | if (fellow.income > 150000.0) 37 | puts("!!"); 38 | else if (fellow.income > 75000.0) 39 | puts("!"); 40 | else 41 | puts("."); 42 | printf("\n%40s%s\n", " ", "See you soon,"); 43 | printf("%40s%s\n", " ", "Shalala"); 44 | return 0; 45 | } -------------------------------------------------------------------------------- /Chapter-14 Structures and Other Data Forms/example/14.4-friends.c: -------------------------------------------------------------------------------- 1 | // friends.c - 使用指向结构的指针 2 | #include 3 | #define LEN 20 4 | struct names { 5 | char first[LEN]; 6 | char last[LEN]; 7 | }; 8 | struct guy { 9 | struct names handle; 10 | char favfood[LEN]; 11 | char job[LEN]; 12 | float income; 13 | }; 14 | 15 | int main(void) 16 | { 17 | struct guy fellow[2] = { 18 | { 19 | { "Ewen", "Villard" }, 20 | "grilled salmon", 21 | "personality coach", 22 | 68112.00 23 | }, 24 | { 25 | { "Rodney", "Swillbelly" }, 26 | "tripe", 27 | "tabloid editor", 28 | 432400.00 29 | } 30 | }; 31 | struct guy * him; 32 | printf("address #1: %p #2: %p\n", &fellow[0], &fellow[1]); 33 | him = &fellow[0]; 34 | printf("pointer #1: %p #2: %p\n", him, him + 1); 35 | printf("him -> income is $%.2f: (*him).income is $%.2f\n", 36 | him -> income, (*him).income); 37 | him++; 38 | printf("him->favfood is %s: him->handle.last is %s\n", 39 | him -> favfood, him -> handle.last); 40 | return 0; 41 | } -------------------------------------------------------------------------------- /Chapter-14 Structures and Other Data Forms/example/14.5-funds1.c: -------------------------------------------------------------------------------- 1 | // funds1.c - 把结构成员作为参数传递 2 | #include 3 | #define FUNDLEN 50 4 | struct funds { 5 | char bank[FUNDLEN]; 6 | double bankfund; 7 | char save[FUNDLEN]; 8 | double savefund; 9 | }; 10 | double sum(double, double); 11 | 12 | int main(void) 13 | { 14 | struct funds stan = { 15 | "Garlic-Melon Bank", 16 | 4032.27, 17 | "Lucky's Savings and Loan", 18 | 8543.94 19 | }; 20 | printf("Stan has atotal of $%.2f.\n", 21 | sum(stan.bankfund, stan.savefund)); 22 | return 0; 23 | } 24 | // 两个double 类型的数相加 25 | double sum(double x, double y) 26 | { 27 | return (x + y); 28 | } -------------------------------------------------------------------------------- /Chapter-14 Structures and Other Data Forms/example/14.6-funds2.c: -------------------------------------------------------------------------------- 1 | // funds1.c - 把结构成员作为参数传递 2 | #include 3 | #define FUNDLEN 50 4 | struct funds { 5 | char bank[FUNDLEN]; 6 | double bankfund; 7 | char save[FUNDLEN]; 8 | double savefund; 9 | }; 10 | double sum(const struct funds *); 11 | 12 | int main(void) 13 | { 14 | struct funds stan = { 15 | "Garlic-Melon Bank", 16 | 4032.27, 17 | "Lucky's Savings and Loan", 18 | 8543.94 19 | }; 20 | printf("Stan has atotal of $%.2f.\n", 21 | sum(&stan)); 22 | return 0; 23 | } 24 | // 两个double 类型的数相加 25 | double sum(const struct funds * money) 26 | { 27 | return money->bankfund + money->savefund; 28 | } -------------------------------------------------------------------------------- /Chapter-14 Structures and Other Data Forms/example/14.7-funds3.c: -------------------------------------------------------------------------------- 1 | // funds1.c - 把结构成员作为参数传递 2 | #include 3 | #define FUNDLEN 50 4 | struct funds { 5 | char bank[FUNDLEN]; 6 | double bankfund; 7 | char save[FUNDLEN]; 8 | double savefund; 9 | }; 10 | double sum(struct funds moolah); 11 | 12 | int main(void) 13 | { 14 | struct funds stan = { 15 | "Garlic-Melon Bank", 16 | 4032.27, 17 | "Lucky's Savings and Loan", 18 | 8543.94 19 | }; 20 | printf("Stan has atotal of $%.2f.\n", 21 | sum(stan)); 22 | return 0; 23 | } 24 | // 两个double 类型的数相加 25 | double sum(struct funds moolah) 26 | { 27 | return moolah.bankfund + moolah.savefund; 28 | } -------------------------------------------------------------------------------- /Chapter-15 Bit Fiddling/README.md: -------------------------------------------------------------------------------- 1 | # 第十五章 位操作 2 | 3 | 计算硬件与二进制记数系统密不可分,因为二进制数的1和0可用于表示计算机内存和寄存器中位的开闭状态。虽然C不允许以二进制形式书写数字,但是它识别与二进制相关的八进制和十六进制记数法。正如每个二进制数字表示1位一样,每个八进制位代表3位,每个十六进制位代表4位。这种关系使得二进制转为八进制或十六进制较为简单。 4 | 5 | C提供多种按位运算符,之所以称为按位是因为它们单独操作一个值中的每个位。~运算符将其运算对象的每一位取反,将1转为0,0转为1。按位与运算符(&)通过两个运算对象形成一个值。如果两运算对象中相同号位都为1,那么该值中对应的位为1;否则,该位为0。按位或运算符(|)同样通过两个运算对象形成一个值。如果两运算对象中相同号位有一个为1或都为1,那么该值中对应的位为1;否则,该位为0。按位异或运算符(^)也有类似的操作,只有两运算对象中相同号位有一个为1时,结果值中对应的位才为1。 6 | 7 | C还有左移(<<)和右移(>>)运算符。这两个运算符使位组合中的所有位都向左或向右移动指定数量的位,以形成一个新值。对于左移运算符,空出的位置设为0。对于右移运算符,如果是无符号类型的值,空出的位设为0;如果是有符号类型的值,右移运算符的行为取决于实现。 8 | 9 | 可以在结构中使用位字段操控一个值中的单独位或多组位。具体细节因实现而异。 10 | 11 | 可以使用_Alignas强制执行数据存储区上的对齐要求。 12 | 13 | 这些位工具帮助C程序处理硬件问题,因此它们通常用于依赖实现的场合中。 -------------------------------------------------------------------------------- /Chapter-15 Bit Fiddling/example/15.1-binbit.c: -------------------------------------------------------------------------------- 1 | // binbit.c - 使用位操作显示二进制 2 | #include 3 | #include // 提供CHAR_BIT,表示每字节的位数 4 | char * itobs(int, char *); 5 | void show_bstr(const char *); 6 | int main(void) 7 | { 8 | char bin_str[CHAR_BIT * sizeof(int) + 1]; 9 | int number; 10 | puts("Enter integers and see them in binary."); 11 | puts("Non-numeric input terminates program."); 12 | while (scanf("%d", &number) == 1) 13 | { 14 | itobs(number, bin_str); 15 | printf("%d is \n", number); 16 | show_bstr(bin_str); 17 | putchar('\n'); 18 | } 19 | puts("Bye!"); 20 | return 0; 21 | } 22 | 23 | char * itobs(int n, char *ps) 24 | { 25 | int i; 26 | const static int size = CHAR_BIT * sizeof(int); 27 | for (i = size - 1; i >= 0; i--, n >>= 1) 28 | ps[i] = (01 & n) + '0'; 29 | ps[size] = '\0'; 30 | return ps; 31 | } 32 | 33 | void show_bstr(const char * str) 34 | { 35 | int i = 0; 36 | while (str[i]) 37 | { 38 | putchar(str[i]); 39 | if (++i % 4 == 0 && str[i]) 40 | putchar(' '); 41 | } 42 | } -------------------------------------------------------------------------------- /Chapter-16 The C Preprocessor and the C Library/example/16.1-preproc.c: -------------------------------------------------------------------------------- 1 | // preproc.c - 简单的预处理示例 2 | #include 3 | #define TWO 2 // 可以使用注释 4 | #define OW "Consistency is the last refuge of the unimagina\ 5 | tive.-Oscar Wilde" // 反斜杠把该定义延续到下一行 6 | #define FOUR TWO * TWO 7 | #define PX printf("X is %d.\n", x) 8 | #define FMT "X is %d.\n" 9 | 10 | int main(void) 11 | { 12 | int x = TWO; 13 | PX; 14 | x = FOUR; 15 | printf(FMT, x); 16 | printf("%s\n", OW); 17 | printf("TWO: OW\n"); 18 | return 0; 19 | } -------------------------------------------------------------------------------- /Chapter-16 The C Preprocessor and the C Library/example/16.10-names.h: -------------------------------------------------------------------------------- 1 | // names.h - 修订后的names_st头文件,避免重复包含 2 | #ifndef NAMES_H_ 3 | 4 | #define NAMES_H_ 5 | // 明示常量 6 | #define SLEN 32 7 | // 结构声明 8 | struct names_st 9 | { 10 | char first[SLEN]; 11 | char last[SLEN]; 12 | }; 13 | // 类型定义 14 | typedef struct names_st names; 15 | // 函数原型 16 | void get_names(names *); 17 | void show_names(const names *); 18 | char * s_gets(char * st, int n); 19 | 20 | #endif -------------------------------------------------------------------------------- /Chapter-16 The C Preprocessor and the C Library/example/16.11-doubincl.c: -------------------------------------------------------------------------------- 1 | // doubincl.c - 包含头文件两次 2 | #include 3 | #include "16.10-names.h" 4 | #include "16.10-names.h" // 不小心第二次包含头文件 5 | 6 | int main(void) 7 | { 8 | puts(__FILE__); 9 | printf("%d\n", __LINE__); 10 | printf("%ld\n", __STDC_VERSION__); 11 | names winner = { "Less", "Ismoor" }; 12 | printf("The winner is %s %s.\n", winner.first, winner.last); 13 | return 0; 14 | } -------------------------------------------------------------------------------- /Chapter-16 The C Preprocessor and the C Library/example/16.12-predef.c: -------------------------------------------------------------------------------- 1 | // predef.c - 预定义宏和预定义标识符 2 | #include 3 | void why_me(); 4 | 5 | int main() 6 | { 7 | printf("The file is %s.\n", __FILE__); 8 | printf("The date is %s.\n", __DATE__); 9 | printf("The time is %s.\n", __TIME__); 10 | printf("The version is %ld.\n", __STDC_VERSION__); 11 | printf("This is line %d.\n", __LINE__); 12 | printf("This function is %s\n", __func__); 13 | why_me(); 14 | return 0; 15 | } 16 | 17 | void why_me() 18 | { 19 | printf("This function is %s\n", __func__); 20 | printf("This is line %d.\n", __LINE__); 21 | } -------------------------------------------------------------------------------- /Chapter-16 The C Preprocessor and the C Library/example/16.13-mytype.c: -------------------------------------------------------------------------------- 1 | // mytype.c 2 | #include 3 | #define MYTYPE(X) _Generic((X), \ 4 | int: "int",\ 5 | float: "float",\ 6 | double: "double",\ 7 | long: "long",\ 8 | int *: "int *",\ 9 | default: "other"\ 10 | ) 11 | 12 | int main(void) 13 | { 14 | int d = 5; 15 | printf("%s\n", MYTYPE(d)); // d是int类型 16 | printf("%s\n", MYTYPE(2.0 * d)); // 2.0 * d 是double类型 17 | printf("%s\n", MYTYPE(3L)); // 3L是long类型 18 | printf("%s\n", MYTYPE(&d)); // &d的类型是int* 19 | printf("%s\n", MYTYPE(3LL)); // &d的类型是int* 20 | return 0; 21 | } -------------------------------------------------------------------------------- /Chapter-16 The C Preprocessor and the C Library/example/16.14-rect_pol.c: -------------------------------------------------------------------------------- 1 | // rect_pol.c - 把直角坐标转换为极坐标 2 | #include 3 | #include 4 | #define RAD_TO_DEG (180 / (4 * atan(1))) 5 | typedef struct polar_v { 6 | double magnitude; 7 | double angle; 8 | } Polar_V; 9 | typedef struct rect_v { 10 | double x; 11 | double y; 12 | } Rect_V; 13 | Polar_V rect_to_polar(Rect_V); 14 | 15 | int main(void) 16 | { 17 | Rect_V input; 18 | Polar_V result; 19 | puts("Enter x and y coordinates; enter q to quit:"); 20 | while (scanf("%lf %lf", &input.x, &input.y) == 2) 21 | { 22 | result = rect_to_polar(input); 23 | printf("magnitude = %0.2f, angle = %0.2f\n", 24 | result.magnitude, result.angle); 25 | } 26 | puts("Bye."); 27 | return 0; 28 | } 29 | 30 | Polar_V rect_to_polar(Rect_V rv) 31 | { 32 | Polar_V pv; 33 | pv.magnitude = sqrt(rv.x * rv.x + rv.y * rv.y); 34 | if (pv.magnitude == 0) 35 | pv.angle = 0.0; 36 | else 37 | pv.angle = RAD_TO_DEG * atan2(rv.y, rv.x); 38 | return pv; 39 | } -------------------------------------------------------------------------------- /Chapter-16 The C Preprocessor and the C Library/example/16.15-generic.c: -------------------------------------------------------------------------------- 1 | // generic.c - 定义泛型宏 2 | #include 3 | #include 4 | #define RAD_TO_DEG (180 / (4 * atanl(1))) 5 | // 泛型平方根函数 6 | #define SQRT(X) _Generic((X),\ 7 | long double: sqrtl,\ 8 | float: sqrtf,\ 9 | default: sqrt\ 10 | )(X) 11 | // 泛型正弦函数,角度的单位为度 12 | #define SIN(X) _Generic((X),\ 13 | long double: sinl((X) / RAD_TO_DEG),\ 14 | float: sinf((X) / RAD_TO_DEG),\ 15 | default: sin((X) / RAD_TO_DEG)\ 16 | ) 17 | 18 | int main(void) 19 | { 20 | float x = 45.0f; 21 | double xx = 45.0; 22 | long double xxx = 45.0L; 23 | long double y = SQRT(x); 24 | long double yy = SQRT(xx); 25 | long double yyy = SQRT(xxx); 26 | printf("%.17Lf\n", y); // 匹配float 27 | printf("%.17Lf\n", yy); // 匹配default 28 | printf("%.17Lf\n", yyy); // 匹配long double 29 | int i = 45; 30 | yy = SQRT(i); // 匹配default 31 | printf("%.17Lf\n", yy); 32 | yyy = SIN(xxx); // 匹配long double 33 | printf("%.17Lf\n", yyy); 34 | return 0; 35 | } -------------------------------------------------------------------------------- /Chapter-16 The C Preprocessor and the C Library/example/16.16-byebye.c: -------------------------------------------------------------------------------- 1 | // byebye.c - atexit()示例 2 | #include 3 | #include 4 | void sign_off(void); 5 | void too_bad(void); 6 | 7 | int main(void) 8 | { 9 | int n; 10 | atexit(sign_off); // 注册sign_off()函数 11 | puts("Enter an integer:"); 12 | if (scanf("%d", &n) != 1) 13 | { 14 | puts("That's no integer!"); 15 | atexit(too_bad); // 注册too_bad()函数 16 | exit(EXIT_FAILURE); 17 | } 18 | printf("%d is %s.\n", n, (n % 2 == 0) ? "even" : "odd"); 19 | return 0; 20 | } 21 | 22 | void sign_off(void) 23 | { 24 | puts("Thus terminates another magnificent program from"); 25 | puts("SeeSaw Software!"); 26 | } 27 | 28 | void too_bad(void) 29 | { 30 | puts("SeeSaw Software extends its heartfelt condolences"); 31 | puts("to you upon the failure of your program"); 32 | } -------------------------------------------------------------------------------- /Chapter-16 The C Preprocessor and the C Library/example/16.17-qsorter.c: -------------------------------------------------------------------------------- 1 | // qsorter.c - 用qsort()排序一组数字 2 | #include 3 | #include 4 | #define NUM 40 5 | void fillarray(double ar[], int n); 6 | void showarray(double ar[], int n); 7 | int mycomp(const void * p1, const void * p2); 8 | 9 | int main(void) 10 | { 11 | double vals[NUM]; 12 | fillarray(vals, NUM); 13 | puts("Random list:"); 14 | showarray(vals, NUM); 15 | qsort(vals, NUM, sizeof(double), mycomp); 16 | puts("\nSorted list:"); 17 | showarray(vals, NUM); 18 | return 0; 19 | } 20 | 21 | void fillarray(double ar[], int n) 22 | { 23 | int i; 24 | for (i = 0; i < n; i++) 25 | ar[i] = (double)rand() / ((double)rand() + 0.1); 26 | } 27 | 28 | void showarray(double ar[], int n) 29 | { 30 | int i; 31 | for (i = 0; i < n; i++) 32 | { 33 | printf("%9.4f", ar[i]); 34 | if (i % 6 == 5) 35 | putchar('\n'); 36 | } 37 | if (i % 6 != 0) 38 | putchar('\n'); 39 | } 40 | 41 | // 按从小到大排序 42 | int mycomp(const void * p1, const void * p2) 43 | { 44 | // 要使用指向double的指针来访问这两个值 45 | const double * a1 = (const double *) p1; 46 | const double * a2 = (const double *) p2; 47 | if (*a1 < *a2) 48 | return -1; 49 | else if (*a1 == *a2) 50 | return 0; 51 | else 52 | return 1; 53 | } -------------------------------------------------------------------------------- /Chapter-16 The C Preprocessor and the C Library/example/16.18-assert.c: -------------------------------------------------------------------------------- 1 | // assert.c - 使用assert.c 2 | #include 3 | #include 4 | #define NDEBUG 5 | #include 6 | 7 | int main(void) 8 | { 9 | double x, y, z; 10 | puts("Enter a pair of numbers (0 0 to quit):"); 11 | while (scanf("%lf %lf", &x, &y) == 2 && (x != 0 || y != 0)) 12 | { 13 | z = x * x - y * y; 14 | assert(z >= 0); 15 | printf("answer is %f\n", sqrt(z)); 16 | puts("Next pair of numbers: "); 17 | } 18 | puts("Done"); 19 | return 0; 20 | } -------------------------------------------------------------------------------- /Chapter-16 The C Preprocessor and the C Library/example/16.19-statasrt.c: -------------------------------------------------------------------------------- 1 | // statsrt.c - 使用 _Static_assert 2 | #include 3 | #include 4 | _Static_assert(CHAR_BIT == 16, "16-bix char falsely assumed"); 5 | 6 | int main(void) 7 | { 8 | puts("char is 16 bits."); 9 | return 0; 10 | } -------------------------------------------------------------------------------- /Chapter-16 The C Preprocessor and the C Library/example/16.2-mac_arg.c: -------------------------------------------------------------------------------- 1 | // mac_arg.c - 带参数的宏 2 | #include 3 | #define SQUARE(X) X*X 4 | #define PR(X) printf("The result is %d.\n", X) 5 | 6 | int main(void) 7 | { 8 | int x = 5; 9 | int z; 10 | printf("x = %d\n", x); 11 | z = SQUARE(x); 12 | printf("Evaluating SQUARE(x):"); 13 | PR(z); 14 | z = SQUARE(2); 15 | printf("Evaluating SQUARE(2):"); 16 | PR(z); 17 | printf("Evaluating SQUARE(x + 2):"); 18 | PR(SQUARE(x + 2)); 19 | printf("Evaluating 100/SQUARE(2):"); 20 | PR(100 / SQUARE(2)); 21 | printf("x is %d.\n", x); 22 | printf("Evaluating SQUARE(++x):"); 23 | PR(SQUARE(++x)); 24 | printf("Afret incrementing, x is %x.\n", x); 25 | return 0; 26 | } -------------------------------------------------------------------------------- /Chapter-16 The C Preprocessor and the C Library/example/16.21-varargs.c: -------------------------------------------------------------------------------- 1 | // varargs.c - 使用可变参数 use variable number of arguments 2 | #include 3 | #include 4 | double sum(int, ...); 5 | 6 | int main(void) 7 | { 8 | double s, t; 9 | s = sum(3, 1.1, 2.5, 13.3); 10 | t = sum(6, 1.1, 2.1, 13.1, 4.1, 5.1, 6.1); 11 | printf("return value for" 12 | "sum(3, 1.1, 2.5, 13.3): %g\n", s); 13 | printf("return value for" 14 | "sum(6, 1.1, 2.1, 13.1, 4.1, 5.1, 6.1): %g\n", t); 15 | return 0; 16 | } 17 | 18 | double sum(int lim, ...) 19 | { 20 | va_list ap; // 声明一个对象储存参数 21 | double tot = 0; 22 | int i; 23 | va_start(ap, lim); // 把ap初始化为参数列表 24 | for (i = 0; i < lim; i++) 25 | tot += va_arg(ap, double); // 访问参数列表中的每一项 26 | va_end(ap); // 清理工作 27 | return tot; 28 | } -------------------------------------------------------------------------------- /Chapter-16 The C Preprocessor and the C Library/example/16.3-subst.c: -------------------------------------------------------------------------------- 1 | // subst.c - 在字符串中替换 2 | #include 3 | #define PSQR(x) printf("The square of " #x " is %d.\n", ((x)*(x))); 4 | 5 | int main(void) 6 | { 7 | int y = 5; 8 | PSQR(y); 9 | PSQR(2 + 4); 10 | return 0; 11 | } -------------------------------------------------------------------------------- /Chapter-16 The C Preprocessor and the C Library/example/16.4-glue.c: -------------------------------------------------------------------------------- 1 | // glue.c - 使用##运算符 2 | #include 3 | #define XNAME(n) x ## n 4 | #define PRINT_XN(n) printf("x" #n " = %d\n", x ## n); 5 | 6 | int main(void) 7 | { 8 | int XNAME(1) = 14; // 变成int x1 = 14; 9 | int XNAME(2) = 20; // 变成int x2 = 20; 10 | int x3 = 30; 11 | PRINT_XN(1); // 变成printf("x1 = %d\n", x1); 12 | PRINT_XN(2); // 变成printf("x2 = %d\n", x2); 13 | PRINT_XN(3); // 变成printf("x3 = %d\n", x3); 14 | return 0; 15 | } -------------------------------------------------------------------------------- /Chapter-16 The C Preprocessor and the C Library/example/16.5-variadic.c: -------------------------------------------------------------------------------- 1 | // variadic.c - 变参宏 2 | #include 3 | #include 4 | #define PR(X, ...) printf("Message " #X ":" __VA_ARGS__) 5 | 6 | int main(void) 7 | { 8 | double x = 48; 9 | double y; 10 | y = sqrt(x); 11 | PR(1, "x = %g\n", x); 12 | PR(2, "x = %.2f, y = %.4f\n", x, y); 13 | return 0; 14 | } -------------------------------------------------------------------------------- /Chapter-16 The C Preprocessor and the C Library/example/16.6-names_st.h: -------------------------------------------------------------------------------- 1 | // names_st.h - names_st 结构的头文件 2 | #include 3 | #define SLEN 32 4 | // 结构声明 5 | struct names_st 6 | { 7 | char first[SLEN]; 8 | char last[SLEN]; 9 | }; 10 | // 类型定义 11 | typedef struct names_st names; 12 | // 函数原型 13 | void get_names(names *); 14 | void show_names(const names *); 15 | char * s_gets(char * st, int n); 16 | -------------------------------------------------------------------------------- /Chapter-16 The C Preprocessor and the C Library/example/16.7-name_st.c: -------------------------------------------------------------------------------- 1 | // names_st.c - 定义names_st.h中的函数 2 | #include 3 | #include "16.6-names_st.h" 4 | // 函数定义 5 | void get_names(names * pn) 6 | { 7 | printf("Please enter your first name:"); 8 | s_gets(pn->first, SLEN); 9 | printf("Please enter your last name:"); 10 | s_gets(pn->last, SLEN); 11 | } 12 | 13 | void show_names(const names * pn) 14 | { 15 | printf("%s %s", pn->first, pn->last); 16 | } 17 | 18 | char * s_gets(char * st, int n) 19 | { 20 | char * ret_val; 21 | char * find; 22 | ret_val = fgets(st, n, stdin); 23 | if (ret_val) 24 | { 25 | find = strchr(st, '\n'); 26 | if (find) 27 | *find = '\0'; 28 | else 29 | while (getchar() != '\n') 30 | continue; 31 | } 32 | return ret_val; 33 | } -------------------------------------------------------------------------------- /Chapter-16 The C Preprocessor and the C Library/example/16.8-useheader.c: -------------------------------------------------------------------------------- 1 | // useheader.c - 使用names_st结构 2 | #include 3 | #include "16.6-names_st.h" 4 | // 记住要链接16.7-names_st.c 5 | 6 | int main(void) 7 | { 8 | names candidate; 9 | get_names(&candidate); 10 | printf("Let's welcome "); 11 | show_names(&candidate); 12 | printf(" to this program!\n"); 13 | return 0; 14 | } -------------------------------------------------------------------------------- /Chapter-16 The C Preprocessor and the C Library/example/16.9-ifdef.c: -------------------------------------------------------------------------------- 1 | // ifdef.c - 使用条件编译 2 | #include 3 | #define JUST_CHECKING 4 | // #undef JUST_CHECKING 5 | #define LIMIT 4 6 | 7 | int main(void) 8 | { 9 | int i; 10 | int total = 0; 11 | for (i = 1; i <= LIMIT; i++) 12 | { 13 | total += 2 * i * i + 1; 14 | #ifdef JUST_CHECKING 15 | printf("i = %d, running total = %d\n", i, total); 16 | #endif 17 | } 18 | printf("Grand total = %d\n", total); 19 | return 0; 20 | } -------------------------------------------------------------------------------- /Chapter-17 Advanced Data Representation/example/17.8-use_q.c: -------------------------------------------------------------------------------- 1 | // use_q.c - 驱动程序测试Queue接口 2 | // 与17.7-queue.c一起编译 3 | #include 4 | #include "17.6-queue.h" 5 | 6 | int main(void) 7 | { 8 | Queue line; 9 | Item temp; 10 | char ch; 11 | InitializeQueue(&line); 12 | puts("Testing the Queue interface. Type a to add a value,"); 13 | puts("type d to delete a value, and type q to quit."); 14 | while ((ch = getchar()) != 'q') 15 | { 16 | if (ch != 'a' && ch != 'd') 17 | continue; 18 | if (ch == 'a') 19 | { 20 | printf("Integer to add: "); 21 | scanf("%d", &temp); 22 | if (!QueueIsFull(&line)) 23 | { 24 | printf("Putting %d into queue\n", temp); 25 | EnQueue(temp, &line); 26 | } 27 | else 28 | puts("Queue is full!"); 29 | } 30 | else 31 | { 32 | if (QueueIsEmpty(&line)) 33 | puts("Queue is empty!"); 34 | else 35 | { 36 | DeQueue(&temp, &line); 37 | printf("Removing %d from queue\n", temp); 38 | } 39 | } 40 | printf("%d items in queue\n", QueueItemCount(&line)); 41 | puts("Type a to add, d to delete, q to quit:"); 42 | } 43 | EmptyTheQueue(&line); 44 | puts("Bye!"); 45 | return 0; 46 | } -------------------------------------------------------------------------------- /Chapter-2 Introducing C/example/2.1-first.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) /* 一个简单的C程序 */ 4 | { 5 | int num; /* 定义一个名为num的变量 */ 6 | num = 1; /* 为num赋一个值 */ 7 | printf("I am a simple "); /* 使用printf()函数 */ 8 | printf("computer.\n"); 9 | printf("My favorite number is %d because it is first.\n", num); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /Chapter-2 Introducing C/example/2.2-fathm_ft.c: -------------------------------------------------------------------------------- 1 | // fathm_ft.c -- 把2音寻转换成英寸 2 | #include  3 | int main(void) 4 | { 5 | int feet, fathoms; 6 | fathoms = 2; 7 | feet = 6 * fathoms; 8 | printf("There are %d feet in %d fathoms!\n", feet, fathoms); 9 | printf("Yes, I said %d feet!\n", 6 * fathoms); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /Chapter-2 Introducing C/example/2.3-two_func.c: -------------------------------------------------------------------------------- 1 | //* two_func.c -- 一个文件中包含两个函数 */ 2 | #include  3 | void butler(void); /* ANSI/ISO C函数原型 */ 4 | 5 | int main(void) 6 | { 7 | printf("I will summon the butler function.\n"); 8 | butler(); 9 | printf("Yes. Bring me some tea and writeable DVDs.\n"); 10 | return 0; 11 | } 12 | 13 | void butler(void) /* 函数定义开始 */ 14 | { 15 | printf("You rang, sir?\n"); 16 | } 17 | -------------------------------------------------------------------------------- /Chapter-2 Introducing C/exercise/2-1.c: -------------------------------------------------------------------------------- 1 | // 编写一个程序,调用一次 printf()函数,把你的姓名打印在一行。 2 | // 再调 用一次 printf()函数,把你的姓名分别打印在两行。 3 | // 然后,再调用两次printf() 函数,把你的姓名打印在一行。 4 | // 输出应如下所示(当然要把示例的内容换成 你的姓名): 5 | // Logan Lee <- 第一次打印的内容 6 | // Logan <- 第二次打印的内容 7 | // Lee <- 第二次打印的内容 8 | // Logan Lee <- 第三次和第四次打印的内容 9 | 10 | #include 11 | 12 | int main(void) 13 | { 14 | printf("Logan Lee\n"); 15 | printf("Logan\nLee\n"); 16 | printf("Logan "); 17 | printf("Lee\n"); 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /Chapter-2 Introducing C/exercise/2-2.c: -------------------------------------------------------------------------------- 1 | // 编写一个程序,打印你的姓名和地址。 2 | 3 | #include 4 | 5 | int main(void) 6 | { 7 | printf("Logan Lee\n"); 8 | printf("ShenZhen, China.\n"); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /Chapter-2 Introducing C/exercise/2-3.c: -------------------------------------------------------------------------------- 1 | // 编写一个程序把你的年龄转换成天数,并显示这两个值。这里不用考 虑闰年的问题。 2 | 3 | #include 4 | 5 | int ageToDays(int age); 6 | 7 | int main(void) 8 | { 9 | int myAge = 26; 10 | int days = ageToDays(myAge); 11 | printf("age: %d, days: %d\n", myAge, days); 12 | return 0; 13 | } 14 | 15 | int ageToDays(int age) 16 | { 17 | return age * 365; 18 | } 19 | -------------------------------------------------------------------------------- /Chapter-2 Introducing C/exercise/2-4.c: -------------------------------------------------------------------------------- 1 | // 编写一个程序,生成以下输出: 2 | // For he's a jolly good fellow! 3 | // For he's a jolly good fellow! 4 | // For he's a jolly good fellow! 5 | // Which nobody can deny! 6 | // 除了 main()函数以外,该程序还要调用两个自定义函数:一个名为jolly(),用于打印前3条消息,调用一次打印一条; 7 | // 另一个函数名为deny(),打印最后一条消息。 8 | 9 | #include 10 | 11 | void jolly(void); 12 | void deny(void); 13 | 14 | int main(void) 15 | { 16 | jolly(); 17 | jolly(); 18 | jolly(); 19 | deny(); 20 | return 0; 21 | } 22 | 23 | void jolly(void) 24 | { 25 | printf("For he's a jolly good fellow!\n"); 26 | } 27 | 28 | void deny(void) 29 | { 30 | printf("Which nobody can deny!\n"); 31 | } 32 | -------------------------------------------------------------------------------- /Chapter-2 Introducing C/exercise/2-5.c: -------------------------------------------------------------------------------- 1 | // 编写一个程序,生成以下输出: 2 | 3 | // Brazil, Russia, India, China 4 | // India, China, 5 | // Brazil, Russia 6 | 7 | // 除了main()以外,该程序还要调用两个自定义函数:一个名为br(),调用一次打印一次“Brazil, Russia”; 8 | // 另一个名为ic(),调用一次打印一次“India, China”。其他内容在main()函数中完成。 9 | 10 | #include 11 | 12 | void br(void); 13 | void ic(void); 14 | 15 | int main(void) 16 | { 17 | br(); 18 | printf(", "); 19 | ic(); 20 | printf("\n"); 21 | ic(); 22 | printf(",\n"); 23 | br(); 24 | printf("\n"); 25 | return 0; 26 | } 27 | 28 | void br(void) 29 | { 30 | printf("Brazil, Russia"); 31 | } 32 | 33 | void ic(void) 34 | { 35 | printf("India, China"); 36 | } 37 | -------------------------------------------------------------------------------- /Chapter-2 Introducing C/exercise/2-6.c: -------------------------------------------------------------------------------- 1 | // 编写一个程序,创建一个整型变量toes,并将toes设置为10。 2 | // 程序中还要计算toes的两倍和toes的平方。 3 | // 该程序应打印3个值,并分别描述以示区分。 4 | 5 | #include 6 | 7 | int getDouble(int); 8 | int getSquare(int); 9 | 10 | int main(void) { 11 | int toes = 10; 12 | printf("double toes: %d\n", getDouble(toes)); 13 | printf("square toes: %d\n", getSquare(toes)); 14 | return 0; 15 | } 16 | 17 | int getDouble(int num) 18 | { 19 | return 2 * num; 20 | } 21 | 22 | int getSquare(int num) 23 | { 24 | return num * num; 25 | } 26 | -------------------------------------------------------------------------------- /Chapter-2 Introducing C/exercise/2-7.c: -------------------------------------------------------------------------------- 1 | // 许多研究表明,微笑益处多多。编写一个程序,生成以下格式的输出: 2 | // Smile!Smile!Smile! 3 | // Smile!Smile! 4 | // Smile! 5 | // 该程序要定义一个函数,该函数被调用一次打印一次“Smile!”,根据程序的需要使用该函数。 6 | 7 | #include 8 | 9 | void smile(void); 10 | 11 | int main(void) 12 | { 13 | smile(); 14 | smile(); 15 | smile(); 16 | printf("\n"); 17 | smile(); 18 | smile(); 19 | printf("\n"); 20 | smile(); 21 | printf("\n"); 22 | return 0; 23 | } 24 | 25 | void smile(void) 26 | { 27 | printf("Smile!"); 28 | } 29 | -------------------------------------------------------------------------------- /Chapter-2 Introducing C/exercise/2-8.c: -------------------------------------------------------------------------------- 1 | // 在C语言中,函数可以调用另一个函数。 2 | // 编写一个程序,调用一个名为one_three()的函数。 3 | // 该函数在一行打印单词“one”,再调用第2个函数 two(),然后在另一行打印单词“three”。 4 | // two()函数在一行显示单词“two”。 5 | // main()函数在调用 one_three()函数前要打印短语“starting now:”,并在调用完毕后显示短语“done!”。 6 | // 因此,该程序的输出应如下所示: 7 | 8 | // starting now: 9 | // one 10 | // two 11 | // three 12 | // done! 13 | #include 14 | 15 | void one_three(void); 16 | void two(void); 17 | 18 | int main(void) 19 | { 20 | printf("starting now:\n"); 21 | one_three(); 22 | printf("done!\n"); 23 | } 24 | 25 | void one_three(void) 26 | { 27 | printf("one\n"); 28 | two(); 29 | printf("three\n"); 30 | } 31 | 32 | void two(void) 33 | { 34 | printf("two\n"); 35 | } 36 | -------------------------------------------------------------------------------- /Chapter-2 Introducing C/images/1-c-program-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/logan70/C-Primer-Plus-6th-Notes-CN/6d4beffefdbf6ebe4893974a274d0cfb112605b6/Chapter-2 Introducing C/images/1-c-program-structure.png -------------------------------------------------------------------------------- /Chapter-2 Introducing C/images/2-keywords-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/logan70/C-Primer-Plus-6th-Notes-CN/6d4beffefdbf6ebe4893974a274d0cfb112605b6/Chapter-2 Introducing C/images/2-keywords-1.png -------------------------------------------------------------------------------- /Chapter-2 Introducing C/images/2-keywords-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/logan70/C-Primer-Plus-6th-Notes-CN/6d4beffefdbf6ebe4893974a274d0cfb112605b6/Chapter-2 Introducing C/images/2-keywords-2.png -------------------------------------------------------------------------------- /Chapter-3 Data and C/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/logan70/C-Primer-Plus-6th-Notes-CN/6d4beffefdbf6ebe4893974a274d0cfb112605b6/Chapter-3 Data and C/.DS_Store -------------------------------------------------------------------------------- /Chapter-3 Data and C/example/3.1-platinum.c: -------------------------------------------------------------------------------- 1 | /* platinum.c -- your weight in platinum */ 2 | #include 3 | 4 | int main(void) 5 | { 6 | float weight; // 你的体重 7 | float value; /* 相等重量的白金价值 */ 8 | printf("Are you worth your weight in platinum?\n"); 9 | printf("Let's check it out.\n"); 10 | printf("Please enter your weight in pounds: "); /* 获取用户的输入 */ 11 | scanf("%f", &weight); 12 | /* 假设白金的价格是每盎司$1700 */ 13 | /* 14.5833用于把英镑常衡盎司转换为金衡盎司[ */ 14 | value = 1700.0 * weight * 14.5833; 15 | printf("Your weight in platinum is worth $%.2f.\n", value); 16 | printf("You are easily worth that! If platinum prices drop,\n"); 17 | printf("eat more to maintain your value.\n"); 18 | return 0; 19 | } -------------------------------------------------------------------------------- /Chapter-3 Data and C/example/3.2-print1.c: -------------------------------------------------------------------------------- 1 | /* print1.c - 演示printf()的一些特性 */ 2 | #include 3 | 4 | int main(void) 5 | { 6 | int ten = 12; 7 | int two = 2; 8 | printf("Doing it right: "); 9 | printf("%d minus %d is %d\n", ten, 2, ten - two); 10 | printf("Doing it wrong: "); 11 | printf("%d minus %d is %d\n", ten); // 遗漏两个参数 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter-3 Data and C/example/3.3-bases.c: -------------------------------------------------------------------------------- 1 | /* bases.c - 以十进制、八进制、十六进制打印十进制数100 */ 2 | 3 | #include 4 | 5 | int main(void) 6 | { 7 | int x = 100; 8 | printf("dec = %d; octal = %o; hex = %x\n", x, x, x); 9 | printf("dec = %d; octal = %#o; hex = %#x; HEX = %#X\n", x, x, x, x); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /Chapter-3 Data and C/example/3.4-print2.c: -------------------------------------------------------------------------------- 1 | /* print2.c - 更多printf()的特性 */ 2 | #include 3 | 4 | int main(void) 5 | { 6 | unsigned int un = 3000000000; /* int为32位和short为16位的系统 */ 7 | short end = 200; 8 | long big = 65537; 9 | long long verybig = 12345678908642; 10 | printf("un = %u and not %d\n", un, un); 11 | printf("big = %ld and not %hd\n", big, big); 12 | printf("verybig = %lld and not %d\n", verybig, verybig); 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /Chapter-3 Data and C/example/3.5-charcode.c: -------------------------------------------------------------------------------- 1 | /* charcode.c - 显示字符的代码编号 */ 2 | #include 3 | 4 | int main(void) 5 | { 6 | char ch; 7 | printf("Please enter a character.\n"); 8 | scanf("%c", &ch); // 用户输入字符 9 | printf("The code for %c is %d.\n", ch, ch); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /Chapter-3 Data and C/example/3.7-showf_pt.c: -------------------------------------------------------------------------------- 1 | /* showf_pt.c - 以两种方式显示float类型的值 */ 2 | #include 3 | 4 | int main(void) 5 | { 6 | float aboat = 32000.0; 7 | double abet = 2.14e9; 8 | long double dip = 5.32e-5; 9 | printf("%f can be written %e\n", aboat, aboat); 10 | // 下一行要求编译器支持C99或其中的相关特性 11 | printf("And it's %a in hexadecimal, powers of 2 notations\n", aboat); 12 | printf("%f can be written %e\n", abet, abet); 13 | printf("%Lf canbe written %Le\n", dip, dip); 14 | printf("And it's %La in hexadecimal, powers of 2 notations\n", dip); 15 | return 0; 16 | } -------------------------------------------------------------------------------- /Chapter-3 Data and C/example/3.8-typesize.c: -------------------------------------------------------------------------------- 1 | /* typesize.c - 打印类型大小 */ 2 | #include 3 | 4 | int main(void) 5 | { 6 | /* C99为类型大小提供%zd转换说明 */ 7 | printf("Type short has a size of %zd bytes.\n", sizeof(short)); 8 | printf("Type int has a size of %zd bytes.\n", sizeof(int)); 9 | printf("Type char has a size of %zd bytes.\n", sizeof(char)); 10 | printf("Type long has a size of %zd bytes.\n", sizeof(long)); 11 | printf("Type long long has a size of %zd bytes.\n", sizeof(long long)); 12 | printf("Type float has a size of %zd bytes.\n", sizeof(float)); 13 | printf("Type double has a size of %zd bytes.\n", sizeof(double)); 14 | printf("Type long double has a size of %zd bytes.\n", sizeof(long double)); 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /Chapter-3 Data and C/example/3.9-badcount.c: -------------------------------------------------------------------------------- 1 | /* badcount.c - 参数错误的情况 */ 2 | #include 3 | 4 | int main(void) 5 | { 6 | int n = 4; 7 | int m = 5; 8 | float f = 7.0f; 9 | float g = 8.0f; 10 | printf("%d\n", n, m); // 参数太多 11 | printf("%d %d %d\n", n); // 参数太少 12 | printf("%d %d\n", f, g); // 值的类型不匹配 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /Chapter-3 Data and C/example/floaterr.c: -------------------------------------------------------------------------------- 1 | /* floaterr.c - 演示舍入错误 */ 2 | #include 3 | 4 | int main(void) { 5 | float a, b; 6 | b = 2.0e20 + 1.0; 7 | a = b - 2.0e20; 8 | printf("%f \n", a); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /Chapter-3 Data and C/exercise/3-2.c: -------------------------------------------------------------------------------- 1 | /** 2 | * 编写一个程序,要求提示输入一个ASCII码值(如,66),然后打印输入的字符 3 | */ 4 | #include 5 | 6 | int main(void) 7 | { 8 | int ascii; 9 | printf("请输入一个ASCII码值(如,66):\n"); 10 | scanf("%d", &ascii); 11 | printf("您输入的ASCII码转换为字符后为:%c\n", ascii); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter-3 Data and C/exercise/3-3.c: -------------------------------------------------------------------------------- 1 | /** 2 | * 编写一个程序,发出一声警报,然后打印下面的文本: 3 | * Startled by the sudden sound, Sally shouted, 4 | * "By the Great Pumpkin, what was that!" 5 | */ 6 | #include 7 | 8 | int main(void) 9 | { 10 | printf("\ 11 | \aStartled by the sudden sound, Sally shouted,\n\ 12 | \"By the Great Pumpkin, what was that!\"\n"); 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /Chapter-3 Data and C/exercise/3-4.c: -------------------------------------------------------------------------------- 1 | /** 2 | * 编写一个程序,读取一个浮点数 3 | * 先打印成小数点形式,再打印成指数形式。 4 | * 然后,如果系统支持,再打印成p记数法(即十六进制记数法)。 5 | * 按以下格式输出(实际显示的指数位数因系统而异): 6 | * Enter a floating-point value: 64.25 7 | * fixed-point notation: 64.250000 8 | * exponential notation: 6.425000e+01 9 | * p notation: 0x1.01p+6 10 | */ 11 | #include 12 | 13 | int main(void) 14 | { 15 | float num; 16 | printf("Enter a floating-point value:"); 17 | scanf("%f", &num); 18 | printf("fixed-point notation: %f\n", num); 19 | printf("exponential notation: %e\n", num); 20 | printf("p notation: %a\n", num); 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /Chapter-3 Data and C/exercise/3-5.c: -------------------------------------------------------------------------------- 1 | /** 2 | * 一年大约有3.156e7秒。编写一个程序,提示用户输入年龄,然后显示该年龄对应的秒数。 3 | */ 4 | 5 | #include 6 | #define SECS_IN_ONE_YEAR (3.156e7) 7 | 8 | int main(void) 9 | { 10 | int age; 11 | printf("请输入您的年龄:"); 12 | scanf("%d", &age); 13 | printf("该年龄对应 %e 秒\n", SECS_IN_ONE_YEAR * age); 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /Chapter-3 Data and C/exercise/3-6.c: -------------------------------------------------------------------------------- 1 | /** 2 | * 1个水分子的质量约为3.0×10 −23 克。1夸脱水大约是950克。 3 | * 编写一个程序,提示用户输入水的夸脱数,并显示水分子的数量。 4 | */ 5 | #include 6 | 7 | int main(void) 8 | { 9 | float kt; 10 | printf("请输入水的夸脱数:"); 11 | scanf("%f", &kt); 12 | printf("%f 夸脱水的水分子数量为 %e\n", kt, kt * 950 / 3.0e-23); 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /Chapter-3 Data and C/exercise/3-7.c: -------------------------------------------------------------------------------- 1 | /** 2 | * 1英寸相当于2.54厘米。 3 | * 编写一个程序,提示用户输入身高(/英寸),然后以厘米为单位显示身高。 4 | */ 5 | #include 6 | 7 | int main(void) 8 | { 9 | float inches; 10 | printf("请输入您的身高(单位:英寸):"); 11 | scanf("%f", &inches); 12 | // %.2f代表小数点后保留两位 13 | printf("您的身高转换为厘米为 %.2f 厘米\n", inches * 2.54); 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /Chapter-3 Data and C/exercise/3-8.c: -------------------------------------------------------------------------------- 1 | /** 2 | * 在美国的体积测量系统中 3 | * 1品脱等于2杯,1杯等于8盎司,1盎司等于2大汤勺,1大汤勺等于3茶勺。 4 | * 编写一个程序,提示用户输入杯数,并以品脱、盎司、汤勺、茶勺为单位显示等价容量。 5 | * 思考对于该程序,为何使用浮点类型比整数类型更合适? 6 | */ 7 | // 容量不一定正好是整数的,而且杯换算为品脱可能产生小数位,所以用浮点类型更合适 8 | #include 9 | 10 | int main(void) 11 | { 12 | float cups; 13 | printf("请输入杯数:"); 14 | scanf("%f", &cups); 15 | printf("杯数:%f\n品脱数:%f\n盎司数:%f\n汤勺数:%f\n茶勺数:%f\n", 16 | cups, 17 | cups / 2, 18 | cups * 8, 19 | cups * 8 * 2, 20 | cups * 8 * 2 * 3 21 | ); 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /Chapter-3 Data and C/images/1-datatype-key-word.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/logan70/C-Primer-Plus-6th-Notes-CN/6d4beffefdbf6ebe4893974a274d0cfb112605b6/Chapter-3 Data and C/images/1-datatype-key-word.png -------------------------------------------------------------------------------- /Chapter-3 Data and C/images/2-escape-squence.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/logan70/C-Primer-Plus-6th-Notes-CN/6d4beffefdbf6ebe4893974a274d0cfb112605b6/Chapter-3 Data and C/images/2-escape-squence.png -------------------------------------------------------------------------------- /Chapter-3 Data and C/images/3-data-show-and-storage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/logan70/C-Primer-Plus-6th-Notes-CN/6d4beffefdbf6ebe4893974a274d0cfb112605b6/Chapter-3 Data and C/images/3-data-show-and-storage.png -------------------------------------------------------------------------------- /Chapter-3 Data and C/images/4-decimal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/logan70/C-Primer-Plus-6th-Notes-CN/6d4beffefdbf6ebe4893974a274d0cfb112605b6/Chapter-3 Data and C/images/4-decimal.png -------------------------------------------------------------------------------- /Chapter-3 Data and C/images/5-review-question-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/logan70/C-Primer-Plus-6th-Notes-CN/6d4beffefdbf6ebe4893974a274d0cfb112605b6/Chapter-3 Data and C/images/5-review-question-6.png -------------------------------------------------------------------------------- /Chapter-3 Data and C/images/6-review-question-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/logan70/C-Primer-Plus-6th-Notes-CN/6d4beffefdbf6ebe4893974a274d0cfb112605b6/Chapter-3 Data and C/images/6-review-question-7.png -------------------------------------------------------------------------------- /Chapter-4 Character Strings and Formatted Input-Output/example/4.1-talkback.c: -------------------------------------------------------------------------------- 1 | // talkback.c - 演示与用户交互 2 | #include 3 | #include // 提供strlen()函数的原型 4 | #define DENSITY 62.4 // 人体密度(单位:磅/立方英尺) 5 | 6 | int main(void) 7 | { 8 | float weight, volume; 9 | int size, letters; 10 | char name[40]; // name是一个可容纳40个字符的数组 11 | printf("Hi! What's your first name?\n"); 12 | scanf("%s", name); 13 | printf("%s, what's your weight in pounds?\n", name); 14 | scanf("%f", &weight); 15 | size = sizeof name; 16 | letters = strlen(name); 17 | volume = weight / DENSITY; 18 | printf("Well, %s, your volume is %2.2f cubic feet.\n", 19 | name, volume); 20 | printf("Also, your first name has %d letters,\n", letters); 21 | printf("and we have %d bytes to store it.\n", size); 22 | return 0; 23 | } -------------------------------------------------------------------------------- /Chapter-4 Character Strings and Formatted Input-Output/example/4.10-stringf.c: -------------------------------------------------------------------------------- 1 | // stringf.c - 字符串格式 2 | #include 3 | #define BLURB "Authentic imitation!" 4 | 5 | int main(void) 6 | { 7 | printf("[%2s]\n", BLURB); 8 | printf("[%24s]\n", BLURB); 9 | printf("[%24.5s]\n", BLURB); 10 | printf("[%-24.5s]\n", BLURB); 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /Chapter-4 Character Strings and Formatted Input-Output/example/4.11-intconv.c: -------------------------------------------------------------------------------- 1 | // intconv.c 一些不匹配的整形转换 2 | #include 3 | #define PAGES 336 4 | #define WORDS 65618 5 | 6 | int main(void) 7 | { 8 | short num = PAGES; 9 | short mnum = -PAGES; 10 | printf("num as short and unsigned short: %hd %hu\n", num, num); 11 | printf("-num as short and unsigned short: %hd %hu\n", mnum, mnum); 12 | printf("num as int and char: %d %c\n", num, num); 13 | printf("WORDS as int, short, and char: %d %hd %c\n", WORDS, WORDS, WORDS); 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /Chapter-4 Character Strings and Formatted Input-Output/example/4.12-floatcnv.c: -------------------------------------------------------------------------------- 1 | // floatcnv.c - 不匹配的浮点型转换 2 | #include 3 | 4 | int main(void) 5 | { 6 | float n1 = 3.0; 7 | double n2 = 3.0; 8 | long n3 = 2000000000; 9 | long n4 = 1234567890; 10 | printf("%.1e %.1e %.1e %.1e\n", n1, n2, n3, n4); 11 | printf("%ld %ld\n", n3, n4); 12 | printf("%ld %ld %ld %ld\n", n1, n2, n3, n4); 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /Chapter-4 Character Strings and Formatted Input-Output/example/4.13-prntval.c: -------------------------------------------------------------------------------- 1 | // prntval.c - printf()的返回值 2 | #include 3 | 4 | int main(void) 5 | { 6 | int bph2o = 212; 7 | int rv; 8 | rv = printf("%d F iswater's boiling point.\n", bph2o); 9 | printf("The printf() function printed %d characters.\n", rv); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /Chapter-4 Character Strings and Formatted Input-Output/example/4.14-longstrg.c: -------------------------------------------------------------------------------- 1 | // longstrg.c - 打印较长的字符串 2 | #include 3 | 4 | int main(void) 5 | { 6 | printf("Here's one way to print a "); 7 | printf("long string.\n"); 8 | printf("Here's another way to print a \ 9 | long string.\n"); 10 | printf("Here's the newest way to pirnt a " 11 | "long string.\n"); // ANSI C 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter-4 Character Strings and Formatted Input-Output/example/4.15-input.c: -------------------------------------------------------------------------------- 1 | // input.c - 何时使用& 2 | #include 3 | 4 | int main(void) 5 | { 6 | int age; // 变量 7 | float assets; // 变量 8 | char pet[30]; // 字符数组,用于储存字符串 9 | printf("Enter your age, assets, and favorite pet.\n"); 10 | scanf("%d %f", &age, &assets); // 这里要使用& 11 | scanf("%s", pet); // 字符数组不使用& 12 | printf("%d $%.2f%s\n", age, assets, pet); 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /Chapter-4 Character Strings and Formatted Input-Output/example/4.16-varwid.c: -------------------------------------------------------------------------------- 1 | // varwid.c - 使用变宽输出字段 2 | #include 3 | 4 | int main(void) 5 | { 6 | unsigned width, precision; 7 | int number = 256; 8 | double weight = 242.5; 9 | printf("Enter a field width:\n"); 10 | scanf("%d", &width); 11 | printf("The number is : %*d:\n", width, number); 12 | printf("Now enter a width and a precision:\n"); 13 | scanf("%d %d", &width, &precision); 14 | printf("Weithg = %*.*f\n", width, precision, weight); 15 | printf("Done!\n"); 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /Chapter-4 Character Strings and Formatted Input-Output/example/4.17-skip2.c: -------------------------------------------------------------------------------- 1 | // skip2.c - 跳过输入中的前两个整数 2 | #include 3 | 4 | int main(void) 5 | { 6 | int n; 7 | printf("Please enter three integers:\n"); 8 | scanf("%*d %*d %d", &n); 9 | printf("The last integer was %d\n", n); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /Chapter-4 Character Strings and Formatted Input-Output/example/4.2-praise1.c: -------------------------------------------------------------------------------- 1 | // praise1.c - 使用不同类型的字符串 2 | #include 3 | #define PRAISE "You are an extraordinary being." 4 | 5 | int main(void) 6 | { 7 | char name[40]; 8 | printf("What's your name? "); 9 | scanf("%s", name); 10 | printf("Hello, %s.%s\n", name, PRAISE); 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /Chapter-4 Character Strings and Formatted Input-Output/example/4.3-praise2.c: -------------------------------------------------------------------------------- 1 | // praise2.c 2 | //如果编译器不识别%zd,尝试换成%u或%lu 3 | #include 4 | #include // 提供strlen()函数的原型 5 | #define PRAISE "You are an extraordinary being." 6 | 7 | int main(void) 8 | { 9 | char name[40]; 10 | printf("What's your name?"); 11 | scanf("%s", name); 12 | printf("Hello, %s.%s\n", name, PRAISE); 13 | printf("Your name of %zd letters occupies %zd memory cells.\n", 14 | strlen(name), sizeof name); 15 | printf("The phrase of praise has %zd letters ", strlen(PRAISE)); 16 | printf("and occupies %zd memory cells.\n", sizeof PRAISE); 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /Chapter-4 Character Strings and Formatted Input-Output/example/4.4-pizza.c: -------------------------------------------------------------------------------- 1 | // pizza.c - 在比萨饼程序中使用已定义的常量 2 | #include 3 | #define PI 3.14159 4 | 5 | int main(void) 6 | { 7 | float area, circum, radius; 8 | printf("What is the radius of your pizza?\n"); 9 | scanf("%f", &radius); 10 | area = PI * radius * radius; 11 | circum = 2.0 * PI * radius; 12 | printf("Your basic pizza parameters are as follows:\n"); 13 | printf("circumference = %1.2f, area = %1.2f\n", circum, area); 14 | return 0; 15 | } -------------------------------------------------------------------------------- /Chapter-4 Character Strings and Formatted Input-Output/example/4.5-defines.c: -------------------------------------------------------------------------------- 1 | // defines.c - 使用limit.h和float.h头文件中定义的明示常量 2 | // 编译器要完全支持C99标准才能识别LLONG_MIN标识符 3 | #include 4 | #include // 整形限制 5 | #include // 浮点型限制 6 | 7 | int main(void) 8 | { 9 | printf("Some number limits for this system:\n"); 10 | printf("Biggest int: %d\n", INT_MAX); 11 | printf("Smallest long long: %lld\n", LLONG_MIN); 12 | printf("One byte = %d bits on this system.\n", CHAR_BIT); 13 | printf("Largest double: %e\n", DBL_MAX); 14 | printf("Smallest normal float: %e\n", FLT_MIN); 15 | printf("float precision = %d digits\n", FLT_DIG); 16 | printf("float epsilon = %e\n", FLT_EPSILON); 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /Chapter-4 Character Strings and Formatted Input-Output/example/4.6-printout.c: -------------------------------------------------------------------------------- 1 | // printout.c - 使用转换说明 2 | #include 3 | #define PI 3.141593 4 | 5 | int main(void) 6 | { 7 | int number = 7; 8 | float pies = 12.75; 9 | int cost = 7800; 10 | printf("The %d contestants ate %f berry pies.\n", number, pies); 11 | printf("The value of pi is %f.\n", PI); 12 | printf("Farewell! thou art too dear for my possessing.\n"); 13 | printf("%c%d\n", '$', 2 * cost); 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /Chapter-4 Character Strings and Formatted Input-Output/example/4.7-width.c: -------------------------------------------------------------------------------- 1 | // width.c - 字段宽度 2 | #include 3 | #define PAGES 959 4 | #define NEG -959 5 | 6 | int main(void) 7 | { 8 | printf("*%d*\n", PAGES); 9 | printf("*%2d*\n", PAGES); 10 | printf("*%10d*\n", PAGES); 11 | printf("*%-10d*\n", PAGES); 12 | printf("*%010d*\n", PAGES); 13 | printf("*%x*\n", PAGES); 14 | printf("*%#x*\n", PAGES); 15 | printf("*% d*\n", PAGES); 16 | printf("*% d*\n", NEG); 17 | printf("*%+d*\n", PAGES); 18 | printf("*%+d*\n", NEG); 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /Chapter-4 Character Strings and Formatted Input-Output/example/4.8-floats.c: -------------------------------------------------------------------------------- 1 | // floats.c - 一些浮点型修饰符的组合 2 | #include 3 | 4 | int main(void) 5 | { 6 | const double RENT = 3852.99; // const变量 7 | printf("*%f*\n", RENT); 8 | printf("*%e*\n", RENT); 9 | printf("*%4.2f*\n", RENT); 10 | printf("*%3.1f*\n", RENT); 11 | printf("*%10.3f*\n", RENT); 12 | printf("*%10.3E*\n", RENT); 13 | printf("*%+4.2f*\n", RENT); 14 | printf("*%010.2f*\n", RENT); 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /Chapter-4 Character Strings and Formatted Input-Output/example/4.9-flags.c: -------------------------------------------------------------------------------- 1 | // flag.c - 演示一些格式标记 2 | #include 3 | 4 | int main(void) 5 | { 6 | printf("%x %X %#x\n", 31, 31, 31); 7 | printf("**%d**% d**% d**\n", 42, 42, -42); 8 | printf("**%5d**%5.3d**%05d**%05.3d**\n", 6, 6, 6, 6); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /Chapter-4 Character Strings and Formatted Input-Output/exercise/4-1.c: -------------------------------------------------------------------------------- 1 | // 4-1 编写一个程序,提示用户输入名和姓,然后以“名,姓”的格式打印出来。 2 | #include 3 | 4 | int main(void) 5 | { 6 | char fName[40]; 7 | char lName[40]; 8 | printf("Please enter your first name:\n"); 9 | scanf("%s", fName); 10 | printf("Please enter your last name:\n"); 11 | scanf("%s", lName); 12 | printf("%s,%s\n", fName, lName); 13 | return 0; 14 | } -------------------------------------------------------------------------------- /Chapter-4 Character Strings and Formatted Input-Output/exercise/4-2.c: -------------------------------------------------------------------------------- 1 | // 4-2 编写一个程序,提示用户输入名字,并执行一下操作: 2 | // a.打印名字,包括双引号; 3 | // b.在宽度为20的字段右端打印名字,包括双引号; 4 | // c.在宽度为20的字段左端打印名字,包括双引号; 5 | // d.在比姓名宽度宽3的字段中打印名字。 6 | #include 7 | #include 8 | 9 | int main(void) 10 | { 11 | char name[40]; 12 | printf("Please enter your name:\n"); 13 | scanf("%s", name); 14 | // a 15 | printf("\"%s\"\n", name); 16 | // b 17 | printf("\"%20s\"\n", name); 18 | // c 19 | printf("\"%-20s\"\n", name); 20 | // d 21 | int width = strlen(name) + 3; 22 | printf("%*s\n", width, name); 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /Chapter-4 Character Strings and Formatted Input-Output/exercise/4-3.c: -------------------------------------------------------------------------------- 1 | // 4-3 编写一个程序,读取一个浮点数,首先以小数点记数法打印 2 | // 然后以指数记数法打印。用下面的格式进行输出 3 | // (系统不同,指数记数法显示的位 数可能不同): 4 | // a.输入21.3或2.1e+001; 5 | // b.输入+21.290或2.129E+001; 6 | #include 7 | 8 | int main(void) 9 | { 10 | float num; 11 | printf("Please enter a number:\n"); 12 | scanf("%f", &num); 13 | printf("%.1f %.1e\n", num, num); 14 | printf("%+.3f %.3e\n", num, num); 15 | return 0; 16 | } -------------------------------------------------------------------------------- /Chapter-4 Character Strings and Formatted Input-Output/exercise/4-4.c: -------------------------------------------------------------------------------- 1 | // 4-4 4.编写一个程序,提示用户输入身高(单位:英寸)和姓名, 2 | // 然后以下 面的格式显示用户刚输入的信息: 3 | // Dabney, you are 6.208 feet tall 4 | // 使用float类型,并用/作为除号。 5 | // 如果你愿意,可以要求用户以厘米为 单位输入身高,并以米为单位显示出来。 6 | #include 7 | 8 | int main(void) 9 | { 10 | char name[40]; 11 | float height; 12 | printf("Please enter your name:\n"); 13 | scanf("%s", name); 14 | printf("Please enter your height(cm):\n"); 15 | scanf("%f", &height); 16 | printf("%s, your are %.3f meter tall\n", name, height / 100); 17 | return 0; 18 | } -------------------------------------------------------------------------------- /Chapter-4 Character Strings and Formatted Input-Output/exercise/4-5.c: -------------------------------------------------------------------------------- 1 | // 4-5 编写一个程序,提示用户输入以兆位每秒(Mb/s)为单位的下载速度 2 | // 和以兆字节(MB)为单位的文件大小。 3 | // 程序中应计算文件的下载时间。 4 | // 注意,这里1字节等于8位。使用float类型,并用/作为除号。 5 | // 该程序要以下面的格式打印 3 个变量的值(下载速度、文件大小和下载时间), 6 | // 显示小数点后面两位数字: 7 | // At 18.12 megabits per second, a file of 2.20 megabytes 8 | // downloads in 0.97 seconds. 9 | #include 10 | 11 | int main(void) 12 | { 13 | float speed, fileSize; 14 | printf("Please enter your download speed(Mb/s):\n"); 15 | scanf("%f", &speed); 16 | printf("Please enter your file size(MB):\n"); 17 | scanf("%f", &fileSize); 18 | printf("At %.2f megabits per second, a file of %.2f megabytes\n" 19 | "downloads in %.2f seconds.\n", 20 | speed, fileSize, 21 | fileSize / (speed / 8) 22 | ); 23 | return 0; 24 | } -------------------------------------------------------------------------------- /Chapter-4 Character Strings and Formatted Input-Output/exercise/4-6.c: -------------------------------------------------------------------------------- 1 | // 4-6 2 | // 编写一个程序,先提示用户输入名,然后提示用户输入姓。 3 | // 在一行打印用户输入的名和姓,下一行分别打印名和姓的字母数。 4 | // 字母数要与相应名和姓的结尾对齐 5 | // 接下来,再打印相同的信息,但是字母个数与相应名和姓的开头对齐 6 | #include 7 | #include 8 | 9 | int main(void) 10 | { 11 | char fName[40]; 12 | char lName[40]; 13 | int len1, len2; 14 | printf("Please enter your first name:\n"); 15 | scanf("%s", fName); 16 | printf("Please enter your last name:\n"); 17 | scanf("%s", lName); 18 | len1 = (int)(strlen(fName)); 19 | len2 = (int)(strlen(lName)); 20 | printf("%s %s\n", fName, lName); 21 | printf("%*d %*d\n", len1, len1, len2, len2); 22 | printf("%s %s\n", fName, lName); 23 | printf("%-*d %-*d\n", len1, len1, len2, len2); 24 | return 0; 25 | } -------------------------------------------------------------------------------- /Chapter-4 Character Strings and Formatted Input-Output/exercise/4-7.c: -------------------------------------------------------------------------------- 1 | // 4-7 2 | // 编写一个程序,将一个double类型的变量设置为1.0/3.0, 3 | // 一个float类型的变量设置为1.0/3.0。 4 | // 分别显示两次计算的结果各3次:一次显示小数点后面6位数字; 5 | // 一次显示小数点后面12位数字; 6 | // 一次显示小数点后面16位数字。 7 | // 程序中要包含float.h头文件,并显示FLT_DIG和DBL_DIG的值。 8 | // 1.0/3.0 的值与这些值一致吗? 9 | #include 10 | #include 11 | 12 | int main(void) 13 | { 14 | double num1 = 1.0 / 3.0; 15 | float num2 = 1.0 / 3.0; 16 | printf("%.6f %.6f\n", num1, num2); 17 | printf("%.12f %.12f\n", num1, num2); 18 | printf("%.16f %.16f\n", num1, num2); 19 | printf("FLT_DIG is %d\n", FLT_DIG); 20 | printf("DBL_DIG is %d\n", DBL_DIG); 21 | return 0; 22 | } -------------------------------------------------------------------------------- /Chapter-4 Character Strings and Formatted Input-Output/exercise/4-8.c: -------------------------------------------------------------------------------- 1 | // 4-8 2 | // 编写一个程序,提示用户输入旅行的里程和消耗的汽油量。 3 | // 然后计算并显示消耗每加仑汽油行驶的英里数,显示小数点后面一位数字。 4 | // 接下来,使用1加仑大约3.785升,1英里大约为1.609千米, 5 | // 把单位是英里/加仑的值转换为升/100公里(欧洲通用的燃料消耗表示法), 6 | // 并显示结果,显示小数点后面 1 位数字。 7 | // 注意,美国采用的方案测量消耗单位燃料的行程(值越大越好), 8 | // 而欧洲则采用单位距离消耗的燃料测量方案(值越低越好)。 9 | // 使用 #define 创建符号常量或使用 const 限定符创建变量来表示两个转换系数。 10 | #include 11 | #define GALLON_TO_LITRE 3.785 12 | #define MILE_TO_KM 1.609 13 | 14 | int main(void) 15 | { 16 | double mileage, consumption, stdUS, stdEU; 17 | printf("Please enter your mileage(miles):\n"); 18 | scanf("%lf", &mileage); 19 | printf("Please enter your consumption(gallons):\n"); 20 | scanf("%lf", &consumption); 21 | stdUS = mileage / consumption; 22 | printf("%.1f miles per gallon.\n", stdUS); 23 | stdEU = (consumption * GALLON_TO_LITRE) / (mileage * MILE_TO_KM / 100); 24 | printf("%.1f litres per 100km.\n", stdEU); 25 | return 0; 26 | } -------------------------------------------------------------------------------- /Chapter-4 Character Strings and Formatted Input-Output/images/1-manifest-constants-limits.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/logan70/C-Primer-Plus-6th-Notes-CN/6d4beffefdbf6ebe4893974a274d0cfb112605b6/Chapter-4 Character Strings and Formatted Input-Output/images/1-manifest-constants-limits.png -------------------------------------------------------------------------------- /Chapter-4 Character Strings and Formatted Input-Output/images/2-manifest-constants-float.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/logan70/C-Primer-Plus-6th-Notes-CN/6d4beffefdbf6ebe4893974a274d0cfb112605b6/Chapter-4 Character Strings and Formatted Input-Output/images/2-manifest-constants-float.png -------------------------------------------------------------------------------- /Chapter-4 Character Strings and Formatted Input-Output/images/3-printf-conversion-specification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/logan70/C-Primer-Plus-6th-Notes-CN/6d4beffefdbf6ebe4893974a274d0cfb112605b6/Chapter-4 Character Strings and Formatted Input-Output/images/3-printf-conversion-specification.png -------------------------------------------------------------------------------- /Chapter-4 Character Strings and Formatted Input-Output/images/4-printf-modifier.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/logan70/C-Primer-Plus-6th-Notes-CN/6d4beffefdbf6ebe4893974a274d0cfb112605b6/Chapter-4 Character Strings and Formatted Input-Output/images/4-printf-modifier.png -------------------------------------------------------------------------------- /Chapter-4 Character Strings and Formatted Input-Output/images/5-printf-flags.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/logan70/C-Primer-Plus-6th-Notes-CN/6d4beffefdbf6ebe4893974a274d0cfb112605b6/Chapter-4 Character Strings and Formatted Input-Output/images/5-printf-flags.png -------------------------------------------------------------------------------- /Chapter-4 Character Strings and Formatted Input-Output/images/6-scanf-modifier.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/logan70/C-Primer-Plus-6th-Notes-CN/6d4beffefdbf6ebe4893974a274d0cfb112605b6/Chapter-4 Character Strings and Formatted Input-Output/images/6-scanf-modifier.png -------------------------------------------------------------------------------- /Chapter-4 Character Strings and Formatted Input-Output/images/7-scanf-flags-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/logan70/C-Primer-Plus-6th-Notes-CN/6d4beffefdbf6ebe4893974a274d0cfb112605b6/Chapter-4 Character Strings and Formatted Input-Output/images/7-scanf-flags-2.png -------------------------------------------------------------------------------- /Chapter-4 Character Strings and Formatted Input-Output/images/7-scanf-flags.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/logan70/C-Primer-Plus-6th-Notes-CN/6d4beffefdbf6ebe4893974a274d0cfb112605b6/Chapter-4 Character Strings and Formatted Input-Output/images/7-scanf-flags.png -------------------------------------------------------------------------------- /Chapter-5 Operators, Expressions, and Statements/README.md: -------------------------------------------------------------------------------- 1 | # 第五章 运算符、表达式和语句 2 | 3 | ## 运算符 4 | 5 | C 语言有许多运算符,如本章讨论的赋值运算符和算术运算符。一般而言,运算符需要一个或多个运算对象才能完成运算生成一个值。只需要一个运算对象的运算符(如负号和sizeof)称为一元运算符,需要两个运算对象的运算符(如加法运算符和乘法运算符)称为二元运算符。 6 | 7 | ## 表达式 8 | 9 | 表达式由运算符和运算对象组成。在C语言中,每个表达式都有一个值,包括赋值表达式和比较表达式。运算符优先级规则决定了表达式中各项的求值顺序。当两个运算符共享一个运算对象时,先进行优先级高的运算。如果运算符的优先级相等,由结合律(从左往右或从右往左)决定求值顺序。 10 | 11 | ## 语句 12 | 13 | 大部分语句都以分号结尾。最常用的语句是表达式语句。用花括号括起来的一条或多条语句构成了复合语句(或称为块)。while语句是一种迭代语句,只要测试条件为真,就重复执行循环体中的语句。 14 | 15 | ## 类型转换 16 | 17 | 在C语言中,许多类型转换都是自动进行的。当char和short类型出现在表达式里或作为函数的参数(函数原型除外)时,都会被升级为int类型; float类型在函数参数中时,会被升级为double类型。 18 | 19 | 当把一种类型的值赋给另一种类型的变量时,值将被转换成与变量的类型相同。当把较大类型转换成较小类型时(如,long转换成short,或 double 转换成 float),可能会丢失数据。 -------------------------------------------------------------------------------- /Chapter-5 Operators, Expressions, and Statements/example/5.1-shoes1.c: -------------------------------------------------------------------------------- 1 | // shoes1.c - 把鞋码换成英寸 2 | #include 3 | #define ADJUST 7.31 4 | 5 | int main(void) 6 | { 7 | const double SCALE = 0.333; // const变量 8 | double shoe, foot; 9 | shoe = 9.0; 10 | foot = SCALE * shoe + ADJUST; 11 | printf("Shoe size(men's) foot length\n"); 12 | printf("%10.1f %15.2f inches\n", shoe, foot); 13 | return 0; 14 | } -------------------------------------------------------------------------------- /Chapter-5 Operators, Expressions, and Statements/example/5.10-add_one.c: -------------------------------------------------------------------------------- 1 | // add_one.c - 递增:前缀和后缀 2 | #include 3 | 4 | int main(void) 5 | { 6 | int ultra = 0, super = 0; 7 | while (super < 5) 8 | { 9 | super++; 10 | ++ultra; 11 | printf("super = %d, ultra = %d \n", super, ultra); 12 | } 13 | return 0; 14 | } -------------------------------------------------------------------------------- /Chapter-5 Operators, Expressions, and Statements/example/5.11-post_pre.c: -------------------------------------------------------------------------------- 1 | // post_pre.c - 前缀和后缀 2 | #include 3 | 4 | int main(void) 5 | { 6 | int a = 1, b = 1; 7 | int a_post, pre_b; 8 | a_post = a++; // 后缀递增 9 | pre_b = ++b; // 前缀递增 10 | printf("a a_post b pre_b \n"); 11 | printf("%1d %5d %5d %5d\n", a, a_post, b, pre_b); 12 | return 0; 13 | } -------------------------------------------------------------------------------- /Chapter-5 Operators, Expressions, and Statements/example/5.12-bottles.c: -------------------------------------------------------------------------------- 1 | // bottles.c 递减运算符 2 | #include 3 | #define MAX 100 4 | 5 | int main(void) 6 | { 7 | int count = MAX + 1; 8 | while (--count > 0) { 9 | printf("%d bottles of spring water on the wall, " 10 | "%d bottles of spring water!\n", count, count); 11 | printf("Take one down and pass it around,\n"); 12 | printf("%d bottles of spring water!\n\n", count - 1); 13 | } 14 | return 0; 15 | } -------------------------------------------------------------------------------- /Chapter-5 Operators, Expressions, and Statements/example/5.13-addemup.c: -------------------------------------------------------------------------------- 1 | // addemup.c - 几种常见的语句 2 | #include 3 | 4 | int main(void) // 计算前20个整数的和 5 | { 6 | int count, sum; // 声明 7 | count = 0; // 表达式语句 8 | sum = 0; // 表达式语句 9 | while (count++ < 20) // 迭代语句 10 | { 11 | sum = sum + count; 12 | } 13 | printf("sum = %d\n", sum); // 表达式语句 14 | return 0; // 跳转语句 15 | } -------------------------------------------------------------------------------- /Chapter-5 Operators, Expressions, and Statements/example/5.14-convert.c: -------------------------------------------------------------------------------- 1 | // convert.c - 自动类型转换 2 | #include 3 | 4 | int main(void) 5 | { 6 | char ch; 7 | int i; 8 | float fll; 9 | fl = i = ch = 'C'; 10 | printf("ch = %c, i = %d, fl = %2.2f\n", ch, i, fl); 11 | ch = ch + 1; 12 | i = fl + 2 * ch; 13 | fl = 2.0 * ch + i; 14 | printf("ch = %c, i = %d, fl = %2.2f\n", ch, i, fl); 15 | ch = 1107; 16 | printf("Now ch = %c\n", ch) 17 | ch = 80.89; 18 | printf("Now ch = %c\n", ch); 19 | return 0; 20 | } -------------------------------------------------------------------------------- /Chapter-5 Operators, Expressions, and Statements/example/5.15-pound.c: -------------------------------------------------------------------------------- 1 | // pound.c - 定义一个带参数的函数 2 | #include 3 | 4 | void pound(int n); // ANSI函数原型声明 5 | 6 | int main(void) 7 | { 8 | int times = 5; 9 | char ch = '!'; // ASCII码是33 10 | float f = 6.0f; 11 | pound(times); // int类型参数 12 | pound(ch); // 和pound((int)ch);相同 13 | pound(f); // 和pound((int)f);相同 14 | return 0; 15 | } 16 | 17 | void pound(int n) // ANSI风格函数头,该函数接受一个int类型的参数 18 | { 19 | while (n-- > 0) 20 | printf("#"); 21 | printf("\n"); 22 | } -------------------------------------------------------------------------------- /Chapter-5 Operators, Expressions, and Statements/example/5.2-shoes2.c: -------------------------------------------------------------------------------- 1 | // shoes2.c - 计算多个不同鞋码对应的脚长 2 | #include 3 | #define ADJUST 7.31 // 字符常量 4 | 5 | int main(void) 6 | { 7 | const double SCALE = 0.333; // const变量 8 | double shoe, foot; 9 | printf("Shoe size (men's) foot length\n"); 10 | shoe = 3.0; 11 | while(shoe < 18.5) // while 循环开始 12 | { 13 | foot = SCALE * shoe + ADJUST; 14 | printf("%10.1f %15.2f inches\n", shoe, foot); 15 | shoe = shoe + 1.0; 16 | } // 块结束 17 | printf("If the shoe fits, wear it.\n"); 18 | return 0; 19 | } -------------------------------------------------------------------------------- /Chapter-5 Operators, Expressions, and Statements/example/5.3-golf.c: -------------------------------------------------------------------------------- 1 | // golf.c - 高尔夫锦标赛记分卡 2 | #include 3 | 4 | int main(void) 5 | { 6 | int jane, tarzan, cheeta; 7 | cheeta = tarzan = jane = 68; 8 | printf(" cheeta tarzan jane\n"); 9 | printf("Fitst round score %4d %8d %8d\n", cheeta, tarzan, jane); 10 | return 0; 11 | } -------------------------------------------------------------------------------- /Chapter-5 Operators, Expressions, and Statements/example/5.4-squares.c: -------------------------------------------------------------------------------- 1 | // squares.c - 计算1~20的平方 2 | #include 3 | 4 | int main(void) 5 | { 6 | int num = 1; 7 | while (num < 21) 8 | { 9 | printf("%4d %6d\n", num, num * num); 10 | num = num + 1; 11 | } 12 | return 0; 13 | } -------------------------------------------------------------------------------- /Chapter-5 Operators, Expressions, and Statements/example/5.5-wheat.c: -------------------------------------------------------------------------------- 1 | // wheat.c - 指数增长 2 | #include 3 | #define SQUARES 64 // 棋盘中的方格数 4 | int main(void) 5 | { 6 | const double CROP = 2E16; // 世界小麦年产谷粒数 7 | double current, total; 8 | int count = 1; 9 | printf("square grains total "); 10 | printf("fraction of \n"); 11 | printf(" added grains "); 12 | printf("world total\n"); 13 | total = current = 1.0; // 从1颗谷粒开始 14 | printf("%4d %13.2e %12.2e %12.2e\n", count, current, total, total / CROP); 15 | while (count < SQUARES) 16 | { 17 | count = count + 1; 18 | current = 2.0 * current; // 下一个方格谷粒翻倍 19 | total = total + current; // 更新总数 20 | printf("%4d %13.2e %12.2e %12.2e\n", count, current, total, total / CROP); 21 | } 22 | printf("That's all.\n"); 23 | return 0; 24 | } -------------------------------------------------------------------------------- /Chapter-5 Operators, Expressions, and Statements/example/5.6-divide.c: -------------------------------------------------------------------------------- 1 | // divide.c - 演示除法 2 | #include 3 | 4 | int main(void) 5 | { 6 | printf("integer division 5/4 is %d \n", 5 / 4); 7 | printf("integer division: 6/3 is %d \n", 6 / 3); 8 | printf("Integer division 7/44 is %d \n", 7 / 4); 9 | printf("floating division: 7./4. is %1.2f \n", 7. / 4.); 10 | printf("mixed division: 7./4 is %1.2f \n", 7. / 4); 11 | return 0; 12 | } -------------------------------------------------------------------------------- /Chapter-5 Operators, Expressions, and Statements/example/5.7-rules.c: -------------------------------------------------------------------------------- 1 | // rules.c - 优先级测试 2 | #include 3 | 4 | int main(void) 5 | { 6 | int top, score; 7 | top = score = - (2 + 5) * 6 + (4 + 3 * (2 + 3)); 8 | printf("top = %d, score = %d\n", top, score); 9 | return 0; 10 | } -------------------------------------------------------------------------------- /Chapter-5 Operators, Expressions, and Statements/example/5.8-sizeof.c: -------------------------------------------------------------------------------- 1 | // sizeof.c - 使用sizeof运算符 2 | // 使用C99新增的%zd转换说明 - 如果编译器不支持%zd,请将其改为%u或%lu 3 | #include 4 | 5 | int main(void) 6 | { 7 | int n = 0; 8 | size_t intsize; 9 | intsize = sizeof (int); 10 | printf("n = %d, n has %zd bytes; all ints have %zd bytes.\n", 11 | n, sizeof n, intsize); 12 | return 0; 13 | } -------------------------------------------------------------------------------- /Chapter-5 Operators, Expressions, and Statements/example/5.9-min_sec.c: -------------------------------------------------------------------------------- 1 | // min_sec.c - 把秒数转换成分和秒 2 | #include 3 | #define SEC_PER_MIN 60 // 1分钟60秒 4 | 5 | int main(void) 6 | { 7 | int sec, min, left; 8 | printf("Convert seconds to minutes and seconds!\n"); 9 | printf("Enter the number of seconds( <= 0 to quit): \n"); 10 | scanf("%d", &sec); // 读取秒数 11 | while (sec > 0) 12 | { 13 | min = sec / SEC_PER_MIN; // 截断分钟数 14 | left = sec % SEC_PER_MIN; // 剩下的秒数 15 | printf("%d seconds is %d minutes, %d seconds.\n", sec, min, left); 16 | printf("Enter next value (<=0 to quit):\n"); 17 | scanf("%d", &sec); 18 | } 19 | printf("Done!\n"); 20 | return 0; 21 | } -------------------------------------------------------------------------------- /Chapter-5 Operators, Expressions, and Statements/exercise/5-1.c: -------------------------------------------------------------------------------- 1 | // 编写一个程序,把用分钟表示的时间转换成用小时和分钟表示的时间。 2 | // 使用#define或const创建一个表示60的符号常量或const变量。 3 | // 通过while循环让用户重复输入值,直到用户输入小于或等于0的值才停止循环。 4 | #include 5 | #define MIN_PER_HOUR 60 6 | 7 | int main(void) 8 | { 9 | int inputMin, hour, min; 10 | printf("Please input the number of minutes:\n"); 11 | scanf("%d", &inputMin); 12 | while (inputMin > 0) 13 | { 14 | hour = inputMin / MIN_PER_HOUR; 15 | min = inputMin % MIN_PER_HOUR; 16 | printf("%d minutes is %d hours and %d minutes.\n", 17 | inputMin, hour, min); 18 | printf("Please input the number of minutes:\n"); 19 | scanf("%d", &inputMin); 20 | } 21 | printf("Done!\n"); 22 | return 0; 23 | } -------------------------------------------------------------------------------- /Chapter-5 Operators, Expressions, and Statements/exercise/5-2.c: -------------------------------------------------------------------------------- 1 | // 编写一个程序,提示用户输入一个整数,然后打印从该数到比该数大10的所有整数 2 | // (例如,用户输入5,则打印5~15的所有整数,包括5和 15)。 3 | // 要求打印的各值之间用一个空格、制表符或换行符分开。 4 | #include 5 | #define COUNT 10 6 | int main(void) 7 | { 8 | int i = 0; 9 | int num; 10 | printf("Please enter a number:\n"); 11 | scanf("%d", &num); 12 | while (i++ < 10) 13 | printf("%5d", num++); 14 | printf("%5d\n", num); 15 | return 0; 16 | } -------------------------------------------------------------------------------- /Chapter-5 Operators, Expressions, and Statements/exercise/5-3.c: -------------------------------------------------------------------------------- 1 | // 编写一个程序,提示用户输入天数,然后将其转换成周数和天数。 2 | // 例如,用户输入18,则转换成2周4天。以下面的格式显示结果: 3 | // 18 days are 2 weeks, 4 days. 4 | // 通过while循环让用户重复输入天数,当用户输入一个非正值时(如0 或-20),循环结束。 5 | #include 6 | #define DAY_PER_WEEK 7 7 | int main(void) 8 | { 9 | int inputDay, week, day; 10 | printf("Please input the number of days:\n"); 11 | scanf("%d", &inputDay); 12 | while (inputDay > 0) 13 | { 14 | week = inputDay / DAY_PER_WEEK; 15 | day = inputDay % DAY_PER_WEEK; 16 | printf("%d days is %d weeks and %d days.\n", 17 | inputDay, week, day); 18 | printf("Please input the number of days:\n"); 19 | scanf("%d", &inputDay); 20 | } 21 | printf("Done!\n"); 22 | return 0; 23 | } -------------------------------------------------------------------------------- /Chapter-5 Operators, Expressions, and Statements/exercise/5-4.c: -------------------------------------------------------------------------------- 1 | // 编写一个程序,提示用户输入一个身高(单位:厘米), 2 | // 并分别以厘米和英寸为单位显示该值,允许有小数部分。 3 | // 程序应该能让用户重复输入身高,直到用户输入一个非正值。其输出示例如下: 4 | // Enter a height in centimeters: 182 5 | // 182.0 cm = 5 feet, 11.7 inches 6 | // Enter a height in centimeters (<=0 to quit): 168.7 7 | // 168.0 cm = 5 feet, 6.4 inches 8 | // Enter a height in centimeters (<=0 to quit): 0 9 | // bye 10 | #include 11 | #define CM_PER_INCH 2.54 12 | #define INCH_PER_FEET 12.0 13 | 14 | int main(void) 15 | { 16 | int feets; 17 | double input, inches, minches; 18 | printf("Enter a height in centimeters: "); 19 | scanf("%lf", &input); 20 | while(input > 0) 21 | { 22 | inches = input / CM_PER_INCH; 23 | feets = (int)(inches / INCH_PER_FEET); 24 | minches = inches - (feets * INCH_PER_FEET); 25 | printf("%.1f cm = %d feet, %.1f inches\n", 26 | input, feets, minches); 27 | printf("Enter a height in centimeters (<= 0 to quit): "); 28 | scanf("%lf", &input); 29 | } 30 | printf("bye\n"); 31 | return 0; 32 | } -------------------------------------------------------------------------------- /Chapter-5 Operators, Expressions, and Statements/exercise/5-5.c: -------------------------------------------------------------------------------- 1 | // 修改程序addemup.c(程序清单5.13),你可以认为addemup.c是计算20天里赚多少钱的程序 2 | // (假设第1天赚$1、第2天赚$2、第3天赚$3,以此类推)。 3 | // 修改程序,使其可以与用户交互,根据用户输入的数进行计算 4 | // (即, 用读入的一个变量来代替20)。 5 | #include 6 | 7 | int main(void) // 计算20个整数的和 8 | { 9 | int i = 0, sum = 0, days; 10 | printf("Please enter the number of days:\n"); 11 | scanf("%d", &days); 12 | while (i++ < days) 13 | { 14 | sum = sum + i; 15 | } 16 | printf("sum = %d\n", sum); 17 | return 0; 18 | } -------------------------------------------------------------------------------- /Chapter-5 Operators, Expressions, and Statements/exercise/5-6.c: -------------------------------------------------------------------------------- 1 | // 修改编程练习5的程序,使其能计算整数的平方和(可以认为第1天赚 $1、第2天赚$4、第3天赚$9,以此类推,这看起来很不错)。 2 | // C没有平方函数,但是可以用n * n来表示n的平方。 3 | #include 4 | 5 | int main(void) // 计算20个整数的和 6 | { 7 | int i = 0, sum = 0, days; 8 | printf("Please enter the number of days:\n"); 9 | scanf("%d", &days); 10 | while (i++ < days) 11 | { 12 | sum = sum + i * i; 13 | } 14 | printf("sum = %d\n", sum); 15 | return 0; 16 | } -------------------------------------------------------------------------------- /Chapter-5 Operators, Expressions, and Statements/exercise/5-7.c: -------------------------------------------------------------------------------- 1 | // 编写一个程序,提示用户输入一个double类型的数,并打印该数的立方值。 2 | // 自己设计一个函数计算并打印立方值。main()函数要把用户输入的值传递给该函数。 3 | #include 4 | 5 | double cube(double num); 6 | 7 | int main(void) 8 | { 9 | double num; 10 | printf("Please enter a number:\n"); 11 | scanf("%lf", &num); 12 | printf("The cube of %f is %f.\n", num, cube(num)); 13 | } 14 | 15 | double cube(double num) 16 | { 17 | return num * num * num; 18 | } -------------------------------------------------------------------------------- /Chapter-5 Operators, Expressions, and Statements/exercise/5-8.c: -------------------------------------------------------------------------------- 1 | // 编写一个程序,显示求模运算的结果。 2 | // 把用户输入的第1个整数作为求模运算符的第2个运算对象,该数在运算过程中保持不变。 3 | // 用户后面输入的数是第1个运算对象。当用户输入一个非正值时,程序结束。 4 | // 其输出示例如下: 5 | // This program computes moduli. 6 | // Enter an integer to serve as the second operand: 256 7 | // Now enter the first operand: 438 8 | // 438 % 256 is 182 9 | // Enter next number for first operand (<= 0 to quit): 1234567 10 | // 1234567 % 256 is 135 11 | // Enter next number for first operand (<= 0 to quit): 0 12 | // Done 13 | #include 14 | 15 | int main(void) 16 | { 17 | int base, num; 18 | printf("This program computes moduli.\n"); 19 | printf("Enter an integer to serve as the second operand: "); 20 | scanf("%d", &base); 21 | printf("Now enter the first operand: "); 22 | scanf("%d", &num); 23 | while (num > 0) 24 | { 25 | printf("%d %% %d is %d\n", num, base, num % base); 26 | printf("Enter next number for first operand(<= 0 to quit): "); 27 | scanf("%d", &num); 28 | } 29 | printf("Done\n"); 30 | return 0; 31 | } -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/README.md: -------------------------------------------------------------------------------- 1 | # 第六章 C控制语句:循环 2 | 3 | ## `while`循环 4 | 5 | **入口条件循环** 6 | 7 | 伪代码: 8 | 9 | ``` 10 | 获得初值 11 | while (值满足测试条件) 12 | { 13 | 处理改值 14 | 获取下一个值 15 | } 16 | ``` 17 | 18 | ## `for`循环 19 | 20 | **入口条件循环** 21 | 22 | ``` 23 | for (获得初值; 值满足测试条件; 获得下一个值) 24 | { 25 | 处理该值 26 | } 27 | ``` 28 | 29 | ## `do while`循环 30 | 31 | **出口条件循环** 32 | 33 | ``` 34 | do { 35 | 处理该值 36 | 获取下一个值 37 | } while (值满足测试条件); 38 | ``` 39 | 40 | ## 循环的选择 41 | 42 | 1. 执行循环之后测试条件,则选择`do while`循环; 43 | 2. 当循环涉及初始化和更新变量时,选择`for`循环; 44 | 3. 其他情况下选择`while`循环。 45 | 46 | ## _Bool 类型 47 | 48 | C99新增了_Bool类型,该类型的变量只能存储1或0,1为真,0为假。 49 | 50 | 关系表达式为真,则表达式的值为1;关系表达式为假,则表达式的值为0。 51 | -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/example/6.1-summing.c: -------------------------------------------------------------------------------- 1 | // summing.c - 根据用户键入的整数求和 2 | #include 3 | 4 | int main(void) 5 | { 6 | long num; 7 | long sum = 0L; 8 | int status; 9 | printf("Please enter an integer to be summed"); 10 | printf("(q to quit): "); 11 | status = scanf("%ld", &num); 12 | while(status == 1) 13 | { 14 | sum = sum + num; 15 | printf("Please enter next integer (q to quit): "); 16 | status = scanf("%ld", &num); 17 | } 18 | printf("Those integers sum to %ld.\n", sum); 19 | return 0; 20 | } -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/example/6.10-sweetie1.c: -------------------------------------------------------------------------------- 1 | // sweetie1.c 2 | #include 3 | 4 | int main(void) 5 | { 6 | const int NUMBER = 22; 7 | int count = 1; 8 | while (count <= NUMBER) 9 | { 10 | printf("Be my Valentine!\n"); 11 | count++; 12 | } 13 | return 0; 14 | } -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/example/6.11-sweetie2.c: -------------------------------------------------------------------------------- 1 | // sweetie2.c - 使用for循环的计数循环 2 | #include 3 | 4 | int main(void) 5 | { 6 | const int NUMBER = 22; 7 | int count; 8 | for (count = 1; count <= NUMBER; count++) 9 | printf("Be my Valentine!\n"); 10 | return 0; 11 | } -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/example/6.12-for_cube.c: -------------------------------------------------------------------------------- 1 | // for_cube.c - 使用for循环创建一个立方表 2 | #include 3 | 4 | int main(void) 5 | { 6 | int num; 7 | printf(" n n cubed\n"); 8 | for (num = 1; num <= 6; num++) 9 | printf("%5d %5d\n", num, num * num * num); 10 | return 0; 11 | } -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/example/6.13-postage.c: -------------------------------------------------------------------------------- 1 | // postage.c - 一类邮资 2 | #include 3 | 4 | int main(void) 5 | { 6 | const int FIRST_OZ = 46; 7 | const int NEXT_OZ = 20; 8 | int ounces, cost; 9 | printf(" ounces cost\n"); 10 | for (ounces = 1, cost = FIRST_OZ; ounces <= 16; 11 | ounces++, cost += NEXT_OZ) 12 | printf("%5d $%4.2f\n", ounces, cost / 100.0); 13 | return 0; 14 | } -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/example/6.14-zeno.c: -------------------------------------------------------------------------------- 1 | // zeno.c - 求序列的和 2 | #include 3 | 4 | int main(void) 5 | { 6 | int t_ct;// 计数项 7 | double time, power_of_2; 8 | int limit; 9 | printf("Enter the number of terms you want: "); 10 | scanf("%d", &limit); 11 | for (time = 0, power_of_2 = 1, t_ct = 1; t_ct <= limit; t_ct++, power_of_2 *= 2.0) 12 | { 13 | time += 1.0 / power_of_2; 14 | printf("time = %f when terms = %d.\n", time, t_ct); 15 | } 16 | return 0; 17 | } -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/example/6.15-do_while.c: -------------------------------------------------------------------------------- 1 | // do_while.c - 出口条件循环 2 | #include 3 | 4 | int main(void) 5 | { 6 | const int secret_code = 13; 7 | int code_entered; 8 | do 9 | { 10 | printf("To enter the triskaidekaphobia therapy club,\n"); 11 | printf("please enter eht secret code number: "); 12 | scanf("%d", &code_entered); 13 | } while (code_entered != secret_code); 14 | printf("Congratulations! You are cured!\n"); 15 | return 0; 16 | } -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/example/6.16-entry.c: -------------------------------------------------------------------------------- 1 | // entry.c - 出口条件循环 2 | #include 3 | 4 | int main(void) 5 | { 6 | const int secret_code = 13; 7 | int code_entered; 8 | printf("To enter the triskaidekaphobia therapy club,\n"); 9 | printf("please enter the secret code number: "); 10 | scanf("%d", &code_entered); 11 | while (code_entered != secret_code) 12 | { 13 | printf("To enter the triskaidekaphobia therapy club,\n"); 14 | printf("please enter the secret code number: "); 15 | scanf("%d", &code_entered); 16 | } 17 | printf("Congratulations! You are cured!\n"); 18 | return 0; 19 | } -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/example/6.17-rows1.c: -------------------------------------------------------------------------------- 1 | // rows1.c - 使用嵌套循环 2 | #include 3 | #define ROWS 6 4 | #define CHARS 10 5 | 6 | int main(void) 7 | { 8 | int row; 9 | char ch; 10 | for (row = 0; row < ROWS; row++) 11 | { 12 | for (ch = 'A';ch < ('A' + CHARS); ch++) 13 | printf("%c", ch); 14 | printf("\n"); 15 | } 16 | return 0; 17 | } -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/example/6.18-rows2.c: -------------------------------------------------------------------------------- 1 | // rows2.c - 依赖外部循环的嵌套循环 2 | #include 3 | int main(void) 4 | { 5 | const int ROWS = 6; 6 | const int CHARS = 6; 7 | int row; 8 | char ch; 9 | for (row = 0; row < ROWS; row++) 10 | { 11 | for (ch = ('A' + row); ch < ('A' + CHARS); ch++) 12 | printf("%c", ch); 13 | printf("\n"); 14 | } 15 | return 0; 16 | } -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/example/6.19-scores_in.c: -------------------------------------------------------------------------------- 1 | // scores_in.c - 使用循环处理数组 2 | #include 3 | #define SIZE 10 4 | #define PAR 72 5 | 6 | int main(void) 7 | { 8 | int index, score[SIZE]; 9 | int sum = 0; 10 | float average; 11 | printf("Enter %d golf scores: \n", SIZE); 12 | for (index = 0; index < SIZE; index++) 13 | scanf("%d", &score[index]); 14 | printf("The scores read in are as follows:\n"); 15 | for (index = 0; index < SIZE; index++) 16 | printf("%5d", score[index]); 17 | printf("\n"); 18 | for (index = 0; index < SIZE; index++) 19 | sum += score[index]; 20 | average = (float) sum / SIZE; 21 | printf("Sum of scores = %d, average = %.2f\n", sum, average); 22 | printf("That's a handicap of %+.0f.\n", average - PAR); 23 | return 0; 24 | } -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/example/6.2-when.c: -------------------------------------------------------------------------------- 1 | // when.c - 何时退出循环 2 | #include 3 | 4 | int main(void) 5 | { 6 | int n = 5; 7 | while (n < 7) 8 | { 9 | printf("n = %d\n", n); 10 | n++; 11 | printf("Now n = %d\n", n); 12 | } 13 | printf("The loop has finished.\n"); 14 | return 0; 15 | } -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/example/6.20-power.c: -------------------------------------------------------------------------------- 1 | // power.c - 计算数的整数幂 2 | #include 3 | 4 | double power(double n, int p); 5 | 6 | int main(void) 7 | { 8 | double x, xpow; 9 | int exp; 10 | printf("Enter a number and the positive integer power"); 11 | printf(" to which\nthe number will be raised. Enteerq"); 12 | printf(" to quit.\n"); 13 | while(scanf("%lf%d", &x, &exp) == 2) 14 | { 15 | xpow = power(x, exp); 16 | printf("%.3g to the power %d is %.5g\n", x, exp, xpow); 17 | printf("Enter next pair of numbers or q to quit.\n"); 18 | } 19 | printf("Hope you enjoyed this power trip -- bye!\n"); 20 | return 0; 21 | } 22 | 23 | double power(double n, int p) 24 | { 25 | double pow = 1; 26 | int i; 27 | for (i = 1; i <=p; i++) 28 | pow *= n; 29 | return pow; 30 | } -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/example/6.3-while1.c: -------------------------------------------------------------------------------- 1 | // while1.c - 注意花括号的使用 2 | // 糟糕的代码创建了一个无限循环 3 | #include 4 | int main(void) 5 | { 6 | int n = 0; 7 | while (n < 3) 8 | printf("n is %d\n", n); 9 | n++; 10 | printf("That's all this program does\n"); 11 | return 0; 12 | } -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/example/6.4-while2.c: -------------------------------------------------------------------------------- 1 | // while2.c - 注意分号的位置 2 | #include 3 | 4 | int main(void) 5 | { 6 | int n = 0; 7 | while (n++ < 3); 8 | printf("n is %d\n", n); 9 | printf("That's all this program does.\n"); 10 | return 0; 11 | } -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/example/6.5-cmpflt.c: -------------------------------------------------------------------------------- 1 | // cmpflt.c - 浮点数比较 2 | #include 3 | #include 4 | 5 | int main(void) 6 | { 7 | const double ANSWER = 3.14159; 8 | double response; 9 | printf("What is the value of pi?\n"); 10 | scanf("%lf", &response); 11 | while (fabs(response - ANSWER) > 0.0001) 12 | { 13 | printf("Try again!\n"); 14 | scanf("%lf", &response); 15 | } 16 | printf("Close enough!\n"); 17 | return 0; 18 | } -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/example/6.6-t_and_f.c: -------------------------------------------------------------------------------- 1 | // t_and_f.c - C中的真和假的值 2 | #include 3 | 4 | int main(void) 5 | { 6 | int true_val, false_val; 7 | true_val = (10 > 2); 8 | false_val = (10 == 2); 9 | printf("true = %d; false = %d \n", true_val, false_val); 10 | return 0; 11 | } -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/example/6.7-truth.c: -------------------------------------------------------------------------------- 1 | // truth.c - 哪些值为真 2 | #include 3 | 4 | int main(void) 5 | { 6 | int n = 3; 7 | while (n) 8 | printf("%2d is true\n", n--); 9 | printf("%2d is false\n", n); 10 | n = -3; 11 | while (n) 12 | printf("%2d is true\n", n++); 13 | printf("%2d is false\n", n); 14 | return 0; 15 | } -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/example/6.8-trouble.c: -------------------------------------------------------------------------------- 1 | // trouble.c - 误用=会导致无限循环 2 | #include 3 | 4 | int main(void) 5 | { 6 | long num; 7 | long sum = 0L; 8 | int status; 9 | printf("Please enter an integer to be summed (q to quit): "); 10 | status = scanf("%ld", &num); 11 | while (status = 1) 12 | { 13 | sum = sum + num; 14 | printf("Please enter next integer (q to quit): "); 15 | status = scanf("%ld", &num); 16 | } 17 | printf("Those integers sum to %ld.\n", sum); 18 | return 0; 19 | } -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/example/6.9-boolean.c: -------------------------------------------------------------------------------- 1 | // boolean.c - 使用_Bool类型的变量variable 2 | #include 3 | 4 | int main(void) 5 | { 6 | long num; 7 | long sum = 0L; 8 | _Bool input_is_good; 9 | printf("Please enter an integer to be summed "); 10 | printf("(q to quit): "); 11 | input_is_good = (scanf("%ld", &num) == 1); 12 | while (input_is_good) 13 | { 14 | sum = sum + num; 15 | printf("Please enter next integer (q to quit): "); 16 | input_is_good = (scanf("%ld", &num) == 1); 17 | } 18 | printf("Those integers sum to %ld.\n", sum); 19 | return 0; 20 | } -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/exercise/6-1.c: -------------------------------------------------------------------------------- 1 | // 编写一个程序,创建一个包含26个元素的数组,并在其中储存26个小写字母。 2 | // 然后打印数组的所有内容。 3 | #include 4 | #define COUNT 26 5 | int main(void) 6 | { 7 | char arr[COUNT]; 8 | char ch = 'a'; 9 | int i; 10 | for (i = 0; i < COUNT; i++) 11 | arr[i] = ch + i; 12 | for (i = 0; i < COUNT; i++) 13 | printf("%c", arr[i]); 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/exercise/6-10.c: -------------------------------------------------------------------------------- 1 | // 10. 编写一个程序,要求用户输入一个上限整数和一个下限整数, 2 | // 计算从上限到下限范围内所有整数的平方和,并显示计算结果。 3 | // 然后程序继续提示用户输入上限和下限整数,并显示结果, 4 | // 直到用户输入的上限整数小于下限整数为止。程序的运行示例如下: 5 | // Enter lower and upper integer limits: 5 9 6 | // The sums of the squares from 25 to 81 is 255 7 | // Enter next set of limits: 3 25 8 | // The sums of the squares from 9 to 625 is 5520 9 | // Enter next set of limits: 5 5 Done 10 | #include 11 | 12 | int getSumOfSquare(int num1, int num2); 13 | 14 | int main(void) 15 | { 16 | int num1, num2; 17 | printf("Enter lower and upper integer limits: "); 18 | while (scanf("%d %d", &num1, &num2) == 2 && num1 < num2) 19 | { 20 | printf("The sums of the squares from %d to %d is %d\n", 21 | num1 * num1, num2 * num2, getSumOfSquare(num1, num2)); 22 | printf("Enter next set of limits: "); 23 | } 24 | printf("Done\n"); 25 | return 0; 26 | } 27 | 28 | int getSumOfSquare(int num1, int num2) 29 | { 30 | int i, result = 0; 31 | for (i = num1; i <= num2; i++) 32 | result += i * i; 33 | return result; 34 | } 35 | -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/exercise/6-11.c: -------------------------------------------------------------------------------- 1 | // 11. 编写一个程序,在数组中读入8个整数,然后按倒序打印这8个整数。 2 | #include 3 | #define LENGTH 8 4 | 5 | int main(void) 6 | { 7 | int arr[LENGTH]; 8 | int i = 0; 9 | do 10 | { 11 | printf("Enter a number: "); 12 | scanf("%d", &arr[i]); 13 | } while (++i < LENGTH); 14 | for (i = LENGTH - 1; i >= 0; i--) 15 | printf("%d\n", arr[i]); 16 | return 0; 17 | } -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/exercise/6-12.c: -------------------------------------------------------------------------------- 1 | // 12. 考虑下面两个无限序列: 2 | // 1.0 + 1.0/2.0 + 1.0/3.0 + 1.0/4.0 + ... 3 | // 1.0 - 1.0/2.0 + 1.0/3.0 - 1.0/4.0 + ... 4 | // 编写一个程序计算这两个无限序列的总和,直到到达某次数。 5 | // 提示:奇数个-1 相乘得-1,偶数个-1相乘得1。 6 | // 让用户交互地输入指定的次数,当用户输入0或负值时结束输入。 7 | // 查看运行100项、1000项、10000项后的总和, 是否发现每个序列都收敛于某值? 8 | #include 9 | #define BASE 1.0 10 | 11 | int main(void) 12 | { 13 | double divisor = BASE, dividend; 14 | double result1, result2; 15 | int count, i; 16 | printf("Enter the count: "); 17 | while (scanf("%d", &count) == 1) 18 | { 19 | for (i = 0, dividend = 0, result1 = 0, result2 = 0; i < count; i++) 20 | { 21 | result1 += divisor / ++dividend; 22 | if (i % 2 == 0) { 23 | result2 += divisor / dividend; 24 | } else { 25 | result2 -= divisor / dividend; 26 | } 27 | } 28 | printf("%f %f\n", result1, result2); 29 | printf("Enter the count(q to quit): "); 30 | } 31 | printf("Done\n"); 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/exercise/6-13.c: -------------------------------------------------------------------------------- 1 | // 13. 编写一个程序,创建一个包含8个元素的int类型数组, 2 | // 分别把数组元素设置为2的前8次幂。 3 | // 使用for循环设置数组元素的值,使用do while循环显示数组元素的值。 4 | #include 5 | #include 6 | #define LENGTH 8 7 | 8 | int main(void) 9 | { 10 | int arr[LENGTH]; 11 | int i; 12 | for (i = 0; i < LENGTH; i++) 13 | { 14 | arr[i] = pow(2, i + 1); 15 | printf("%d ", arr[i]); 16 | } 17 | printf("\n"); 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/exercise/6-14.c: -------------------------------------------------------------------------------- 1 | // 14. 编写一个程序,创建两个包含8个元素的double类型数组, 2 | // 使用循环提示用户为第一个数组输入8个值。 3 | // 第二个数组元素的值设置为第一个数组对应元素的累积之和。 4 | // 例如,第二个数组的第4个元素的值是第一个数组前4个元素之和, 5 | // 第二个数组的第5个元素的值是第一个数组前5个元素之和 6 | // (用嵌套循环可以完成,但是利用第二个数组的第5个元素是第二个数组的第4个元素 7 | // 与第一个数组的第5个元素之和,只用一个循环就能完成任务,不需要使用嵌套循环)。 8 | // 最后,使用循环显示两个数组的内容,第一个数组显示成一行, 9 | // 第二个数组显示在第一个数组的下一行,而且每个元素都与第一 个数组各元素相对应。 10 | #include 11 | 12 | int main(void) 13 | { 14 | const int len = 8; 15 | double arr1[len], arr2[len]; 16 | int i = 0; 17 | for (i = 0; i < len; i++) 18 | { 19 | printf("Enter a float num: "); 20 | scanf("%lf", &arr1[i]); 21 | if (i == 0) { 22 | arr2[i] = arr1[i]; 23 | } else { 24 | arr2[i] = arr2[i - 1] + arr1[i]; 25 | } 26 | } 27 | printf("\n"); 28 | for (i = 0; i < len; i++) 29 | { 30 | printf("%6.2f", arr1[i]); 31 | } 32 | printf("\n"); 33 | for (i = 0; i < len; i++) 34 | { 35 | printf("%6.2f", arr2[i]); 36 | } 37 | printf("\n"); 38 | return 0; 39 | } -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/exercise/6-15.c: -------------------------------------------------------------------------------- 1 | // 15. 编写一个程序,读取一行输入,然后把输入的内容倒序打印出来。 2 | // 可以把输入储存在char类型的数组中,假设每行字符不超过255。 3 | // 回忆一下,根据%c转换说明,scanf()函数一次只能从输入中读取一个字符, 4 | // 而且在用户按下Enter键时scanf()函数会生成一个换行字符(\n)。 5 | #include 6 | 7 | int main(void) 8 | { 9 | char str[255]; 10 | int i = 0; 11 | do 12 | { 13 | scanf("%c", &str[i]); 14 | } while (str[i] != '\n' && ++i < 255); 15 | do { 16 | printf("%c", str[i]); 17 | } while (i-- > 0); 18 | printf("\n"); 19 | return 0; 20 | } -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/exercise/6-16.c: -------------------------------------------------------------------------------- 1 | // 16. Daphne以10%的单利息投资了100美元(也就是说, 2 | // 每年投资获利相当于原始投资的10%)。 3 | // Deirdre以5%的复合利息投资了 100 美元(也就是说,利息是当前余额的5%, 4 | // 包含之前的利息)。编写一个程序, 5 | // 计算需要多少年Deirdre的投资额才会超过Daphne,并显示那时两人的投资额。 6 | #include 7 | #define ORIGINAL_MONEY 100.0 8 | 9 | int main(void) 10 | { 11 | int year = 0; 12 | double money1 = ORIGINAL_MONEY, money2 = ORIGINAL_MONEY; 13 | const double RATE1 = 0.1, RATE2 = 0.05; 14 | do { 15 | money1 += ORIGINAL_MONEY * RATE1; 16 | money2 += money2 * RATE2; 17 | year++; 18 | } while (money2 <= money1); 19 | printf("money1 = %.2f, money2 = %.2f, year = %d.\n", 20 | money1, money2, year); 21 | return 0; 22 | } -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/exercise/6-17.c: -------------------------------------------------------------------------------- 1 | // 17. Chuckie Lucky赢得了100万美元(税后),他把奖金存入年利率8%的账户。 2 | // 在每年的最后一天,Chuckie取出10万美元。编写一个程序,计算多少年后 3 | // Chuckie会取完账户的钱? 4 | #include 5 | 6 | int main(void) 7 | { 8 | double sum = 100.0; 9 | int year = 0; 10 | do { 11 | year++; 12 | sum += sum * 0.08 - 10; 13 | } while (sum > 0); 14 | printf("year = %d\n", year); 15 | return 0; 16 | } -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/exercise/6-18.c: -------------------------------------------------------------------------------- 1 | // 18. Rabnud博士加入了一个社交圈。起初他有5个朋友。 2 | // 他注意到他的朋友数量以下面的方式增长。第1周少了1个朋友,剩下的朋友数量翻倍; 3 | // 第2周少了2个朋友,剩下的朋友数量翻倍。一般而言,第N周少了N个朋友, 4 | // 剩下的朋友数量翻倍。编写一个程序,计算并显示Rabnud博士每周的朋友数量。 5 | // 该程序一直运行,直到超过邓巴数(Dunbar’s number)。 6 | // 邓巴数是粗略估算一个人在社交圈中有稳定关系的成员的最大值,该值大约是150。 7 | #include 8 | 9 | int main(void) 10 | { 11 | int friends = 5, weeks = 0; 12 | do { 13 | friends -= 1; 14 | friends *= 2; 15 | weeks++; 16 | } while (friends <= 150); 17 | printf("friends = %d, weeks = %d\n", friends, weeks); 18 | return 0; 19 | } -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/exercise/6-2.c: -------------------------------------------------------------------------------- 1 | // 2. 使用嵌套循环,按下面的格式打印字符: 2 | // $ 3 | // $$ 4 | // $$$ 5 | // $$$$ 6 | // $$$$$ 7 | #include 8 | #define ROWS 5 9 | int main(void) 10 | { 11 | int i, j; 12 | for (i = 1; i <= ROWS; i++) 13 | { 14 | for (j = 1; j <= i; j++) 15 | printf("$"); 16 | printf("\n"); 17 | } 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/exercise/6-3.c: -------------------------------------------------------------------------------- 1 | // 3. 使用嵌套循环,按下面的格式打印字母: 2 | // F 3 | // FE 4 | // FED 5 | // FEDC 6 | // FEDCB 7 | // FEDCBA 8 | #include 9 | #define ROWS 6 10 | 11 | int main(void) 12 | { 13 | char ch = 'F'; 14 | int i, j; 15 | for (i = 1; i <= ROWS; i++) 16 | { 17 | for (j = 0; j < i; j++) 18 | printf("%c", ch - j); 19 | printf("\n"); 20 | } 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/exercise/6-4.c: -------------------------------------------------------------------------------- 1 | // 使用嵌套循环,按下面的格式打印字母: 2 | // A 3 | // BC 4 | // DEF 5 | // GHIJ 6 | // KLMNO 7 | // PQRSTU 8 | #include 9 | #define ROWS 6 10 | 11 | int main(void) 12 | { 13 | char ch = 'A'; 14 | int i, j; 15 | for (i = 1; i <= ROWS; i++) 16 | { 17 | for (j = 0; j < i; j++) 18 | printf("%c", ch++); 19 | printf("\n"); 20 | } 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/exercise/6-5.c: -------------------------------------------------------------------------------- 1 | // 5. 编写一个程序,提示用户输入大写字母。 2 | // 使用嵌套循环以下面金字塔型的格式打印字母: 3 | // A 4 | // ABA 5 | // ABCBA 6 | // ABCDCBA 7 | // ABCDEDCBA 8 | // 打印这样的图形,要根据用户输入的字母来决定。 9 | // 例如,上面的图形是在用户输入E后的打印结果。 10 | // 提示:用外层循环处理行,每行使用3个内层循环, 11 | // 分别处理空格、以升序打印字母、以降序打印字母。 12 | #include 13 | #define start 'A' 14 | 15 | int main(void) 16 | { 17 | int rows, i, j; 18 | char ch, base = 'A'; 19 | do 20 | { 21 | printf("Please enter an uppercase character: \n"); 22 | scanf("%c", &ch); 23 | } while (ch < 'A' || ch > 'Z'); 24 | rows = (int)ch - base + 1; 25 | for (i = 1; i <= rows; i++) { 26 | for (j = 0; j < i; j++) 27 | printf("%c", base +j); 28 | for (j -= 2; j >= 0; j--) 29 | printf("%c", base +j); 30 | printf("\n"); 31 | } 32 | return 0; 33 | } -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/exercise/6-6.c: -------------------------------------------------------------------------------- 1 | // 6. 编写一个程序打印一个表格,每一行打印一个整数、该数的平方、该数的立方。 2 | // 要求用户输入表格的上下限。使用一个for循环。 3 | #include 4 | 5 | int main(void) 6 | { 7 | int start, end, i; 8 | printf("Please enter an upper limitand and a lower limit: \n"); 9 | scanf("%d %d", &start, &end); 10 | printf("number square cube\n"); 11 | for (i = start; i <= end; i++) 12 | printf("%6d %6d %6d\n", i, i * i, i * i * i); 13 | return 0; 14 | } -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/exercise/6-7.c: -------------------------------------------------------------------------------- 1 | // 7. 编写一个程序把一个单词读入一个字符数组中,然后倒序打印这个单词。 2 | // 提示:strlen()函数(第4章介绍过)可用于计算数组最后一个字符的下标。 3 | #include 4 | #include 5 | 6 | int main(void) 7 | { 8 | char word[40]; 9 | int len, i; 10 | printf("Enter a word: \n"); 11 | scanf("%s", word); 12 | len = strlen(word); 13 | for (i = len - 1; i >= 0; i--) 14 | printf("%c", word[i]); 15 | printf("\n"); 16 | return 0; 17 | } -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/exercise/6-8.c: -------------------------------------------------------------------------------- 1 | // 8. 编写一个程序,要求用户输入两个浮点数,并打印两数之差除以两数乘积的结果。 2 | // 在用户输入非数字之前,程序应循环处理用户输入的每对值。 3 | #include 4 | 5 | int main(void) 6 | { 7 | double num1, num2; 8 | int valid; 9 | printf("Enter two float numbers: \n"); 10 | while (scanf("%lf %lf", &num1, &num2) == 2) 11 | { 12 | printf("%.2f\n", (num1 - num2) / (num1 * num2)); 13 | printf("Enter next two float numbers(non-numeric to quit): \n"); 14 | } 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /Chapter-6 C Control Statements: Looping/exercise/6-9.c: -------------------------------------------------------------------------------- 1 | // 9. 修改练习8,使用一个函数返回计算的结果。 2 | #include 3 | 4 | double getResult(double num1, double num2); 5 | 6 | int main(void) 7 | { 8 | double num1, num2; 9 | int valid; 10 | printf("Enter two float numbers: \n"); 11 | while (scanf("%lf %lf", &num1, &num2) == 2) 12 | { 13 | printf("%.2f\n", getResult(num1, num2)); 14 | printf("Enter next two float numbers(non-numeric to quit): \n"); 15 | } 16 | return 0; 17 | } 18 | 19 | double getResult(double num1, double num2) 20 | { 21 | return (num1 - num2) / (num1 * num2); 22 | } 23 | -------------------------------------------------------------------------------- /Chapter-7 C Control Statements: Branching and Jumps/README.md: -------------------------------------------------------------------------------- 1 | # 第七章 C控制语句:分支和跳转 2 | 3 | if语句使用测试条件控制程序是否执行测试条件后面的一条简单语句或复合语句。如果测试表达式的值是非零值,则执行语句;如果测试表达式的值是零,则不执行语句。 4 | 5 | if else语句可用于二选一的情况。如果测试条件是非零,则执行else前面的语句;如果测试表达式的值是零,则执行else后面的语句。在else后面使用另一个if语句形成else if,可构造多选一的结构。 6 | 7 | 在多数情况下,用条件运算符(?:)写成的表达式比if else语句更简洁。 8 | 9 | switch语句可以在一系列以整数作为标签的语句中进行选择。如果紧跟在switch关键字后的测试条件的整数值与某标签匹配,程序就转至执行匹配的标签语句,然后在遇到break之前,继续执行标签语句后面的语句。 10 | 11 | break、continue和goto语句都是跳转语句,使程序流跳转至程序的另一处。break语句使程序跳转至紧跟在包含break语句的循环或switch末尾的下一条语句。continue语句使程序跳出当前循环的剩余部分,并开始下一轮迭代。 -------------------------------------------------------------------------------- /Chapter-7 C Control Statements: Branching and Jumps/example/7.1-colddays.c: -------------------------------------------------------------------------------- 1 | // colddays.c - 找出0℃以下的天数占总天数的百分比 2 | #include 3 | 4 | int main(void) 5 | { 6 | const int FREEZING = 0; 7 | float temperature; 8 | int cold_days = 0; 9 | int all_days = 0; 10 | printf("Enter eht list of daily low temperatures.\n"); 11 | printf("Use Celsius, and enter q to quit.\n"); 12 | while (scanf("%f", &temperature) == 1) 13 | { 14 | all_days++; 15 | if (temperature < FREEZING) 16 | cold_days++; 17 | } 18 | if (all_days != 0) 19 | printf("%d days total: %.1f%% were below freezing.\n", 20 | all_days, 100.0 * (float)cold_days / all_days); 21 | if (all_days == 0) 22 | printf("No data entered!\n"); 23 | return 0; 24 | } -------------------------------------------------------------------------------- /Chapter-7 C Control Statements: Branching and Jumps/example/7.2-cypher1.c: -------------------------------------------------------------------------------- 1 | // cypher1.c - 更改输入,空格不变 2 | #include 3 | #define SPACE ' ' 4 | 5 | int main(void) 6 | { 7 | char ch; 8 | ch = getchar(); 9 | while (ch != '\n') 10 | { 11 | if (ch == SPACE) 12 | putchar(ch); 13 | else 14 | putchar(ch + 1); 15 | ch = getchar(); 16 | } 17 | putchar(ch); 18 | return 0; 19 | } -------------------------------------------------------------------------------- /Chapter-7 C Control Statements: Branching and Jumps/example/7.3-cypher2.c: -------------------------------------------------------------------------------- 1 | // cypher2.c - 替换输入的字母,非字母字符保持不变 2 | #include 3 | #include 4 | 5 | int main(void) 6 | { 7 | char ch; 8 | while ((ch = getchar()) != '\n') 9 | { 10 | if (isalpha(ch)) 11 | putchar(ch + 1); 12 | else 13 | putchar(ch); 14 | } 15 | putchar(ch); 16 | return 0; 17 | } -------------------------------------------------------------------------------- /Chapter-7 C Control Statements: Branching and Jumps/review-questions/Answers.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/logan70/C-Primer-Plus-6th-Notes-CN/6d4beffefdbf6ebe4893974a274d0cfb112605b6/Chapter-7 C Control Statements: Branching and Jumps/review-questions/Answers.md -------------------------------------------------------------------------------- /Chapter-8 Character Input-Output and Input Validation/README.md: -------------------------------------------------------------------------------- 1 | # 第八章 字符输入/输出和输入验证 2 | 3 | 许多程序使用getchar()逐字符读取输入。通常,系统使用行缓冲输入,即当用户按下Enter键后输入才被传送给程序。按下Enter键也传送了一个换行符,编程时要注意处理这个换行符。ANSIC把缓冲输入作为标准。 4 | 5 | 通过标准I/O包中的一系列函数,以统一的方式处理不同系统中的不同文件形式,是C语言的特性之一。getchar()和scanf()函数也属于这一系列。当检测到文件结尾时,这两个函数都返回EOF(被定义在stdio.h头文件中)。在不同系统中模拟文件结尾条件的方式稍有不同。在UNIX系统中,在一行开始处按下Ctrl+D可以模拟文件结尾条件;而在DOS系统中则使用Ctrl+Z。 6 | 7 | 许多操作系统(包括UNIX和DOS)都有重定向的特性,因此可以用文件代替键盘和屏幕进行输入和输出。读到EOF即停止读取的程序可用于键盘输入和模拟文件结尾信号,或者用于重定向文件。 8 | 9 | 混合使用getchar()和scanf()时,如果在调用getchar()之前,scanf()在输入行留下一个换行符,会导致一些问题。不过,意识到这个问题就可以在程序中妥善处理。 10 | 11 | 编写程序时,要认真设计用户界面。事先预料一些用户可能会犯的错误,然后设计程序妥善处理这些错误情况。 -------------------------------------------------------------------------------- /Chapter-8 Character Input-Output and Input Validation/example/8.2-echo_eof.c: -------------------------------------------------------------------------------- 1 | // echo_eof.c - 重复输入,直到文件结尾 2 | #include 3 | 4 | int main(void) 5 | { 6 | int ch; 7 | while ((ch = getchar()) != EOF) 8 | putchar(ch + 1); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /Chapter-8 Character Input-Output and Input Validation/example/8.3-file_eof.c: -------------------------------------------------------------------------------- 1 | // file_eof.c - 打开一个文件并显示该文件 2 | #include 3 | #include 4 | 5 | int main(void) 6 | { 7 | int ch; 8 | FILE * fp; 9 | char fname[50]; // 储存文件名 10 | printf("Enter the name of the file: "); 11 | scanf("%s", fname); 12 | fp = fopen(fname, "r"); // 打开待读取文件 13 | if (fp == NULL) // 如果失败 14 | { 15 | printf("Failed to open file. Bye\n"); 16 | exit(1); // 退出程序 17 | } 18 | // getc(fp)从打开的文件中获取一个字符 19 | while ((ch = getc(fp)) != EOF) 20 | putchar(ch); 21 | fclose(fp); // 关闭文件 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /Chapter-8 Character Input-Output and Input Validation/review-questions/Answers.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/logan70/C-Primer-Plus-6th-Notes-CN/6d4beffefdbf6ebe4893974a274d0cfb112605b6/Chapter-8 Character Input-Output and Input Validation/review-questions/Answers.md -------------------------------------------------------------------------------- /Chapter-9 Functions/example/9.1-lethead1.c: -------------------------------------------------------------------------------- 1 | // lethead1.c 2 | #include 3 | #define NAME "GIGATHINK, INC." 4 | #define ADDRESS "101 Megabuck Plaza" 5 | #define PLACE "Megapolis, CA 94904" 6 | #define WIDTH 40 7 | 8 | void starbar(void); 9 | int main(void) 10 | { 11 | starbar(); 12 | printf("%s\n", NAME); 13 | printf("%s\n", ADDRESS); 14 | printf("%s\n", PLACE); 15 | starbar(); 16 | return 0; 17 | } 18 | void starbar(void) 19 | { 20 | int count; 21 | for (count = 1; count <= WIDTH; count++) 22 | putchar('*'); 23 | putchar('\n'); 24 | } 25 | -------------------------------------------------------------------------------- /Chapter-9 Functions/example/9.10-hotel.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "9.11-hotel.h" 3 | int menu(void) 4 | { 5 | int code, status; 6 | printf("\n%s%s\n", STARS, STARS); 7 | printf("Enter the number of the desired hotel:\n"); 8 | printf("1) Fairfield Arms 2) Hotel Olympic\n"); 9 | printf("3) Chertworthy Plaza 4) The Stockton\n"); 10 | printf("5) quit\n"); 11 | printf("%s%s\n", STARS, STARS); 12 | while ((status = scanf("%d", &code)) != 1 || 13 | (code < 1 || code > 5)) 14 | { 15 | if (status != 1) 16 | scanf("%*s"); // 处理非整数输入 17 | printf("Enter an integer from 1 to 5, please.\n"); 18 | } 19 | return code; 20 | } 21 | 22 | int getnights(void) 23 | { 24 | int nights; 25 | printf("How many nights are needed? "); 26 | while (scanf("%d", &nights) != 1) 27 | { 28 | scanf("%*s"); // 处理非整数输入 29 | printf("Please enter an integer, such as 2.\n"); 30 | } 31 | return nights; 32 | } 33 | 34 | void showprice(double rate, int nights) 35 | { 36 | int n; 37 | double total = 0.0; 38 | double factor = 1.0; 39 | for (n = 1; n <= nights; n++, factor *= DISCOUNT) 40 | total += rate * factor; 41 | printf("The total cost will be $%0.2f.\n", total); 42 | } 43 | -------------------------------------------------------------------------------- /Chapter-9 Functions/example/9.11-hotel.h: -------------------------------------------------------------------------------- 1 | // hotel.h - 符号常量和函数原型 2 | #define QUIT 5 3 | #define HOTEL1 180.00 4 | #define HOTEL2 225.00 5 | #define HOTEL3 255.00 6 | #define HOTEL4 355.00 7 | #define DISCOUNT 0.95 8 | #define STARS "***************************" 9 | 10 | // 显示选择列表 11 | int menu(void); 12 | //返回预订天数 13 | int getnights(void); 14 | // 根据费率、入住天数计算费用并显示结果 15 | void showprice(double rate, int nights); 16 | -------------------------------------------------------------------------------- /Chapter-9 Functions/example/9.12-loccheck.c: -------------------------------------------------------------------------------- 1 | // loccheck.c - 查看变量被存储在何处 2 | #include 3 | void mikado(int); 4 | int main(void) 5 | { 6 | int pooh = 2, bah = 5; 7 | printf("In main(), pooh = %d and &pooh = %p\n", pooh, &pooh); 8 | printf("In main(), bah = %d and &bah = %p\n", bah, &bah); 9 | mikado(pooh); 10 | return 0; 11 | } 12 | 13 | void mikado(int bah) 14 | { 15 | int pooh = 10; 16 | printf("In mikado(), pooh = %d and &pooh = %p\n", pooh, &pooh); 17 | printf("In mikado(), bah = %d and &bah = %p\n", bah, &bah); 18 | } -------------------------------------------------------------------------------- /Chapter-9 Functions/example/9.13-swap1.c: -------------------------------------------------------------------------------- 1 | // swap1.c - 第一个版本的交换函数 2 | #include 3 | 4 | void interchange(int u, int v); 5 | int main(void) 6 | { 7 | int x = 5, y = 10; 8 | printf("Originally x = %d and y = %d.\n", x, y); 9 | interchange(x, y); 10 | printf("Now x = %d and y = %d.\n", x, y); 11 | return 0; 12 | } 13 | void interchange(int u, int v) 14 | { 15 | int temp; 16 | temp = u; 17 | u = v; 18 | v = temp; 19 | } -------------------------------------------------------------------------------- /Chapter-9 Functions/example/9.14-swap2.c: -------------------------------------------------------------------------------- 1 | // swap2.c - 查找swap1.c的问题 2 | #include 3 | 4 | void interchange(int u, int v); 5 | int main(void) 6 | { 7 | int x = 5, y = 10; 8 | printf("Originally x = %d and y = %d.\n", x, y); 9 | interchange(x, y); 10 | printf("Now x = %d and y = %d.\n", x, y); 11 | return 0; 12 | } 13 | void interchange(int u, int v) 14 | { 15 | int temp; 16 | printf("Originally u = %d and v = %d.\n", u, v); 17 | temp = u; 18 | u = v; 19 | v = temp; 20 | printf("Now u = %d and v = %d.\n", u, v); 21 | } -------------------------------------------------------------------------------- /Chapter-9 Functions/example/9.15-swap3.c: -------------------------------------------------------------------------------- 1 | // swap3.c - 使用指针解决交换函数的问题 2 | #include 3 | void interchange(int * u, int * v); 4 | 5 | int main(void) 6 | { 7 | int x = 5, y = 10; 8 | printf("Originally x = %d and y = %d.\n", x, y); 9 | interchange(&x, &y); 10 | printf("Now x = %d and y = %d.\n", x, y); 11 | return 0; 12 | } 13 | void interchange(int * u, int * v) 14 | { 15 | int temp; 16 | temp = *u; 17 | *u = *v; 18 | *v = temp; 19 | } -------------------------------------------------------------------------------- /Chapter-9 Functions/example/9.2-lethead2.c: -------------------------------------------------------------------------------- 1 | // lethead2.c 2 | #include 3 | #include 4 | #define NAME "GIGATHINK, INC." 5 | #define ADDRESS "101 Megabuck Plaza" 6 | #define PLACE "Megapolis, CA 94904" 7 | #define WIDTH 40 8 | #define SPACE ' ' 9 | void show_n_char(char ch, int num); 10 | 11 | int main(void) 12 | { 13 | int spaces; 14 | show_n_char('*', WIDTH); 15 | putchar('\n'); 16 | spaces = (WIDTH - strlen(NAME)) / 2; 17 | show_n_char(SPACE, spaces); 18 | printf("%s\n", NAME); 19 | spaces = (WIDTH - strlen(ADDRESS)) / 2; 20 | show_n_char(SPACE, spaces); 21 | printf("%s\n", ADDRESS); 22 | spaces = (WIDTH - strlen(PLACE)) / 2; 23 | show_n_char(SPACE, spaces); 24 | printf("%s\n", PLACE); 25 | show_n_char('*', WIDTH); 26 | return 0; 27 | } 28 | void show_n_char(char ch, int num) 29 | { 30 | int count; 31 | for (count = 1; count <= num; count++) 32 | putchar(ch); 33 | } 34 | -------------------------------------------------------------------------------- /Chapter-9 Functions/example/9.3-lesser.c: -------------------------------------------------------------------------------- 1 | // lesser.c - 找出两个整数中较小的一个 2 | #include 3 | int imin(int, int); 4 | 5 | int main(void) 6 | { 7 | int evil1, evil2; 8 | printf("Enter a pair of integers (q to quit): \n"); 9 | whle (scanf("%d %d", &evil1, &evil2) == 2) 10 | { 11 | printf("The lesser of %d and %d is %d.\n", 12 | evil1, evil2, imin(evil1, evil2)); 13 | printf("Enter a pair of integers (q to quit):\n"); 14 | } 15 | printf("Bye.\n"); 16 | return 0; 17 | } 18 | 19 | int imin(int n, int m) 20 | { 21 | int min; 22 | if (n < m) 23 | min = n; 24 | else 25 | min = m; 26 | return min; 27 | } -------------------------------------------------------------------------------- /Chapter-9 Functions/example/9.4-misuse.c: -------------------------------------------------------------------------------- 1 | // misuse.c - 错误地使用函数 2 | #include 3 | int imax(); 4 | int main(void) 5 | { 6 | printf("The maximum of %d and %d is %d.\n", 3, 5, imax(3)); 7 | printf("The maximum of %d and %d is %d.\n", 3, 5, imax(3.0, 5.0)); 8 | return 0; 9 | } 10 | 11 | int imax(n, m) 12 | { 13 | int n, m; 14 | return (n > m ? n : m); 15 | } -------------------------------------------------------------------------------- /Chapter-9 Functions/example/9.5-proto.c: -------------------------------------------------------------------------------- 1 | // proto.c - 使用函数原型 2 | #include 3 | int imax(int, int); /* 函数原型 */ 4 | int main(void) 5 | { 6 | printf("The maximum of %d and %d is %d.\n", 3, 5, imax(3, 5)); 7 | printf("The maximum of %d and %d is %d.\n", 3, 5, imax(3.0, 5.0)); 8 | return 0; 9 | } 10 | int imax(int n, int m) 11 | { 12 | return (n > m ? n : m); 13 | } -------------------------------------------------------------------------------- /Chapter-9 Functions/example/9.6-recur.c: -------------------------------------------------------------------------------- 1 | // recur.c - 递归演示 2 | #include 3 | void up_and_down(int); 4 | int main(void) 5 | { 6 | up_and_down(1); 7 | return 0; 8 | } 9 | 10 | void up_and_down(int n) 11 | { 12 | printf("Level %d: nlocation %p\n", n, &n); 13 | if (n < 4) 14 | up_and_down(n + 1); 15 | printf("LEVEL %d: n location %p\n", n, &n); 16 | } -------------------------------------------------------------------------------- /Chapter-9 Functions/example/9.7-factor.c: -------------------------------------------------------------------------------- 1 | // factor.c - 使用循环和递归计算竭诚 2 | #include 3 | long fact(int n); 4 | long rfact(int n); 5 | 6 | int main(void) 7 | { 8 | int num; 9 | printf("This program calculates factorials.\n"); 10 | printf("Enter a value in the range 0-12 (q to quit):\n"); 11 | while (scanf("%d", &num) == 1) 12 | { 13 | if (num < 0) 14 | printf("No negative numbers, please.\n"); 15 | else if (num > 12) 16 | printf("Keep input under 13.\n"); 17 | else 18 | { 19 | printf("loop: %d factorial = %ld\n", num, fact(num)); 20 | printf("recursion: %d factorial = %ld\n", num, rfact(num)); 21 | } 22 | printf("Enter a value in the range 0-12 (q to quit):\n"); 23 | } 24 | printf("Bye.\n"); 25 | return 0; 26 | } 27 | 28 | long fact(int n) 29 | { 30 | long factorial; 31 | for (factorial = 1; n > 1; n--) 32 | factorial *= n; 33 | return factorial; 34 | } 35 | 36 | long rfact(int n) 37 | { 38 | return n <= 1 ? 1 : (n * rfact(n - 1)); 39 | } -------------------------------------------------------------------------------- /Chapter-9 Functions/example/9.8-binary.c: -------------------------------------------------------------------------------- 1 | // binary.c - 以二进制形式打印十进制整数 2 | #include 3 | void to_binary(unsigned long n); 4 | 5 | int main(void) 6 | { 7 | unsigned long number; 8 | printf("Enter an integer (q to quit):\n"); 9 | while (scanf("%lu", &number) == 1) 10 | { 11 | printf("Binary equivalent: "); 12 | to_binary(number); 13 | putchar('\n'); 14 | printf("Enter an integer (q to quit):\n"); 15 | } 16 | printf("Done.\n"); 17 | return 0; 18 | } 19 | 20 | void to_binary(unsigned long n) 21 | { 22 | if (n >= 2) 23 | to_binary(n / 2); 24 | printf("%u", (unsigned int)n % 2); 25 | } -------------------------------------------------------------------------------- /Chapter-9 Functions/example/9.9-usehotel.c: -------------------------------------------------------------------------------- 1 | // usehotel.c - 房间费率程序 2 | // 与程序清单9.10一起变异 3 | #include 4 | #include "9.11-hotel.h" // 定义符号常量,声明函数 5 | int main(void) 6 | { 7 | int nights; 8 | double hotel_rate; 9 | int code; 10 | while ((code = menu()) != QUIT) 11 | { 12 | switch (code) 13 | { 14 | case 1: hotel_rate = HOTEL1; 15 | break; 16 | case 2: hotel_rate = HOTEL2; 17 | break; 18 | case 3: hotel_rate = HOTEL3; 19 | break; 20 | case 4: hotel_rate = HOTEL4; 21 | break; 22 | default: hotel_rate = 0.0; 23 | printf("Oops!\n"); 24 | break; 25 | } 26 | nights = getnights(); 27 | showprice(hotel_rate, nights); 28 | } 29 | printf("Thank you and goodbye.\n"); 30 | return 0; 31 | } -------------------------------------------------------------------------------- /Chapter-9 Functions/exercise/9-1.c: -------------------------------------------------------------------------------- 1 | // 1. 设计一个函数min(x, y),返回两个double类型值的较小值。 2 | // 在一个简单 的驱动程序中测试该函数。 3 | #include 4 | 5 | double min (double x, double y); 6 | int main(void) 7 | { 8 | double num1 = 10.0, num2 = 9.9, res; 9 | res = min(num1, num2); 10 | if (res == num2) 11 | printf("9.9 is less than 10.0, Correct!\n"); 12 | else 13 | printf("Wrong"); 14 | return 0; 15 | } 16 | 17 | double min(double x, double y) 18 | { 19 | return x > y ? y : x; 20 | } -------------------------------------------------------------------------------- /Chapter-9 Functions/exercise/9-10.c: -------------------------------------------------------------------------------- 1 | // 为了让程序清单9.8中的to_binary()函数更通用,编写一个to_base_n() 2 | // 函数接受两个在2~10范围内的参数,然后以第2个参数中指定的进制打印第1个参数的数值。 3 | // 例如,to_base_n(129, 8)显示的结果为201,也就是129的 八进制数。 4 | // 在一个完整的程序中测试该函数。 5 | #include 6 | 7 | void to_base_n(int num, int sys) 8 | { 9 | if (sys < 2 || sys > 10) 10 | { 11 | printf("The secont argument must between 2 and 10.\n"); 12 | } 13 | if (num >= sys) 14 | to_base_n(num / sys, sys); 15 | printf("%d", num % sys); 16 | } 17 | int main(void) 18 | { 19 | to_base_n(129, 8); 20 | putchar('\n'); 21 | to_base_n(129, 2); 22 | return 0; 23 | } -------------------------------------------------------------------------------- /Chapter-9 Functions/exercise/9-11.c: -------------------------------------------------------------------------------- 1 | // 11. 编写并测试Fibonacci()函数,该函数用循环代替递归计算斐波那契数。 2 | #include 3 | 4 | void Fibonacci(int count); 5 | 6 | int main(void) 7 | { 8 | Fibonacci(10); 9 | return 0; 10 | } 11 | 12 | void Fibonacci(int count) 13 | { 14 | int i; 15 | int prev, cur, temp; 16 | for (i = 1; i <= count; i++) 17 | { 18 | if (i == 1) 19 | { 20 | prev = 0; 21 | cur = 1; 22 | } else { 23 | temp = prev + cur; 24 | prev = cur; 25 | cur = temp; 26 | } 27 | printf("%d ", cur); 28 | } 29 | printf("\nDone.\n"); 30 | } -------------------------------------------------------------------------------- /Chapter-9 Functions/exercise/9-2.c: -------------------------------------------------------------------------------- 1 | // 2. 设计一个函数chline(ch, i, j),打印指定的字符j行i列。 2 | // 在一个简单的驱动程序中测试该函数。 3 | #include 4 | 5 | void chline(char ch, int rows, int cols); 6 | int main(void) 7 | { 8 | chline('*', 2, 10); 9 | return 0; 10 | } 11 | 12 | void chline(char ch, int rows, int cols) 13 | { 14 | int i, j; 15 | for (i = 0; i < rows; i++) 16 | { 17 | for (j = 0; j < cols; j++) 18 | putchar(ch); 19 | putchar('\n'); 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter-9 Functions/exercise/9-3.c: -------------------------------------------------------------------------------- 1 | // 3.编写一个函数,接受3个参数:一个字符和两个整数。 2 | // 字符参数是待打印的字符,第1个整数指定一行中打印字符的次数, 3 | // 第2个整数指定打印指定字符的行数。编写一个调用该函数的程序。 4 | #include 5 | 6 | void myprint(char ch, int cols, int rows); 7 | 8 | int main(void) 9 | { 10 | myprint('*', 10, 5); 11 | return 0; 12 | } 13 | 14 | void myprint(char ch, int cols, int rows) 15 | { 16 | int i, j; 17 | for (i = 0; i < rows; i++) 18 | { 19 | for (j = 0; j < cols; j++) 20 | putchar(ch); 21 | putchar('\n'); 22 | } 23 | } -------------------------------------------------------------------------------- /Chapter-9 Functions/exercise/9-4.c: -------------------------------------------------------------------------------- 1 | // 4. 两数的调和平均数这样计算:先得到两数的倒数, 2 | // 然后计算两个倒数的平均值,最后取计算结果的倒数。 3 | // 编写一个函数,接受两个double类型的参数, 4 | // 返回这两个参数的调和平均数。 5 | #include 6 | 7 | double getHarmonicAverage(double x, double y); 8 | 9 | int main(void) 10 | { 11 | double res; 12 | res = getHarmonicAverage(10.0, 20.0); 13 | printf("The harmonic average of 10.0 and 20.0 is %.2f", res); 14 | return 0; 15 | } 16 | 17 | double getHarmonicAverage(double x, double y) 18 | { 19 | double recx = 1 / x, recy = 1 / y; 20 | return 1 / ((recx + recy) / 2); 21 | } -------------------------------------------------------------------------------- /Chapter-9 Functions/exercise/9-7.c: -------------------------------------------------------------------------------- 1 | // 7. 编写一个函数,从标准输入中读取字符,直到遇到文件结尾。 2 | // 程序要报告每个字符是否是字母。如果是,还要报告该字母在字母表 3 | // 中的数值位置。例如,c和C在字母表中的位置都是3。 4 | // 合并一个函数,以一个字符作为参数,如果该字符是一个字母则 5 | // 返回一个数值位置,否则返回-1。 6 | #include 7 | #include 8 | 9 | int get_char_pos(char ch); 10 | 11 | int main(void) 12 | { 13 | int ch; 14 | int pos; 15 | while ((ch = getchar()) != EOF) 16 | pos = get_char_pos(ch); 17 | printf("Done!\n"); 18 | return 0; 19 | } 20 | 21 | int get_char_pos(char ch) 22 | { 23 | int pos = -1; 24 | if (isspace(ch)) 25 | return pos; 26 | if (isalpha(ch)) 27 | { 28 | pos = tolower(ch) - 'a' + 1; 29 | printf("the position of %c is %d.\n", ch, pos); 30 | } 31 | else 32 | { 33 | printf("%c is not a alphabet.\n", ch); 34 | } 35 | return pos; 36 | } -------------------------------------------------------------------------------- /Chapter-9 Functions/exercise/9-8.c: -------------------------------------------------------------------------------- 1 | // 8.第6章的程序清单6.20中,power()函数返回一个double类型数的正整数次幂。 2 | // 改进该函数,使其能正确计算负幂。另外,函数要处理0的任何次幂都为0, 3 | // 任何数的0次幂都为1(函数应报告0的0次幂未定义,因此把该值处理为1)。 4 | // 要使用一个循环,并在程序中测试该函数。 5 | #include 6 | #include 7 | 8 | double power(double num, int n); 9 | 10 | int main(void) 11 | { 12 | power(0, 0); 13 | power(0, 10); 14 | power(10.0, 0); 15 | power(10.0, 3); 16 | power(10.0, -3); 17 | return 0; 18 | } 19 | 20 | double power(double num, int n) 21 | { 22 | int i; 23 | double res; 24 | if (num == 0) { 25 | res = n == 0 ? 1 : 0; 26 | } 27 | if (n == 0) 28 | res = 1; 29 | else 30 | { 31 | for (i = 0, res = 1; i < abs(n); i++) 32 | res *= num; 33 | if (n < 0 ) 34 | res = 1 / res; 35 | } 36 | printf("%.2g ^ %d = %.2g\n", num, n, res); 37 | return res; 38 | } -------------------------------------------------------------------------------- /Chapter-9 Functions/exercise/9-9.c: -------------------------------------------------------------------------------- 1 | // 9. 使用递归函数重写编程练习8 2 | #include 3 | #include 4 | 5 | double power(double num, int n); 6 | 7 | int main(void) 8 | { 9 | printf("%.2g ^ %d = %.2g\n", 0.0, 0, power(0.0, 0)); 10 | printf("%.2g ^ %d = %.2g\n", 0.0, 10, power(0.0, 10)); 11 | printf("%.2g ^ %d = %.2g\n", 10.0, 0, power(10.0, 0)); 12 | printf("%.2g ^ %d = %.2g\n", 10.0, 3, power(10.0, 3)); 13 | printf("%.2g ^ %d = %.2g\n", 10.0, -3, power(10.0, -3)); 14 | return 0; 15 | } 16 | 17 | double power(double num, int n) 18 | { 19 | int i; 20 | double res; 21 | if (num == 0) { 22 | res = n == 0 ? 1 : 0; 23 | } 24 | if (n == 0) 25 | res = 1; 26 | else if (n > 0) 27 | for (i = 0, res = 1; i < n; i++) 28 | res *= num; 29 | else 30 | res = power(num, -n); 31 | return res; 32 | } -------------------------------------------------------------------------------- /cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/logan70/C-Primer-Plus-6th-Notes-CN/6d4beffefdbf6ebe4893974a274d0cfb112605b6/cover.jpg -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "C-Primer-Plus-6th-Notes-CN", 3 | "version": "1.0.0", 4 | "description": "Reading-Notes for 《C Primer Plus》", 5 | "main": "index.js", 6 | "scripts": { 7 | "next": "node build/ready-to-learn-next-chapter.js", 8 | "build": "node build/index.js" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/logan70/C-Primer-Plus-6th-Notes-CN.git" 13 | }, 14 | "keywords": [], 15 | "author": "", 16 | "license": "ISC", 17 | "bugs": { 18 | "url": "https://github.com/logan70/C-Primer-Plus-6th-Notes-CN/issues" 19 | }, 20 | "homepage": "https://github.com/logan70/C-Primer-Plus-6th-Notes-CN#readme" 21 | } 22 | --------------------------------------------------------------------------------