├── .gitignore ├── LICENSE ├── README.md ├── chapter03 ├── exce2.c ├── exce3.c ├── exce4.c ├── exce5.c ├── exec6.c ├── prog1.c ├── prog2.c ├── prog3.c ├── prog4.c ├── prog5.c └── prog6.c ├── chapter04 ├── exce4.c ├── exce5.c ├── exce6.c ├── exce7.c ├── exce8.c ├── prog41.c ├── prog42.c ├── prog43.c ├── prog44.c └── prog45.c ├── chapter05 ├── exce10.c ├── exce11.c ├── exce2.c ├── exce3.c ├── exce4.c ├── exce5.c ├── exce6.c ├── exce7.c ├── exce8.c ├── exce92.c ├── exce93.c ├── exce94.c ├── exce95.c ├── prog51.c ├── prog52.c ├── prog53.c ├── prog53a.c ├── prog54.c ├── prog55.c ├── prog56.c ├── prog57.c ├── prog58.c └── prog59.c ├── chapter06 ├── exce2.c ├── exce3.c ├── exce4.c ├── exce5.c ├── exce6.c ├── exce7.c ├── prog61.c ├── prog610.c ├── prog610a.c ├── prog62.c ├── prog63.c ├── prog64.c ├── prog65.c ├── prog66.c ├── prog67.c ├── prog68.c ├── prog68a.c └── prog69.c ├── chapter07 ├── exce2.c ├── exce3.c ├── exce4.c ├── exce5.c ├── exce6.c ├── exce7.c ├── prog71.c ├── prog72.c ├── prog73.c ├── prog74.c ├── prog75.c ├── prog76.c ├── prog77.c ├── prog78.c └── test.c ├── chapter08 ├── exce10.c ├── exce11.c ├── exce12.c ├── exce13.c ├── exce14a.c ├── exce14b.c ├── exce14c.c ├── exce14d.c ├── exce15.c ├── exce16.c ├── exce2.c ├── exce3.c ├── exce4.c ├── exce5.c ├── exce6.c ├── exce7.c ├── exce8.c ├── exce9.c ├── prog81.c ├── prog811.c ├── prog812.c ├── prog813.c ├── prog813a.c ├── prog814.c ├── prog815.c ├── prog816.c ├── prog82.c ├── prog83.c ├── prog84.c ├── prog85.c ├── prog86.c ├── prog87.c ├── prog88.c ├── prog88a.c └── prog89.c ├── chapter09 ├── exce2 ├── exce2.c ├── exce2a.c ├── exce3 ├── exce3.c ├── exce4 ├── exce4.c ├── exce5 ├── exce5.c ├── exce6 ├── exce6.c ├── prog91.c ├── prog92.c ├── prog93 ├── prog93.c ├── prog94 ├── prog94.c ├── prog95 ├── prog95.c ├── prog96 ├── prog96.c ├── prog97 └── prog97.c ├── chapter10 ├── exce10 ├── exce10.c ├── exce11 ├── exce11.c ├── exce11a ├── exce11a.c ├── exce12 ├── exce12.c ├── exce13 ├── exce13.c ├── exce14 ├── exce14.c ├── exce14a.c ├── exce2 ├── exce2.c ├── exce3 ├── exce3.c ├── exce4 ├── exce4.c ├── exce5 ├── exce5.c ├── exce5a ├── exce5a.c ├── exce6 ├── exce6.c ├── exce7 ├── exce7.c ├── exce8 ├── exce8.c ├── exce8a ├── exce8a.c ├── exce9 ├── exce9.c ├── prog101 ├── prog101.c ├── prog1010 ├── prog1010.c ├── prog1011 ├── prog1011.c ├── prog102 ├── prog102.c ├── prog103 ├── prog103.c ├── prog104 ├── prog104.c ├── prog105 ├── prog105.c ├── prog106 ├── prog106.c ├── prog107 ├── prog107.c ├── prog108 ├── prog108.c ├── prog109 └── prog109.c ├── chapter11 ├── Pointers.md ├── Pointers.md~ ├── exce10 ├── exce10.c ├── exce11 ├── exce11.c ├── exce12 ├── exce12.c ├── exce2 ├── exce2.c ├── exce3 ├── exce3.c ├── exce4 ├── exce4.c ├── exce5 ├── exce5.c ├── exce6 ├── exce6.c ├── exce7 ├── exce7.c ├── exce8 ├── exce8.c ├── exce9 ├── exce9.c ├── prog111 ├── prog111.c ├── prog1110 ├── prog1110.c ├── prog1111 ├── prog1111.c ├── prog1112 ├── prog1112.c ├── prog1113 ├── prog1113.c ├── prog1114 ├── prog1114.c ├── prog1115 ├── prog1115.c ├── prog112 ├── prog112.c ├── prog113 ├── prog113.c ├── prog114 ├── prog114.c ├── prog115 ├── prog115.c ├── prog116 ├── prog116.c ├── prog117 ├── prog117.c ├── prog118 ├── prog118.c ├── prog119 └── prog119.c ├── chapter12 ├── exce2.c ├── exce3.c ├── exce4.c ├── exce5.c ├── exce6.c ├── exce7.c ├── exce8.c ├── prog1201 ├── prog1201.c ├── prog1202 ├── prog1202.c ├── prog1203.c └── prog1204.c ├── chapter13 The Preprocessor ├── exce.h ├── exce10.c ├── exce11.c ├── exce3.c ├── exce4.c ├── exce5.c ├── exce6.c ├── exce7.c ├── exce8.c ├── exce9.c ├── float.h ├── limits.h ├── metric.h ├── prog1301.c ├── prog1302.c ├── prog1303.c └── stdio.h ├── chapter14 More on Data Types ├── exce1.c ├── exce2.c ├── exce3.c └── prog1401.c ├── chapter16 Input and Output Operations in C ├── copyme ├── exce2.c ├── exce3.c ├── exce4.c ├── exce5.c ├── exce6.c ├── prog1601.c ├── prog1602.c └── prog1603.c ├── chapter17 Miscellaneous and Advanced Features └── prog1701.c ├── chapter18 Debugging Programs ├── prog1801.c ├── prog1802.c ├── prog1803.c ├── prog1804.c └── prog1805.c ├── chapter19 Object-Oriented Programming └── prog1901.c └── e /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | *.obj 5 | *.elf 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Libraries 12 | *.lib 13 | *.a 14 | *.la 15 | *.lo 16 | 17 | # Shared objects (inc. Windows DLLs) 18 | *.dll 19 | *.so 20 | *.so.* 21 | *.dylib 22 | 23 | # Executables 24 | *.exe 25 | *.out 26 | *.app 27 | *.i*86 28 | *.x86_64 29 | *.hex 30 | 31 | # Debug files 32 | *.dSYM/ 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Programming in C 3rd 2 | **C语言编程--一本全面的C语言入门教程,书内演示程序与练习。** 3 | 4 | [TOC] 5 | 6 | --- 7 | ### 第1章 入门 8 | 9 | --- 10 | ### 第2章 基础知识 11 | 12 | --- 13 | ### 第3章 编译并运行第一个程序 14 | 15 | --- 16 | ### 第4章 变量、数据类型和算术表达式 17 | 18 | --- 19 | ### 第5章 循环 20 | 21 | --- 22 | ### 第6章 进行判断 23 | 24 | --- 25 | ### 第7章 使用数组 26 | 27 | --- 28 | ### 第8章 使用函数 29 | 30 | --- 31 | ### 第9章 使用结构 32 | 33 | --- 34 | ### 第10章 字符串 35 | 36 | --- 37 | ### 第11章 指针 38 | 39 | --- 40 | ### 第12章 位运算 41 | 42 | --- 43 | ### 第13章 预处理器 44 | 45 | --- 46 | ### 第14章 进一步讨论数据类型 47 | 48 | --- 49 | ### 第15章 处理大型程序 50 | 51 | --- 52 | ### 第16章 C语言的输入和输出 53 | 54 | --- 55 | ### 第17章 杂项和高级特性 56 | 57 | --- 58 | ### 第18章 调试程序 59 | 60 | --- 61 | ### 第19章 面向对象编程 62 | 63 | 64 | ### 附录A C语言小结 65 | 66 | --- 67 | ### 附录B C语言标准库 68 | 69 | --- 70 | ### 附录C 使用gcc编译程序 71 | 72 | --- 73 | ### 附录D 常见编程错误 74 | 75 | --- 76 | ### 附录E C语言的其他资源 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /chapter03/exce2.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main (void) 3 | { 4 | printf("1.In C, lowercase letters are significant.\n"); 5 | printf("2.main is where program exexution begins.\n"); 6 | printf("3.Opening and closing braces enclose program statements in a routine.\n"); 7 | printf("4.All program statements must be terminated by a semicolon"); 8 | 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /chapter03/exce3.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main (void) 3 | { 4 | printf("Testing..."); 5 | printf("....1"); 6 | printf("...2"); 7 | printf("..3"); 8 | printf("\n"); 9 | // only one line 10 | 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /chapter03/exce4.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main (void) 3 | { 4 | int value1, value2, answer; 5 | value1 = 87; 6 | value2 = 15; 7 | 8 | answer = value1 - value2; 9 | printf("The answer of %i minus %i is %i\n", value1, value2, answer); 10 | 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /chapter03/exce5.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter03/exce5.c -------------------------------------------------------------------------------- /chapter03/exec6.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main (void) 3 | { 4 | int answer, result; 5 | 6 | answer = 100; 7 | result = answer - 10; 8 | printf("The result is %i\n", result + 5); 9 | 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /chapter03/prog1.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | printf("Programing is fun.\n"); 6 | 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /chapter03/prog2.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | printf("Programing is fun.\n"); 6 | printf("And programing in C is even more fun.\n"); 7 | 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /chapter03/prog3.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | printf("Testing...\n..1\n...2\n....3\n"); 6 | 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /chapter03/prog4.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int sum; 6 | 7 | sum = 50 + 25; 8 | printf("The sum of 50 and 25 is %i\n", sum); 9 | 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /chapter03/prog5.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int value1, value2, sum; 6 | 7 | value1 = 50; 8 | value2 = 25; 9 | sum = value1 + value2; 10 | printf("The sum of %i and %i is %i\n", value1, value2, sum); 11 | 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /chapter03/prog6.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter03/prog6.c -------------------------------------------------------------------------------- /chapter04/exce4.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter04/exce4.c -------------------------------------------------------------------------------- /chapter04/exce5.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main (void){ 4 | char c, d; 5 | 6 | c = 'd'; 7 | d = c; 8 | printf ("d = %c\n", d); 9 | 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /chapter04/exce6.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main (void){ 4 | float x = 2.55; 5 | float sum; 6 | 7 | sum = 3 * x * x * x - 5 * x * x + 6; 8 | printf ("3x3 - 5x2 + 6 = %f\n", sum); 9 | 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /chapter04/exce7.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main (void){ 4 | float a = (3.31 * 10 - 8 * 2.01 * 10 - 7); 5 | float b = (7.16 * 10 - 6 + 2.01 * 10 - 8); 6 | float answer; 7 | 8 | answer = a / b; 9 | printf ("(3.31 * 10 - 8 * 2.01 * 10 - 7) / (7.16 * 10 - 6 + 2.01 * 10 - 8) \n = %e\n", answer); 10 | 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /chapter04/exce8.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main (void){ 4 | int i1 = 365, j1 = 7; 5 | int i2 = 12258, j2 = 23; 6 | int i3 = 996, j3 = 4; 7 | 8 | int Next_multiple_1 = i1 + j1 - i1 % j1; 9 | int Next_multiple_2 = i2 + j2 - i2 % j2; 10 | int Next_multiple_3 = i3 + j3 - i3 % j3; 11 | 12 | printf ("Next_multiple_1 is %i\n", Next_multiple_1); 13 | printf ("Next_multiple_2 is %i\n", Next_multiple_2); 14 | printf ("Next_multiple_3 is %i\n", Next_multiple_3); 15 | 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /chapter04/prog41.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main (void) 3 | { 4 | int integerVar = 100; 5 | float floatingVar = 331.79; 6 | double doubleVar = 8.44e+11; 7 | char charVar = 'W'; 8 | 9 | _Bool boolVar = 0; 10 | 11 | printf("integerVar = %i\n", integerVar); 12 | printf("floatingVar = %f\n", floatingVar); 13 | printf("doubleVar = %e\n", doubleVar); 14 | printf("doubleVar = %g\n", doubleVar); 15 | printf("charVar = %c\n", charVar); 16 | 17 | printf("boolVar = %i\n", boolVar); 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /chapter04/prog42.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter04/prog42.c -------------------------------------------------------------------------------- /chapter04/prog43.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter04/prog43.c -------------------------------------------------------------------------------- /chapter04/prog44.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter04/prog44.c -------------------------------------------------------------------------------- /chapter04/prog45.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter04/prog45.c -------------------------------------------------------------------------------- /chapter05/exce10.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter05/exce10.c -------------------------------------------------------------------------------- /chapter05/exce11.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter05/exce11.c -------------------------------------------------------------------------------- /chapter05/exce2.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter05/exce2.c -------------------------------------------------------------------------------- /chapter05/exce3.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter05/exce3.c -------------------------------------------------------------------------------- /chapter05/exce4.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter05/exce4.c -------------------------------------------------------------------------------- /chapter05/exce5.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter05/exce5.c -------------------------------------------------------------------------------- /chapter05/exce6.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter05/exce6.c -------------------------------------------------------------------------------- /chapter05/exce7.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter05/exce7.c -------------------------------------------------------------------------------- /chapter05/exce8.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter05/exce8.c -------------------------------------------------------------------------------- /chapter05/exce92.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter05/exce92.c -------------------------------------------------------------------------------- /chapter05/exce93.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter05/exce93.c -------------------------------------------------------------------------------- /chapter05/exce94.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter05/exce94.c -------------------------------------------------------------------------------- /chapter05/exce95.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter05/exce95.c -------------------------------------------------------------------------------- /chapter05/prog51.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter05/prog51.c -------------------------------------------------------------------------------- /chapter05/prog52.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter05/prog52.c -------------------------------------------------------------------------------- /chapter05/prog53.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter05/prog53.c -------------------------------------------------------------------------------- /chapter05/prog53a.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter05/prog53a.c -------------------------------------------------------------------------------- /chapter05/prog54.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter05/prog54.c -------------------------------------------------------------------------------- /chapter05/prog55.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter05/prog55.c -------------------------------------------------------------------------------- /chapter05/prog56.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter05/prog56.c -------------------------------------------------------------------------------- /chapter05/prog57.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter05/prog57.c -------------------------------------------------------------------------------- /chapter05/prog58.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter05/prog58.c -------------------------------------------------------------------------------- /chapter05/prog59.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter05/prog59.c -------------------------------------------------------------------------------- /chapter06/exce2.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter06/exce2.c -------------------------------------------------------------------------------- /chapter06/exce3.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter06/exce3.c -------------------------------------------------------------------------------- /chapter06/exce4.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter06/exce4.c -------------------------------------------------------------------------------- /chapter06/exce5.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter06/exce5.c -------------------------------------------------------------------------------- /chapter06/exce6.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter06/exce6.c -------------------------------------------------------------------------------- /chapter06/exce7.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter06/exce7.c -------------------------------------------------------------------------------- /chapter06/prog61.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter06/prog61.c -------------------------------------------------------------------------------- /chapter06/prog610.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter06/prog610.c -------------------------------------------------------------------------------- /chapter06/prog610a.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter06/prog610a.c -------------------------------------------------------------------------------- /chapter06/prog62.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter06/prog62.c -------------------------------------------------------------------------------- /chapter06/prog63.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter06/prog63.c -------------------------------------------------------------------------------- /chapter06/prog64.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter06/prog64.c -------------------------------------------------------------------------------- /chapter06/prog65.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter06/prog65.c -------------------------------------------------------------------------------- /chapter06/prog66.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter06/prog66.c -------------------------------------------------------------------------------- /chapter06/prog67.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter06/prog67.c -------------------------------------------------------------------------------- /chapter06/prog68.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter06/prog68.c -------------------------------------------------------------------------------- /chapter06/prog68a.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter06/prog68a.c -------------------------------------------------------------------------------- /chapter06/prog69.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter06/prog69.c -------------------------------------------------------------------------------- /chapter07/exce2.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter07/exce2.c -------------------------------------------------------------------------------- /chapter07/exce3.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter07/exce3.c -------------------------------------------------------------------------------- /chapter07/exce4.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter07/exce4.c -------------------------------------------------------------------------------- /chapter07/exce5.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter07/exce5.c -------------------------------------------------------------------------------- /chapter07/exce6.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter07/exce6.c -------------------------------------------------------------------------------- /chapter07/exce7.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter07/exce7.c -------------------------------------------------------------------------------- /chapter07/prog71.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter07/prog71.c -------------------------------------------------------------------------------- /chapter07/prog72.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter07/prog72.c -------------------------------------------------------------------------------- /chapter07/prog73.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter07/prog73.c -------------------------------------------------------------------------------- /chapter07/prog74.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter07/prog74.c -------------------------------------------------------------------------------- /chapter07/prog75.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter07/prog75.c -------------------------------------------------------------------------------- /chapter07/prog76.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter07/prog76.c -------------------------------------------------------------------------------- /chapter07/prog77.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter07/prog77.c -------------------------------------------------------------------------------- /chapter07/prog78.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter07/prog78.c -------------------------------------------------------------------------------- /chapter07/test.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main (void) 4 | { 5 | int P[151], i, j; 6 | int n = 150; 7 | 8 | for (i = 2; i <= n; ++i) 9 | P[i] = 0; 10 | 11 | i = 2; 12 | 13 | while (i <= n) { 14 | if (P[i] == 0) 15 | printf ("%i ", i); 16 | 17 | j = 1; 18 | 19 | while (i * j <= n) { 20 | P[i * j] = 1; 21 | ++j; 22 | } 23 | 24 | ++i; 25 | } 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /chapter08/exce10.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter08/exce10.c -------------------------------------------------------------------------------- /chapter08/exce11.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter08/exce11.c -------------------------------------------------------------------------------- /chapter08/exce12.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter08/exce12.c -------------------------------------------------------------------------------- /chapter08/exce13.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter08/exce13.c -------------------------------------------------------------------------------- /chapter08/exce14a.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter08/exce14a.c -------------------------------------------------------------------------------- /chapter08/exce14b.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter08/exce14b.c -------------------------------------------------------------------------------- /chapter08/exce14c.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter08/exce14c.c -------------------------------------------------------------------------------- /chapter08/exce14d.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter08/exce14d.c -------------------------------------------------------------------------------- /chapter08/exce15.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter08/exce15.c -------------------------------------------------------------------------------- /chapter08/exce16.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter08/exce16.c -------------------------------------------------------------------------------- /chapter08/exce2.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter08/exce2.c -------------------------------------------------------------------------------- /chapter08/exce3.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter08/exce3.c -------------------------------------------------------------------------------- /chapter08/exce4.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter08/exce4.c -------------------------------------------------------------------------------- /chapter08/exce5.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter08/exce5.c -------------------------------------------------------------------------------- /chapter08/exce6.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter08/exce6.c -------------------------------------------------------------------------------- /chapter08/exce7.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter08/exce7.c -------------------------------------------------------------------------------- /chapter08/exce8.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter08/exce8.c -------------------------------------------------------------------------------- /chapter08/exce9.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter08/exce9.c -------------------------------------------------------------------------------- /chapter08/prog81.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter08/prog81.c -------------------------------------------------------------------------------- /chapter08/prog811.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter08/prog811.c -------------------------------------------------------------------------------- /chapter08/prog812.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter08/prog812.c -------------------------------------------------------------------------------- /chapter08/prog813.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter08/prog813.c -------------------------------------------------------------------------------- /chapter08/prog813a.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter08/prog813a.c -------------------------------------------------------------------------------- /chapter08/prog814.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter08/prog814.c -------------------------------------------------------------------------------- /chapter08/prog815.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter08/prog815.c -------------------------------------------------------------------------------- /chapter08/prog816.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter08/prog816.c -------------------------------------------------------------------------------- /chapter08/prog82.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter08/prog82.c -------------------------------------------------------------------------------- /chapter08/prog83.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter08/prog83.c -------------------------------------------------------------------------------- /chapter08/prog84.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter08/prog84.c -------------------------------------------------------------------------------- /chapter08/prog85.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter08/prog85.c -------------------------------------------------------------------------------- /chapter08/prog86.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter08/prog86.c -------------------------------------------------------------------------------- /chapter08/prog87.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter08/prog87.c -------------------------------------------------------------------------------- /chapter08/prog88.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter08/prog88.c -------------------------------------------------------------------------------- /chapter08/prog88a.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter08/prog88a.c -------------------------------------------------------------------------------- /chapter08/prog89.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter08/prog89.c -------------------------------------------------------------------------------- /chapter09/exce2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter09/exce2 -------------------------------------------------------------------------------- /chapter09/exce2.c: -------------------------------------------------------------------------------- 1 | // 计算两个任意日期之间的天数 2 | #include 3 | 4 | struct date{ 5 | int year; 6 | int month; 7 | int day; 8 | }; 9 | 10 | int f(int year, int month){ 11 | if(month <= 2) 12 | return (year - 1); 13 | else 14 | return year; 15 | }; 16 | 17 | int g(int month){ 18 | if(month <= 2) 19 | return (month + 13); 20 | else 21 | return (month + 1); 22 | }; 23 | 24 | int calculateN(struct date someDay){ 25 | int N; 26 | 27 | N = 1461 * f(someDay.year, someDay.month) / 4 + 153 * g(someDay.month) / 5 + someDay.day; 28 | 29 | // 对于1800年3月1日到1900年2月28日之间的日期来说,N值需要+1; 30 | // 对于1700年3月1日到1800年2月28日之间的日期来说,N值需要+2; 31 | // 如何描述出这之间的日期? 32 | 33 | return N; 34 | }; 35 | 36 | int main(void){ 37 | int n1, n2; 38 | struct date day1, day2; 39 | int calculateN(struct date someDay); 40 | 41 | printf("请输入第一个日期: (yyyy/mm/dd) \n"); 42 | scanf("%i /%i /%i", &day1.year, &day1.month, &day1.day); 43 | n1 = calculateN(day1); 44 | printf("第一天的N值为: %i \n", n1); 45 | 46 | printf("请输入第二个日期: (yyyy/mm/dd) \n"); 47 | scanf("%i /%i /%i", &day2.year, &day2.month, &day2.day); 48 | n2 = calculateN(day2); 49 | printf("第二天的N值为: %i \n", n2); 50 | 51 | printf("这两个日期之间的天数是: %i\n", (n2 - n1)); 52 | 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /chapter09/exce2a.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct date{ 4 | int year; 5 | int month; 6 | int day; 7 | }; 8 | 9 | int f(int year,int month){ 10 | // 三元运算符 11 | return (month <= 2) ? (year-1) : (year); 12 | } 13 | 14 | int g(int month){ 15 | return (month <= 2) ? (month + 13) : (month + 1); 16 | } 17 | 18 | long int daysOfDate(struct date d){ 19 | int f(int year,int month); 20 | int g(int month); 21 | 22 | return 1461 * f(d.year,d.month) / 4 + 153 * g(d.month) / 5 + d.day; 23 | } 24 | 25 | int main(void){ 26 | long int daysOfDate(struct date d); 27 | struct date d1,d2; 28 | 29 | printf("Input date (yyyy mm dd): "); 30 | scanf("%i %i %i",&d1.year,&d1.month,&d1.day); 31 | 32 | printf("Input next date (yyyy mm dd): "); 33 | scanf("%i %i %i",&d2.year,&d2.month,&d2.day); 34 | 35 | printf("The days between the two date is: %li\n", 36 | daysOfDate(d2) - daysOfDate(d1)); 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /chapter09/exce3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter09/exce3 -------------------------------------------------------------------------------- /chapter09/exce3.c: -------------------------------------------------------------------------------- 1 | // 接受两个struct time 参数,返回一个struct time 类型的参数,表示这两个参数之间流逝的时间 2 | // 注意穿越午夜的特殊情况。 3 | #include 4 | 5 | struct time{ 6 | int hours; 7 | int minutes; 8 | int seconds; 9 | }; 10 | 11 | struct time elapsed_time(struct time time1, struct time time2){ 12 | struct time time3; 13 | 14 | if(time2.hours >= time1.hours){ 15 | time3.hours = time2.hours - time1.hours - 1; 16 | time3.minutes = time2.minutes + (59 - time1.minutes); 17 | time3.seconds = time2.seconds + (60 - time1.seconds); 18 | 19 | if(time3.seconds >= 60){ 20 | time3.seconds -= 60; 21 | time3.minutes += 1; 22 | if(time3.minutes >=60){ 23 | time3.minutes -= 60; 24 | time3.hours += 1; 25 | } 26 | } 27 | 28 | return time3; 29 | } 30 | // 穿越午夜的情况 31 | else{ 32 | time3.hours = time2.hours + (24 - time1.hours); 33 | time3.minutes = time2.minutes + (59 - time1.minutes); 34 | time3.seconds = time2.seconds + (60 - time1.seconds); 35 | 36 | if(time3.seconds >= 60){ 37 | time3.seconds -= 60; 38 | time3.minutes += 1; 39 | if(time3.minutes >=60){ 40 | time3.minutes -= 60; 41 | time3.hours += 1; 42 | } 43 | } 44 | 45 | return time3; 46 | } 47 | }; 48 | 49 | void printTime(struct time t){ 50 | printf("流逝的时间为%i小时%i分%i秒。\n", t.hours, t.minutes, t.seconds); 51 | } 52 | 53 | int main(void){ 54 | struct time time1, time2, time3; 55 | struct time elapsed_time(struct time time1, struct time time2); 56 | 57 | printf("请输入第一个时间: (24:59:59) \n"); 58 | scanf("%i :%i :%i", &time1.hours, &time1.minutes, &time1.seconds); 59 | printf("请输入第二个时间: (24:59:59) \n"); 60 | scanf("%i :%i :%i", &time2.hours,&time2.minutes, &time2.seconds); 61 | 62 | time3 = elapsed_time(time1, time2); 63 | 64 | printTime(time3); 65 | 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /chapter09/exce4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter09/exce4 -------------------------------------------------------------------------------- /chapter09/exce4.c: -------------------------------------------------------------------------------- 1 | // 利用习题2中的N值来计算该数字代表的日期对应的是星期几 2 | #include 3 | 4 | // 没有字符串数组就只能用二维字符数组显示星期了 5 | const char weeks[7][3] = { 6 | {'M','o','n'}, {'T','u','e'}, {'W','e','n'}, {'T','h','u'}, {'F','r','i'}, {'S','a','t'}, {'S','u','n'} 7 | }; 8 | 9 | struct date{ 10 | int year; 11 | int month; 12 | int day; 13 | }; 14 | 15 | int f(int year,int month){ 16 | // 三元运算符 17 | return (month <= 2) ? (year-1) : (year); 18 | } 19 | 20 | int g(int month){ 21 | return (month <= 2) ? (month + 13) : (month + 1); 22 | } 23 | 24 | long int daysOfDate(struct date d){ 25 | int f(int year,int month); 26 | int g(int month); 27 | 28 | return 1461 * f(d.year,d.month) / 4 + 153 * g(d.month) / 5 + d.day; 29 | } 30 | 31 | int weekOfDate(struct date d){ 32 | long int daysOfDate(struct date d); 33 | 34 | int week = (daysOfDate(d) - 621049) % 7; 35 | 36 | return week; 37 | } 38 | 39 | int main(void){ 40 | int i, n; 41 | struct date d; 42 | int weekOfDate(struct date d); 43 | 44 | printf("请输入一个日期: (yyyy/mm/dd)\n"); 45 | scanf("%i / %i / %i", &d.year, &d.month, &d.day); 46 | 47 | n = weekOfDate(d); 48 | 49 | printf("该日期对应的星期名字为: "); 50 | 51 | for(i = 0; i < 3; ++i) 52 | printf("%c", weeks[n-1][i]); 53 | 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /chapter09/exce5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter09/exce5 -------------------------------------------------------------------------------- /chapter09/exce5.c: -------------------------------------------------------------------------------- 1 | // clockKeeper 2 | // 以秒为单位更新时间的程序 3 | #include 4 | #include 5 | 6 | struct time{ 7 | int hour; 8 | int minutes; 9 | int seconds; 10 | } ; 11 | 12 | // 以秒为单位更新时间的函数 13 | struct time timeUpdate(struct time now){ 14 | ++now.seconds; 15 | if(now.seconds == 60){ 16 | now.seconds = 0; 17 | ++now.minutes; 18 | 19 | if(now.minutes == 60){ 20 | now.minutes = 0; 21 | ++now.hour; 22 | 23 | if(now.hour == 24) 24 | now.hour = 0; 25 | } 26 | } 27 | return now; 28 | } 29 | 30 | struct date{ 31 | int month; 32 | int day; 33 | int year; 34 | }; 35 | 36 | // 计算下一天日期的函数 37 | struct date dateUpdate(struct date today){ 38 | struct date tomorrow; 39 | int numberOfDays(struct date d); 40 | 41 | if(today.day != numberOfDays(today)){ 42 | tomorrow.day = today.day + 1; 43 | tomorrow.month = today.month; 44 | tomorrow.year = today.year; 45 | } 46 | else if(today.month == 12){ 47 | tomorrow.day = 1; 48 | tomorrow.month = 1; 49 | tomorrow.year = today.year + 1; 50 | } 51 | else{ 52 | tomorrow.day = 1; 53 | tomorrow.month = today.month + 1; 54 | tomorrow.year = today.year; 55 | } 56 | 57 | return tomorrow; 58 | } 59 | 60 | // 查找一月中日期数的函数 61 | int numberOfDays(struct date d){ 62 | int days; 63 | bool isLeapYear(struct date d); 64 | const int daysPerMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 65 | 66 | if(isLeapYear(d) && d.month == 2) 67 | days = 29; 68 | else 69 | days = daysPerMonth[d.month - 1]; 70 | 71 | return days; 72 | } 73 | 74 | // 判断是否为闰年的函数 75 | bool isLeapYear(struct date d){ 76 | bool leapYearFlag; 77 | 78 | if((d.year % 4 == 0 && d.year % 100 != 0 )|| d.year % 400 == 0) 79 | leapYearFlag = true; // 闰年 80 | else 81 | leapYearFlag = false; // 非闰年 82 | 83 | return leapYearFlag; 84 | } 85 | 86 | struct dateAndTime{ 87 | struct time now; 88 | struct date d; 89 | }; 90 | 91 | struct dateAndTime clockKeeper (struct dateAndTime dat){ 92 | struct time timeUpdate(struct time now); 93 | struct date dateUpdate(struct date d); 94 | 95 | dat.now = timeUpdate(dat.now); 96 | // 时间过午夜则更新日期 97 | if(dat.now.hour == 0) 98 | dat.d = dateUpdate(dat.d); 99 | 100 | return dat; 101 | }; 102 | 103 | int main(void){ 104 | struct dateAndTime clockKeeper(struct dateAndTime dat); 105 | struct dateAndTime dat; 106 | 107 | // 使用复合字面量赋值 108 | dat.now = (struct time){23, 59, 59}; 109 | dat.d = (struct date){2, 28, 2016}; 110 | 111 | dat = clockKeeper(dat); 112 | 113 | printf("%i:%i:%i: %i/%i/%i", dat.now.hour, dat.now.minutes, dat.now.seconds, 114 | dat.d.month, dat.d.day, dat.d.year); 115 | 116 | return 0; 117 | } 118 | -------------------------------------------------------------------------------- /chapter09/exce6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter09/exce6 -------------------------------------------------------------------------------- /chapter09/exce6.c: -------------------------------------------------------------------------------- 1 | // 将9.4中的dateUpdate函数替换为使用复合字面量的版本 2 | 3 | #include 4 | #include 5 | 6 | struct date{ 7 | int month; 8 | int day; 9 | int year; 10 | }; 11 | 12 | // 计算下一天日期的函数 13 | struct date dateUpdate(struct date today){ 14 | struct date tomorrow; 15 | int numberOfDays(struct date d); 16 | 17 | if(today.day != numberOfDays(today)){ 18 | tomorrow = (struct date){today.month, today.day + 1, today.year}; 19 | } 20 | else if(today.month == 12){ 21 | tomorrow = (struct date){1, 1, today.year + 1}; 22 | } 23 | else{ 24 | tomorrow = (struct date){today.month + 1, 1, today.year}; 25 | } 26 | 27 | return tomorrow; 28 | } 29 | 30 | // 查找一月中日期数的函数 31 | int numberOfDays(struct date d){ 32 | int days; 33 | bool isLeapYear(struct date d); 34 | const int daysPerMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 35 | 36 | if(isLeapYear(d) && d.month == 2) 37 | days = 29; 38 | else 39 | days = daysPerMonth[d.month - 1]; 40 | 41 | return days; 42 | } 43 | 44 | // 判断是否为闰年的函数 45 | bool isLeapYear(struct date d){ 46 | bool leapYearFlag; 47 | 48 | if((d.year % 4 == 0 && d.year % 100 != 0 )|| d.year % 400 == 0) 49 | leapYearFlag = true; // 闰年 50 | else 51 | leapYearFlag = false; // 非闰年 52 | 53 | return leapYearFlag; 54 | } 55 | 56 | int main(void){ 57 | struct date dateUpdate(struct date today); 58 | struct date thisDay, nextDay; 59 | 60 | printf("Enter today's date (mm dd yyyy) \n"); 61 | scanf("%i /%i /%i", &thisDay.month, &thisDay.day, &thisDay.year); 62 | 63 | nextDay = dateUpdate(thisDay); 64 | 65 | printf("Tomorrow's date is %i /%i /%.2i.\n", nextDay.month, 66 | nextDay.day, nextDay.year % 100); 67 | 68 | return 0; 69 | } 70 | 71 | -------------------------------------------------------------------------------- /chapter09/prog91.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter09/prog91.c -------------------------------------------------------------------------------- /chapter09/prog92.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter09/prog92.c -------------------------------------------------------------------------------- /chapter09/prog93: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter09/prog93 -------------------------------------------------------------------------------- /chapter09/prog93.c: -------------------------------------------------------------------------------- 1 | // 考虑闰年的情况,对于计算下一天程序的修正 2 | #include 3 | #include 4 | 5 | struct date{ 6 | int month; 7 | int day; 8 | int year; 9 | }; 10 | 11 | int main(void){ 12 | struct date today, tomorrow; 13 | // 每个月的天数 14 | int numberOfDays(struct date d); 15 | 16 | printf("Enter today's date (mm dd yyyy): "); 17 | scanf("%i%i%i", &today.month, &today.day, &today.year); 18 | 19 | if(today.day != numberOfDays(today)){ 20 | tomorrow.day = today.day + 1; 21 | tomorrow.month = today.month; 22 | tomorrow.year = today.year; 23 | } 24 | else if(today.month == 12){ 25 | // 年尾 26 | tomorrow.day = 1; 27 | tomorrow.month = 1; 28 | tomorrow.year = today.year + 1; 29 | } 30 | else{ 31 | // 月末 32 | tomorrow.day = 1; 33 | tomorrow.month = today.month + 1; 34 | tomorrow.year = today.year; 35 | } 36 | 37 | printf("Tomorrow's date is %i/%i/%.2i.\n", tomorrow.month, 38 | tomorrow.day, tomorrow.year % 100); 39 | 40 | return 0; 41 | } 42 | 43 | // 查找一个月中日期数的函数 44 | int numberOfDays(struct date d){ 45 | int days; 46 | bool isLeapYear (struct date d); 47 | const int daysPerMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 48 | 49 | if(isLeapYear(d) == true && d.month == 2) 50 | days = 29; 51 | else 52 | days = daysPerMonth[d.month - 1]; 53 | return days; 54 | } 55 | 56 | // 判断是否为闰年的函数 57 | bool isLeapYear(struct date d){ 58 | bool leapYearFlag; 59 | 60 | if((d.year % 4 == 0 && d.year % 100 != 0 )|| d.year % 400 == 0) 61 | leapYearFlag = true; // 闰年 62 | else 63 | leapYearFlag = false; // 非闰年 64 | 65 | return leapYearFlag; 66 | } 67 | -------------------------------------------------------------------------------- /chapter09/prog94: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter09/prog94 -------------------------------------------------------------------------------- /chapter09/prog94.c: -------------------------------------------------------------------------------- 1 | // 计算下一天日期的程序(第二版) 2 | 3 | #include 4 | #include 5 | 6 | struct date{ 7 | int month; 8 | int day; 9 | int year; 10 | }; 11 | 12 | // 计算下一天日期的函数 13 | struct date dateUpdate(struct date today){ 14 | struct date tomorrow; 15 | int numberOfDays(struct date d); 16 | 17 | if(today.day != numberOfDays(today)){ 18 | tomorrow.day = today.day + 1; 19 | tomorrow.month = today.month; 20 | tomorrow.year = today.year; 21 | } 22 | else if(today.month == 12){ 23 | // 年尾 24 | tomorrow.day = 1; 25 | tomorrow.month = 1; 26 | tomorrow.year = today.year + 1; 27 | } 28 | else{ 29 | // 月末 30 | tomorrow.day = 1; 31 | tomorrow.month = today.month + 1; 32 | tomorrow.year = today.year; 33 | } 34 | 35 | return tomorrow; 36 | } 37 | 38 | // 查找一月中日期数的函数 39 | int numberOfDays(struct date d){ 40 | int days; 41 | bool isLeapYear(struct date d); 42 | const int daysPerMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 43 | 44 | if(isLeapYear(d) && d.month == 2) 45 | days = 29; 46 | else 47 | days = daysPerMonth[d.month - 1]; 48 | 49 | return days; 50 | } 51 | 52 | // 判断是否为闰年的函数 53 | bool isLeapYear(struct date d){ 54 | bool leapYearFlag; 55 | 56 | if((d.year % 4 == 0 && d.year % 100 != 0 )|| d.year % 400 == 0) 57 | leapYearFlag = true; // 闰年 58 | else 59 | leapYearFlag = false; // 非闰年 60 | 61 | return leapYearFlag; 62 | } 63 | 64 | int main(void){ 65 | struct date dateUpdate(struct date today); 66 | struct date thisDay, nextDay; 67 | 68 | printf("Enter today's date (mm dd yyyy)\n"); 69 | scanf("%i /%i /%i", &thisDay.month, &thisDay.day, &thisDay.year); 70 | 71 | nextDay = dateUpdate(thisDay); 72 | 73 | printf("Tomorrow's date is %i/%i/%.2i.\n", nextDay.month, 74 | nextDay.day, nextDay.year % 100); 75 | 76 | return 0; 77 | } 78 | 79 | -------------------------------------------------------------------------------- /chapter09/prog95: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter09/prog95 -------------------------------------------------------------------------------- /chapter09/prog95.c: -------------------------------------------------------------------------------- 1 | // 以秒为单位更新时间的程序 2 | #include 3 | 4 | struct time{ 5 | int hour; 6 | int minutes; 7 | int seconds; 8 | } ; 9 | 10 | int main(void){ 11 | struct time timeUpdate(struct time now); 12 | struct time currentTime, nextTime; 13 | 14 | printf("Enter the time (hh:mm:ss); "); 15 | scanf("%i :%i :%i ", ¤tTime.hour, 16 | ¤tTime.minutes, ¤tTime.seconds); 17 | 18 | nextTime = timeUpdate(currentTime); 19 | printf("Updated time is %.2i:%.2i:%.2i\n", nextTime.hour, 20 | nextTime.minutes, nextTime.seconds); 21 | 22 | return 0; 23 | } 24 | 25 | // 以秒为单位更新时间的函数 26 | struct time timeUpdate(struct time now){ 27 | ++now.seconds; 28 | if(now.seconds == 60){ 29 | // 下一分钟 30 | now.seconds = 0; 31 | ++now.minutes; 32 | 33 | if(now.minutes == 60){ 34 | // 下一小时 35 | now.minutes = 0; 36 | ++now.hour; 37 | 38 | if(now.hour == 24) 39 | // 午夜 40 | now.hour = 0; 41 | } 42 | } 43 | return now; 44 | } 45 | -------------------------------------------------------------------------------- /chapter09/prog96: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter09/prog96 -------------------------------------------------------------------------------- /chapter09/prog96.c: -------------------------------------------------------------------------------- 1 | // 演示结构数组的程序 2 | #include 3 | 4 | struct time{ 5 | int hour; 6 | int minutes; 7 | int seconds; 8 | }; 9 | 10 | int main(void){ 11 | struct time timeUpdate(struct time now); 12 | struct time testTimes[5] = { 13 | {11, 59, 59}, {12, 0, 0}, {1, 29, 59}, 14 | {23, 59, 59}, {19, 12, 27} 15 | }; 16 | int i; 17 | 18 | for(i = 0; i < 5; ++i){ 19 | printf("Time is %.2i:%.2i:%.2i", testTimes[i].hour, 20 | testTimes[i].minutes, testTimes[i].seconds); 21 | 22 | testTimes[i] = timeUpdate(testTimes[i]); 23 | 24 | printf(" ...one second later it's %.2i:%.2i:%.2i\n", 25 | testTimes[i].hour, testTimes[i].minutes, testTimes[i].seconds); 26 | } 27 | 28 | return 0; 29 | } 30 | 31 | // 以秒为单位更新时间的函数 32 | struct time timeUpdate(struct time now){ 33 | ++now.seconds; 34 | if(now.seconds == 60){ 35 | now.seconds = 0; 36 | ++now.minutes; 37 | 38 | if(now.minutes == 60){ 39 | now.minutes = 0; 40 | ++now.hour; 41 | 42 | if(now.hour == 24) 43 | now.hour = 0; 44 | } 45 | } 46 | return now; 47 | } 48 | -------------------------------------------------------------------------------- /chapter09/prog97: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter09/prog97 -------------------------------------------------------------------------------- /chapter09/prog97.c: -------------------------------------------------------------------------------- 1 | // 演示结构数组的程序 2 | #include 3 | 4 | int main(void){ 5 | int i; 6 | struct month{ 7 | int numberOfDays; 8 | char name[3]; 9 | }; 10 | 11 | const struct month months[12] = { 12 | {31, {'J', 'a', 'n'}}, {28, {'F', 'e', 'b'}}, 13 | {31, {'M','a','r'}}, {30, {'A', 'p', 'r'}}, 14 | {31, {'M','a','y'}}, {30, {'J', 'u', 'n'}}, 15 | {31, {'J', 'u', 'l'}}, {31, {'A', 'u', 'g'}}, 16 | {30, {'S', 'e', 'p'}}, {31, {'O', 'c', 't'}}, 17 | {30, {'N', 'o', 'v'}}, {31, {'D', 'e', 'c'}}, 18 | }; 19 | 20 | printf("Month Number of Days\n"); 21 | printf("------------------------------------\n"); 22 | 23 | for(i = 0; i < 12; ++i) 24 | printf("%c%c%c %i\n", months[i].name[0], months[i].name[1], 25 | months[i].name[2], months[i].numberOfDays); 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /chapter10/exce10: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter10/exce10 -------------------------------------------------------------------------------- /chapter10/exce10.c: -------------------------------------------------------------------------------- 1 | // 编写dictionarySort函数,对10.9的字典进行排序 2 | #include 3 | #include 4 | 5 | struct entry{ 6 | char word[15]; 7 | char definition[50]; 8 | }; 9 | 10 | int compareStrings(const char s1[], const char s2[]){ 11 | int i = 0, answer; 12 | 13 | while(s1[i] == s2[i] && s1[i] != '\0' && s2[i] != '\0') 14 | ++i; 15 | if(s1[i] < s2[i]) 16 | answer = -1; 17 | else if(s1[i] == s2[i]) 18 | answer = 0; 19 | else answer = 1; 20 | 21 | return answer; 22 | } 23 | 24 | void dictionarySort(struct entry dict[10]){ 25 | int compareStrings(const char s1[], const char s2[]); 26 | struct entry temp; 27 | int i, j, answer; 28 | 29 | for(i = 0; i < 9; ++i) 30 | for(j = i + 1; j < 10; ++j){ 31 | answer = compareStrings(dict[i].word, dict[j].word); 32 | if(answer == -1){ 33 | temp = dict[i]; 34 | dict[i] = dict[j]; 35 | dict[j] = temp; 36 | } 37 | } 38 | } 39 | 40 | int main(void){ 41 | void dictionarySort(struct entry dict[10]); 42 | int i; 43 | struct entry dictionary[10] = { 44 | {"abyss", "a bottomless pit"}, 45 | {"acumen", "mentally sharp; keen"}, 46 | {"aardvark", "a burrowing African mamal"}, 47 | {"agar", "a jelly made from seaweed"}, 48 | {"ahoy", "a nautical call of greeting"}, 49 | {"aigrette", "an ornamental cluster of feathers"}, 50 | {"addle", "to become confused"}, 51 | {"aerie", "a high nest"}, 52 | {"affix", "to append; attach"}, 53 | {"ajar", "partially opened"}, 54 | }; 55 | 56 | dictionarySort(dictionary); 57 | 58 | for(i = 0; i < 10; ++i) 59 | printf("%s\n", dictionary[i].word); 60 | 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /chapter10/exce11: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter10/exce11 -------------------------------------------------------------------------------- /chapter10/exce11.c: -------------------------------------------------------------------------------- 1 | // 考虑负数的情况 2 | #include 3 | 4 | int strToInt(char string[]){ 5 | int i = 0, intValue, result = 0, isMinus= 0; 6 | 7 | if(string[0] == '-'){ 8 | isMinus = 1; 9 | i = 1; 10 | } 11 | 12 | for(; (string[i] >= '0' && string[i] <= '9'); ++i){ 13 | intValue = string[i] - '0'; 14 | result = result * 10 + intValue; 15 | } 16 | 17 | if(isMinus){ 18 | result = -1 * result; 19 | } 20 | 21 | return result; 22 | } 23 | 24 | int main(void){ 25 | int strToInt(char string[]); 26 | 27 | printf("%i\n", strToInt("-245")); 28 | printf("%i\n", strToInt("100") + 25); 29 | printf("%i\n", strToInt("13x5")); 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /chapter10/exce11a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter10/exce11a -------------------------------------------------------------------------------- /chapter10/exce11a.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int strToInt(const char string[]) 4 | { 5 | int i = 0,intValue,result = 0,isMinus = 0; 6 | 7 | if('-' == string[0]){ 8 | isMinus = 1; 9 | i = 1; 10 | } 11 | 12 | for(; string[i] >= '0' && string[i] <= '9'; ++i){ 13 | intValue = string[i] - '0'; 14 | result = result * 10 + intValue; 15 | } 16 | 17 | if(isMinus) 18 | result = -1 * result; 19 | 20 | return result; 21 | } 22 | 23 | int main(void) 24 | { 25 | int strToInt(const char string[]); 26 | 27 | printf("%i\n",strToInt("245")); 28 | printf("%i\n",strToInt("-245")); 29 | printf("%i\n",strToInt("245") + 25); 30 | printf("%i\n",strToInt("-245") + 25); 31 | printf("%i\n",strToInt("13x5")); 32 | printf("%i\n",strToInt("-13x5")); 33 | 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /chapter10/exce12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter10/exce12 -------------------------------------------------------------------------------- /chapter10/exce12.c: -------------------------------------------------------------------------------- 1 | // 考虑浮点数的情况 2 | #include 3 | 4 | float strToFloat(char string[]){ 5 | int i, j = 0, intValue, isMinus = 0, isFloat = 0; 6 | float result; 7 | 8 | if(string[0] == '-'){ 9 | isMinus = 1; 10 | i = 1; 11 | } 12 | 13 | for(; (string[i] >= '0' && string[i] <= '9'); ++i){ 14 | intValue = string[i] - '0'; 15 | result = result * 10 + intValue; 16 | } 17 | 18 | if(string[i] == '.'){ 19 | isFloat = 1; 20 | for(++i; (string[i] >= '0' && string[i] <= '9'); ++i){ 21 | intValue = string[i] - '0'; 22 | result = result * 10 + intValue; 23 | ++j; 24 | } 25 | } 26 | 27 | if(isFloat){ 28 | for(; j > 0; --j) 29 | result = result / 10; 30 | } 31 | 32 | if(isMinus){ 33 | result = -1 * result; 34 | } 35 | 36 | return result; 37 | } 38 | 39 | int main(void){ 40 | float strToFloat(char string[]); 41 | 42 | printf("%f\n", strToFloat("-867.6921")); 43 | 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /chapter10/exce13: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter10/exce13 -------------------------------------------------------------------------------- /chapter10/exce13.c: -------------------------------------------------------------------------------- 1 | // 编写uppercase的函数 2 | #include 3 | 4 | void uppercase(char source[]){ 5 | int i; 6 | for(i = 0; source[i] != '\0'; ++i) 7 | if(source[i] >= 'a' && source[i] <= 'z') 8 | source[i] = source[i] - 'a' + 'A'; 9 | } 10 | 11 | int main(void){ 12 | void uppercase(char source[]); 13 | char text[] = "hello world!"; 14 | 15 | uppercase(text); 16 | 17 | printf("%s", text); 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /chapter10/exce14: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter10/exce14 -------------------------------------------------------------------------------- /chapter10/exce14.c: -------------------------------------------------------------------------------- 1 | // 编写intToStr的函数 2 | #include 3 | 4 | void intToStr(int value, char result[]){ 5 | char intString[81]; 6 | int i, j = 0; 7 | 8 | if(value < 0){ 9 | result[0] = '-'; 10 | value = - value; 11 | j = 1; 12 | } 13 | 14 | do{ 15 | intString[i] = value % 10; 16 | ++i; 17 | value = value / 10; 18 | }while(value != 0); 19 | 20 | for(--i; i >= 0; --i){ 21 | result[j] = intString[i] + '0'; 22 | ++j; 23 | } 24 | 25 | result[j] = '\0'; 26 | } 27 | 28 | int main(void){ 29 | void intToStr(int value, char result[]); 30 | char result[81]; 31 | 32 | intToStr(-867, result); 33 | 34 | printf("%s", result); 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /chapter10/exce14a.c: -------------------------------------------------------------------------------- 1 | #include 2 | void intToStr(int value,char string[]) 3 | { 4 | int i = 0,j = 0,right_digit; 5 | char intString[32]; 6 | 7 | if(value < 0){ 8 | value *= -1; 9 | string[0] = '-'; 10 | j = 1; 11 | } 12 | 13 | do{ 14 | right_digit = value % 10; 15 | intString[i] = right_digit; 16 | ++i; 17 | value /= 10; 18 | }while(value); 19 | 20 | --i; 21 | 22 | while(i >= 0){ 23 | string[j] = intString[i] + '0'; 24 | ++j; 25 | --i; 26 | } 27 | 28 | string[j] = '\0'; 29 | } 30 | 31 | int main(void) 32 | { 33 | void intToStr(int value,char string[]); 34 | 35 | char text1[8]; 36 | char text2[8]; 37 | intToStr(123,text1); 38 | intToStr(-123,text2); 39 | printf("%s\n",text1); 40 | printf("%s\n",text2); 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /chapter10/exce2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter10/exce2 -------------------------------------------------------------------------------- /chapter10/exce2.c: -------------------------------------------------------------------------------- 1 | // prog104的另一结果 2 | // 检验字符串是否相等的函数 3 | #include 4 | #include 5 | 6 | bool equalStrings(const char s1[], const char s2[]){ 7 | int i = 0; 8 | bool areEqual; 9 | 10 | // 原while语句: while(s1[i] == s2 [i] && s1[i] != '\0' && s2[i] != '\0') 11 | // 为什么结果一致? 12 | while(s1[i] == s2 [i] && s1[i] != '\0') 13 | ++i; 14 | 15 | if(s1[i] == '\0' && s2[i] == '\0') 16 | areEqual = true; 17 | else 18 | areEqual = false; 19 | 20 | return areEqual; 21 | } 22 | 23 | int main(void){ 24 | bool equalStrings(const char s1[], const char s2[]); 25 | const char stra[] = "string compare test"; 26 | const char strb[] = "string"; 27 | 28 | printf("%i\n", equalStrings(stra, strb)); 29 | printf("%i\n", equalStrings(stra, stra)); 30 | printf("%i\n", equalStrings(strb, "string")); 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /chapter10/exce3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter10/exce3 -------------------------------------------------------------------------------- /chapter10/exce3.c: -------------------------------------------------------------------------------- 1 | // 修正将包含(')的单词作为两个单词处理,并且使之能够处理正负号开头的、并包含逗号的数字 2 | // 计算一段文本的单词数目的函数 3 | #include 4 | #include 5 | 6 | // 判断一个字符是否是字母的函数 7 | bool alphabetic(const char c){ 8 | if( (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ) 9 | return true; 10 | else 11 | return false; 12 | } 13 | 14 | bool numeric(const char c){ 15 | if(c >= '0' && c <= '9') 16 | return true; 17 | else 18 | return false; 19 | } 20 | 21 | // 从终端读取一行文字的函数 22 | void readLine (char buffer[]){ 23 | char character; 24 | int i = 0; 25 | 26 | do{ 27 | character = getchar(); 28 | buffer[i] = character; 29 | ++i; 30 | }while(character != '\n'); 31 | 32 | buffer[i - 1] = '\0'; 33 | } 34 | 35 | // 计算一个字符串中单词数的函数 36 | int countWords(const char string[]){ 37 | int i, wordCount = 0; 38 | bool lookingForWord = true, alphabetic(const char c); 39 | bool numeric(const char c); 40 | 41 | for(i = 0; string[i] != '\0'; ++i){ 42 | if(alphabetic(string[i]) || numeric(string[i])){ 43 | if(lookingForWord){ 44 | ++wordCount; 45 | lookingForWord = false; 46 | } 47 | } 48 | else if(string[i] == ',' || string[i] == '\'' || string[i] == '-') 49 | continue; 50 | else 51 | lookingForWord = true; 52 | } 53 | 54 | return wordCount; 55 | } 56 | 57 | int main(void){ 58 | int countWords(const char string[]); 59 | 60 | const char text1[] = "-$20,000."; 61 | const char text2[] = "And here we go... again."; 62 | char i = '$'; 63 | 64 | printf("%s - words = %i\n",text1,countWords(text1)); 65 | printf("%s - words = %i\n",text2,countWords(text2)); 66 | printf("%i - $", i); 67 | 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /chapter10/exce4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter10/exce4 -------------------------------------------------------------------------------- /chapter10/exce4.c: -------------------------------------------------------------------------------- 1 | // 编写substring函数,从字符串中裁剪出特定的部分 2 | #include 3 | 4 | void substring(const char source[81], int start, int count, char result[81]){ 5 | int i; 6 | for(i = 0; i < count && source[i] != '\0'; ++i) 7 | result[i] = source[i + start]; 8 | result[i] = '\0'; 9 | 10 | printf("The new string is %s.\n", result); 11 | } 12 | 13 | int main(void){ 14 | void substring(const char source[81], int start, int count, char result[81]); 15 | char result[81]; 16 | 17 | substring("character", 4, 3, result); 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /chapter10/exce5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter10/exce5 -------------------------------------------------------------------------------- /chapter10/exce5.c: -------------------------------------------------------------------------------- 1 | // 编写findString函数,检查一个字符串是否包含另外一个字符串,失败 2 | #include 3 | 4 | int findString(const char source[], const char search[]){ 5 | int i, j; 6 | 7 | for(i = 0; source[i] != '\0'; ++i){ 8 | for(j = 0; search[j] != '\0'; ++j) 9 | if(source[i + j] == search[j]) 10 | return i; 11 | } 12 | 13 | return -1; 14 | } 15 | 16 | int main(void){ 17 | int findString(const char source[], const char search[]); 18 | 19 | printf("%i", findString("a chatterbox", "hoat")); 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /chapter10/exce5a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter10/exce5a -------------------------------------------------------------------------------- /chapter10/exce5a.c: -------------------------------------------------------------------------------- 1 | // 编写findString函数,检查一个字符串是否包含另外一个字符串 2 | #include 3 | 4 | int findString(const char source[],const char destination[]){ 5 | int i,j; 6 | 7 | for(i = 0; source[i] != '\0'; ++i){ 8 | j = 0; 9 | while(source[i+j] == destination[j] && destination[j] != '\0') 10 | ++j; 11 | if(destination[j] == '\0') 12 | return i; 13 | } 14 | 15 | return -1; 16 | } 17 | 18 | int main(void){ 19 | int findString(const char source[], const char search[]); 20 | 21 | printf("%i", findString("a chatterbox", "hoat")); 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /chapter10/exce6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter10/exce6 -------------------------------------------------------------------------------- /chapter10/exce6.c: -------------------------------------------------------------------------------- 1 | // 编写removeString函数,从一个字符串中删除一定数量的字符 2 | #include 3 | 4 | void removeString(char source[], int start, int counts){ 5 | int i; 6 | 7 | for(i = 0; source[start + counts +i] != '\0'; ++i) 8 | source[start + i] = source[start + counts + i]; 9 | 10 | source[start + i] = '\0'; 11 | } 12 | 13 | int main(void){ 14 | void removeString(char source[], int start, int counts); 15 | char text[] = "the wrong son"; 16 | 17 | removeString(text, 4, 6); 18 | 19 | printf("%s", text); 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /chapter10/exce7: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter10/exce7 -------------------------------------------------------------------------------- /chapter10/exce7.c: -------------------------------------------------------------------------------- 1 | // 编写insertString函数,将某个字符串插入到另外一个字符串中 2 | #include 3 | 4 | void insertString(char source[], const char insertChars[], int start){ 5 | int i, j; 6 | char result[81]; 7 | 8 | for(i = 0; i < start; ++i) 9 | result[i] = source[i]; 10 | for(i = 0; insertChars[i] != '\0'; ++i) 11 | result[start + i] = insertChars[i]; 12 | for(j = 0; source[j] != '\0'; ++j) 13 | result[start + i +j] = source[start + j]; 14 | 15 | result[start + i + j] = '\0'; 16 | 17 | for(j = 0; result[j] != '\0'; ++j) 18 | source[j] = result[j]; 19 | source[j] = '\0'; 20 | } 21 | 22 | int main(void){ 23 | void insertString(char source[], const char insertChars[], int start); 24 | char text[] = "the wrong son"; 25 | 26 | insertString(text, "per", 10); 27 | printf("%s", text); 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /chapter10/exce8: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter10/exce8 -------------------------------------------------------------------------------- /chapter10/exce8.c: -------------------------------------------------------------------------------- 1 | // 编写replaceString函数,将findString,removeString和insertString这三个函数组合起来 2 | #include 3 | #include 4 | 5 | int findString(const char source[],const char destination[]){ 6 | int i,j; 7 | 8 | for(i = 0; source[i] != '\0'; ++i){ 9 | j = 0; 10 | while(source[i+j] == destination[j] && destination[j] != '\0') 11 | ++j; 12 | if(destination[j] == '\0') 13 | return i; 14 | } 15 | 16 | return -1; 17 | } 18 | 19 | void removeString(char source[], int start, int counts){ 20 | int i; 21 | 22 | if(counts < 0 || start == -1) 23 | return; 24 | 25 | for(i = 0; source[start + counts +i] != '\0'; ++i) 26 | source[start + i] = source[start + counts + i]; 27 | 28 | source[start + i] = '\0'; 29 | } 30 | 31 | void insertString(char source[], const char insertChars[], int start){ 32 | int i, j; 33 | char result[81]; 34 | 35 | if(start == -1) 36 | return; 37 | 38 | for(i = 0; i < start; ++i) 39 | result[i] = source[i]; 40 | for(i = 0; insertChars[i] != '\0'; ++i) 41 | result[start + i] = insertChars[i]; 42 | for(j = 0; source[j] != '\0'; ++j) 43 | result[start + i +j] = source[start + j]; 44 | 45 | result[start + i + j] = '\0'; 46 | 47 | for(j = 0; result[j] != '\0'; ++j) 48 | source[j] = result[j]; 49 | source[j] = '\0'; 50 | } 51 | 52 | void replaceString(char source[], const char s1[], const char s2[]){ 53 | int findString(const char source[],const char destination[]); 54 | void removeString(char source[], int start, int counts); 55 | void insertString(char source[], const char insertChars[], int start); 56 | int start; 57 | 58 | start = findString(source, s1); 59 | 60 | removeString(source, start, strlen(s1)); 61 | 62 | insertString(source, s2, start); 63 | 64 | printf("%s", source); 65 | } 66 | 67 | int main(void){ 68 | void replaceString(char source[], const char s1[], const char s2[]); 69 | char text1[] = "the wrong person"; 70 | char text2[] = "per"; 71 | char text3[] = ""; 72 | 73 | replaceString(text1, text2, text3); 74 | 75 | return 0; 76 | } 77 | -------------------------------------------------------------------------------- /chapter10/exce8a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter10/exce8a -------------------------------------------------------------------------------- /chapter10/exce8a.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int findString(const char source[],const char destination[]) 5 | { 6 | int i,j; 7 | 8 | for(i = 0; source[i] != '\0'; ++i){ 9 | j = 0; 10 | 11 | while(source[i+j] == destination[j] && destination[j] != '\0') 12 | ++j; 13 | 14 | if(destination[j] == '\0') 15 | return i; 16 | } 17 | 18 | return -1; 19 | } 20 | 21 | void removeString(char source[],int start,int count) 22 | { 23 | int i; 24 | 25 | if(count <= 0 || start+count > strlen(source)) 26 | return; 27 | 28 | for(i = 0; source[start+count+i] != '\0'; ++i){ 29 | source[start+i] = source[start+count+i]; 30 | } 31 | 32 | source[start+i] = '\0'; 33 | } 34 | 35 | void insertString(char source[],char insert[],int start) 36 | { 37 | int i,j; 38 | int len1 = strlen(source); 39 | int len2 = strlen(insert); 40 | char *newString = (char *)malloc((len1+len2+1) * sizeof(char)); 41 | 42 | if(start < 0 || start > len1) 43 | return; 44 | 45 | for(i = 0; i < start; ++i) 46 | newString[i] = source[i]; 47 | for(j = 0; insert[j] != '\0'; ++j) 48 | newString[i+j] = insert[j]; 49 | for(; source[i] != '\0'; ++i) 50 | newString[i+j] = source[i]; 51 | 52 | newString[i+j] = '\0'; 53 | 54 | for(i = 0; newString[i] != '\0'; ++i) 55 | source[i] = newString[i]; 56 | 57 | source[i] = '\0'; 58 | free(newString); 59 | } 60 | 61 | void replaceString(char source[],char s1[],char s2[]) 62 | { 63 | int findString(const char source[],const char destination[]); 64 | void removeString(char source[],int start,int count); 65 | void insertString(char source[],char insert[],int start); 66 | 67 | int start = findString(source,s1); 68 | 69 | if(-1 == start) 70 | return; 71 | 72 | removeString(source,start,strlen(s1)); 73 | insertString(source,s2,start); 74 | } 75 | 76 | int main(void) 77 | { 78 | void replaceString(char source[],char s1[],char s2[]); 79 | 80 | char text[50] = "the wrong son"; 81 | //replaceString(text,"son","man"); 82 | //replaceString(text,"wrong","right"); 83 | replaceString(text,"sonb","man"); 84 | printf("%s\n",text); 85 | 86 | return 0; 87 | } 88 | -------------------------------------------------------------------------------- /chapter10/exce9: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter10/exce9 -------------------------------------------------------------------------------- /chapter10/exce9.c: -------------------------------------------------------------------------------- 1 | // 改进replaceString函数,删除字符串中所有的指定字符 2 | #include 3 | #include 4 | #include 5 | 6 | int findString(const char source[],const char destination[]){ 7 | int i,j; 8 | 9 | for(i = 0; source[i] != '\0'; ++i){ 10 | j = 0; 11 | while(source[i+j] == destination[j] && destination[j] != '\0') 12 | ++j; 13 | if(destination[j] == '\0') 14 | return i; 15 | } 16 | 17 | return -1; 18 | } 19 | 20 | void removeString(char source[], int start, int counts){ 21 | int i; 22 | 23 | if(counts < 0 || start == -1) 24 | return; 25 | 26 | for(i = 0; source[start + counts +i] != '\0'; ++i) 27 | source[start + i] = source[start + counts + i]; 28 | 29 | source[start + i] = '\0'; 30 | } 31 | 32 | void insertString(char source[], const char insertChars[], int start){ 33 | int i, j; 34 | char result[81]; 35 | 36 | if(start == -1) 37 | return; 38 | 39 | for(i = 0; i < start; ++i) 40 | result[i] = source[i]; 41 | for(i = 0; insertChars[i] != '\0'; ++i) 42 | result[start + i] = insertChars[i]; 43 | for(j = 0; source[j] != '\0'; ++j) 44 | result[start + i +j] = source[start + j]; 45 | 46 | result[start + i + j] = '\0'; 47 | 48 | for(j = 0; result[j] != '\0'; ++j) 49 | source[j] = result[j]; 50 | source[j] = '\0'; 51 | } 52 | 53 | bool replaceString(char source[], const char s1[], const char s2[]){ 54 | int findString(const char source[],const char destination[]); 55 | void removeString(char source[], int start, int counts); 56 | void insertString(char source[], const char insertChars[], int start); 57 | int start; 58 | 59 | start = findString(source, s1); 60 | 61 | if(start == -1) 62 | return false; 63 | else{ 64 | removeString(source, start, strlen(s1)); 65 | insertString(source, s2, start); 66 | 67 | return true; 68 | } 69 | } 70 | 71 | int main(void){ 72 | bool replaceString(char source[], const char s1[], const char s2[]); 73 | bool stillFound; 74 | char text1[] = "the wrong person"; 75 | char text2[] = "e"; 76 | char text3[] = ""; 77 | 78 | do 79 | stillFound = replaceString(text1, text2, text3); 80 | while(stillFound == true); 81 | 82 | printf("%s", text1); 83 | 84 | return 0; 85 | } 86 | -------------------------------------------------------------------------------- /chapter10/prog101: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter10/prog101 -------------------------------------------------------------------------------- /chapter10/prog101.c: -------------------------------------------------------------------------------- 1 | // 合并字符数组 2 | #include 3 | 4 | void concat (char result[], const char str1[], int n1, const char str2[], int n2){ 5 | int i, j; 6 | 7 | // 复制str1到result 8 | for(i = 0; i < n1; ++i) 9 | result[i] = str1[i]; 10 | 11 | // 复制str2到result 12 | for(j = 0; j < n2; ++j) 13 | result[n1 + j] = str2[j]; 14 | } 15 | 16 | int main(void){ 17 | void concat(char result[], const char str1[], int n1, const char str2[], int n2); 18 | const char s1[5] = {'T','e','s','t',' '}; 19 | const char s2[6] = {'w','o','r','k','s','.'}; 20 | char s3[11]; 21 | int i; 22 | 23 | concat(s3, s1, 5, s2, 6); 24 | 25 | for(i = 0; i < 11; ++i) 26 | printf("%c", s3[i]); 27 | printf("\n"); 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /chapter10/prog1010: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter10/prog1010 -------------------------------------------------------------------------------- /chapter10/prog1010.c: -------------------------------------------------------------------------------- 1 | // 使用二分查找法修正字典查找程序 2 | #include 3 | 4 | struct entry{ 5 | char word[15]; 6 | char definition[50]; 7 | }; 8 | 9 | // 比较两个字符串的函数 10 | int compareStrings(const char s1[], const char s2[]){ 11 | int i = 0, answer; 12 | 13 | while(s1[i] == s2[i] && s1[i] != '\0' && s2[i] != '\0') 14 | ++i; 15 | if(s1[i] < s2[i]) 16 | answer = -1; 17 | else if(s1[i] == s2[i]) 18 | answer = 0; 19 | else answer = 1; 20 | 21 | return answer; 22 | } 23 | 24 | // 在字典中查找单词的函数 25 | int lookup(const struct entry dictionary[], const char search[], const int entries){ 26 | int low = 0; 27 | int high = entries - 1; 28 | int mid, result; 29 | int compareStrings(const char s1[], const char s2[]); 30 | 31 | while(low <= high){ 32 | mid = (low + high) / 2; 33 | result = compareStrings(dictionary[mid].word, search); 34 | 35 | if(result == -1) 36 | low = mid + 1; 37 | else if(result == 1) 38 | high = mid - 1; 39 | else 40 | return mid; /*查找到*/ 41 | } 42 | return -1; /*未找到*/ 43 | } 44 | 45 | int main(void){ 46 | const struct entry dictionary[100] = { 47 | {"aardvark", "a burrowing African mamal"}, 48 | {"abyss", "a bottomless pit"}, 49 | {"acumen", "mentally sharp; keen"}, 50 | {"addle", "to become confused"}, 51 | {"aerie", "a high nest"}, 52 | {"affix", "to append; attach"}, 53 | {"agar", "a jelly made from seaweed"}, 54 | {"ahoy", "a nautical call of greeting"}, 55 | {"aigrette", "an ornamental cluster of feathers"}, 56 | {"ajar", "partially opened"}, 57 | }; 58 | 59 | int entries = 10; 60 | char word[15]; 61 | int entry; 62 | int lookup (const struct entry dictionary[], const char search[], const int entries); 63 | 64 | printf("Enter word: "); 65 | scanf("%14s", word); 66 | 67 | entry = lookup(dictionary, word, entries); 68 | 69 | if(entry != -1) 70 | printf("%s\n", dictionary[entry].definition); 71 | else 72 | printf("Sorry, the word %s is not in my dictionary.\n", word); 73 | 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /chapter10/prog1011: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter10/prog1011 -------------------------------------------------------------------------------- /chapter10/prog1011.c: -------------------------------------------------------------------------------- 1 | // 将字符串转换为对应整数的函数 2 | #include 3 | 4 | int strToInt(const char string[]){ 5 | int i, intValue, result = 0; 6 | 7 | for(i = 0; string[i] >= '0' && string[i] <= '9'; ++i){ 8 | intValue = string[i] - '0'; 9 | result = result * 10 + intValue; 10 | } 11 | 12 | return result; 13 | } 14 | 15 | int main(void){ 16 | int strToInt(const char string[]); 17 | 18 | printf("%i\n", strToInt("245")); 19 | printf("%i\n", strToInt("100") + 25); 20 | printf("%i\n", strToInt("13x5")); 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /chapter10/prog102: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter10/prog102 -------------------------------------------------------------------------------- /chapter10/prog102.c: -------------------------------------------------------------------------------- 1 | // 计算字符串中的字符个数的函数 2 | #include 3 | 4 | int stringLength(const char string[]){ 5 | int count = 0; 6 | 7 | while(string[count] != '\0') 8 | ++count; 9 | 10 | return count; 11 | } 12 | 13 | int main(void){ 14 | int stringLength(const char string[]); 15 | const char word1[] = {'a', 's', 't', 'e', 'r', '\0'}; 16 | const char word2[] = {'a', 't', '\0'}; 17 | const char word3[] = {'a', 'w', 'e', '\0'}; 18 | 19 | printf("%i %i %i\n", stringLength(word1), 20 | stringLength(word2), stringLength(word3)); 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /chapter10/prog103: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter10/prog103 -------------------------------------------------------------------------------- /chapter10/prog103.c: -------------------------------------------------------------------------------- 1 | // 连接字符串,使用'\0' 2 | #include 3 | 4 | int main(void){ 5 | void concat(char result[], const char str1[], const char str2[]); 6 | const char s1[] = {"Test "}; 7 | const char s2[] = {"works."}; 8 | char s3[20]; 9 | 10 | concat(s3, s1, s2); 11 | 12 | printf("%s\n", s3); 13 | return 0; 14 | } 15 | 16 | // 连接两个字符串的函数 17 | void concat(char result[], const char str1[], const char str2[]){ 18 | int i, j; 19 | 20 | // 复制str1到result 21 | for(i = 0; str1[i] != '\0'; ++i) 22 | result[i] = str1[i]; 23 | 24 | // 复制str2到result 25 | for(j = 0; str2[j] != '\0'; ++j) 26 | result[i + j] = str2[j]; 27 | 28 | // 使用null字符作为连接字符串的结尾 29 | result[i + j] = '\0'; 30 | } 31 | -------------------------------------------------------------------------------- /chapter10/prog104: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter10/prog104 -------------------------------------------------------------------------------- /chapter10/prog104.c: -------------------------------------------------------------------------------- 1 | // 检验字符串是否相等的函数 2 | #include 3 | #include 4 | 5 | bool equalStrings(const char s1[], const char s2[]){ 6 | int i = 0; 7 | bool areEqual; 8 | 9 | while(s1[i] == s2 [i] && s1[i] != '\0' && s2[i] != '\0') 10 | ++i; 11 | 12 | if(s1[i] == '\0' && s2[i] == '\0') 13 | areEqual = true; 14 | else 15 | areEqual = false; 16 | 17 | return areEqual; 18 | } 19 | 20 | int main(void){ 21 | bool equalStrings(const char s1[], const char s2[]); 22 | const char stra[] = "string compare test"; 23 | const char strb[] = "string"; 24 | 25 | printf("%i\n", equalStrings(stra, strb)); 26 | printf("%i\n", equalStrings(stra, stra)); 27 | printf("%i\n", equalStrings(strb, "string")); 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /chapter10/prog105: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter10/prog105 -------------------------------------------------------------------------------- /chapter10/prog105.c: -------------------------------------------------------------------------------- 1 | // 使用scanf函数读取字符串的函数 2 | #include 3 | 4 | int main(void){ 5 | char s1[81], s2[81], s3[81]; 6 | 7 | printf("Enter text:\n"); 8 | 9 | scanf("%s%s%s", s1, s2, s3); 10 | 11 | printf("\ns1 = %s\ns2 = %s\ns3 = %s\n", s1, s2, s3); 12 | 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /chapter10/prog106: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter10/prog106 -------------------------------------------------------------------------------- /chapter10/prog106.c: -------------------------------------------------------------------------------- 1 | // 读取一行数据的函数 2 | #include 3 | 4 | int main(void) { 5 | int i; 6 | char line[81]; 7 | void readLine(char buffer[]); 8 | 9 | for(i = 0; i < 3; ++i){ 10 | readLine(line); 11 | printf("%s\n\n", line); 12 | } 13 | 14 | return 0; 15 | } 16 | 17 | // 从终端读取一行文字的函数 18 | void readLine (char buffer[]){ 19 | char character; 20 | int i = 0; 21 | 22 | do{ 23 | character = getchar(); 24 | buffer[i] = character; 25 | ++i; 26 | }while(character != '\n'); 27 | 28 | // 循环最后一次执行的时候,循环变量已经增加过了。 29 | buffer[i - 1] = '\0'; 30 | } 31 | -------------------------------------------------------------------------------- /chapter10/prog107: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter10/prog107 -------------------------------------------------------------------------------- /chapter10/prog107.c: -------------------------------------------------------------------------------- 1 | // 判断一个字符是否为字母的函数 2 | #include 3 | #include 4 | 5 | bool alphabetic(const char c){ 6 | if( (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) 7 | return true; 8 | else 9 | return false; 10 | } 11 | 12 | /*计算一个字符串中单词数的函数*/ 13 | int countWords(const char string[]){ 14 | int i, wordCount = 0; 15 | // lookinfForWord,标志位,表示当前程序是否正在查找一个新词的开始字母。 16 | bool lookingForWord = true, alphabetic(const char c); 17 | 18 | for(i = 0; string[i] != '\0'; ++i){ 19 | if(alphabetic(string[i])){ 20 | if(lookingForWord){ 21 | ++wordCount; 22 | // 扫描到首字母计数器加1后,标志位设置为false, 23 | // 不进行任何处理,对字符串字母的循环继续遍历 24 | lookingForWord = false; 25 | } 26 | } 27 | // 遍历到空格或其他情况时,标志位设置为true,开始扫描新字符串 28 | else 29 | lookingForWord = true; 30 | } 31 | return wordCount; 32 | } 33 | 34 | int main(void){ 35 | const char text1[] = "Well, here goes."; 36 | const char text2[] = "And here we go... again."; 37 | int countWords(const char string[]); 38 | 39 | printf("%s - words = %i\n", text1, countWords(text1)); 40 | printf("%s - words = %i\n", text2, countWords(text2)); 41 | 42 | return 0; 43 | 44 | } 45 | -------------------------------------------------------------------------------- /chapter10/prog108: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter10/prog108 -------------------------------------------------------------------------------- /chapter10/prog108.c: -------------------------------------------------------------------------------- 1 | // 计算一段文本的单词数目的函数 2 | #include 3 | #include 4 | 5 | // 判断一个字符是否是字母的函数 6 | bool alphabetic(const char c){ 7 | if( (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) 8 | return true; 9 | else 10 | return false; 11 | } 12 | 13 | // 从终端读取一行文字的函数 14 | void readLine (char buffer[]){ 15 | char character; 16 | int i = 0; 17 | 18 | do{ 19 | character = getchar(); 20 | buffer[i] = character; 21 | ++i; 22 | }while(character != '\n'); 23 | 24 | buffer[i - 1] = '\0'; 25 | } 26 | 27 | // 计算一个字符串中单词数的函数 28 | int countWords(const char string[]){ 29 | int i, wordCount = 0; 30 | bool lookingForWord = true, alphabetic(const char c); 31 | 32 | for(i = 0; string[i] != '\0'; ++i){ 33 | if(alphabetic(string[i])){ 34 | if(lookingForWord){ 35 | ++wordCount; 36 | lookingForWord = false; 37 | } 38 | } 39 | else 40 | lookingForWord = true; 41 | } 42 | 43 | return wordCount; 44 | } 45 | 46 | // 用户输入最后一行文字以后,再额外多输入一个空行 47 | // readLine函数读取到该空行时,程序将再用作缓冲区的数组的第一个位置上存储一个空字符 48 | // 缓冲区的数组的第一个位置不是已经存放字符了么?空字符不会覆盖它? 49 | int main(void){ 50 | char text[81]; 51 | int totalWords = 0; 52 | int countWords(const char string[]); 53 | void readLine(char buffer[]); 54 | bool endOfText = false; 55 | 56 | printf("Type in your text.\n"); 57 | printf("When you are done, press 'RETURN'.\n\n"); 58 | 59 | while(! endOfText){ 60 | readLine(text); 61 | if(text[0] == '\0') 62 | endOfText = true; 63 | else 64 | totalWords += countWords(text); 65 | } 66 | printf("\nThere are %i words in the above text.\n", totalWords); 67 | 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /chapter10/prog109: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter10/prog109 -------------------------------------------------------------------------------- /chapter10/prog109.c: -------------------------------------------------------------------------------- 1 | // 字典查找的函数 2 | #include 3 | #include 4 | 5 | // 词条的结构 6 | struct entry{ 7 | char word[15]; 8 | char definition[50]; 9 | }; 10 | 11 | // 判断字符串是否相等的函数 12 | bool equalStrings(const char s1[], const char s2[]){ 13 | int i = 0; 14 | bool areEqual; 15 | 16 | while(s1[i] == s2 [i] && s1[i] != '\0' && s2[i] != '\0') 17 | ++i; 18 | 19 | if(s1[i] == '\0' && s2[i] == '\0') 20 | areEqual = true; 21 | else 22 | areEqual = false; 23 | 24 | return areEqual; 25 | } 26 | 27 | // 在字典中查找单词的函数 28 | int lookup (const struct entry dictionary[], const char search[], const int entries){ 29 | int i; 30 | bool equalStrings(const char s1[], const char s2[]); 31 | 32 | for(i = 0; i < entries; ++i) 33 | if(equalStrings(search, dictionary[i].word)) 34 | return i; 35 | 36 | return -1; 37 | } 38 | 39 | int main(void){ 40 | const struct entry dictionary[100] = { 41 | {"aardvark", "a burrowing African mamal"}, 42 | {"abyss", "a bottomless pit"}, 43 | {"acumen", "mentally sharp; keen"}, 44 | {"addle", "to become confused"}, 45 | {"aerie", "a high nest"}, 46 | {"affix", "to append; attach"}, 47 | {"agar", "a jelly made from seaweed"}, 48 | {"ahoy", "a nautical call of greeting"}, 49 | {"aigrette", "an ornamental cluster of feathers"}, 50 | {"ajar", "partially opened"}, 51 | }; 52 | 53 | char word[10]; 54 | int entries = 10; 55 | int entry; 56 | int lookup (const struct entry dictionary[], const char search[], const int entries); 57 | 58 | printf("Enter word: "); 59 | scanf("%14s", word); 60 | entry = lookup(dictionary, word, entries); 61 | 62 | if(entry != -1) 63 | printf("%s\n", dictionary[entry].definition); 64 | 65 | else 66 | printf("Sorry, the word %s is not in my dictionary.\n", word); 67 | 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /chapter11/Pointers.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: C语言编程--指针 4 | --- 5 | 6 | ##间接 7 | 指针提供了一个间接的方法来存取一个特定数据项中的数值。 8 | 9 | ##定义指针变量 10 | 定义如下的一个变量: 11 | `int count = 10;` 12 | 定义另一个变量,可以使用它以间接的方式来存取count的值: 13 | `int *int_pointer;` 14 | 在C语言中,以上语句中的*代表int_pointer是一个整型指针变量。这样,程序就可以用int_pointer来间接地存取一个或多个整型数值。 15 | 16 | &操作符为地址运算符, 在C语言中用于生成指向某个目标的指针。 17 | 若x是一个特定类型的变量,则表达式&x就是这个变量的指针。 18 | 表达式&x可以被赋予任何一个指针变量,只要它被声明为和x的类型相同的指针。 19 | 用如下语句建立int_pointer和count之间的间接引用关系。 20 | `int_pointer = &count;` 21 | 上面的表达式将一个指向变量count的指针,而不是变量count的值赋予变量int_pointer。 22 | 23 | 为了获取指针变量int_pointer指向的变量count所包含的内容,可以使用*操作符,即指针运算符。如果定义x为整型变量,则以下语句: 24 | `x = *int_pointer;` 25 | 将int_pointer通过间接关系所指向的值赋予变量x。因为int_pointer先前被设为指向count,所以这个语句将包含在变量count的值10,赋予变量x。 26 | 27 | 28 | ##在表达式中运用指针 29 | `int i1 = 5, i2, *p1, *p2;` 30 | `p1 = &i1;` 31 | `i2 = *p1 / 2 + 10;` 32 | `p2 = p1;` 33 | 结果为: 34 | `i1 = 5, i2 = 12, *p1 = 5, *p2 = 5;` 35 | 如果一个指针px指向一个变量x,且px被定义为和x相同类型的指针,那么表达式中*px的用法等同于x。 36 | 37 | ##使用指针和结构 38 | 定义一个如下的数据结构: 39 | 40 | struct date{ 41 | int month; 42 | int day; 43 | int year; 44 | }; 45 | 46 | 定义一个结构变量: 47 | `Struct date todaysDate;` 48 | 定义一个指向结构的指针: 49 | `Struct date *datePtr;` 50 | 使该指针指向todaysDate: 51 | `datePtr = &todaysDate;` 52 | 存取结构中的一个成员: 53 | `(*datePtr).day = 21;` 54 | 结构指针运算符:->,即(*x).y可以表示为x->y. 55 | 56 | ###包含指针的结构 57 | 定义一个结构intPtrs,包含三个整型指针。 58 | 59 | struct intPtrs{ 60 | int *p1; 61 | int *p2; 62 | int *p3; 63 | }; 64 | 65 | 定义一个结构类型的变量intPtrs: 66 | `struct intPtrs pointers;` 67 | 将该变量内的p2指针指向的整型数的值设为-97: 68 | `*pinters.p2 = -97;` 69 | 70 | ###链表 71 | 定义一个如下结构: 72 | 73 | struct entry{ 74 | int value; 75 | struct entry *next; 76 | }; 77 | 78 | 创建一个链表: 79 | int main(void){ 80 | struct entry n1, n2, n3; 81 | struct entry *list_pointer = &n1; // 显示链表的头指针 82 | 83 | n1.value = 100; 84 | n1.next = &n2; 85 | 86 | n2.value = 200; 87 | n2.next = &n3; 88 | 89 | n3.value = 300; 90 | n3.next = (struct entry *) 0; // 用空指针来标识链表的表尾 91 | 92 | while(list_pointer != (struct entry *) 0){ 93 | printf("%i\n", list_pointer->value); 94 | list_pointer = list_pointer->next;; 95 | } 96 | 97 | return 0; 98 | } 99 | 100 | ##关键字const和指针 101 | 假定有如下声明: 102 | `char c = 'x'` 103 | `char *charPtr = &c;` 104 | 指针变量charPtr被设为指向变量c,如果它总是指向c,则可被声明为一个指针常量如下: 105 | `char * const charPtr = &c;` 106 | (读法为“charPtr是一个指向字符的指针常量”)因此,类似的下面的一个语句: 107 | `charPtr = &d; // 不是有效的,即该指针不会指向其他变量` 108 | 109 | 如果charPtr指向的位置的值不会通过使用指针变量charPtr被改变,则可使用如下声明: 110 | `const char *charPtr = &c;` 111 | (读法为“charPtr指向一个字符常量”)因此,类似下面的语句: 112 | `*charPtr = 'Y'; // 不是有效的,即该指针指向的变量值不能通过指针来改变` 113 | 114 | 在指针变量和它所指向的单元都不改变的情况下,可应用下面的声明: 115 | `const char * const *charPtr = &c;` 116 | 第一个const表明指针指向的单元的内容不会被改变,第二个const表明指针本身不会被改变。 117 | 118 | ##指针和函数 119 | 1.将指针作为参数传递给函数: 120 | 121 | void print_list(struct entry *pointer){ 122 | ... 123 | } 124 | 125 | 接下来接可以将形式参数pointer当作一个正常的指针变量使用了。 126 | 在调用函数时,指针的值将被复制到形式参数中。 127 | 尽管函数不能改变指针参数,但却可以改变指针指向的数据元素: 128 | 129 | void exchange(int * const pint1, int * const pint2){ 130 | int temp; 131 | 132 | temp = *pint1; 133 | *pint1 = *pint2; 134 | *pint2 = temp; 135 | } 136 | 137 | int main(void){ 138 | void exchange(int * const pint1, int * const pint2); 139 | int i1 = -5, i2 = 66, *p1 = &i1, *p2 = &i2; 140 | 141 | printf("i1 = %i, i2 = %i\n", i1, i2); // -5, 66 142 | 143 | exchange(p1, p2); 144 | printf("i1 = %i, i2 = %i\n", i1, i2); // 66, -5 145 | 146 | exchange(&i1, &i2); 147 | printf("i1 = %i, i2 = %i\n", i1, i2); // -5, 66 148 | 149 | return 0; 150 | } 151 | 152 | 函数exchange的功能时交换由它的两个指针参数(const)所指向的整型变量的值。 153 | 若是不用指针,我们就无法写出exchange函数来交换两个整型的值,因为函数被限制为只能返回一个单值,另外函数不能改变它的参数。 154 | 155 | 2.函数返回一个指针 156 | 定义一个函数,查找一个链表以找出给定的值,返回值是一个指向结构entry的指针: 157 | 158 | struct entry *findEntry(struct entry *listPtr, int match){ 159 | while(listPtr != (struct entry *) 0){ 160 | if(listPtr->value == match) 161 | return (listPtr); 162 | else 163 | listPtr = listPtr->next; 164 | } 165 | return (struct entry *) 0; 166 | } 167 | 168 | int main(void){ 169 | struct entry *findEntry(struct entry *listPtr, int match); 170 | struct entry n1, n2, n3; 171 | struct entry *listPtr, *listStart = &n1; 172 | int search; 173 | 174 | n1.value = 100; 175 | n1.next = &n2; 176 | 177 | n2.value = 200; 178 | n2.next = &n3; 179 | 180 | n3.value = 300; 181 | n3.next = 0; 182 | 183 | printf("Enter value to locate: "); 184 | scanf("%i", &search); 185 | 186 | listPtr = findEntry(listStart, search); 187 | 188 | if(listPtr != (struct entry *) 0) 189 | printf("Found %i.\n", listPtr->value); 190 | else 191 | printf("Not found.\n"); 192 | 193 | return 0; 194 | } 195 | 196 | 可以将字典组织成链表,方便插入和删除,缺点是不方便查找,比如无法使用二分查找。 197 | 树可以对元素进行方便的插入和删除,其查找速度也很快。 198 | 199 | ##指针和数组 200 | 如果a是一个元素为x类型的数组,px是x的指针类型,而i和n时整型常量或变量,则语句: 201 | `px = a; // px = &a[0];` 202 | 用来将指针px指向a的第一个元素,表达式: 203 | `*(px + i)` 204 | 用来引用包含在a[i]中的值。进而,语句: 205 | `px += n;` 206 | 用来将px指向数组中的第n号元素,不管数组中的元素到底是那种类型。 207 | 208 | ###关于程序的优化 209 | 通常情况下,(按照顺序)使用下标变量访问数组元素的过程会比使用指针访问花费更多的时间。 210 | 使用指针来存取数组元素的主要原因就是这样产生的代码通常效率更高。 211 | 212 | ###数组还是指针 213 | 如果我们想用下标来引用传递给一个函数的数组元素,需要将相应的形式参数声明为数组。这样就更准确地表明了函数中使用的是数组。如下所示: 214 | `int arraySum(int array[], const int n); ` 215 | 相似的,如果我们将形式参数作为一个指向数组的指针使用,则要将它声明为一个指针类型: 216 | `int arraySum(int *array, const int n); //声明符号array为一个整型指针` 217 | 218 | ###指向字符串的指针 219 | 用指针来编写copyString: 220 | 221 | void copyString(char *to, char *from){ 222 | for(; *from != '\0'; ++from, ++to) 223 | *to = *from; 224 | 225 | *to = '\0'; 226 | } 227 | 228 | int main(void){ 229 | void copyString(char *to, char *from); 230 | char string1[] = "A string to be copied."; 231 | char string2[50]; 232 | 233 | copyString(string2, string1); 234 | printf("%s\n", string2); 235 | 236 | copyString(string2, "So is this."); 237 | printf("%s\n", string2); 238 | 239 | return 0; 240 | } 241 | 242 | ###字符串常量和指针 243 | 如果text是一个字符数组,用下面语句初始化text: 244 | `char text[80] = "This is okay.";` 245 | C语言将这些字符串的字符本身保存在数组array的对应位置。 246 | 247 | 如果text是一个字符指针,用下面语句初始化text: 248 | `char *text = "This is okay.";` 249 | 则将一个指向字符串"This is okey."的指针赋值到text。 250 | 251 | 用如下方法建立一个叫做days的数组,它包含指向一个星期中每一天的名字的字符指针: 252 | `char *days[] = {"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};` 253 | 数组days被定义为包含7个元素,每个元素都是一个指向字符串的指针。于是, 254 | days[0]包含指向字符串"Sunday"的指针,days[1]包含指向字符串"Monday"的指针,等等。 255 | 可以用下面的语句显示一个星期第三天的名字: 256 | `printf("%s\n", days[3]);` 257 | 258 | ###递增和递减运算符 259 | `++i`,++放置在操作数的前面,递增运算符可以看成是“前加”; 260 | `i++`,++放置在操作数的后面,递增运算符可以看成是“后加”; 261 | 前置和后置运算符的差别: 262 | 1. 263 | 假定有两个整型变量i和j,如果我们将i设为0,则下面语句: 264 | `j = ++i;` 265 | 将1赋值给j,而不是0。在前置运算符的情况下,变量的值首先被加1,然后再参加到表达式的求值中。因此前面的表达式中,变量i的值首先由0递增为1,然后其值被赋给j,等价于如下语句: 266 | `++i;` 267 | `j = i;` 268 | 269 | 如果我们在语句中用了“后加”运算符: 270 | `j = i++;` 271 | 则i的值实在先赋值给j之后才递增的。因此前面的表达式中,先将0赋值给j,然后对i进行递增操作,即加1,等价于如下语句: 272 | `j = i;` 273 | `++i;` 274 | 275 | 2. 276 | 另举一个例子。如果i为1,则下面语句: 277 | `x = a[--i];` 278 | 将a[0]的值赋给x。因为,变量i在其值作为下标使用之前,已经进行了递减操作。而语句: 279 | `x = a[i--];` 280 | 将a[1]的值赋给x。因为,变量i在其值作为下标使用过之后,才进行递减操作。 281 | 282 | 3. 283 | 再举一个例子说明前置和后置递增和递减运算符的差别。函数调用: 284 | `printf("%i\n", ++i); // 如果i为100,则printf调用显示101,语句执行完毕i为101` 285 | 在i递增后才将其值传递给printf函数,然而,函数调用: 286 | `printf("%i\n", i++); // 如果i为100,则printf调用显示100,语句执行完毕i为101` 287 | 在将i的值传递给printf函数之后,才对i进行递增操作。 288 | 289 | 4. 290 | 最后一个例子:如果textPtr时一个字符指针,则表达式: 291 | `*(++textPtr)` 292 | 首先递增textPtr,然后取出它所指向的字符。然而,表达式: 293 | `*(textPtr++)` 294 | 在它的值递增之前就取回了textPtr所指向的字符。不管是哪种情况,圆括号都不是必需的,因为*和++运算符具有相同的优先级,而且它们是“自右向左”结合的。 295 | 296 | 在赋值语句里使用后置递增运算符来重写copyString函数: 297 | 298 | // copyString函数的修订版本 299 | #include 300 | void copyString(char *to, char *from){ 301 | // 空字符的值等价于值0 302 | while(*from) 303 | *to++ = *from++; 304 | 305 | *to = '\0'; 306 | } 307 | 308 | int main(void){ 309 | void copyString(char *to, char *from); 310 | char string1[] = "A string to be copied."; 311 | char string2[50]; 312 | 313 | copyString(string2, string1); 314 | printf("%s\n", string2); 315 | 316 | copyString(string2, "So is this."); 317 | printf("%s\n", string2); 318 | 319 | return 0; 320 | } 321 | 322 | ##指针运算 323 | C语言中两个指针减法操作的结果是它们之间所包含元素的个数。 324 | 由两个指针的减操作产生的结果的实际类型时ptrdiff_t,它在标准头函数文件里定义。 325 | 因此,如果a是一个指向任意元素类型的数组,而b时另一个同类型的指针,该指针指向同一数组更远的一个位置,则表达式b-a代表这两个指针之间的元素个数。 326 | 例如,如果p时一个指向数组x的某个元素的指针,则语句: 327 | `n = p - x;` 328 | 将p所指的元素的下标数赋值给变量n(假定n是一个整型变量)。因此,如果p由以下语句设置为指向第100个元素: 329 | `p = &x[99];` 330 | 那么,变量n在前面的减操作完成后值为99. 331 | 指针相加同理? 332 | 333 | ##指向函数的指针 334 | 为了使用指向函数的指针,C语言编译器不仅需要知道指向函数的指针变量,还要知道函数返回值的类型,还包括它的参数的数量和类型。为了声明符号fnPtr为一个“指向一个返回整数且不带任何参数的函数”的指针,我们使用如下声明: 335 | `int (*fnPtr)(void);` 336 | *fnPtr两边的小括号时必需的,否则,因为函数调用运算符()比指针运算符*的优先级高,C语言编译器将会把前面的语句作为一个函数的声明,这个函数叫做fnPtr,它返回一个指向整型数的指针。 337 | 为了将函数指针指向一个指定的函数,我们可以简单地将函数的名字赋值给它。因此如果lookup是一个函数,它返回一个整型,且没有参数,则语句: 338 | `fnPtr = lookup;` 339 | 将一个指向函数的指针存储到函数指针变量fnPtr之中。 340 | 如果需要通过函数指针变量间接调用函数,我们可以在函数指针变量后面加上函数调用操作符--即一对小括号,然后在小括号里列出要传递给函数的参数。例如: 341 | `entry = fnPtr();` 342 | 调用了由fnPtr指向的函数,并存储返回值到变量entry之中。 343 | 344 | 函数指针的一个最常用的用途时将函数作为参数传递给其他函数。例如标准C语言库函数qsort就用到这个特性。 345 | 函数指针的另一个常见应用时用来产生一个派遣表。我们不能将函数存储到一个数组元素中,但是我们可以将函数指针存储到数组中。通过函数指针,我们可以生成一个包含函数指针的表。 346 | 347 | ##指针和内存地址 348 | 在C语言里,当我们对一个变量运用地址运算符时,得到的结果就是这个变量在计算机内存里的实际地址。所以,下面的语句: 349 | `intPtr = &count;` 350 | 将计算机分配给变量count的内存地址赋值给intPtr。因此,如果count存储在地址0x8868,包含了一个值为10,则这个语句将值0x8868赋予intPtr. 351 | 用对一个指针变量运用指针运算符,如下表达式所示: 352 | `*intPtr` 353 | 则告诉计算机,将包含在指针变量的值看作是一个内存地址。于是计算机取出内存地址里存储的值,并根据指针变量的类型对该值作出解释。 354 | -------------------------------------------------------------------------------- /chapter11/Pointers.md~: -------------------------------------------------------------------------------- 1 | ##间接 2 | 指针提供了一个间接的方法来存取一个特定数据项中的数值。 3 | 4 | ##定义指针变量 5 | 定义如下的一个变量: 6 | `int count = 10;` 7 | 定义另一个变量,可以使用它以间接的方式来存取count的值: 8 | `int *int_pointer;` 9 | 在C语言中,以上语句中的*代表int_pointer是一个整型指针变量。这样,程序就可以用int_pointer来间接地存取一个或多个整型数值。 10 | 11 | &操作符为地址运算符, 在C语言中用于生成指向某个目标的指针。 12 | 若x是一个特定类型的变量,则表达式&x就是这个变量的指针。 13 | 表达式&x可以被赋予任何一个指针变量,只要它被声明为和x的类型相同的指针。 14 | 用如下语句建立int_pointer和count之间的间接引用关系。 15 | `int_pointer = &count;` 16 | 上面的表达式将一个指向变量count的指针,而不是变量count的值赋予变量int_pointer。 17 | 18 | 为了获取指针变量int_pointer指向的变量count所包含的内容,可以使用*操作符,即指针运算符。如果定义x为整型变量,则以下语句: 19 | `x = *int_pointer;` 20 | 将int_pointer通过间接关系所指向的值赋予变量x。因为int_pointer先前被设为指向count,所以这个语句将包含在变量count的值10,赋予变量x。 21 | 22 | 23 | ##在表达式中运用指针 24 | `int i1 = 5, i2, *p1, *p2;` 25 | `p1 = &i1;` 26 | `i2 = *p1 / 2 + 10;` 27 | `p2 = p1;` 28 | 结果为: 29 | `i1 = 5, i2 = 12, *p1 = 5, *p2 = 5;` 30 | 如果一个指针px指向一个变量x,且px被定义为和x相同类型的指针,那么表达式中*px的用法等同于x。 31 | 32 | ##使用指针和结构 33 | 定义一个如下的数据结构: 34 | 35 | struct date{ 36 | int month; 37 | int day; 38 | int year; 39 | }; 40 | 41 | 定义一个结构变量: 42 | `Struct date todaysDate;` 43 | 定义一个指向结构的指针: 44 | `Struct date *datePtr;` 45 | 使该指针指向todaysDate: 46 | `datePtr = &todaysDate;` 47 | 存取结构中的一个成员: 48 | `(*datePtr).day = 21;` 49 | 结构指针运算符:->,即(*x).y可以表示为x->y. 50 | 51 | ###包含指针的结构 52 | 定义一个结构intPtrs,包含三个整型指针。 53 | 54 | struct intPtrs{ 55 | int *p1; 56 | int *p2; 57 | int *p3; 58 | }; 59 | 60 | 定义一个结构类型的变量intPtrs: 61 | `struct intPtrs pointers;` 62 | 将该变量内的p2指针指向的整型数的值设为-97: 63 | `*pinters.p2 = -97;` 64 | 65 | ###链表 66 | 定义一个如下结构: 67 | 68 | struct entry{ 69 | int value; 70 | struct entry *next; 71 | }; 72 | 73 | 创建一个链表: 74 | int main(void){ 75 | struct entry n1, n2, n3; 76 | struct entry *list_pointer = &n1; // 显示链表的头指针 77 | 78 | n1.value = 100; 79 | n1.next = &n2; 80 | 81 | n2.value = 200; 82 | n2.next = &n3; 83 | 84 | n3.value = 300; 85 | n3.next = (struct entry *) 0; // 用空指针来标识链表的表尾 86 | 87 | while(list_pointer != (struct entry *) 0){ 88 | printf("%i\n", list_pointer->value); 89 | list_pointer = list_pointer->next;; 90 | } 91 | 92 | return 0; 93 | } 94 | 95 | ##关键字const和指针 96 | 假定有如下声明: 97 | `char c = 'x'` 98 | `char *charPtr = &c;` 99 | 指针变量charPtr被设为指向变量c,如果它总是指向c,则可被声明为一个指针常量如下: 100 | `char * const charPtr = &c;` 101 | (读法为“charPtr是一个指向字符的指针常量”)因此,类似的下面的一个语句: 102 | `charPtr = &d; // 不是有效的,即该指针不会指向其他变量` 103 | 104 | 如果charPtr指向的位置的值不会通过使用指针变量charPtr被改变,则可使用如下声明: 105 | `const char *charPtr = &c;` 106 | (读法为“charPtr指向一个字符常量”)因此,类似下面的语句: 107 | `*charPtr = 'Y'; // 不是有效的,即该指针指向的变量值不能通过指针来改变` 108 | 109 | 在指针变量和它所指向的单元都不改变的情况下,可应用下面的声明: 110 | `const char * const *charPtr = &c;` 111 | 第一个const表明指针指向的单元的内容不会被改变,第二个const表明指针本身不会被改变。 112 | 113 | ##指针和函数 114 | 1.将指针作为参数传递给函数: 115 | 116 | void print_list(struct entry *pointer){ 117 | ... 118 | } 119 | 120 | 接下来接可以将形式参数pointer当作一个正常的指针变量使用了。 121 | 在调用函数时,指针的值将被复制到形式参数中。 122 | 尽管函数不能改变指针参数,但却可以改变指针指向的数据元素: 123 | 124 | void exchange(int * const pint1, int * const pint2){ 125 | int temp; 126 | 127 | temp = *pint1; 128 | *pint1 = *pint2; 129 | *pint2 = temp; 130 | } 131 | 132 | int main(void){ 133 | void exchange(int * const pint1, int * const pint2); 134 | int i1 = -5, i2 = 66, *p1 = &i1, *p2 = &i2; 135 | 136 | printf("i1 = %i, i2 = %i\n", i1, i2); // -5, 66 137 | 138 | exchange(p1, p2); 139 | printf("i1 = %i, i2 = %i\n", i1, i2); // 66, -5 140 | 141 | exchange(&i1, &i2); 142 | printf("i1 = %i, i2 = %i\n", i1, i2); // -5, 66 143 | 144 | return 0; 145 | } 146 | 147 | 函数exchange的功能时交换由它的两个指针参数(const)所指向的整型变量的值。 148 | 若是不用指针,我们就无法写出exchange函数来交换两个整型的值,因为函数被限制为只能返回一个单值,另外函数不能改变它的参数。 149 | 150 | 2.函数返回一个指针 151 | 定义一个函数,查找一个链表以找出给定的值,返回值是一个指向结构entry的指针: 152 | 153 | struct entry *findEntry(struct entry *listPtr, int match){ 154 | while(listPtr != (struct entry *) 0){ 155 | if(listPtr->value == match) 156 | return (listPtr); 157 | else 158 | listPtr = listPtr->next; 159 | } 160 | return (struct entry *) 0; 161 | } 162 | 163 | int main(void){ 164 | struct entry *findEntry(struct entry *listPtr, int match); 165 | struct entry n1, n2, n3; 166 | struct entry *listPtr, *listStart = &n1; 167 | int search; 168 | 169 | n1.value = 100; 170 | n1.next = &n2; 171 | 172 | n2.value = 200; 173 | n2.next = &n3; 174 | 175 | n3.value = 300; 176 | n3.next = 0; 177 | 178 | printf("Enter value to locate: "); 179 | scanf("%i", &search); 180 | 181 | listPtr = findEntry(listStart, search); 182 | 183 | if(listPtr != (struct entry *) 0) 184 | printf("Found %i.\n", listPtr->value); 185 | else 186 | printf("Not found.\n"); 187 | 188 | return 0; 189 | } 190 | 191 | 可以将字典组织成链表,方便插入和删除,缺点是不方便查找,比如无法使用二分查找。 192 | 树可以对元素进行方便的插入和删除,其查找速度也很快。 193 | 194 | ##指针和数组 195 | 如果a是一个元素为x类型的数组,px是x的指针类型,而i和n时整型常量或变量,则语句: 196 | `px = a; // px = &a[0];` 197 | 用来将指针px指向a的第一个元素,表达式: 198 | `*(px + i)` 199 | 用来引用包含在a[i]中的值。进而,语句: 200 | `px += n;` 201 | 用来将px指向数组中的第n号元素,不管数组中的元素到底是那种类型。 202 | 203 | ###关于程序的优化 204 | 通常情况下,(按照顺序)使用下标变量访问数组元素的过程会比使用指针访问花费更多的时间。 205 | 使用指针来存取数组元素的主要原因就是这样产生的代码通常效率更高。 206 | 207 | ###数组还是指针 208 | 如果我们想用下标来引用传递给一个函数的数组元素,需要将相应的形式参数声明为数组。这样就更准确地表明了函数中使用的是数组。如下所示: 209 | `int arraySum(int array[], const int n); ` 210 | 相似的,如果我们将形式参数作为一个指向数组的指针使用,则要将它声明为一个指针类型: 211 | `int arraySum(int *array, const int n); //声明符号array为一个整型指针` 212 | 213 | ###指向字符串的指针 214 | 用指针来编写copyString: 215 | 216 | void copyString(char *to, char *from){ 217 | for(; *from != '\0'; ++from, ++to) 218 | *to = *from; 219 | 220 | *to = '\0'; 221 | } 222 | 223 | int main(void){ 224 | void copyString(char *to, char *from); 225 | char string1[] = "A string to be copied."; 226 | char string2[50]; 227 | 228 | copyString(string2, string1); 229 | printf("%s\n", string2); 230 | 231 | copyString(string2, "So is this."); 232 | printf("%s\n", string2); 233 | 234 | return 0; 235 | } 236 | 237 | ###字符串常量和指针 238 | 如果text是一个字符数组,用下面语句初始化text: 239 | `char text[80] = "This is okay.";` 240 | C语言将这些字符串的字符本身保存在数组array的对应位置。 241 | 242 | 如果text是一个字符指针,用下面语句初始化text: 243 | `char *text = "This is okay.";` 244 | 则将一个指向字符串"This is okey."的指针赋值到text。 245 | 246 | 用如下方法建立一个叫做days的数组,它包含指向一个星期中每一天的名字的字符指针: 247 | `char *days[] = {"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};` 248 | 数组days被定义为包含7个元素,每个元素都是一个指向字符串的指针。于是, 249 | days[0]包含指向字符串"Sunday"的指针,days[1]包含指向字符串"Monday"的指针,等等。 250 | 可以用下面的语句显示一个星期第三天的名字: 251 | `printf("%s\n", days[3]);` 252 | 253 | ###递增和递减运算符 254 | `++i`,++放置在操作数的前面,递增运算符可以看成是“前加”; 255 | `i++`,++放置在操作数的后面,递增运算符可以看成是“后加”; 256 | 前置和后置运算符的差别: 257 | 1. 258 | 假定有两个整型变量i和j,如果我们将i设为0,则下面语句: 259 | `j = ++i;` 260 | 将1赋值给j,而不是0。在前置运算符的情况下,变量的值首先被加1,然后再参加到表达式的求值中。因此前面的表达式中,变量i的值首先由0递增为1,然后其值被赋给j,等价于如下语句: 261 | `++i;` 262 | `j = i;` 263 | 264 | 如果我们在语句中用了“后加”运算符: 265 | `j = i++;` 266 | 则i的值实在先赋值给j之后才递增的。因此前面的表达式中,先将0赋值给j,然后对i进行递增操作,即加1,等价于如下语句: 267 | `j = i;` 268 | `++i;` 269 | 270 | 2. 271 | 另举一个例子。如果i为1,则下面语句: 272 | `x = a[--i];` 273 | 将a[0]的值赋给x。因为,变量i在其值作为下标使用之前,已经进行了递减操作。而语句: 274 | `x = a[i--];` 275 | 将a[1]的值赋给x。因为,变量i在其值作为下标使用过之后,才进行递减操作。 276 | 277 | 3. 278 | 再举一个例子说明前置和后置递增和递减运算符的差别。函数调用: 279 | `printf("%i\n", ++i); // 如果i为100,则printf调用显示101,语句执行完毕i为101` 280 | 在i递增后才将其值传递给printf函数,然而,函数调用: 281 | `printf("%i\n", i++); // 如果i为100,则printf调用显示100,语句执行完毕i为101` 282 | 在将i的值传递给printf函数之后,才对i进行递增操作。 283 | 284 | 4. 285 | 最后一个例子:如果textPtr时一个字符指针,则表达式: 286 | `*(++textPtr)` 287 | 首先递增textPtr,然后取出它所指向的字符。然而,表达式: 288 | `*(textPtr++)` 289 | 在它的值递增之前就取回了textPtr所指向的字符。不管是哪种情况,圆括号都不是必需的,因为*和++运算符具有相同的优先级,而且它们是“自右向左”结合的。 290 | 291 | 在赋值语句里使用后置递增运算符来重写copyString函数: 292 | 293 | // copyString函数的修订版本 294 | #include 295 | void copyString(char *to, char *from){ 296 | // 空字符的值等价于值0 297 | while(*from) 298 | *to++ = *from++; 299 | 300 | *to = '\0'; 301 | } 302 | 303 | int main(void){ 304 | void copyString(char *to, char *from); 305 | char string1[] = "A string to be copied."; 306 | char string2[50]; 307 | 308 | copyString(string2, string1); 309 | printf("%s\n", string2); 310 | 311 | copyString(string2, "So is this."); 312 | printf("%s\n", string2); 313 | 314 | return 0; 315 | } 316 | 317 | ##指针运算 318 | C语言中两个指针减法操作的结果是它们之间所包含元素的个数。 319 | 由两个指针的减操作产生的结果的实际类型时ptrdiff_t,它在标准头函数文件里定义。 320 | 因此,如果a是一个指向任意元素类型的数组,而b时另一个同类型的指针,该指针指向同一数组更远的一个位置,则表达式b-a代表这两个指针之间的元素个数。 321 | 例如,如果p时一个指向数组x的某个元素的指针,则语句: 322 | `n = p - x;` 323 | 将p所指的元素的下标数赋值给变量n(假定n是一个整型变量)。因此,如果p由以下语句设置为指向第100个元素: 324 | `p = &x[99];` 325 | 那么,变量n在前面的减操作完成后值为99. 326 | 指针相加同理? 327 | 328 | ##指向函数的指针 329 | 为了使用指向函数的指针,C语言编译器不仅需要知道指向函数的指针变量,还要知道函数返回值的类型,还包括它的参数的数量和类型。为了声明符号fnPtr为一个“指向一个返回整数且不带任何参数的函数”的指针,我们使用如下声明: 330 | `int (*fnPtr)(void);` 331 | *fnPtr两边的小括号时必需的,否则,因为函数调用运算符()比指针运算符*的优先级高,C语言编译器将会把前面的语句作为一个函数的声明,这个函数叫做fnPtr,它返回一个指向整型数的指针。 332 | 为了将函数指针指向一个指定的函数,我们可以简单地将函数的名字赋值给它。因此如果lookup是一个函数,它返回一个整型,且没有参数,则语句: 333 | `fnPtr = lookup;` 334 | 将一个指向函数的指针存储到函数指针变量fnPtr之中。 335 | 如果需要通过函数指针变量间接调用函数,我们可以在函数指针变量后面加上函数调用操作符--即一对小括号,然后在小括号里列出要传递给函数的参数。例如: 336 | `entry = fnPtr();` 337 | 调用了由fnPtr指向的函数,并存储返回值到变量entry之中。 338 | 339 | 函数指针的一个最常用的用途时将函数作为参数传递给其他函数。例如标准C语言库函数qsort就用到这个特性。 340 | 函数指针的另一个常见应用时用来产生一个派遣表。我们不能将函数存储到一个数组元素中,但是我们可以将函数指针存储到数组中。通过函数指针,我们可以生成一个包含函数指针的表。 341 | 342 | ##指针和内存地址 343 | 在C语言里,当我们对一个变量运用地址运算符时,得到的结果就是这个变量在计算机内存里的实际地址。所以,下面的语句: 344 | `intPtr = &count;` 345 | 将计算机分配给变量count的内存地址赋值给intPtr。因此,如果count存储在地址0x8868,包含了一个值为10,则这个语句将值0x8868赋予intPtr. 346 | 用对一个指针变量运用指针运算符,如下表达式所示: 347 | `*intPtr` 348 | 则告诉计算机,将包含在指针变量的值看作是一个内存地址。于是计算机取出内存地址里存储的值,并根据指针变量的类型对该值作出解释。 349 | -------------------------------------------------------------------------------- /chapter11/exce10: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter11/exce10 -------------------------------------------------------------------------------- /chapter11/exce10.c: -------------------------------------------------------------------------------- 1 | // 用字符指针代替数组来实现compareStrings函数 2 | #include 3 | 4 | int compareStrings(const char *s1, const char *s2){ 5 | int answer; 6 | 7 | while(*s1 == *s2 && *s1 != '\0' && *s2 != '\0') 8 | ++s1, ++s2; 9 | if(*s1 < *s2) 10 | answer = -1; 11 | else if(*s1 == *s2) 12 | answer = 0; 13 | else answer = 1; 14 | 15 | return answer; 16 | } 17 | 18 | int main(void){ 19 | int compareStrings(const char *s1, const char *s2); 20 | 21 | printf("%i", compareStrings("hello", "hall")); 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /chapter11/exce11: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter11/exce11 -------------------------------------------------------------------------------- /chapter11/exce11.c: -------------------------------------------------------------------------------- 1 | // 编写dateUpdate函数,它用一个指向date结构的指针作为参数。 2 | 3 | #include 4 | #include 5 | 6 | struct date{ 7 | int month; 8 | int day; 9 | int year; 10 | }; 11 | 12 | 13 | void dateUpdate(struct date *today){ 14 | int numberOfDays(struct date d); 15 | 16 | if(today->day != numberOfDays(*today)){ 17 | ++today->day; 18 | } 19 | else if(today->month == 12){ 20 | today->day = 1; 21 | today->month = 1; 22 | ++today->year ; 23 | } 24 | else{ 25 | today->day = 1; 26 | ++today->month; 27 | } 28 | } 29 | 30 | int numberOfDays(struct date d){ 31 | int days; 32 | bool isLeapYear(struct date d); 33 | const int daysPerMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 34 | 35 | if(isLeapYear(d) && d.month == 2) 36 | days = 29; 37 | else 38 | days = daysPerMonth[d.month - 1]; 39 | 40 | return days; 41 | } 42 | 43 | bool isLeapYear(struct date d){ 44 | bool leapYearFlag; 45 | 46 | if((d.year % 4 == 0 && d.year % 100 != 0 )|| d.year % 400 == 0) 47 | leapYearFlag = true; // 闰年 48 | else 49 | leapYearFlag = false; // 非闰年 50 | 51 | return leapYearFlag; 52 | } 53 | 54 | int main(void){ 55 | void dateUpdate(struct date *today); 56 | struct date thisDay; 57 | 58 | printf("Enter today's date (mm dd yyyy)\n"); 59 | scanf("%i /%i /%i", &thisDay.month, &thisDay.day, &thisDay.year); 60 | 61 | dateUpdate(&thisDay); 62 | 63 | printf("Tomorrow's date is %i/%i/%.2i.\n", thisDay.month, 64 | thisDay.day, thisDay.year % 100); 65 | 66 | return 0; 67 | } 68 | 69 | 70 | -------------------------------------------------------------------------------- /chapter11/exce12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter11/exce12 -------------------------------------------------------------------------------- /chapter11/exce12.c: -------------------------------------------------------------------------------- 1 | // 判断printf语句集合中每个printf是否有效 2 | // 所以printf()函数的默认参数是个指针?两个参数的情况下,第一个也是指针? 3 | #include 4 | 5 | int main(void){ 6 | char *message = "Programming in C is fun\n"; 7 | char message2[] = "You said it\n"; 8 | char *format = "x = %i\n"; 9 | int x = 100; 10 | 11 | /*** set1 ***/ 12 | printf ("Programming in C is fun\n"); 13 | printf("%s", "Programming in C is fun\n"); 14 | printf("%s", message); 15 | // printf(message); 16 | 17 | /*** set2 ***/ 18 | printf("You said it\n"); 19 | printf("%s", message2); 20 | // printf(message2); 21 | printf("%s", &message2[0]); 22 | 23 | /*** set3 ***/ 24 | printf("said it\n"); 25 | // printf(message2 + 4); 26 | printf("%s", message2 + 4); 27 | printf("%s", &message2[4]); 28 | 29 | /*** set4 ***/ 30 | printf("x = %i\n", x); 31 | printf(format, x); 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /chapter11/exce2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter11/exce2 -------------------------------------------------------------------------------- /chapter11/exce2.c: -------------------------------------------------------------------------------- 1 | // 编写函数insertEntry,该函数插入一个新结点到链表之中。 2 | #include 3 | 4 | struct entry{ 5 | int value; 6 | struct entry *next; 7 | }; 8 | 9 | void insertEntry(struct entry *to, struct entry *from){ 10 | // 将原来单元的指向赋给新来单元的指向 11 | from->next = to->next; 12 | // 将原来单元的指向改为指向新来的单元 13 | to->next = from; 14 | } 15 | 16 | int main(void){ 17 | void insertEntry(struct entry *to, struct entry *from); 18 | 19 | struct entry n1, n2, n3, newEntry; 20 | struct entry *list_pointer = &n1; 21 | 22 | n1.value = 100; 23 | n1.next = &n2; 24 | 25 | n2.value = 200; 26 | n2.next = &n3; 27 | 28 | n3.value = 300; 29 | n3.next = (struct entry *) 0; 30 | 31 | newEntry.value = 9000; 32 | newEntry.next = 0; 33 | 34 | // insertEntry(&n1, &newEntry); 35 | insertEntry(&n2, &newEntry); 36 | // insertEntry(&n3, &newEntry); 37 | 38 | while(list_pointer != (struct entry *) 0){ 39 | printf("%i\n", list_pointer->value); 40 | list_pointer = list_pointer->next;; 41 | } 42 | 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /chapter11/exce3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter11/exce3 -------------------------------------------------------------------------------- /chapter11/exce3.c: -------------------------------------------------------------------------------- 1 | // 函数insertEntry修订版,可以在表头之前插入一个新元素。 2 | #include 3 | 4 | struct entry{ 5 | int value; 6 | struct entry *next; 7 | }; 8 | 9 | void insertEntry(struct entry *to, struct entry *from){ 10 | from->next = to->next; 11 | to->next = from; 12 | } 13 | 14 | int main(void){ 15 | void insertEntry(struct entry *to, struct entry *from); 16 | 17 | struct entry n1, n2, n3, head, newEntry; 18 | struct entry *list_pointer ; 19 | 20 | head.value = -1; 21 | head.next = &n1; 22 | 23 | n1.value = 100; 24 | n1.next = &n2; 25 | 26 | n2.value = 200; 27 | n2.next = &n3; 28 | 29 | n3.value = 300; 30 | n3.next = (struct entry *) 0; 31 | 32 | newEntry.value = 9000; 33 | newEntry.next = 0; 34 | 35 | insertEntry(&head, &newEntry); 36 | 37 | list_pointer = &head; 38 | // 略去表头的值 39 | while(list_pointer->next != (struct entry *) 0){ 40 | printf("%i\n", list_pointer->next->value); 41 | list_pointer = list_pointer->next;; 42 | } 43 | 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /chapter11/exce4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter11/exce4 -------------------------------------------------------------------------------- /chapter11/exce4.c: -------------------------------------------------------------------------------- 1 | // 编写removeEntry以从链表中删除一个元素。 2 | // 它唯一的参数时一个指向链表元素的指针。 3 | #include 4 | 5 | struct entry{ 6 | int value; 7 | struct entry *next; 8 | }; 9 | 10 | void removeEntry(struct entry *source){ 11 | if(source->next == (struct entry *)0) 12 | return; 13 | source->next = source ->next->next; 14 | }; 15 | 16 | int main(void){ 17 | void insertEntry(struct entry *to, struct entry *from); 18 | 19 | struct entry n1, n2, n3, head; 20 | struct entry *list_pointer ; 21 | 22 | head.value = -1; 23 | head.next = &n1; 24 | 25 | n1.value = 100; 26 | n1.next = &n2; 27 | 28 | n2.value = 200; 29 | n2.next = &n3; 30 | 31 | n3.value = 300; 32 | n3.next = (struct entry *) 0; 33 | 34 | removeEntry(&head); 35 | 36 | list_pointer = &head; 37 | while(list_pointer->next != (struct entry *) 0){ 38 | printf("%i\n", list_pointer->next->value); 39 | list_pointer = list_pointer->next;; 40 | } 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /chapter11/exce5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter11/exce5 -------------------------------------------------------------------------------- /chapter11/exce5.c: -------------------------------------------------------------------------------- 1 | // 实现一个双向链表 2 | #include 3 | 4 | struct entry{ 5 | struct entry *prev; 6 | int value; 7 | struct entry *next; 8 | }; 9 | 10 | int main(void){ 11 | struct entry n1, n2, n3, head; 12 | struct entry *list_pointer; 13 | 14 | head.prev = 0; 15 | head.value = -1; 16 | head.next = &n1; 17 | 18 | n1.prev = &head; 19 | n1.value = 100; 20 | n1.next = &n2; 21 | 22 | n2.prev = &n1; 23 | n2.value = 200; 24 | n2.next = &n3; 25 | 26 | n3.prev = &n2; 27 | n3.value = 300; 28 | n3.next = 0; 29 | 30 | list_pointer = & head; 31 | while(list_pointer->next != (struct entry *)0){ 32 | printf("%i\n", list_pointer->next->value); 33 | list_pointer = list_pointer->next; 34 | } 35 | 36 | list_pointer = & n3; 37 | while(list_pointer->prev != (struct entry *)0){ 38 | printf("%i\n", list_pointer->value); 39 | list_pointer = list_pointer->prev; 40 | } 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /chapter11/exce6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter11/exce6 -------------------------------------------------------------------------------- /chapter11/exce6.c: -------------------------------------------------------------------------------- 1 | // 为双向链表编写inserEntry和removeEntry函数 2 | #include 3 | 4 | struct entry{ 5 | struct entry *prev; 6 | int value; 7 | struct entry *next; 8 | }; 9 | 10 | void insertEntry(struct entry *to, struct entry *from){ 11 | from->next = to->next->next; 12 | to->next->prev = from; 13 | 14 | to->next = from; 15 | from->prev = to; 16 | } 17 | 18 | void removeEntry(struct entry *source){ 19 | // 不能删除表头和表尾N 20 | if(source->prev == (struct entry *)0 || source->next == (struct entry *)0) 21 | return; 22 | source->next->prev = source->prev; 23 | source->prev->next = source->next; 24 | } 25 | 26 | int main(void){ 27 | struct entry n1, n2, n3, head, newEntry; 28 | struct entry *list_pointer; 29 | 30 | head.prev = 0; 31 | head.value = -1; 32 | head.next = &n1; 33 | 34 | n1.prev = &head; 35 | n1.value = 100; 36 | n1.next = &n2; 37 | 38 | n2.prev = &n1; 39 | n2.value = 200; 40 | n2.next = &n3; 41 | 42 | n3.prev = &n2; 43 | n3.value = 300; 44 | n3.next = 0; 45 | 46 | newEntry.prev = 0; 47 | newEntry.value = 2000; 48 | newEntry.next = 0; 49 | 50 | insertEntry(&n1, &newEntry); 51 | 52 | removeEntry(&n2); 53 | 54 | list_pointer = & head; 55 | while(list_pointer->next != (struct entry *)0){ 56 | printf("%i\n", list_pointer->next->value); 57 | list_pointer = list_pointer->next; 58 | } 59 | 60 | list_pointer = & n3; 61 | while(list_pointer->prev != (struct entry *)0){ 62 | printf("%i\n", list_pointer->value); 63 | list_pointer = list_pointer->prev; 64 | } 65 | 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /chapter11/exce7: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter11/exce7 -------------------------------------------------------------------------------- /chapter11/exce7.c: -------------------------------------------------------------------------------- 1 | // 使用重写sort函数 2 | #include 3 | 4 | void sort (int *a, int n){ 5 | int *aptr1, *aptr2, temp; 6 | 7 | for ( aptr1 = a; aptr1 < a + n - 1; ++aptr1 ) 8 | for ( aptr2 = aptr1 + 1; aptr2 < a + n; ++aptr2 ) 9 | if ( *aptr1 > *aptr2 ) { 10 | temp = *aptr1; 11 | *aptr1 = *aptr2; 12 | *aptr2 = temp; 13 | } 14 | } 15 | 16 | int main(void){ 17 | int i; 18 | int array[16] = {34, -5, 6, 0, 12, 100, 56, 22, 19 | 44, -3, -9, 12, 17, 22, 6, 11}; 20 | void sort(int *a, int n); 21 | 22 | printf("The array before the sort:\n"); 23 | 24 | for(i = 0; i < 16; ++i) 25 | printf("%i ", array[i]); 26 | 27 | sort(array, 16); 28 | 29 | printf("\n\nThe array after the sort:\n"); 30 | 31 | for(i = 0; i < 16; ++i) 32 | printf("%i ", array[i]); 33 | 34 | printf("\n"); 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /chapter11/exce8: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter11/exce8 -------------------------------------------------------------------------------- /chapter11/exce8.c: -------------------------------------------------------------------------------- 1 | // 编写sort3的函数,可以对三个整数按升序进行排列 2 | #include 3 | 4 | void sort3(int *a, int *b, int *c){ 5 | int temp; 6 | 7 | if(*a > *b){ 8 | temp = *a; 9 | *a = *b; 10 | *b = temp; 11 | } 12 | if(*b > *c){ 13 | temp = *b; 14 | *b = *c; 15 | *c = temp; 16 | } 17 | if(*a > *c){ 18 | temp = *a; 19 | *a = *c; 20 | *c = temp; 21 | } 22 | } 23 | 24 | int main(void){ 25 | void sort3(int *a, int *b, int *c); 26 | int a = 10, b = 3, c = 5; 27 | 28 | printf("Before: a = %i, b = %i, c = %i\n", a, b, c); 29 | 30 | sort3(&a, &b, &c); 31 | 32 | printf("After: a = %i, b = %i, c = %i\n", a, b, c); 33 | 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /chapter11/exce9: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter11/exce9 -------------------------------------------------------------------------------- /chapter11/exce9.c: -------------------------------------------------------------------------------- 1 | // 用指针实现readLine函数 2 | #include 3 | 4 | void readLine(char *buffer){ 5 | char character; 6 | 7 | do{ 8 | character = getchar(); 9 | *buffer++ = character; 10 | }while(character != '\n'); 11 | 12 | // 循环最后一次执行的时候,循环变量已经增加过了。 13 | *(buffer - 1)= '\0'; 14 | } 15 | 16 | int main(void) { 17 | int i; 18 | char line[81]; 19 | void readLine(char *buffer); 20 | 21 | for(i = 0; i < 3; ++i){ 22 | readLine(line); 23 | printf("%s\n\n", line); 24 | } 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /chapter11/prog111: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter11/prog111 -------------------------------------------------------------------------------- /chapter11/prog111.c: -------------------------------------------------------------------------------- 1 | // 举例说明指针 2 | #include 3 | 4 | int main(void){ 5 | int count = 10, x; 6 | 7 | // 定义int_pointer为指向整型的指针型变量 8 | int *int_pointer; 9 | 10 | // 将地址运算符&应用于变量count,生成了一个指向该变量的指针, 11 | // 然后将该指针赋予变量int_pointer 12 | int_pointer = &count; 13 | 14 | // 通过指针间接第存取变量count的值 15 | x = *int_pointer; 16 | 17 | printf("count = %i, x = %i\n", count, x); 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /chapter11/prog1110: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter11/prog1110 -------------------------------------------------------------------------------- /chapter11/prog1110.c: -------------------------------------------------------------------------------- 1 | // 从函数返回一个指针 2 | #include 3 | 4 | struct entry{ 5 | int value; 6 | struct entry *next; 7 | }; 8 | 9 | // 查找一个链表以找出给定的值,返回值是一个指向结构entry的指针 10 | struct entry *findEntry(struct entry *listPtr, int match){ 11 | while(listPtr != (struct entry *) 0){ 12 | if(listPtr->value == match) 13 | return (listPtr); 14 | else 15 | listPtr = listPtr->next; 16 | } 17 | return (struct entry *) 0; 18 | } 19 | 20 | int main(void){ 21 | struct entry *findEntry(struct entry *listPtr, int match); 22 | struct entry n1, n2, n3; 23 | struct entry *listPtr, *listStart = &n1; 24 | int search; 25 | 26 | n1.value = 100; 27 | n1.next = &n2; 28 | 29 | n2.value = 200; 30 | n2.next = &n3; 31 | 32 | n3.value = 300; 33 | n3.next = 0; 34 | 35 | printf("Enter value to locate: "); 36 | scanf("%i", &search); 37 | 38 | listPtr = findEntry(listStart, search); 39 | 40 | if(listPtr != (struct entry *) 0) 41 | printf("Found %i.\n", listPtr->value); 42 | else 43 | printf("Not found.\n"); 44 | 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /chapter11/prog1111: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter11/prog1111 -------------------------------------------------------------------------------- /chapter11/prog1111.c: -------------------------------------------------------------------------------- 1 | // 使用指向数组的指针 2 | // 计算整数数组所有元素之和的函数 3 | 4 | #include 5 | 6 | int arraySum(int array[], const int n){ 7 | int sum = 0, *ptr; 8 | int * const arrayEnd = array + n; 9 | 10 | for(ptr = array; ptr < arrayEnd; ++ptr) 11 | sum += *ptr; 12 | 13 | return sum; 14 | } 15 | 16 | int main(void){ 17 | int arraySum(int array[], const int n); 18 | int values[10] = {3, 7, -9, 3, 6, -1, 7, 9, 1, -5}; 19 | 20 | printf("The sum is %i\n", arraySum(values, 10)); 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /chapter11/prog1112: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter11/prog1112 -------------------------------------------------------------------------------- /chapter11/prog1112.c: -------------------------------------------------------------------------------- 1 | // 将函数的形式参数声明为一个指针类型,作为一个指向数组的指针使用 2 | // 计算整数数组所有元素之和的函数 3 | 4 | #include 5 | 6 | int arraySum(int *array, const int n){ 7 | int sum = 0; 8 | int * const arrayEnd = array + n; 9 | 10 | // array本身值的修改不会影响数组values的内容 11 | for(; array < arrayEnd; ++array) 12 | sum += *array; 13 | 14 | return sum; 15 | } 16 | 17 | int main(void){ 18 | int arraySum(int *array, const int n); 19 | int values[10] = {3, 7, -9, 3, 6, -1, 7, 9, 1, -5}; 20 | 21 | printf("The sum is %i\n", arraySum(values, 10)); 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /chapter11/prog1113: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter11/prog1113 -------------------------------------------------------------------------------- /chapter11/prog1113.c: -------------------------------------------------------------------------------- 1 | // 指针版本的copyString 2 | #include 3 | 4 | void copyString(char *to, char *from){ 5 | for(; *from != '\0'; ++from, ++to) 6 | *to = *from; 7 | 8 | *to = '\0'; 9 | } 10 | 11 | int main(void){ 12 | void copyString(char *to, char *from); 13 | char string1[] = "A string to be copied."; 14 | char string2[50]; 15 | 16 | copyString(string2, string1); 17 | printf("%s\n", string2); 18 | 19 | copyString(string2, "So is this."); 20 | printf("%s\n", string2); 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /chapter11/prog1114: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter11/prog1114 -------------------------------------------------------------------------------- /chapter11/prog1114.c: -------------------------------------------------------------------------------- 1 | // copyString函数的修订版本 2 | #include 3 | void copyString(char *to, char *from){ 4 | // 空字符的值等价于值0 5 | while(*from) 6 | *to++ = *from++; 7 | 8 | *to = '\0'; 9 | } 10 | 11 | int main(void){ 12 | void copyString(char *to, char *from); 13 | char string1[] = "A string to be copied."; 14 | char string2[50]; 15 | 16 | copyString(string2, string1); 17 | printf("%s\n", string2); 18 | 19 | copyString(string2, "So is this."); 20 | printf("%s\n", string2); 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /chapter11/prog1115: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter11/prog1115 -------------------------------------------------------------------------------- /chapter11/prog1115.c: -------------------------------------------------------------------------------- 1 | // 用指针来计算字符串的长度 2 | #include 3 | 4 | int stringLength(const char *string){ 5 | const char *cptr = string; 6 | while(*cptr) 7 | ++cptr; 8 | return cptr - string; 9 | } 10 | 11 | int main(void){ 12 | int stringLength(const char *string); 13 | 14 | printf("%i ", stringLength("stringLength test")); 15 | printf("%i ", stringLength("")); 16 | printf("%i\n", stringLength("complete")); 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /chapter11/prog112: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter11/prog112 -------------------------------------------------------------------------------- /chapter11/prog112.c: -------------------------------------------------------------------------------- 1 | // 指针的进一步应用 2 | #include 3 | 4 | int main(void){ 5 | char c = 'Q'; 6 | char *char_pointer = &c; 7 | 8 | printf("%c %c\n", c, *char_pointer); 9 | 10 | c = '/'; 11 | printf("%c %c\n", c, *char_pointer); 12 | 13 | *char_pointer = '('; 14 | printf("%c %c\n", c, *char_pointer); 15 | 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /chapter11/prog113: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter11/prog113 -------------------------------------------------------------------------------- /chapter11/prog113.c: -------------------------------------------------------------------------------- 1 | // 在表达式中运用指针 2 | #include 3 | int main(void){ 4 | int i1, i2; 5 | int *p1, *p2; 6 | 7 | i1 = 5; 8 | p1 = &i1; 9 | i2 = *p1 / 2 + 10; 10 | p2 = p1; 11 | 12 | printf("i1 = %i, i2 = %i, *p1 = %i, *p2 = %i\n", i1, i2, *p1, *p2); 13 | 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /chapter11/prog114: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter11/prog114 -------------------------------------------------------------------------------- /chapter11/prog114.c: -------------------------------------------------------------------------------- 1 | // 结构指针应用程序 2 | // 指向结构的指针 (*x).y可以用结构指针运算符表示为x->y 3 | 4 | #include 5 | 6 | int main(void){ 7 | struct date{ 8 | int month; 9 | int day; 10 | int year; 11 | }; 12 | 13 | struct date today, *datePtr; 14 | 15 | datePtr = &today; 16 | 17 | datePtr->month = 3; 18 | datePtr->day = 30; 19 | datePtr->year = 2016; 20 | 21 | printf("Today's date is %i/%i/%.2i.\n", 22 | datePtr->month, datePtr->day, datePtr->year % 100); 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /chapter11/prog115: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter11/prog115 -------------------------------------------------------------------------------- /chapter11/prog115.c: -------------------------------------------------------------------------------- 1 | // 使用包含指针的结构 2 | #include 3 | 4 | int main(void){ 5 | struct intPtrs{ 6 | int *p1; 7 | int *p2; 8 | }; 9 | 10 | struct intPtrs pointers; 11 | int i1 = 100, i2; 12 | 13 | pointers.p1 = &i1; 14 | pointers.p2 = &i2; 15 | *pointers.p2 = -97; 16 | 17 | printf("i1 = %i, *pointers.p1 = %i\n", i1, *pointers.p1); 18 | printf("i2 = %i, *pointers.p2 = %i\n", i2, *pointers.p2); 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /chapter11/prog116: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter11/prog116 -------------------------------------------------------------------------------- /chapter11/prog116.c: -------------------------------------------------------------------------------- 1 | // 应用链表的函数 2 | #include 3 | 4 | int main(void){ 5 | struct entry{ 6 | int value; 7 | struct entry *next; 8 | }; 9 | 10 | struct entry n1, n2, n3; 11 | int i; 12 | n1.value = 100; 13 | n2.value = 200; 14 | n3.value = 300; 15 | n1.next = &n2; 16 | n2.next = &n3; 17 | i = n1.next->value; 18 | printf("%i ", i); 19 | printf("%i\n", n2.next->value); 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /chapter11/prog117: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter11/prog117 -------------------------------------------------------------------------------- /chapter11/prog117.c: -------------------------------------------------------------------------------- 1 | // 遍历一个链表 2 | #include 3 | 4 | int main(void){ 5 | struct entry{ 6 | int value; 7 | struct entry *next; 8 | }; 9 | 10 | struct entry n1, n2, n3; 11 | struct entry *list_pointer = &n1; // 显示链表的头指针 12 | 13 | n1.value = 100; 14 | n1.next = &n2; 15 | 16 | n2.value = 200; 17 | n2.next = &n3; 18 | 19 | n3.value = 300; 20 | n3.next = (struct entry *) 0; // 用空指针来标识链表的表尾 21 | 22 | while(list_pointer != (struct entry *) 0){ 23 | printf("%i\n", list_pointer->value); 24 | list_pointer = list_pointer->next;; 25 | } 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /chapter11/prog118: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter11/prog118 -------------------------------------------------------------------------------- /chapter11/prog118.c: -------------------------------------------------------------------------------- 1 | // 应用指针和函数的程序 2 | 3 | #include 4 | 5 | void test(int *int_pointer){ 6 | *int_pointer = 100; 7 | } 8 | 9 | int main(void){ 10 | void test(int *int_pointer); 11 | int i = 50, *p = &i; 12 | 13 | printf("Before the call to test i = %i\n", i); 14 | test(p); 15 | printf("After the call to test i = %i\n", i); 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /chapter11/prog119: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter11/prog119 -------------------------------------------------------------------------------- /chapter11/prog119.c: -------------------------------------------------------------------------------- 1 | // 运用指针修改数值 2 | // 若是不用指针,我们就无法写出exchange函数来交换两个整型的值, 3 | // 因为函数被限制为只能返回一个单值,另外函数不能改变它的参数 4 | #include 5 | 6 | // int * const pint 指针常量,总是指向某个常量,指向不改变 7 | void exchange(int * const pint1, int * const pint2){ 8 | int temp; 9 | 10 | temp = *pint1; 11 | *pint1 = *pint2; 12 | *pint2 = temp; 13 | } 14 | 15 | int main(void){ 16 | void exchange(int * const pint1, int * const pint2); 17 | int i1 = -5, i2 = 66, *p1 = &i1, *p2 = &i2; 18 | 19 | printf("i1 = %i, i2 = %i\n", i1, i2); 20 | 21 | exchange(p1, p2); 22 | printf("i1 = %i, i2 = %i\n", i1, i2); 23 | 24 | exchange(&i1, &i2); 25 | printf("i1 = %i, i2 = %i\n", i1, i2); 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /chapter12/exce2.c: -------------------------------------------------------------------------------- 1 | // 编写程序确定计算机执行的是算术右移还是逻辑右移 2 | #include 3 | 4 | int main(void){ 5 | signed int w1 = -1 % 32; 6 | signed int flag; 7 | 8 | printf("%x\n", w1); 9 | w1 >>= 1; 10 | printf("%x\n", w1); 11 | flag = w1 >> 31; 12 | 13 | if(flag == -1) 14 | printf("SAR\n"); // 算术右移 15 | else 16 | printf("SHR\n"); // 逻辑右移 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /chapter12/exce3.c: -------------------------------------------------------------------------------- 1 | // 编写int_size函数,返回计算机上一个int所包含的位数 2 | #include 3 | int int_size(){ 4 | unsigned int bits; 5 | int size = 0; 6 | 7 | bits = ~0; 8 | 9 | while(bits){ 10 | ++size; 11 | bits >>= 1; 12 | } 13 | 14 | return size; 15 | } 16 | 17 | int main(void){ 18 | int int_size(); 19 | 20 | printf("%i\n", int_size()); // 32 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /chapter12/exce4.c: -------------------------------------------------------------------------------- 1 | // 实现一个旋转移位的函数(不用做任何假设) 2 | #include 3 | 4 | int int_size(){ 5 | unsigned int bits; 6 | int size = 0; 7 | 8 | bits = ~0; 9 | 10 | while(bits){ 11 | ++size; 12 | bits >>= 1; 13 | } 14 | 15 | return size; 16 | } 17 | 18 | // 将无符号整数旋转左移或右移的函数 19 | 20 | unsigned int rotate(unsigned int value, int n){ 21 | int int_size(); 22 | unsigned int result, bits; 23 | int size; 24 | 25 | size = int_size(); 26 | 27 | if(n > 0) 28 | n = n % size; 29 | else 30 | n = -(n % size); 31 | 32 | if(n == 0) 33 | result = value; 34 | else if(n > 0){ // 左旋 35 | bits = value >> (size - n); 36 | result = value << n | bits; 37 | } 38 | else{ // 右旋 39 | n = -n; 40 | bits = value << (size - n); 41 | result = value >> n | bits; 42 | 43 | } 44 | 45 | return result; 46 | } 47 | 48 | 49 | int main(void){ 50 | unsigned int w1 = 0xabcdef00u, w2 = 0xffff1122u; 51 | unsigned int rotate(unsigned int value, int n); 52 | 53 | printf("%x\n", rotate(w1, 8)); // cdef00ab 54 | printf("%x\n", rotate(w1, -16)); // ef00abcd 55 | printf("%x\n", rotate(w2, 4)); // fff1122f 56 | printf("%x\n", rotate(w2, -2)); // fffc448b 57 | printf("%x\n", rotate(w1, 0)); // abcdef00 58 | printf("%x\n", rotate(w1, 44)); // def00abc 59 | 60 | return 0; 61 | } 62 | 63 | -------------------------------------------------------------------------------- /chapter12/exce5.c: -------------------------------------------------------------------------------- 1 | // 编写bit_test函数,两个参数,一个无符号整数和一个位数n。 2 | // 当该无符号数的第n位为1时,令函数返回1;当第n位为0时返回0(左起算第n位)。 3 | // 相应地编写bit_set,参数同上,将第n位设置为1,并返回设置的结果。 4 | #include 5 | 6 | int bit_test(unsigned int test, int n){ 7 | if(n < 0 || n > 32) 8 | return 0; 9 | if((test >> (31 - n)) & 0x1) 10 | return 1; 11 | else 12 | return 0; 13 | } 14 | unsigned int bit_set(unsigned int test, int n){ 15 | if(n < 0 || n > 32) 16 | return 0; 17 | 18 | return test | (1 << (31 - n)); 19 | } 20 | 21 | int main(void){ 22 | int bit_test(unsigned int test, int n); 23 | unsigned int bit_set(unsigned int test, int n); 24 | unsigned int word1 = 0xffffff0fu; 25 | 26 | printf("%i\n", bit_test(word1, 23)); 27 | 28 | printf("%x\n", bit_set(word1, 24)); 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /chapter12/exce6.c: -------------------------------------------------------------------------------- 1 | /* 编写函数bitpat_search(source, pattern, n) 2 | * 函数从最左一位开始搜索整数source,看pattern的最右边的n位是否在source中。 3 | * 如果找到了pattern,函数返回pattern在source中开始的位数编号,没找到则返回-1。 4 | */ 5 | #include 6 | int int_size(){ 7 | unsigned int bits; 8 | int size = 0; 9 | 10 | bits = ~0; 11 | 12 | while(bits){ 13 | ++size; 14 | bits >>= 1; 15 | } 16 | 17 | return size; 18 | } 19 | 20 | int bit_test(unsigned int test, int n){ 21 | if(n < 0 || n > 32) 22 | return 0; 23 | if((test >> (31 - n)) & 0x1) 24 | return 1; 25 | else 26 | return 0; 27 | } 28 | 29 | int bitpat_search(unsigned int source, unsigned int pattern, int n){ 30 | int bit_test(unsigned int test, int n); 31 | int int_size(); 32 | int i, j, size; 33 | 34 | size = int_size(); 35 | 36 | for(i = 0; i <= size - n; ++i){ 37 | if(bit_test(source, i) == bit_test(pattern, 1)){ 38 | j = 1; 39 | while(bit_test(source, i + j) == bit_test(pattern, 1 + j)) 40 | ++j; 41 | if(j == n) 42 | return i; 43 | } 44 | } 45 | 46 | return -1; 47 | } 48 | 49 | int main(void){ 50 | int bitpat_search(unsigned int source, unsigned int pattern, int n); 51 | unsigned int source = 0xe1f4; 52 | unsigned int pattern_1 = 0x5; 53 | unsigned int pattern_2 = 0xf; 54 | int index_1, index_2; 55 | 56 | index_1 = bitpat_search(source, pattern_1, 3); 57 | index_2 = bitpat_search(source, pattern_2, 4); 58 | 59 | printf("%i\n", index_1); 60 | printf("%i\n", index_2); 61 | 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /chapter12/exce7.c: -------------------------------------------------------------------------------- 1 | // 编写bitpat_get函数,提取无符号整数中指定的位串, 2 | // 3个参数分别为unsigned int, 指定开始的位数,要提取的位数。 3 | // 最左边的位数是0。 4 | #include 5 | 6 | int int_size(){ 7 | unsigned int bits; 8 | int size = 0; 9 | 10 | bits = ~0; 11 | 12 | while(bits){ 13 | ++size; 14 | bits >>= 1; 15 | } 16 | 17 | return size; 18 | } 19 | unsigned int bitpat_get(unsigned int value, int n, int count){ 20 | int int_size(); 21 | int word_size; 22 | 23 | word_size = int_size(); 24 | if(n < 0 || n > word_size || count < 0 || count + n > word_size) 25 | return 0; 26 | 27 | // 先将value左移n位 28 | value <<= n; 29 | // 在新的value中取出count位,即右移word_size() - count位。 30 | return value >> (word_size - count); 31 | } 32 | 33 | int main(void){ 34 | unsigned int bitpat_get(unsigned int value, int n, int count); 35 | unsigned int bits; 36 | unsigned int value = 0xe1f4; 37 | int n = 27, count = 3; 38 | 39 | bits = bitpat_get(value, n, count); 40 | printf("%o\n", bits); 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /chapter12/exce8.c: -------------------------------------------------------------------------------- 1 | // 编写函数bitpat_set,将一个特定值赋给一个无符号数中的指定位串。 2 | // 有4个参数,第一个参数是一个指针,指向一个unsigned int,对这个无符号整数中的指定位串进行设置; 3 | // 第二个参数是一个unsigned int,这个无符号数就是将要设置的值; 4 | // 第三个参数为int,指定开始位(最左边的位数是0); 5 | // 第四个参数为int,指定域的长度。 6 | // 对于一个int的长度不做任何假设。 7 | 8 | #include 9 | 10 | int int_size(){ 11 | unsigned int bits; 12 | int size = 0; 13 | 14 | bits = ~0; 15 | 16 | while(bits){ 17 | ++size; 18 | bits >>= 1; 19 | } 20 | 21 | return size; 22 | } 23 | -------------------------------------------------------------------------------- /chapter12/prog1201: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter12/prog1201 -------------------------------------------------------------------------------- /chapter12/prog1201.c: -------------------------------------------------------------------------------- 1 | // 演示二进制与运算的程序 2 | #include 3 | 4 | int main(void){ 5 | unsigned int word1 = 077u, word2 = 0150u, word3 = 0210u; 6 | 7 | printf("%o ", word1 & word2); 8 | printf("%o ", word1 & word1); // 与自己进行按位与运算的结果还是它自己。 9 | printf("%o ", word1 & word2 &word3); 10 | printf("%o\n", word1 & 1); // 提取最右一位,便于判断奇数偶数。 11 | 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /chapter12/prog1202: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tendoasan/ProgrammingInC/3c25e7dab0bd98516460a2a0f39a39af3bdbfd9e/chapter12/prog1202 -------------------------------------------------------------------------------- /chapter12/prog1202.c: -------------------------------------------------------------------------------- 1 | // 说明位运算符的程序 2 | // & 与,如果两个相应二进制位都为1,则结果为1,否则为0; 3 | // | 或, 两个二进制中只要有一个为1,则结果为1,否则为0; 4 | // ^ 异或,两个中有一个为1,但不全为1,则结果为1,否则为0; 5 | // ~ 取反,0变1,1变0. 6 | // 优先级:取反 -> 与 -> 异或 -> 或 7 | #include 8 | 9 | int main(void){ 10 | unsigned int w1 = 0525u, w2 = 0707u, w3 = 0122u; 11 | 12 | printf("%o %o %o\n", w1 & w2, w1 | w2, w1 ^ w2); 13 | printf("%o %o %o\n", ~w1, ~w2, ~w3); 14 | printf("%o %o %o\n", w1 ^ w1, w1 & ~w2, w1 | w2 | w3); 15 | printf ("%o %o\n", w1 | (w2 & w3), w1 | (w2 & ~w3)); 16 | printf("%o %o \n", ~(~w1 & ~w2), ~(~w1 | ~w2)); // 德摩根定律? 17 | // ~(~a & ~b)等价于a | b,~(~a | ~b)等价于a & b。 18 | 19 | w1 ^= w2; 20 | w2 ^= w1; 21 | w1 ^= w2; 22 | printf("w1 = %o, w2 = %o\n", w1, w2); 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /chapter12/prog1203.c: -------------------------------------------------------------------------------- 1 | // 一个移动无符号int的函数,如果为正数左移,为负数右移 2 | #include 3 | 4 | unsigned int shift(unsigned int value, int n){ 5 | if(n > 0) // 左移 6 | value <<= n; 7 | else // 右移 8 | value >>= -n; 9 | 10 | return value; 11 | } 12 | 13 | int main(void){ 14 | unsigned int w1 = 0177777u, w2 = 0444u; 15 | unsigned int shift(unsigned int value, int n); 16 | 17 | printf("%o\t%o\n", shift(w1, 5), w1 << 5); 18 | printf("%o\t%o\n", shift(w1, -6), w1 >> 6); 19 | printf("%o\t%o\n", shift(w2, 0), w2 >> 0); 20 | printf("%o\n", shift(shift(w1, -3), 3)); //将低3位设置为0 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /chapter12/prog1204.c: -------------------------------------------------------------------------------- 1 | // 实现一个旋转移位的函数 2 | #include 3 | 4 | int main(void){ 5 | unsigned int w1 = 0xabcdef00u, w2 = 0xffff1122u; 6 | unsigned int rotate(unsigned int value, int n); 7 | 8 | printf("%x\n", rotate(w1, 8)); // cdef00ab 9 | printf("%x\n", rotate(w1, -16)); // ef00abcd 10 | printf("%x\n", rotate(w2, 4)); // fff1122f 11 | printf("%x\n", rotate(w2, -2)); // fffc448b 12 | printf("%x\n", rotate(w1, 0)); // abcdef00 13 | printf("%x\n", rotate(w1, 44)); // def00abc 14 | 15 | return 0; 16 | } 17 | 18 | // 将无符号整数旋转左移或右移的函数 19 | 20 | unsigned int rotate(unsigned int value, int n){ 21 | unsigned int result, bits; 22 | 23 | // 缩减移动的位数到指定范围 24 | if(n > 0) 25 | n = n % 32; 26 | else 27 | n = -(n % 32); 28 | 29 | if(n == 0) 30 | result = value; 31 | else if(n > 0){ // 左旋 32 | // 提取values最左边的n位,通过将value向右移动(整数的长度-n)位来完成 33 | bits = value >> (32 - n); 34 | // 然后将value左移左移n位,之后将提取的位(bits)与value最右边的相应位进行或运算并将结果存回数据 35 | result = value << n | bits; 36 | } 37 | else{ // 右旋 38 | n = -n; 39 | bits = value << (32 - n); 40 | result = value >> n | bits; 41 | 42 | } 43 | 44 | return result; 45 | } 46 | -------------------------------------------------------------------------------- /chapter13 The Preprocessor/exce.h: -------------------------------------------------------------------------------- 1 | #define MIN(a, b) (((a) < (b))?(a):(b)) 2 | #define MAX2(a, b) (((a) > (b))?(a):(b)) 3 | #define MAX3(a, b, c) (((MAX2(a, b) > (c))?MAX2(a, b):(c))) 4 | #define SHIFT(v, n) (((n) > 0)?((v) << (n)):((v) >> -(n))) 5 | #define IS_UPPER_CASE(x) (((x) >= 'A' && (x) <= 'Z')?(1):(0)) 6 | #define IS_LOWER_CASE(x) (((x) >= 'a' && (x) <= 'z')?(1):(0)) 7 | #define IS_ALPHABETIC(x) (((IS_UPPER_CASE(x) || IS_LOWER_CASE(x))?(1):(0))) 8 | #define IS_DIGIT(x) (((x) >= '0' && (x) <= '9')?(1):(0)) 9 | #define IS_SPECIAL(x) ((IS_ALPHABETIC(x) || IS_DIGIT(x))?(0):(1)) 10 | #define ABSOLUTE_VALUE(x) (((x) >= 0)?(x):(-(x))) 11 | 12 | -------------------------------------------------------------------------------- /chapter13 The Preprocessor/exce10.c: -------------------------------------------------------------------------------- 1 | // 不能打印出来 2 | #include 3 | #define printint(n) printf("%i\n", x ## n) 4 | 5 | int main(void){ 6 | int i; 7 | 8 | for(i = 1; i < 100; ++i) 9 | printx(i); 10 | 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /chapter13 The Preprocessor/exce11.c: -------------------------------------------------------------------------------- 1 | // 验证标准库函数isupper,isalpha和isdigit 2 | #include 3 | #include 4 | 5 | int main(void){ 6 | char a = 'A', b = 'b', c = '6'; 7 | 8 | printf("%i\n", isupper(a)); 9 | printf("%i\n", isalpha(b)); 10 | printf("%i\n", isdigit(c)); 11 | 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /chapter13 The Preprocessor/exce3.c: -------------------------------------------------------------------------------- 1 | // 定义宏MIN返回两值中的较小值 2 | #include 3 | #include "exce.h" 4 | 5 | int main(void){ 6 | int a = 3, b = 9, c; 7 | 8 | c = MIN(a, b); 9 | 10 | printf("c:%i\n", c); 11 | 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /chapter13 The Preprocessor/exce4.c: -------------------------------------------------------------------------------- 1 | // 定义宏MAX3返回三个值中最大的一个 2 | #include 3 | #include "exce.h" 4 | 5 | int main(void){ 6 | int a = 3, b = 6, c = 9, d; 7 | 8 | d = MAX3(a, b, c); 9 | 10 | printf("d:%i\n", d); 11 | 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /chapter13 The Preprocessor/exce5.c: -------------------------------------------------------------------------------- 1 | // 定义宏SHIFT,使其完成prog1203中函数shift相同的功能 2 | #include 3 | #include "exce.h" 4 | 5 | int main(void){ 6 | unsigned int w1 = 0177777u, w2 = 0444u; 7 | 8 | printf("%o\t%o\n", SHIFT(w1, 5), w1 << 5); 9 | printf("%o\t%o\n", SHIFT(w1, -6), w1 >> 6); 10 | printf("%o\t%o\n", SHIFT(w2, 0), w2 >> 0); 11 | printf("%o\n", SHIFT(SHIFT(w1, -3), 3)); 12 | 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /chapter13 The Preprocessor/exce6.c: -------------------------------------------------------------------------------- 1 | // 定义宏IS_UPPER_CASE,该宏检查某个字符是否是大写字母,是则返回非0值,否则返回0 2 | #include 3 | #include "exce.h" 4 | 5 | int main(void){ 6 | char c = 'H'; 7 | 8 | printf("%i\n", IS_UPPER_CASE(c)); 9 | 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /chapter13 The Preprocessor/exce7.c: -------------------------------------------------------------------------------- 1 | // 定义宏IS_ALPHABETIC,检查某个字符是否是字母,是则返回非0值,否则返回0. 2 | #include 3 | #include "exce.h" 4 | 5 | int main(void){ 6 | char c = '0'; 7 | 8 | printf("%i\n", IS_ALPHABETIC(c)); 9 | 10 | return 0; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /chapter13 The Preprocessor/exce8.c: -------------------------------------------------------------------------------- 1 | // 定义宏IS_DIGIT,检查某个字符是否是数字,是则返回非0值,否则返回0. 2 | // 定义IS_SPECIAL,判断是否是特殊字符 3 | #include 4 | #include "exce.h" 5 | 6 | int main(void){ 7 | char a = '1', b = '$'; 8 | 9 | printf("%i\n", IS_DIGIT(a)); 10 | printf("%i\n", IS_SPECIAL(b)); 11 | 12 | return 0; 13 | } 14 | 15 | -------------------------------------------------------------------------------- /chapter13 The Preprocessor/exce9.c: -------------------------------------------------------------------------------- 1 | // 定义宏ABSOLUTE_VALUE,用于计算表达式的绝对值 2 | #include 3 | #include "exce.h" 4 | 5 | int main(void){ 6 | int a = -1, b = 6; 7 | 8 | printf("%i\n", ABSOLUTE_VALUE(a)); 9 | printf("%i\n", ABSOLUTE_VALUE(a + b)); 10 | 11 | return 0; 12 | } 13 | 14 | -------------------------------------------------------------------------------- /chapter13 The Preprocessor/float.h: -------------------------------------------------------------------------------- 1 | #ifndef _MINGW_FLOAT_H_ 2 | /* 3 | * float.h 4 | * 5 | * This file has no copyright assigned and is placed in the Public Domain. 6 | * This file is a part of the mingw-runtime package. 7 | * No warranty is given; refer to the file DISCLAIMER within the package. 8 | * 9 | * Constants related to floating point arithmetic. 10 | * 11 | * Also included here are some non-ANSI bits for accessing the floating 12 | * point controller. 13 | * 14 | */ 15 | #define _MINGW_FLOAT_H_ 16 | /* 17 | * NOTE: 18 | * 19 | * GCC provides float.h, but it doesn't include the non-standard stuff for 20 | * accessing the fp controller. We parse the GCC-supplied header, for its 21 | * standard content, and then define the MS-specific extensions here. 22 | * 23 | * In a MinGW standard Win32 hosted environment, this should be the float.h 24 | * found by a system include path search, but this can't be guaranteed; for 25 | * a cross-compiler setup, the GCC-supplied header, which is guarded by the 26 | * _FLOAT_H___ macro, may be found first, thus... 27 | * 28 | */ 29 | #if !defined(_FLOAT_H___) && !defined(__FLOAT_H) 30 | 31 | /* 32 | * ...when we didn't find the GCC-supplied header first, we want to pull 33 | * it in now; include_next should achieve this, (and we must rely on the 34 | * GCC header maintainers to extend us the same courtesy, to get this one 35 | * pulled in, when the GCC-supplied header is found first). 36 | * 37 | */ 38 | # include_next 39 | #endif 40 | 41 | /* All the headers include this file. */ 42 | #include <_mingw.h> 43 | 44 | /* 45 | * Functions and definitions for controlling the FPU. 46 | */ 47 | #ifndef __STRICT_ANSI__ 48 | 49 | /* TODO: These constants are only valid for x86 machines */ 50 | 51 | /* Control word masks for unMask */ 52 | #define _MCW_EM 0x0008001F /* Error masks */ 53 | #define _MCW_IC 0x00040000 /* Infinity */ 54 | #define _MCW_RC 0x00000300 /* Rounding */ 55 | #define _MCW_PC 0x00030000 /* Precision */ 56 | 57 | /* Control word values for unNew (use with related unMask above) */ 58 | #define _EM_INVALID 0x00000010 59 | #define _EM_DENORMAL 0x00080000 60 | #define _EM_ZERODIVIDE 0x00000008 61 | #define _EM_OVERFLOW 0x00000004 62 | #define _EM_UNDERFLOW 0x00000002 63 | #define _EM_INEXACT 0x00000001 64 | #define _IC_AFFINE 0x00040000 65 | #define _IC_PROJECTIVE 0x00000000 66 | #define _RC_CHOP 0x00000300 67 | #define _RC_UP 0x00000200 68 | #define _RC_DOWN 0x00000100 69 | #define _RC_NEAR 0x00000000 70 | #define _PC_24 0x00020000 71 | #define _PC_53 0x00010000 72 | #define _PC_64 0x00000000 73 | 74 | /* These are also defined in Mingw math.h, needed to work around 75 | GCC build issues. */ 76 | /* Return values for fpclass. */ 77 | #ifndef __MINGW_FPCLASS_DEFINED 78 | #define __MINGW_FPCLASS_DEFINED 1 79 | #define _FPCLASS_SNAN 0x0001 /* Signaling "Not a Number" */ 80 | #define _FPCLASS_QNAN 0x0002 /* Quiet "Not a Number" */ 81 | #define _FPCLASS_NINF 0x0004 /* Negative Infinity */ 82 | #define _FPCLASS_NN 0x0008 /* Negative Normal */ 83 | #define _FPCLASS_ND 0x0010 /* Negative Denormal */ 84 | #define _FPCLASS_NZ 0x0020 /* Negative Zero */ 85 | #define _FPCLASS_PZ 0x0040 /* Positive Zero */ 86 | #define _FPCLASS_PD 0x0080 /* Positive Denormal */ 87 | #define _FPCLASS_PN 0x0100 /* Positive Normal */ 88 | #define _FPCLASS_PINF 0x0200 /* Positive Infinity */ 89 | #endif /* __MINGW_FPCLASS_DEFINED */ 90 | 91 | /* invalid subconditions (_SW_INVALID also set) */ 92 | #define _SW_UNEMULATED 0x0040 /* unemulated instruction */ 93 | #define _SW_SQRTNEG 0x0080 /* square root of a neg number */ 94 | #define _SW_STACKOVERFLOW 0x0200 /* FP stack overflow */ 95 | #define _SW_STACKUNDERFLOW 0x0400 /* FP stack underflow */ 96 | 97 | /* Floating point error signals and return codes */ 98 | #define _FPE_INVALID 0x81 99 | #define _FPE_DENORMAL 0x82 100 | #define _FPE_ZERODIVIDE 0x83 101 | #define _FPE_OVERFLOW 0x84 102 | #define _FPE_UNDERFLOW 0x85 103 | #define _FPE_INEXACT 0x86 104 | #define _FPE_UNEMULATED 0x87 105 | #define _FPE_SQRTNEG 0x88 106 | #define _FPE_STACKOVERFLOW 0x8a 107 | #define _FPE_STACKUNDERFLOW 0x8b 108 | #define _FPE_EXPLICITGEN 0x8c /* raise( SIGFPE ); */ 109 | 110 | #ifndef RC_INVOKED 111 | 112 | #ifdef __cplusplus 113 | extern "C" { 114 | #endif 115 | 116 | /* Set the FPU control word as cw = (cw & ~unMask) | (unNew & unMask), 117 | * i.e. change the bits in unMask to have the values they have in unNew, 118 | * leaving other bits unchanged. */ 119 | _CRTIMP unsigned int __cdecl __MINGW_NOTHROW _controlfp (unsigned int unNew, unsigned int unMask); 120 | _CRTIMP unsigned int __cdecl __MINGW_NOTHROW _control87 (unsigned int unNew, unsigned int unMask); 121 | 122 | 123 | _CRTIMP unsigned int __cdecl __MINGW_NOTHROW _clearfp (void); /* Clear the FPU status word */ 124 | _CRTIMP unsigned int __cdecl __MINGW_NOTHROW _statusfp (void); /* Report the FPU status word */ 125 | #define _clear87 _clearfp 126 | #define _status87 _statusfp 127 | 128 | 129 | /* 130 | MSVCRT.dll _fpreset initializes the control register to 0x27f, 131 | the status register to zero and the tag word to 0FFFFh. 132 | This differs from asm instruction finit/fninit which set control 133 | word to 0x37f (64 bit mantissa precison rather than 53 bit). 134 | By default, the mingw version of _fpreset sets fp control as 135 | per fninit. To use the MSVCRT.dll _fpreset, include CRT_fp8.o when 136 | building your application. 137 | */ 138 | void __cdecl __MINGW_NOTHROW _fpreset (void); 139 | void __cdecl __MINGW_NOTHROW fpreset (void); 140 | 141 | /* Global 'variable' for the current floating point error code. */ 142 | _CRTIMP int * __cdecl __MINGW_NOTHROW __fpecode(void); 143 | #define _fpecode (*(__fpecode())) 144 | 145 | /* 146 | * IEEE recommended functions. MS puts them in float.h 147 | * but they really belong in math.h. 148 | */ 149 | 150 | _CRTIMP double __cdecl __MINGW_NOTHROW _chgsign (double); 151 | _CRTIMP double __cdecl __MINGW_NOTHROW _copysign (double, double); 152 | _CRTIMP double __cdecl __MINGW_NOTHROW _logb (double); 153 | _CRTIMP double __cdecl __MINGW_NOTHROW _nextafter (double, double); 154 | _CRTIMP double __cdecl __MINGW_NOTHROW _scalb (double, long); 155 | 156 | _CRTIMP int __cdecl __MINGW_NOTHROW _finite (double); 157 | _CRTIMP int __cdecl __MINGW_NOTHROW _fpclass (double); 158 | _CRTIMP int __cdecl __MINGW_NOTHROW _isnan (double); 159 | 160 | #ifdef __cplusplus 161 | } 162 | #endif 163 | 164 | #endif /* Not RC_INVOKED */ 165 | 166 | #endif /* Not __STRICT_ANSI__ */ 167 | 168 | #endif /* _MINGW_FLOAT_H_ */ 169 | 170 | -------------------------------------------------------------------------------- /chapter13 The Preprocessor/limits.h: -------------------------------------------------------------------------------- 1 | /* 2 | * limits.h 3 | * This file has no copyright assigned and is placed in the Public Domain. 4 | * This file is a part of the mingw-runtime package. 5 | * No warranty is given; refer to the file DISCLAIMER within the package. 6 | * 7 | * Functions for manipulating paths and directories (included from io.h) 8 | * plus functions for setting the current drive. 9 | * 10 | * Defines constants for the sizes of integral types. 11 | * 12 | * NOTE: GCC should supply a version of this header and it should be safe to 13 | * use that version instead of this one (maybe safer). 14 | * 15 | */ 16 | 17 | #ifndef _LIMITS_H_ 18 | #define _LIMITS_H_ 19 | 20 | /* All the headers include this file. */ 21 | #include <_mingw.h> 22 | 23 | /* 24 | * File system limits 25 | * 26 | * TODO: NAME_MAX and OPEN_MAX are file system limits or not? Are they the 27 | * same as FILENAME_MAX and FOPEN_MAX from stdio.h? 28 | * NOTE: PATH_MAX is the POSIX equivalent for Microsoft's MAX_PATH; the two 29 | * are semantically identical, with a limit of 259 characters for the 30 | * path name, plus one for a terminating NUL, for a total of 260. 31 | */ 32 | #define PATH_MAX 260 33 | 34 | /* 35 | * Characteristics of the char data type. 36 | * 37 | * TODO: Is MB_LEN_MAX correct? 38 | */ 39 | #define CHAR_BIT 8 40 | #define MB_LEN_MAX 2 41 | 42 | #define SCHAR_MIN (-128) 43 | #define SCHAR_MAX 127 44 | 45 | #define UCHAR_MAX 255 46 | 47 | /* TODO: Is this safe? I think it might just be testing the preprocessor, 48 | * not the compiler itself... */ 49 | #if ('\x80' < 0) 50 | #define CHAR_MIN SCHAR_MIN 51 | #define CHAR_MAX SCHAR_MAX 52 | #else 53 | #define CHAR_MIN 0 54 | #define CHAR_MAX UCHAR_MAX 55 | #endif 56 | 57 | /* 58 | * Maximum and minimum values for ints. 59 | */ 60 | #define INT_MAX 2147483647 61 | #define INT_MIN (-INT_MAX-1) 62 | 63 | #define UINT_MAX 0xffffffff 64 | 65 | /* 66 | * Maximum and minimum values for shorts. 67 | */ 68 | #define SHRT_MAX 32767 69 | #define SHRT_MIN (-SHRT_MAX-1) 70 | 71 | #define USHRT_MAX 0xffff 72 | 73 | /* 74 | * Maximum and minimum values for longs and unsigned longs. 75 | * 76 | * TODO: This is not correct for Alphas, which have 64 bit longs. 77 | */ 78 | #define LONG_MAX 2147483647L 79 | #define LONG_MIN (-LONG_MAX-1) 80 | 81 | #define ULONG_MAX 0xffffffffUL 82 | 83 | #ifndef __STRICT_ANSI__ 84 | /* POSIX wants this. */ 85 | #define SSIZE_MAX LONG_MAX 86 | #endif 87 | 88 | #if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) \ 89 | || !defined(__STRICT_ANSI__) 90 | /* ISO C9x macro names */ 91 | #define LLONG_MAX 9223372036854775807LL 92 | #define LLONG_MIN (-LLONG_MAX - 1) 93 | #define ULLONG_MAX (2ULL * LLONG_MAX + 1) 94 | #endif 95 | 96 | /* 97 | * The GNU C compiler also allows 'long long int' 98 | */ 99 | #if !defined(__STRICT_ANSI__) && defined(__GNUC__) 100 | 101 | #define LONG_LONG_MAX 9223372036854775807LL 102 | #define LONG_LONG_MIN (-LONG_LONG_MAX-1) 103 | #define ULONG_LONG_MAX (2ULL * LONG_LONG_MAX + 1) 104 | 105 | /* MSVC compatibility */ 106 | #define _I64_MIN LONG_LONG_MIN 107 | #define _I64_MAX LONG_LONG_MAX 108 | #define _UI64_MAX ULONG_LONG_MAX 109 | 110 | #endif /* Not Strict ANSI and GNU C compiler */ 111 | 112 | 113 | #endif /* not _LIMITS_H_ */ 114 | -------------------------------------------------------------------------------- /chapter13 The Preprocessor/metric.h: -------------------------------------------------------------------------------- 1 | #define INCHES_PER_CENTIMETER 0.394 2 | #define CENTIMETERD_PER_INCH 1 / INCHES_PER_CENTIMETER 3 | 4 | #define QUARTS_PER_LITER 1.057 5 | #define LITERS_PER_QUART 1 / QUARTS_PER_LITER 6 | 7 | #define OUNCES_PER_GRAM 0.035 8 | #define GRAMS_PER_OUNCE 1 / OUNCES_PER_GRAM 9 | -------------------------------------------------------------------------------- /chapter13 The Preprocessor/prog1301.c: -------------------------------------------------------------------------------- 1 | // 演示#define语句 2 | #include 3 | 4 | #define YES 1 5 | #define NO 0 6 | 7 | // 判断整数是否是偶数的函数 8 | int isEven(int number){ 9 | int answer; 10 | 11 | if(number % 2) 12 | answer = NO; 13 | else 14 | answer = YES; 15 | 16 | return answer; 17 | } 18 | 19 | int main(void){ 20 | int isEven(int number); 21 | 22 | if(isEven(17) == YES) 23 | printf("yes\n"); 24 | else 25 | printf("no\n"); 26 | 27 | if(isEven(20) == YES) 28 | printf("yes\n"); 29 | else 30 | printf("no\n"); 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /chapter13 The Preprocessor/prog1302.c: -------------------------------------------------------------------------------- 1 | // 预定义符号的更多例子 2 | /* 计算给定半径的圆面积、圆周长和球体体积的函数*/ 3 | #include 4 | 5 | #define PI 3.141592654 6 | 7 | double area(double r){ 8 | return PI * r * r; 9 | } 10 | 11 | double circumference(double r){ 12 | return 2.0 * PI * r; 13 | } 14 | 15 | double volume(double r){ 16 | return 4.0 / 3.0 * PI * r * r *r; 17 | } 18 | 19 | int main(void){ 20 | double area(double r); 21 | double circumference(double r); 22 | double volume(double r); 23 | 24 | printf("radius = 1: %.4f %.4f %.4f\n", 25 | area(1), circumference(1), volume(1)); 26 | 27 | printf("radius = 4.98: %.4f %.4f %.4f\n", 28 | area(4.98), circumference(4.98), volume(4.98)); 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /chapter13 The Preprocessor/prog1303.c: -------------------------------------------------------------------------------- 1 | /*使用#include的程序 2 | * 注意:本程序假设宏定义在metric.h的文件 3 | * */ 4 | #include 5 | #include "metric.h" 6 | 7 | int main(void){ 8 | float liters, gallons; 9 | 10 | printf("*** Liters to Gallons ***\n\n"); 11 | printf("Enter the number of liters: "); 12 | scanf("%f", &liters); 13 | 14 | gallons = liters * QUARTS_PER_LITER / 4.0; 15 | printf("%g liters = %g gallons\n", liters, gallons); 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /chapter13 The Preprocessor/stdio.h: -------------------------------------------------------------------------------- 1 | /* 2 | * stdio.h 3 | * This file has no copyright assigned and is placed in the Public Domain. 4 | * This file is a part of the mingw-runtime package. 5 | * No warranty is given; refer to the file DISCLAIMER within the package. 6 | * 7 | * Definitions of types and prototypes of functions for standard input and 8 | * output. 9 | * 10 | * NOTE: The file manipulation functions provided by Microsoft seem to 11 | * work with either slash (/) or backslash (\) as the directory separator. 12 | * 13 | */ 14 | 15 | #ifndef _STDIO_H_ 16 | #define _STDIO_H_ 17 | 18 | /* All the headers include this file. */ 19 | #include <_mingw.h> 20 | 21 | #ifndef RC_INVOKED 22 | #define __need_size_t 23 | #define __need_NULL 24 | #define __need_wchar_t 25 | #define __need_wint_t 26 | #include 27 | #define __need___va_list 28 | #include 29 | #endif /* Not RC_INVOKED */ 30 | 31 | 32 | /* Flags for the iobuf structure */ 33 | #define _IOREAD 1 /* currently reading */ 34 | #define _IOWRT 2 /* currently writing */ 35 | #define _IORW 0x0080 /* opened as "r+w" */ 36 | 37 | 38 | /* 39 | * The three standard file pointers provided by the run time library. 40 | * NOTE: These will go to the bit-bucket silently in GUI applications! 41 | */ 42 | #define STDIN_FILENO 0 43 | #define STDOUT_FILENO 1 44 | #define STDERR_FILENO 2 45 | 46 | /* Returned by various functions on end of file condition or error. */ 47 | #define EOF (-1) 48 | 49 | /* 50 | * The maximum length of a file name. You should use GetVolumeInformation 51 | * instead of this constant. But hey, this works. 52 | * Also defined in io.h. 53 | */ 54 | #ifndef FILENAME_MAX 55 | #define FILENAME_MAX (260) 56 | #endif 57 | 58 | /* 59 | * The maximum number of files that may be open at once. I have set this to 60 | * a conservative number. The actual value may be higher. 61 | */ 62 | #define FOPEN_MAX (20) 63 | 64 | /* After creating this many names, tmpnam and tmpfile return NULL */ 65 | #define TMP_MAX 32767 66 | /* 67 | * Tmpnam, tmpfile and, sometimes, _tempnam try to create 68 | * temp files in the root directory of the current drive 69 | * (not in pwd, as suggested by some older MS doc's). 70 | * Redefining these macros does not effect the CRT functions. 71 | */ 72 | #define _P_tmpdir "\\" 73 | #ifndef __STRICT_ANSI__ 74 | #define P_tmpdir _P_tmpdir 75 | #endif 76 | #define _wP_tmpdir L"\\" 77 | 78 | /* 79 | * The maximum size of name (including NUL) that will be put in the user 80 | * supplied buffer caName for tmpnam. 81 | * Inferred from the size of the static buffer returned by tmpnam 82 | * when passed a NULL argument. May actually be smaller. 83 | */ 84 | #define L_tmpnam (16) 85 | 86 | #define _IOFBF 0x0000 /* full buffered */ 87 | #define _IOLBF 0x0040 /* line buffered */ 88 | #define _IONBF 0x0004 /* not buffered */ 89 | 90 | #define _IOMYBUF 0x0008 /* stdio malloc()'d buffer */ 91 | #define _IOEOF 0x0010 /* EOF reached on read */ 92 | #define _IOERR 0x0020 /* I/O error from system */ 93 | #define _IOSTRG 0x0040 /* Strange or no file descriptor */ 94 | #ifdef _POSIX_SOURCE 95 | # define _IOAPPEND 0x0200 96 | #endif 97 | /* 98 | * The buffer size as used by setbuf such that it is equivalent to 99 | * (void) setvbuf(fileSetBuffer, caBuffer, _IOFBF, BUFSIZ). 100 | */ 101 | #define BUFSIZ 512 102 | 103 | /* Constants for nOrigin indicating the position relative to which fseek 104 | * sets the file position. Defined unconditionally since ISO and POSIX 105 | * say they are defined here. 106 | */ 107 | #define SEEK_SET 0 108 | #define SEEK_CUR 1 109 | #define SEEK_END 2 110 | 111 | #ifndef RC_INVOKED 112 | 113 | #ifndef __VALIST 114 | #ifdef __GNUC__ 115 | #define __VALIST __gnuc_va_list 116 | #else 117 | #define __VALIST char* 118 | #endif 119 | #endif /* defined __VALIST */ 120 | 121 | /* 122 | * The structure underlying the FILE type. 123 | * 124 | * Some believe that nobody in their right mind should make use of the 125 | * internals of this structure. Provided by Pedro A. Aranda Gutiirrez 126 | * . 127 | */ 128 | #ifndef _FILE_DEFINED 129 | #define _FILE_DEFINED 130 | typedef struct _iobuf 131 | { 132 | char* _ptr; 133 | int _cnt; 134 | char* _base; 135 | int _flag; 136 | int _file; 137 | int _charbuf; 138 | int _bufsiz; 139 | char* _tmpfname; 140 | } FILE; 141 | #endif /* Not _FILE_DEFINED */ 142 | 143 | 144 | /* 145 | * The standard file handles 146 | */ 147 | #ifndef __DECLSPEC_SUPPORTED 148 | 149 | extern FILE (*_imp___iob)[]; /* A pointer to an array of FILE */ 150 | 151 | #define _iob (*_imp___iob) /* An array of FILE */ 152 | 153 | #else /* __DECLSPEC_SUPPORTED */ 154 | 155 | __MINGW_IMPORT FILE _iob[]; /* An array of FILE imported from DLL. */ 156 | 157 | #endif /* __DECLSPEC_SUPPORTED */ 158 | 159 | #define stdin (&_iob[STDIN_FILENO]) 160 | #define stdout (&_iob[STDOUT_FILENO]) 161 | #define stderr (&_iob[STDERR_FILENO]) 162 | 163 | _BEGIN_C_DECLS 164 | 165 | /* 166 | * File Operations 167 | */ 168 | _CRTIMP FILE* __cdecl __MINGW_NOTHROW fopen (const char*, const char*); 169 | _CRTIMP FILE* __cdecl __MINGW_NOTHROW freopen (const char*, const char*, FILE*); 170 | _CRTIMP int __cdecl __MINGW_NOTHROW fflush (FILE*); 171 | _CRTIMP int __cdecl __MINGW_NOTHROW fclose (FILE*); 172 | /* MS puts remove & rename (but not wide versions) in io.h also */ 173 | _CRTIMP int __cdecl __MINGW_NOTHROW remove (const char*); 174 | _CRTIMP int __cdecl __MINGW_NOTHROW rename (const char*, const char*); 175 | _CRTIMP FILE* __cdecl __MINGW_NOTHROW tmpfile (void); 176 | _CRTIMP char* __cdecl __MINGW_NOTHROW tmpnam (char*); 177 | 178 | #ifndef __STRICT_ANSI__ 179 | _CRTIMP char* __cdecl __MINGW_NOTHROW _tempnam (const char*, const char*); 180 | _CRTIMP int __cdecl __MINGW_NOTHROW _rmtmp(void); 181 | _CRTIMP int __cdecl __MINGW_NOTHROW _unlink (const char*); 182 | 183 | #ifndef NO_OLDNAMES 184 | _CRTIMP char* __cdecl __MINGW_NOTHROW tempnam (const char*, const char*); 185 | _CRTIMP int __cdecl __MINGW_NOTHROW rmtmp(void); 186 | _CRTIMP int __cdecl __MINGW_NOTHROW unlink (const char*); 187 | #endif 188 | #endif /* __STRICT_ANSI__ */ 189 | 190 | _CRTIMP int __cdecl __MINGW_NOTHROW setvbuf (FILE*, char*, int, size_t); 191 | 192 | _CRTIMP void __cdecl __MINGW_NOTHROW setbuf (FILE*, char*); 193 | 194 | /* 195 | * Formatted Output 196 | * 197 | * MSVCRT implementations are not ANSI C99 conformant... 198 | * we offer these conforming alternatives from libmingwex.a 199 | */ 200 | #undef __mingw_stdio_redirect__ 201 | #define __mingw_stdio_redirect__(F) __cdecl __MINGW_NOTHROW __mingw_##F 202 | 203 | extern int __mingw_stdio_redirect__(fprintf)(FILE*, const char*, ...); 204 | extern int __mingw_stdio_redirect__(printf)(const char*, ...); 205 | extern int __mingw_stdio_redirect__(sprintf)(char*, const char*, ...); 206 | extern int __mingw_stdio_redirect__(snprintf)(char*, size_t, const char*, ...); 207 | extern int __mingw_stdio_redirect__(vfprintf)(FILE*, const char*, __VALIST); 208 | extern int __mingw_stdio_redirect__(vprintf)(const char*, __VALIST); 209 | extern int __mingw_stdio_redirect__(vsprintf)(char*, const char*, __VALIST); 210 | extern int __mingw_stdio_redirect__(vsnprintf)(char*, size_t, const char*, __VALIST); 211 | 212 | #if __USE_MINGW_ANSI_STDIO 213 | /* 214 | * User has expressed a preference for C99 conformance... 215 | */ 216 | # undef __mingw_stdio_redirect__ 217 | # ifdef __cplusplus 218 | /* 219 | * For C++ we use inline implementations, to avoid interference 220 | * with namespace qualification, which may result from using #defines. 221 | */ 222 | # define __mingw_stdio_redirect__ inline __cdecl __MINGW_NOTHROW 223 | 224 | # elif defined __GNUC__ 225 | /* 226 | * FIXME: Is there any GCC version prerequisite here? 227 | * 228 | * We also prefer inline implementations for C, when we can be confident 229 | * that the GNU specific __inline__ mechanism is supported. 230 | */ 231 | # define __mingw_stdio_redirect__ static __inline__ __cdecl __MINGW_NOTHROW 232 | 233 | # else 234 | /* 235 | * Can't use inlines; fall back on module local static stubs. 236 | */ 237 | # define __mingw_stdio_redirect__ static __cdecl __MINGW_NOTHROW 238 | # endif 239 | 240 | __mingw_stdio_redirect__ 241 | int fprintf (FILE *__stream, const char *__format, ...) 242 | { 243 | register int __retval; 244 | __builtin_va_list __local_argv; __builtin_va_start( __local_argv, __format ); 245 | __retval = __mingw_vfprintf( __stream, __format, __local_argv ); 246 | __builtin_va_end( __local_argv ); 247 | return __retval; 248 | } 249 | 250 | __mingw_stdio_redirect__ 251 | int printf (const char *__format, ...) 252 | { 253 | register int __retval; 254 | __builtin_va_list __local_argv; __builtin_va_start( __local_argv, __format ); 255 | __retval = __mingw_vprintf( __format, __local_argv ); 256 | __builtin_va_end( __local_argv ); 257 | return __retval; 258 | } 259 | 260 | __mingw_stdio_redirect__ 261 | int sprintf (char *__stream, const char *__format, ...) 262 | { 263 | register int __retval; 264 | __builtin_va_list __local_argv; __builtin_va_start( __local_argv, __format ); 265 | __retval = __mingw_vsprintf( __stream, __format, __local_argv ); 266 | __builtin_va_end( __local_argv ); 267 | return __retval; 268 | } 269 | 270 | __mingw_stdio_redirect__ 271 | int vfprintf (FILE *__stream, const char *__format, __VALIST __local_argv) 272 | { 273 | return __mingw_vfprintf( __stream, __format, __local_argv ); 274 | } 275 | 276 | __mingw_stdio_redirect__ 277 | int vprintf (const char *__format, __VALIST __local_argv) 278 | { 279 | return __mingw_vprintf( __format, __local_argv ); 280 | } 281 | 282 | __mingw_stdio_redirect__ 283 | int vsprintf (char *__stream, const char *__format, __VALIST __local_argv) 284 | { 285 | return __mingw_vsprintf( __stream, __format, __local_argv ); 286 | } 287 | 288 | #else 289 | /* 290 | * Default configuration: simply direct all calls to MSVCRT... 291 | */ 292 | _CRTIMP int __cdecl __MINGW_NOTHROW fprintf (FILE*, const char*, ...); 293 | _CRTIMP int __cdecl __MINGW_NOTHROW printf (const char*, ...); 294 | _CRTIMP int __cdecl __MINGW_NOTHROW sprintf (char*, const char*, ...); 295 | _CRTIMP int __cdecl __MINGW_NOTHROW vfprintf (FILE*, const char*, __VALIST); 296 | _CRTIMP int __cdecl __MINGW_NOTHROW vprintf (const char*, __VALIST); 297 | _CRTIMP int __cdecl __MINGW_NOTHROW vsprintf (char*, const char*, __VALIST); 298 | 299 | #endif 300 | /* 301 | * Regardless of user preference, always offer these alternative 302 | * entry points, for direct access to the MSVCRT implementations. 303 | */ 304 | #undef __mingw_stdio_redirect__ 305 | #define __mingw_stdio_redirect__(F) __cdecl __MINGW_NOTHROW __msvcrt_##F 306 | 307 | _CRTIMP int __mingw_stdio_redirect__(fprintf)(FILE*, const char*, ...); 308 | _CRTIMP int __mingw_stdio_redirect__(printf)(const char*, ...); 309 | _CRTIMP int __mingw_stdio_redirect__(sprintf)(char*, const char*, ...); 310 | _CRTIMP int __mingw_stdio_redirect__(vfprintf)(FILE*, const char*, __VALIST); 311 | _CRTIMP int __mingw_stdio_redirect__(vprintf)(const char*, __VALIST); 312 | _CRTIMP int __mingw_stdio_redirect__(vsprintf)(char*, const char*, __VALIST); 313 | 314 | #undef __mingw_stdio_redirect__ 315 | 316 | /* The following three ALWAYS refer to the MSVCRT implementations... 317 | */ 318 | _CRTIMP int __cdecl __MINGW_NOTHROW _snprintf (char*, size_t, const char*, ...); 319 | _CRTIMP int __cdecl __MINGW_NOTHROW _vsnprintf (char*, size_t, const char*, __VALIST); 320 | _CRTIMP int __cdecl __MINGW_NOTHROW _vscprintf (const char*, __VALIST); 321 | 322 | #ifndef __NO_ISOCEXT /* externs in libmingwex.a */ 323 | /* 324 | * Microsoft does not provide implementations for the following, 325 | * which are required by C99. Note in particular that the corresponding 326 | * Microsoft implementations of _snprintf() and _vsnprintf() are *not* 327 | * compatible with C99, but the following are; if you want the MSVCRT 328 | * behaviour, you *must* use the Microsoft uglified names. 329 | */ 330 | int __cdecl __MINGW_NOTHROW snprintf (char *, size_t, const char *, ...); 331 | int __cdecl __MINGW_NOTHROW vsnprintf (char *, size_t, const char *, __VALIST); 332 | 333 | int __cdecl __MINGW_NOTHROW vscanf (const char * __restrict__, __VALIST); 334 | int __cdecl __MINGW_NOTHROW vfscanf (FILE * __restrict__, const char * __restrict__, 335 | __VALIST); 336 | int __cdecl __MINGW_NOTHROW vsscanf (const char * __restrict__, 337 | const char * __restrict__, __VALIST); 338 | 339 | #endif /* !__NO_ISOCEXT */ 340 | 341 | /* 342 | * Formatted Input 343 | */ 344 | 345 | _CRTIMP int __cdecl __MINGW_NOTHROW fscanf (FILE*, const char*, ...); 346 | _CRTIMP int __cdecl __MINGW_NOTHROW scanf (const char*, ...); 347 | _CRTIMP int __cdecl __MINGW_NOTHROW sscanf (const char*, const char*, ...); 348 | /* 349 | * Character Input and Output Functions 350 | */ 351 | 352 | _CRTIMP int __cdecl __MINGW_NOTHROW fgetc (FILE*); 353 | _CRTIMP char* __cdecl __MINGW_NOTHROW fgets (char*, int, FILE*); 354 | _CRTIMP int __cdecl __MINGW_NOTHROW fputc (int, FILE*); 355 | _CRTIMP int __cdecl __MINGW_NOTHROW fputs (const char*, FILE*); 356 | _CRTIMP char* __cdecl __MINGW_NOTHROW gets (char*); 357 | _CRTIMP int __cdecl __MINGW_NOTHROW puts (const char*); 358 | _CRTIMP int __cdecl __MINGW_NOTHROW ungetc (int, FILE*); 359 | 360 | /* Traditionally, getc and putc are defined as macros. but the 361 | standard doesn't say that they must be macros. 362 | We use inline functions here to allow the fast versions 363 | to be used in C++ with namespace qualification, eg., ::getc. 364 | 365 | _filbuf and _flsbuf are not thread-safe. */ 366 | _CRTIMP int __cdecl __MINGW_NOTHROW _filbuf (FILE*); 367 | _CRTIMP int __cdecl __MINGW_NOTHROW _flsbuf (int, FILE*); 368 | 369 | #if !defined _MT 370 | 371 | __CRT_INLINE int __cdecl __MINGW_NOTHROW getc (FILE* __F) 372 | { 373 | return (--__F->_cnt >= 0) 374 | ? (int) (unsigned char) *__F->_ptr++ 375 | : _filbuf (__F); 376 | } 377 | 378 | __CRT_INLINE int __cdecl __MINGW_NOTHROW putc (int __c, FILE* __F) 379 | { 380 | return (--__F->_cnt >= 0) 381 | ? (int) (unsigned char) (*__F->_ptr++ = (char)__c) 382 | : _flsbuf (__c, __F); 383 | } 384 | 385 | __CRT_INLINE int __cdecl __MINGW_NOTHROW getchar (void) 386 | { 387 | return (--stdin->_cnt >= 0) 388 | ? (int) (unsigned char) *stdin->_ptr++ 389 | : _filbuf (stdin); 390 | } 391 | 392 | __CRT_INLINE int __cdecl __MINGW_NOTHROW putchar(int __c) 393 | { 394 | return (--stdout->_cnt >= 0) 395 | ? (int) (unsigned char) (*stdout->_ptr++ = (char)__c) 396 | : _flsbuf (__c, stdout);} 397 | 398 | #else /* Use library functions. */ 399 | 400 | _CRTIMP int __cdecl __MINGW_NOTHROW getc (FILE*); 401 | _CRTIMP int __cdecl __MINGW_NOTHROW putc (int, FILE*); 402 | _CRTIMP int __cdecl __MINGW_NOTHROW getchar (void); 403 | _CRTIMP int __cdecl __MINGW_NOTHROW putchar (int); 404 | 405 | #endif 406 | 407 | /* 408 | * Direct Input and Output Functions 409 | */ 410 | 411 | _CRTIMP size_t __cdecl __MINGW_NOTHROW fread (void*, size_t, size_t, FILE*); 412 | _CRTIMP size_t __cdecl __MINGW_NOTHROW fwrite (const void*, size_t, size_t, FILE*); 413 | 414 | /* 415 | * File Positioning Functions 416 | */ 417 | 418 | _CRTIMP int __cdecl __MINGW_NOTHROW fseek (FILE*, long, int); 419 | _CRTIMP long __cdecl __MINGW_NOTHROW ftell (FILE*); 420 | _CRTIMP void __cdecl __MINGW_NOTHROW rewind (FILE*); 421 | 422 | #if __MSVCRT_VERSION__ >= 0x800 423 | _CRTIMP int __cdecl __MINGW_NOTHROW _fseek_nolock (FILE*, long, int); 424 | _CRTIMP long __cdecl __MINGW_NOTHROW _ftell_nolock (FILE*); 425 | 426 | _CRTIMP int __cdecl __MINGW_NOTHROW _fseeki64 (FILE*, __int64, int); 427 | _CRTIMP __int64 __cdecl __MINGW_NOTHROW _ftelli64 (FILE*); 428 | _CRTIMP int __cdecl __MINGW_NOTHROW _fseeki64_nolock (FILE*, __int64, int); 429 | _CRTIMP __int64 __cdecl __MINGW_NOTHROW _ftelli64_nolock (FILE*); 430 | #endif 431 | 432 | #ifdef __USE_MINGW_FSEEK /* These are in libmingwex.a */ 433 | /* 434 | * Workaround for limitations on win9x where a file contents are 435 | * not zero'd out if you seek past the end and then write. 436 | */ 437 | 438 | int __cdecl __MINGW_NOTHROW __mingw_fseek (FILE *, long, int); 439 | size_t __cdecl __MINGW_NOTHROW __mingw_fwrite (const void*, size_t, size_t, FILE*); 440 | #define fseek(fp, offset, whence) __mingw_fseek(fp, offset, whence) 441 | #define fwrite(buffer, size, count, fp) __mingw_fwrite(buffer, size, count, fp) 442 | #endif /* __USE_MINGW_FSEEK */ 443 | 444 | /* 445 | * An opaque data type used for storing file positions... The contents of 446 | * this type are unknown, but we (the compiler) need to know the size 447 | * because the programmer using fgetpos and fsetpos will be setting aside 448 | * storage for fpos_t structres. Actually I tested using a byte array and 449 | * it is fairly evident that the fpos_t type is a long (in CRTDLL.DLL). 450 | * Perhaps an unsigned long? TODO? It's definitely a 64-bit number in 451 | * MSVCRT however, and for now `long long' will do. 452 | */ 453 | #ifdef __MSVCRT__ 454 | typedef long long fpos_t; 455 | #else 456 | typedef long fpos_t; 457 | #endif 458 | 459 | _CRTIMP int __cdecl __MINGW_NOTHROW fgetpos (FILE*, fpos_t*); 460 | _CRTIMP int __cdecl __MINGW_NOTHROW fsetpos (FILE*, const fpos_t*); 461 | 462 | /* 463 | * Error Functions 464 | */ 465 | 466 | _CRTIMP int __cdecl __MINGW_NOTHROW feof (FILE*); 467 | _CRTIMP int __cdecl __MINGW_NOTHROW ferror (FILE*); 468 | 469 | #ifdef __cplusplus 470 | inline int __cdecl __MINGW_NOTHROW feof (FILE* __F) 471 | { return __F->_flag & _IOEOF; } 472 | inline int __cdecl __MINGW_NOTHROW ferror (FILE* __F) 473 | { return __F->_flag & _IOERR; } 474 | #else 475 | #define feof(__F) ((__F)->_flag & _IOEOF) 476 | #define ferror(__F) ((__F)->_flag & _IOERR) 477 | #endif 478 | 479 | _CRTIMP void __cdecl __MINGW_NOTHROW clearerr (FILE*); 480 | _CRTIMP void __cdecl __MINGW_NOTHROW perror (const char*); 481 | 482 | 483 | #ifndef __STRICT_ANSI__ 484 | /* 485 | * Pipes 486 | */ 487 | _CRTIMP FILE* __cdecl __MINGW_NOTHROW _popen (const char*, const char*); 488 | _CRTIMP int __cdecl __MINGW_NOTHROW _pclose (FILE*); 489 | 490 | #ifndef NO_OLDNAMES 491 | _CRTIMP FILE* __cdecl __MINGW_NOTHROW popen (const char*, const char*); 492 | _CRTIMP int __cdecl __MINGW_NOTHROW pclose (FILE*); 493 | #endif 494 | 495 | /* 496 | * Other Non ANSI functions 497 | */ 498 | _CRTIMP int __cdecl __MINGW_NOTHROW _flushall (void); 499 | _CRTIMP int __cdecl __MINGW_NOTHROW _fgetchar (void); 500 | _CRTIMP int __cdecl __MINGW_NOTHROW _fputchar (int); 501 | _CRTIMP FILE* __cdecl __MINGW_NOTHROW _fdopen (int, const char*); 502 | _CRTIMP int __cdecl __MINGW_NOTHROW _fileno (FILE*); 503 | _CRTIMP int __cdecl __MINGW_NOTHROW _fcloseall (void); 504 | _CRTIMP FILE* __cdecl __MINGW_NOTHROW _fsopen (const char*, const char*, int); 505 | #ifdef __MSVCRT__ 506 | _CRTIMP int __cdecl __MINGW_NOTHROW _getmaxstdio (void); 507 | _CRTIMP int __cdecl __MINGW_NOTHROW _setmaxstdio (int); 508 | #endif 509 | 510 | /* Microsoft introduced a capability in MSVCR80.DLL and later, to 511 | * set the minimum number of digits to be displayed in a printf() 512 | * floating point exponent; they retro-fitted this in MSVCRT.DLL, 513 | * from Windows-Vista onwards, but we provide our own wrappers in 514 | * libmingwex.a, which make it possible for us to emulate the API 515 | * for any version of MSVCRT.DLL (including WinXP and earlier). 516 | */ 517 | #define _TWO_DIGIT_EXPONENT 1 518 | 519 | /* While Microsoft define the preceding manifest constant, they 520 | * appear to neglect to define its complement, (for restoration 521 | * of their default exponent display format); for orthogonality, 522 | * we will provide this regardless of Microsoft's negligence. 523 | */ 524 | #define _THREE_DIGIT_EXPONENT 0 525 | 526 | unsigned int __cdecl __mingw_get_output_format (void); 527 | unsigned int __cdecl __mingw_set_output_format (unsigned int); 528 | 529 | /* Also appearing for the first time in MSVCR80.DLL, and then also 530 | * retro-fitted to MSVCRT.DLL from Windows-Vista onwards, was this 531 | * pair of functions to control availability of "%n" formatting in 532 | * the MSVCRT.DLL printf() family of functions, for which we also 533 | * provide our own DLL version agnostic wrappers: 534 | */ 535 | int __cdecl __mingw_get_printf_count_output (void); 536 | int __cdecl __mingw_set_printf_count_output (int); 537 | 538 | #if __MSVCRT_VERSION__ >= 0x800 539 | /* 540 | * When the user declares that MSVCR80.DLL features are supported, 541 | * we simply expose the corresponding APIs... 542 | */ 543 | _CRTIMP unsigned int __cdecl __MINGW_NOTHROW _get_output_format (void); 544 | _CRTIMP unsigned int __cdecl __MINGW_NOTHROW _set_output_format (unsigned int); 545 | 546 | _CRTIMP int __cdecl __MINGW_NOTHROW _get_printf_count_output (void); 547 | _CRTIMP int __cdecl __MINGW_NOTHROW _set_printf_count_output (int); 548 | 549 | #else 550 | /* ...otherwise, we emulate the APIs, in a DLL version agnostic 551 | * manner, using our own implementation wrappers. 552 | */ 553 | __CRT_ALIAS unsigned int __cdecl _get_output_format (void) 554 | { return __mingw_get_output_format (); } 555 | 556 | __CRT_ALIAS unsigned int __cdecl _set_output_format (unsigned int __style) 557 | { return __mingw_set_output_format (__style); } 558 | 559 | /* When using our own printf() implementation, "%n" format is ALWAYS 560 | * supported, so we make this API a no-op, reporting it to be so; for 561 | * the alternative case, when using MSVCRT.DLL's printf(), we delegate 562 | * to our wrapper API implementation, which will invoke the API function 563 | * calls within the DLL, if they are available, or persistently report 564 | * the state of "%n" formatting as DISABLED if they are not. 565 | */ 566 | #if __USE_MINGW_ANSI_STDIO 567 | /* 568 | * Note that __USE_MINGW_ANSI_STDIO is not guaranteed to resolve to any 569 | * symbol which will represent a compilable logic state; map it to this 570 | * alternative which will, for the true state... 571 | */ 572 | # define __USE_MINGW_PRINTF 1 573 | #else 574 | /* ...and for the false. 575 | */ 576 | # define __USE_MINGW_PRINTF 0 577 | #endif 578 | 579 | __CRT_ALIAS int __cdecl _get_printf_count_output (void) 580 | { return __USE_MINGW_PRINTF ? 1 : __mingw_get_printf_count_output (); } 581 | 582 | __CRT_ALIAS int __cdecl _set_printf_count_output (int __mode) 583 | { return __USE_MINGW_PRINTF ? 1 : __mingw_set_printf_count_output (__mode); } 584 | #endif 585 | 586 | #ifndef _NO_OLDNAMES 587 | _CRTIMP int __cdecl __MINGW_NOTHROW fgetchar (void); 588 | _CRTIMP int __cdecl __MINGW_NOTHROW fputchar (int); 589 | _CRTIMP FILE* __cdecl __MINGW_NOTHROW fdopen (int, const char*); 590 | _CRTIMP int __cdecl __MINGW_NOTHROW fileno (FILE*); 591 | #endif /* Not _NO_OLDNAMES */ 592 | 593 | #define _fileno(__F) ((__F)->_file) 594 | #ifndef _NO_OLDNAMES 595 | #define fileno(__F) ((__F)->_file) 596 | #endif 597 | 598 | #if defined (__MSVCRT__) && !defined (__NO_MINGW_LFS) 599 | #include 600 | __CRT_INLINE __JMPSTUB__(( FUNCTION = fopen64, REMAPPED = fopen )) 601 | FILE* __cdecl __MINGW_NOTHROW fopen64 (const char* filename, const char* mode) 602 | { return fopen (filename, mode); } 603 | 604 | int __cdecl __MINGW_NOTHROW fseeko64 (FILE*, off64_t, int); 605 | 606 | #ifdef __USE_MINGW_FSEEK 607 | int __cdecl __MINGW_NOTHROW __mingw_fseeko64 (FILE *, off64_t, int); 608 | #define fseeko64(fp, offset, whence) __mingw_fseeko64(fp, offset, whence) 609 | #endif 610 | 611 | __CRT_INLINE __LIBIMPL__(( FUNCTION = ftello64 )) 612 | off64_t __cdecl __MINGW_NOTHROW ftello64 (FILE * stream) 613 | { 614 | fpos_t pos; 615 | if (fgetpos(stream, &pos)) 616 | return -1LL; 617 | else 618 | return ((off64_t) pos); 619 | } 620 | #endif /* __NO_MINGW_LFS */ 621 | 622 | #endif /* Not __STRICT_ANSI__ */ 623 | 624 | /* Wide versions */ 625 | 626 | #ifndef _WSTDIO_DEFINED 627 | /* also in wchar.h - keep in sync */ 628 | _CRTIMP int __cdecl __MINGW_NOTHROW fwprintf (FILE*, const wchar_t*, ...); 629 | _CRTIMP int __cdecl __MINGW_NOTHROW wprintf (const wchar_t*, ...); 630 | _CRTIMP int __cdecl __MINGW_NOTHROW _snwprintf (wchar_t*, size_t, const wchar_t*, ...); 631 | _CRTIMP int __cdecl __MINGW_NOTHROW vfwprintf (FILE*, const wchar_t*, __VALIST); 632 | _CRTIMP int __cdecl __MINGW_NOTHROW vwprintf (const wchar_t*, __VALIST); 633 | _CRTIMP int __cdecl __MINGW_NOTHROW _vsnwprintf (wchar_t*, size_t, const wchar_t*, __VALIST); 634 | _CRTIMP int __cdecl __MINGW_NOTHROW _vscwprintf (const wchar_t*, __VALIST); 635 | _CRTIMP int __cdecl __MINGW_NOTHROW fwscanf (FILE*, const wchar_t*, ...); 636 | _CRTIMP int __cdecl __MINGW_NOTHROW wscanf (const wchar_t*, ...); 637 | _CRTIMP int __cdecl __MINGW_NOTHROW swscanf (const wchar_t*, const wchar_t*, ...); 638 | _CRTIMP wint_t __cdecl __MINGW_NOTHROW fgetwc (FILE*); 639 | _CRTIMP wint_t __cdecl __MINGW_NOTHROW fputwc (wchar_t, FILE*); 640 | _CRTIMP wint_t __cdecl __MINGW_NOTHROW ungetwc (wchar_t, FILE*); 641 | 642 | /* These differ from the ISO C prototypes, which have a maxlen parameter (like snprintf). */ 643 | #ifndef __STRICT_ANSI__ 644 | _CRTIMP int __cdecl __MINGW_NOTHROW swprintf (wchar_t*, const wchar_t*, ...); 645 | _CRTIMP int __cdecl __MINGW_NOTHROW vswprintf (wchar_t*, const wchar_t*, __VALIST); 646 | #endif 647 | 648 | #ifdef __MSVCRT__ 649 | _CRTIMP wchar_t* __cdecl __MINGW_NOTHROW fgetws (wchar_t*, int, FILE*); 650 | _CRTIMP int __cdecl __MINGW_NOTHROW fputws (const wchar_t*, FILE*); 651 | _CRTIMP wint_t __cdecl __MINGW_NOTHROW getwc (FILE*); 652 | _CRTIMP wint_t __cdecl __MINGW_NOTHROW getwchar (void); 653 | _CRTIMP wchar_t* __cdecl __MINGW_NOTHROW _getws (wchar_t*); 654 | _CRTIMP wint_t __cdecl __MINGW_NOTHROW putwc (wint_t, FILE*); 655 | _CRTIMP int __cdecl __MINGW_NOTHROW _putws (const wchar_t*); 656 | _CRTIMP wint_t __cdecl __MINGW_NOTHROW putwchar (wint_t); 657 | _CRTIMP FILE* __cdecl __MINGW_NOTHROW _wfdopen(int, const wchar_t *); 658 | _CRTIMP FILE* __cdecl __MINGW_NOTHROW _wfopen (const wchar_t*, const wchar_t*); 659 | _CRTIMP FILE* __cdecl __MINGW_NOTHROW _wfreopen (const wchar_t*, const wchar_t*, FILE*); 660 | _CRTIMP FILE* __cdecl __MINGW_NOTHROW _wfsopen (const wchar_t*, const wchar_t*, int); 661 | _CRTIMP wchar_t* __cdecl __MINGW_NOTHROW _wtmpnam (wchar_t*); 662 | _CRTIMP wchar_t* __cdecl __MINGW_NOTHROW _wtempnam (const wchar_t*, const wchar_t*); 663 | _CRTIMP int __cdecl __MINGW_NOTHROW _wrename (const wchar_t*, const wchar_t*); 664 | _CRTIMP int __cdecl __MINGW_NOTHROW _wremove (const wchar_t*); 665 | _CRTIMP void __cdecl __MINGW_NOTHROW _wperror (const wchar_t*); 666 | _CRTIMP FILE* __cdecl __MINGW_NOTHROW _wpopen (const wchar_t*, const wchar_t*); 667 | #endif /* __MSVCRT__ */ 668 | 669 | #ifndef __NO_ISOCEXT /* externs in libmingwex.a */ 670 | int __cdecl __MINGW_NOTHROW snwprintf (wchar_t* s, size_t n, const wchar_t* format, ...); 671 | int __cdecl __MINGW_NOTHROW vsnwprintf (wchar_t* s, size_t n, const wchar_t* format, __VALIST arg); 672 | #ifndef __NO_INLINE__ 673 | __CRT_INLINE int __cdecl __MINGW_NOTHROW 674 | vsnwprintf (wchar_t* s, size_t n, const wchar_t* format, __VALIST arg) 675 | { return _vsnwprintf ( s, n, format, arg);} 676 | #endif 677 | int __cdecl __MINGW_NOTHROW vwscanf (const wchar_t * __restrict__, __VALIST); 678 | int __cdecl __MINGW_NOTHROW vfwscanf (FILE * __restrict__, 679 | const wchar_t * __restrict__, __VALIST); 680 | int __cdecl __MINGW_NOTHROW vswscanf (const wchar_t * __restrict__, 681 | const wchar_t * __restrict__, __VALIST); 682 | #endif 683 | 684 | #define _WSTDIO_DEFINED 685 | #endif /* _WSTDIO_DEFINED */ 686 | 687 | #ifndef __STRICT_ANSI__ 688 | #ifdef __MSVCRT__ 689 | #ifndef NO_OLDNAMES 690 | _CRTIMP FILE* __cdecl __MINGW_NOTHROW wpopen (const wchar_t*, const wchar_t*); 691 | #endif /* not NO_OLDNAMES */ 692 | #endif /* MSVCRT runtime */ 693 | 694 | /* 695 | * Other Non ANSI wide functions 696 | */ 697 | _CRTIMP wint_t __cdecl __MINGW_NOTHROW _fgetwchar (void); 698 | _CRTIMP wint_t __cdecl __MINGW_NOTHROW _fputwchar (wint_t); 699 | _CRTIMP int __cdecl __MINGW_NOTHROW _getw (FILE*); 700 | _CRTIMP int __cdecl __MINGW_NOTHROW _putw (int, FILE*); 701 | 702 | #ifndef _NO_OLDNAMES 703 | _CRTIMP wint_t __cdecl __MINGW_NOTHROW fgetwchar (void); 704 | _CRTIMP wint_t __cdecl __MINGW_NOTHROW fputwchar (wint_t); 705 | _CRTIMP int __cdecl __MINGW_NOTHROW getw (FILE*); 706 | _CRTIMP int __cdecl __MINGW_NOTHROW putw (int, FILE*); 707 | #endif /* Not _NO_OLDNAMES */ 708 | 709 | #endif /* __STRICT_ANSI */ 710 | 711 | _END_C_DECLS 712 | 713 | #endif /* Not RC_INVOKED */ 714 | #endif /* _STDIO_H_ */ 715 | -------------------------------------------------------------------------------- /chapter14 More on Data Types/exce1.c: -------------------------------------------------------------------------------- 1 | // 用typedef定义一个函数指针类型 2 | type int (*FnPtr)(void); 3 | -------------------------------------------------------------------------------- /chapter14 More on Data Types/exce2.c: -------------------------------------------------------------------------------- 1 | // 编写一个名为monthName的函数,该函数接收一个enum month类型的参数 2 | // 然后返回一个指向该月份名字的字符指针? 3 | #include 4 | 5 | enum month {january = 1, february, march, april, may, june, 6 | july, august, september, october, novermber, december }; 7 | 8 | char (*) monthName(enum month aMonth){ 9 | return &aMonth; 10 | } 11 | 12 | int main(void){ 13 | enum month aMonth; 14 | 15 | printf("Enter month number: "); 16 | scanf("%i", &aMonth); 17 | 18 | printf("%s\n", monthName(aMonth)); 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /chapter14 More on Data Types/exce3.c: -------------------------------------------------------------------------------- 1 | int main(void){ 2 | float f = 1.00; 3 | short int i = 100; 4 | long int l = 500L; 5 | double d = 15.00; 6 | 7 | f + i; // float 101 8 | l / d; // double 33.3333 9 | i / l + f; // float 1.0 10 | l * i; // long 50000 11 | f / 2; // float 0.5 12 | i / (d * f); // double 6.25 13 | l / (i * 2.0); // double 2.5 14 | l + i / (double) l; // double 501.0 15 | } 16 | -------------------------------------------------------------------------------- /chapter14 More on Data Types/prog1401.c: -------------------------------------------------------------------------------- 1 | // 使用枚举类型 2 | // 打印一个月中的每一天的程序 3 | #include 4 | 5 | int main(void){ 6 | enum month {january = 1, february, march, april, may, june, 7 | july, august, september, october, novermber, december }; 8 | enum month aMonth; 9 | int days; 10 | printf("Enter month number: "); 11 | scanf("%i", &aMonth); 12 | switch(aMonth){ 13 | case january: 14 | case march: 15 | case may: 16 | case july: 17 | case august: 18 | case october: 19 | case december: 20 | days = 31; 21 | break; 22 | case april: 23 | case june: 24 | case september: 25 | case novermber: 26 | days = 30; 27 | break; 28 | case february: 29 | days = 28; 30 | break; 31 | default: 32 | printf("bad month numbe\n"); 33 | days = 0; 34 | break; 35 | } 36 | if(days != 0) 37 | printf("Number of days is %i\n", days); 38 | if(aMonth == february) 39 | printf("...or 29 if it's a leap year\n"); 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /chapter16 Input and Output Operations in C/copyme: -------------------------------------------------------------------------------- 1 | This is a test of the file copy program 2 | that we have just developed using the 3 | fopen, fclose, getc, and putc functions. 4 | -------------------------------------------------------------------------------- /chapter16 Input and Output Operations in C/exce2.c: -------------------------------------------------------------------------------- 1 | // 重新查看前面的三个例子程序,并试着以重定向输入输出的方式运行它们。 2 | #include 3 | -------------------------------------------------------------------------------- /chapter16 Input and Output Operations in C/exce3.c: -------------------------------------------------------------------------------- 1 | // 编写一个程序,将一个文件的内容拷贝到另外一个文件中。 2 | // 在拷贝的时候,将原来文件中所有的小写字母都替换为对应的大写字母。 3 | #include 4 | -------------------------------------------------------------------------------- /chapter16 Input and Output Operations in C/exce4.c: -------------------------------------------------------------------------------- 1 | // 编写程序,交替地读取两个文件,并将其合并输出到标准输出中。 2 | // 如果一个文件中的行数小于另外一个文件,那么程序应该将较长文件的剩余内容也写到标准输出中。 3 | 4 | -------------------------------------------------------------------------------- /chapter16 Input and Output Operations in C/exce5.c: -------------------------------------------------------------------------------- 1 | // 编写程序,该程序将某个文件每一行上从m到n列之间的字符输出到标准输出。 2 | // 我们的程序应该从终端读取m和n的值。 3 | -------------------------------------------------------------------------------- /chapter16 Input and Output Operations in C/exce6.c: -------------------------------------------------------------------------------- 1 | // 编写程序,该程序每次读取并显示某个文件中的20行文本。 2 | // 在显示完之后,我们的程序等待用户输入一个字符,如果用户输入了q,则程序停止运行 3 | // 否则,程序再显示该文件中的20行文本 4 | -------------------------------------------------------------------------------- /chapter16 Input and Output Operations in C/prog1601.c: -------------------------------------------------------------------------------- 1 | // 显示格式化字符串用法的程序 2 | #include 3 | 4 | int main(void){ 5 | char c = 'X'; 6 | char s[] = "abcdefghijkmnopqrstuvwxyz"; 7 | int i = 425; 8 | short int j = 17; 9 | unsigned int u = 0xf179U; 10 | long int l = 75000L; 11 | long long int L = 0x1234567812345678LL; 12 | float f = 12.978F; 13 | double d = -97.4583; 14 | char *cp = &c; 15 | int *ip = &i; 16 | int c1, c2; 17 | 18 | printf("Integers:\n"); 19 | printf("%i %o %x %u\n", i, i, i, i); // 425 651 1a9 425 20 | printf("%x %x %#x %#X\n", i, i, i, i); // 1a9 1A9 0x1a9 0X1A9 21 | printf("%+i % i %07i %.7i\n", i, i, i, i); // +425 425 0000425 0000425 22 | printf("%i %o %x %u\n", j, j, j, j); // 17 21 11 17 23 | printf("%i %o %x %u\n", u, u, u, u); // 61817 170571 f179 61817 24 | printf("%ld %lo %lx %lu\n", l, l, l, l); // 75000 222370 124f8 75000 25 | printf("%lli %llo %llx %llu\n", L, L, L, L); 26 | // 1311768465173141112 110642547402215053170 1234567812345678 1311768465173141112 27 | 28 | printf("\nFloats and Doubles:\n"); 29 | printf("%f %e %g\n", f, f, f); // 12.978000 1.297800e+001 12.978 30 | printf("%.2f %.2e\n", f, f); // 12.98 1.30e+01 31 | printf("%.0f %.0e\n", f, f); // 13 1e+01 32 | printf("%7.2f %7.2e\n", f, f); // 12.98 1.30e+01 33 | printf("%f %e %g\n", d, d, d); // -97.458300 -97.45830e+01 -97.4583 34 | printf("%.*f\n", 3, d); // -97.458 35 | printf("%*.*f\n", 8, 2, d); // -97.46 36 | 37 | printf("\nCharacters:\n"); 38 | printf("%c\n", c); // X 39 | printf("%3c%3c\n", c, c); // X X 40 | printf("%x\n", c); // 58 41 | 42 | printf("\nStrings:\n"); 43 | printf("%s\n", s); // abcdefghijkmnopqrstuvwxyz 44 | printf("%.5s\n", s); // abcde 45 | printf("%30s\n", s); // abcdefghijkmnopqrstuvwxyz 46 | printf("%20.5s\n", s); // abcde 47 | printf("%-20.5s\n", s); // abcde 48 | 49 | printf("\nPointers:\n"); 50 | printf("%p %p\n\n", ip, cp); // 0028FEF0 0028FF0F 51 | 52 | printf("This%n is fun.%n\n", &c1, &c2); 53 | printf("c1 = %i, c2 = %i\n", c1, c2); // 4 12 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /chapter16 Input and Output Operations in C/prog1602.c: -------------------------------------------------------------------------------- 1 | // 显示文件所有字符的程序 2 | // 编译运行后使用如下的命令将其输入重定向到某个文件 copyprog < infile 3 | #include 4 | 5 | int main(void){ 6 | int c; 7 | 8 | while ((c = getchar()) != EOF) 9 | putchar(c); 10 | 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /chapter16 Input and Output Operations in C/prog1603.c: -------------------------------------------------------------------------------- 1 | // 拷贝文件的程序 2 | // 操作失败 Permission denied 3 | #include 4 | int main(void){ 5 | char inName[64], outName[64]; 6 | FILE *in, *out; 7 | int c; 8 | 9 | // 从使用者得到文件名 10 | printf("Enter name of file to be copied: "); 11 | scanf("%63s", inName); 12 | printf("Enter name of output file: "); 13 | scanf("%63s", outName); 14 | 15 | // 打开输入输出文件 16 | if((in = fopen(inName, "r")) == NULL){ 17 | printf("Can't open %s for reading.\n", inName); 18 | return 1; 19 | } 20 | if((out = fopen(outName, "w")) == NULL){ 21 | printf("Can't open %s for writing.\n", outName); 22 | return 2; 23 | } 24 | 25 | // 复制 in 到 out 26 | while((c = getc(in)) != EOF) 27 | putc(c, out); 28 | 29 | // 关闭打开的文件 30 | fclose(in); 31 | fclose(out); 32 | 33 | printf("File has been copied.\n"); 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /chapter17 Miscellaneous and Advanced Features/prog1701.c: -------------------------------------------------------------------------------- 1 | // 使用命令行参数的文件拷贝程序 2 | // 源文件的名字和目标文件的名字都将通过命令行参数指定,而不是提示用户输入 3 | // copyf foo fool 启动程序 4 | #include 5 | 6 | int main(int argc, char *argv[]){ 7 | FILE *in, *out; 8 | int c; 9 | 10 | if(argc != 3){ 11 | fprintf(stderr, "Need two files names\n"); 12 | return 1; 13 | } 14 | if((in = fopen(argv[1], "r")) == NULL){ 15 | fprintf(stderr, "Can't read %s.\n", argv[1]); 16 | return 2; 17 | } 18 | if((out = fopen(argv[2], "w")) == NULL){ 19 | fprintf(stderr, "Can't write %s.\n", argv[2]); 20 | return 3; 21 | } 22 | 23 | while((c = getc(in)) != EOF) 24 | putc(c, out); 25 | 26 | printf("File has been copied.\n"); 27 | fclose(in); 28 | fclose(out); 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /chapter18 Debugging Programs/prog1801.c: -------------------------------------------------------------------------------- 1 | // 使用预处理器增加调试语句 2 | #include 3 | #define DEBUG 4 | 5 | int process(int i, int j, int k){ 6 | return i + j + k; 7 | } 8 | 9 | int main(void){ 10 | int i, j, k, nread; 11 | nread = scanf("%d %d %d", &i, &j, &k); 12 | 13 | #ifdef DEBUG 14 | fprintf(stderr, "Number of integers read = %i\n", nread); 15 | fprintf(stderr, "i = %i, j = %i, k = %i\n", i, j, k); 16 | #endif 17 | 18 | printf("%i\n", process(i, j, k)); 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /chapter18 Debugging Programs/prog1802.c: -------------------------------------------------------------------------------- 1 | // 编译调试语句 2 | // 将字符串参数转化为整型数,使用标准库函数atoi 3 | // gcc -D DEBUG debug.c 4 | #include 5 | #include 6 | #define DEBUG 7 | 8 | int process(int i1, int i2){ 9 | int val; 10 | #ifdef DEBUG 11 | fprintf(stderr, "process(%i, %i)\n", i1, i2); 12 | #endif 13 | 14 | val = i1 * i2; 15 | #ifdef DEBUG 16 | fprintf(stderr, "return %i\n", val); 17 | #endif 18 | return val; 19 | } 20 | 21 | int main(int argc, char *argv[]){ 22 | int arg1 = 0, arg2 = 0; 23 | 24 | if(argc > 1) 25 | arg1 = atoi(argv[1]); 26 | if(argc == 3) 27 | arg2 = atoi(argv[2]); 28 | 29 | #ifdef DEBUG 30 | fprintf(stderr, "processed %i arguments\n", argc - 1); 31 | fprintf(stderr, "arg1 = %i, arg2 = %i\n", arg1, arg2); 32 | #endif 33 | 34 | printf("%i\n", process(arg1, arg2)); 35 | return 0; 36 | } 37 | 38 | -------------------------------------------------------------------------------- /chapter18 Debugging Programs/prog1803.c: -------------------------------------------------------------------------------- 1 | // 定义调试宏DEBUG 2 | // #define DEBUG(fmt, ...) 3 | #include 4 | #include 5 | #define DEBUG(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__) 6 | 7 | int process(int i1, int i2){ 8 | int val; 9 | DEBUG( "process(%i, %i)\n", i1, i2); 10 | val = i1 * i2; 11 | DEBUG("return %i\n", val); 12 | return val; 13 | } 14 | 15 | int main(int argc, char *argv[]){ 16 | int arg1 = 0, arg2 = 0; 17 | 18 | if(argc > 1) 19 | arg1 = atoi(argv[1]); 20 | if(argc == 3) 21 | arg2 = atoi(argv[2]); 22 | 23 | DEBUG("processed %i arguments\n", argc - 1); 24 | DEBUG("arg1 = %i, arg2 = %i\n", arg1, arg2); 25 | printf("%i\n", process(arg1, arg2)); 26 | return 0; 27 | } 28 | 29 | -------------------------------------------------------------------------------- /chapter18 Debugging Programs/prog1804.c: -------------------------------------------------------------------------------- 1 | // 使用gdb调试的一个简单程序 2 | #include 3 | int main(void){ 4 | const int data[5] = {1, 2, 3, 4, 5}; 5 | int i, sum; 6 | 7 | for(i = 0; i >= 0; ++i) 8 | sum += data[i]; 9 | 10 | printf("sum = %i\n", sum); 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /chapter18 Debugging Programs/prog1805.c: -------------------------------------------------------------------------------- 1 | // 使用gdb调试程序 2 | #include 3 | #include 4 | 5 | struct date{ 6 | int month; 7 | int day; 8 | int year; 9 | }; 10 | 11 | struct date foo(struct date x){ 12 | ++x.day; 13 | return x; 14 | } 15 | 16 | int main(void){ 17 | struct date today = {4, 9, 2016}; 18 | int array[5] = {1, 2, 3, 4, 5}; 19 | struct date *newdate, foo(); 20 | char *string = "test string"; 21 | int i = 3; 22 | 23 | newdate = (struct date *)malloc(sizeof(struct date)); 24 | newdate->month = 11; 25 | newdate->day = 15; 26 | newdate->year = 2004; 27 | 28 | today = foo(today); 29 | free(newdate); 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /chapter19 Object-Oriented Programming/prog1901.c: -------------------------------------------------------------------------------- 1 | // 使用C语言处理分数 2 | #include 3 | 4 | typedef struct{ 5 | int numerator; 6 | int denominator; 7 | } Fraction; 8 | 9 | int main(void){ 10 | Fraction myFract; 11 | 12 | myFract.numerator = 1; 13 | myFract.denominator = 3; 14 | printf("The fraction is %i/%i\n", myFract.numerator, myFract.denominator); 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /e: -------------------------------------------------------------------------------- 1 | commit d9c88bc8b7be3ec7a2fecc454129bc180da82e03 2 | Author: tendoasan 3 | Date: Fri Mar 25 00:21:23 2016 +0800 4 | 5 | 以秒为单位更新时间的程序 6 | 7 | commit d03dc9304e45dced2b16028c153bf98bef974e5e 8 | Author: tendoasan 9 | Date: Thu Mar 24 18:04:53 2016 +0800 10 | 11 | 计算第二天日期修正版,进一步封装 12 | 13 | commit 2bbf2fa464cceb6beda8d5adfa770d642e9a0f8e 14 | Author: tendoasan 15 | Date: Thu Mar 24 01:46:40 2016 +0800 16 | 17 | 删除无效文件 18 | 19 | commit 4d0e722b4c606c44cdcca2589fbf2540a0263ac0 20 | Author: tendoasan 21 | Date: Thu Mar 24 01:37:59 2016 +0800 22 | 23 | 考虑闰年,计算下一天 24 | 25 | commit 48a60a349df4fe6d62764703edc0a12459ceb806 26 | Author: tendoasan 27 | Date: Wed Mar 23 18:31:27 2016 +0800 28 | 29 | 计算第二天日期的程序 30 | 31 | commit b844869c6043041df125b14698a9b04e52540a28 32 | Author: tendoasan 33 | Date: Tue Mar 22 19:26:54 2016 +0800 34 | 35 | 显示结构使用的程序 36 | 37 | commit 2c09fc9225ab13e2b09ab839fd471a0e184bac08 38 | Author: tendoasan 39 | Date: Tue Mar 22 01:59:00 2016 +0800 40 | 41 | 第8章 使用函数 练习题 42 | 43 | commit a20517f65aa2839d683c74070f5a1aed31a95436 44 | Author: tendoasan 45 | Date: Mon Mar 21 21:36:11 2016 +0800 46 | 47 | 递归计算阶乘 48 | 49 | commit 96e5b6137404da7130c1151c70f5886c2f871d8c 50 | Author: tendoasan 51 | Date: Mon Mar 21 21:23:28 2016 +0800 52 | 53 | 演示自动变量与局部变量的使用的程序 54 | 55 | commit a079c3e0dfdd62e148d4ffd30247d898393c974a 56 | Author: tendoasan 57 | Date: Mon Mar 21 21:17:31 2016 +0800 58 | 59 | 将一个正整数转换为其他基数的函数 60 | 61 | commit 98f46d69b8de401fa19f2a043cbc078dbeee7fa5 62 | Author: tendoasan 63 | Date: Mon Mar 21 19:57:02 2016 +0800 64 | 65 | 将数组按照升序排列的程序 66 | 67 | commit 52b16e652186428471dad6427e19cdb4af5e6e07 68 | Author: tendoasan 69 | Date: Mon Mar 21 17:31:42 2016 +0800 70 | 71 | 在函数中改变数组元素 72 | 73 | commit fc6ad3a944a327c95ac531ca309dbcbbcb13d200 74 | Author: tendoasan 75 | Date: Mon Mar 21 17:23:20 2016 +0800 76 | 77 | 找出数组中的最小值的函数 78 | 79 | commit 7135dbb83ef7ebaafdd5250eb1aae95035824f7b 80 | Author: tendoasan 81 | Date: Mon Mar 21 13:47:31 2016 +0800 82 | 83 | 计算绝对值与平方根的函数 84 | 85 | commit 5cb35e7ef8e2d1027ae97a6b79b255157d360008 86 | Author: tendoasan 87 | Date: Mon Mar 21 13:17:28 2016 +0800 88 | 89 | 找出两个非负整数的最大公约数,并返回结果的函数 90 | 91 | commit 15182f8001302f69451fc26ddb316e9c2193495d 92 | Author: tendoasan 93 | Date: Mon Mar 21 12:53:27 2016 +0800 94 | 95 | 计算最大公约数(修订版) 96 | 97 | commit 6898a53fce2fc82d205f252fe080b14053070b73 98 | Author: tendoasan 99 | Date: Sun Mar 20 19:50:52 2016 +0800 100 | 101 | 计算第n个三角形数“ 102 | 103 | git commit -m 计算第n个三角形数“ 104 | 105 | commit 87de573460a4545f789d36ea0b4bff89763f74b3 106 | Author: tendoasan 107 | Date: Sun Mar 20 19:45:01 2016 +0800 108 | 109 | 调用更多的函数 110 | 111 | commit 649f9ebb3d7fa8300e9a238c35c20a6cb0f24194 112 | Author: tendoasan 113 | Date: Sun Mar 20 19:42:40 2016 +0800 114 | 115 | 调用函数 116 | 117 | commit 09d1b1d6553a20297c0763a346adb6574c35633f 118 | Author: tendoasan 119 | Date: Sun Mar 20 19:38:17 2016 +0800 120 | 121 | 在C语言中定义函数 122 | 123 | commit b8f7bcbf6a9ff5d28abc6afcecec644e4d27dc8b 124 | Author: tendoasan 125 | Date: Sat Mar 19 22:54:26 2016 +0800 126 | 127 | 第7章 使用数组 练习题 128 | 129 | commit 1cb6cf338981dfdb8457bb74c8524858ea503ef4 130 | Author: tendoasan 131 | Date: Sat Mar 19 20:42:48 2016 +0800 132 | 133 | 可变长度的数组 134 | 135 | commit c634c266f31111c1d403ca15e1ceb3542cc48fde 136 | Author: tendoasan 137 | Date: Fri Mar 18 19:43:17 2016 +0800 138 | 139 | Program to convert a positive integer to another base 140 | 141 | commit d2ad00efb104d45f89687d9fb0679724cb33bba0 142 | Author: tendoasan 143 | Date: Thu Mar 17 18:32:22 2016 +0800 144 | 145 | 数组初始化 146 | 147 | commit 21919e377a6044bc37f52d5378c944be11bfd9e6 148 | Author: tendoasan 149 | Date: Thu Mar 17 18:12:30 2016 +0800 150 | 151 | 产生质数表(修订版2) 152 | 153 | commit b3b503f3c48ca338235de5c2557d7f2f3b0cf01f 154 | Author: tendoasan 155 | Date: Wed Mar 16 18:30:52 2016 +0800 156 | 157 | 产生Fibonacci数 158 | 159 | commit 67b943f5621a19aec3f6cd7fcf47ede07cdc22a6 160 | Author: tendoasan 161 | Date: Tue Mar 15 21:05:23 2016 +0800 162 | 163 | 使用数组计数 164 | 165 | commit 7b04d607ed1205ed5c6174dc0d51efc8119c7d0c 166 | Author: tendoasan 167 | Date: Tue Mar 15 20:53:27 2016 +0800 168 | 169 | 使用数组 170 | 171 | commit d9e39e5bbe453a9783a27c12f40f02b7f05fc474 172 | Author: tendoasan 173 | Date: Mon Mar 14 23:23:34 2016 +0800 174 | 175 | 第6章 进行判断 练习题 176 | 177 | commit 4a4b91e79622c2511e1432847e7490c199087e34 178 | Author: tendoasan 179 | Date: Mon Mar 14 20:37:37 2016 +0800 180 | 181 | 生成质数表的程序(修订版) 182 | 183 | commit 2a337496ebec4240f859065bb665a2141bdd924e 184 | Author: tendoasan 185 | Date: Mon Mar 14 20:34:39 2016 +0800 186 | 187 | 布尔变量,生成质数表 188 | 189 | commit acddd1873f76df8ce75569efb894346459812c6b 190 | Author: tendoasan 191 | Date: Mon Mar 14 20:28:58 2016 +0800 192 | 193 | 布尔变量,生成质数表 194 | 195 | commit 6a6e292b552469c324fc701de0439b3bf4b95986 196 | Author: tendoasan 197 | Date: Mon Mar 14 20:11:40 2016 +0800 198 | 199 | switch,简单表达式求值的修订版 200 | 201 | commit 1cd8ce6fc19ee315886a1d0c50613bc427ed7d2b 202 | Author: tendoasan 203 | Date: Mon Mar 14 19:50:02 2016 +0800 204 | 205 | 简单表达式求值的修订版 206 | 207 | commit fce0dfb041842cbf1dd963983ca741567315ed13 208 | Author: tendoasan 209 | Date: Mon Mar 14 19:43:41 2016 +0800 210 | 211 | 对简单的表达式进行求值 212 | 213 | commit b0ecfd56af7b10b25bdf6fda568e5a618a94b6b3 214 | Author: tendoasan 215 | Date: Mon Mar 14 18:25:24 2016 +0800 216 | 217 | 对终端输入的字符进行分类 218 | 219 | commit da23048b49f392a2d4fd694e7c1362550a0c4e56 220 | Author: tendoasan 221 | Date: Mon Mar 14 18:14:37 2016 +0800 222 | 223 | 符号函数的实现 224 | 225 | commit 1eff3f4a5b223a1163a2ba3df3c1d6e8f0725cff 226 | Author: tendoasan 227 | Date: Mon Mar 14 17:53:01 2016 +0800 228 | 229 | ¶Ïij¸判断某个年份是否是闰年 230 | 231 | commit 6b7a4f961b3f180067dedd1d66cbd91470d0766f 232 | Author: tendoasan 233 | Date: Mon Mar 14 17:24:08 2016 +0800 234 | 235 | 使用if-else结构修订后的判断数字奇偶性的程序 236 | 237 | commit ddf15118dee4144207cf78293264879e2fc243ee 238 | Author: tendoasan 239 | Date: Mon Mar 14 17:21:50 2016 +0800 240 | 241 | 判断数字是奇数还是偶数 242 | 243 | commit ea34eaea9f5923fd31821d40015bb7778929b97d 244 | Author: tendoasan 245 | Date: Mon Mar 14 13:43:55 2016 +0800 246 | 247 | 计算一组成绩的平均值,并统计不及格分数的个数 248 | 249 | commit d8fea36e643017961845cca53fc4415059da7f76 250 | Author: tendoasan 251 | Date: Mon Mar 14 13:30:44 2016 +0800 252 | 253 | 计算某个整数的绝对值 254 | 255 | commit 0db5626fa6922f7ff3a36d621d7ded1ee418383f 256 | Author: tendoasan 257 | Date: Mon Mar 14 12:10:26 2016 +0800 258 | 259 | 第5章 循环 练习题 260 | 261 | commit 44b6a54a490d2ba9fad1f0d85046e5a449839a1a 262 | Author: tendoasan 263 | Date: Mon Mar 14 10:59:37 2016 +0800 264 | 265 | do语句 266 | 267 | commit 92020d835c00d36bc9e2b7b76c2769ee6f700aca 268 | Author: tendoasan 269 | Date: Mon Mar 14 10:32:31 2016 +0800 270 | 271 | while语句 272 | 273 | commit 3e672dd4d9b450cd515e6e90a032c8baad213001 274 | Author: tendoasan 275 | Date: Sun Mar 13 22:07:47 2016 +0800 276 | 277 | for语句 278 | 279 | commit 7eab72daccf941fbc6137d131bb9096c359e36cb 280 | Author: tendoasan 281 | Date: Sun Mar 13 21:31:04 2016 +0800 282 | 283 | 第4章 变量、数据类型和算术表达式 284 | 285 | commit f41cb065b84ebdeb379dd407023948a578baf695 286 | Author: tendoasan 287 | Date: Sun Mar 13 17:58:48 2016 +0800 288 | 289 | 第3章 编译并运行第一个程序 290 | 291 | commit 2945137776863c0214e6624ef829646193d39b17 292 | Author: tendoasan <15510969828@163.com> 293 | Date: Sun Mar 13 17:56:55 2016 +0800 294 | 295 | Initial commit 296 | --------------------------------------------------------------------------------