读数笔记 《C程序设计语言》
读书笔记
-----《C程序设计语言》
暑假期间,读了《C程序设计语言》这本书,我觉得深受启发,在这个课本中我学习到了很多的东西。
我们知道学习一门新的编程语言的唯一方法就是用它去书写编程,对刚入门我们来说,学习的第一个程序大都是“hello,world”
即:#include<stdio.h>
int main()
{
printf("hello, world\n");
}
对于这个简单的代码,却蕴含着许多的重点,第一个就是对于任何一个C语言来说,它都是由函数和变量组成的,引例里的一个函数就是main()函数,main()函数是一个程序的开始,所以对任何一串代码来说都是需要以main()函数开头,即就是都必须包含一个main()函数。第二个函数就是printf函数,printf函数的格式是:printf(“% ”, );它将用于打印””里面的字符串。根据观察这两个函数我们可以发现两个函数之间进行数据交换的一种方法就是调用函数向被调用函数提供一系列的值,将这一系列值称为参数。下来就是关于特征符号:“\n”:表示换行,对于printf函数来说,它是不会自动进行换行的,所以我们可以将引例里面的printf(“hello world\n”);可以改写为printf(“hello”); printf(“world”);printf(“\n”);对于这两个写法来说都是一样的。
对于C语言来说,有着许多常用的头文件:
<stdio.h> 定义了三个变量类型、一些宏和各种函数来执行输入和输出
<ctype.h> 提供了一些函数,可用于测试和映射字符。
<stdlib.h> 定义了四个变量类型、一些宏和各种通用工具函数
<string.h> 定义了一个变量类型、一个宏和各种操作字符数组的函数
<assert.h> 提供了一个名为 assert 的宏,它可用于验证程序做出的假设
<limits.h> 决定了各种变量类型的各种属性 https:
<stddef.h> 定义了各种变量类型和宏。这些定义中的大部分也出现在其它头文件中
<time.h> 定义了四个变量类型、两个宏和各种操作日期和时间的函数
<float.h> 包含了一组与浮点值相关的依赖于平台的常量
<math.h> 定义了各种数学函数和一个宏
<error.h> 定义了一系列表示不同错误代码的宏,这些宏应扩展为类型为 int 的整数常量表达式
<locale.h> 定义了特定地域的设置
<setjmp.h> 定义了宏 setjmp()、函数 longjmp() 和变量类型 jmp_buf,该变量类型会绕过正常的函数调用和返回规则
<signal.h> 定义了一个变量类型 sig_atomic_t、两个函数调用和一些宏来处理程序执行期间报告的不同信号
<stdarg.h> 定义了一个变量类型 va_list 和三个宏,这三个宏可用于在参数个数未知(即参数个数可变)时获取函数中的参数
dir.h 包含有关目录和路径的结构、宏定义和函数。
io.h 包含低级I/O子程序的结构和说明。
alloc.h 说明内存管理函数(分配、释放等)。
再下来是一个简单的关于摄氏温度与华氏温度的转换问题
即:#include<stdio.h>
/*当fahr=0,20,…,300时,分别打印华氏温度和摄氏温度*/
int main()
{
int fahr , celsius ;
int lower , upper , step;
lower = 0;
upper = 300;
step = 20;
fahr = lower;
while(fahr<=upper){
celsius = 5 * (fahr-32)/9;
printf(“%d\t %d\n”,fahr,celsius);
fahr = fahr + step;
}
}
对于这一串代码来说,重要的的点如下,第一点是/* */,这个称为注释,两个符号里面的内容会被编译器自行忽略。第二点就是,我们可以看到在使用fahr、celsius、lower、upper之前都在代码的开始段给他们进行了修饰,如 int fahr,celsius;这就说明在变量使用之前都必须对其进行声明,声明的方法为: 类型名 变量;对于变量来说,我们常用的有int 整型类、float 浮点数型、char 字符型等等其中对于浮点数保留几位小数的方法为:比如说保留三位小数,printf(“%.3f”,i);更有对于把整形转化为浮点数的方法:如 float a;int b;赋值语句为 b=a;。第三点是while循环:
while: while(循环条件){
语句块1;
}
对于while循环来说,对满足循环条件的的内容,执行语句块1里的内容;当不满足循环条件时,循环结束,直接执行while语句之后的东西。第四点就是赋值语句:=就是赋值方式,如celsius = 5 * (fahr-32)/9;对于==来说是等于号,如while(i==1){},意思就是:当且仅当i=1时,这个while循环才能进行下去。
我们通过研究while语句,我们发现while语句适合于先前不知道循环总次数的情况,当我们知道需要这个循环走多少步的时候我们用for循环更会好一点。for循环: for (语句1;语句2;语句3)
{
语句块1;
}
对于这个for循环来说,循环开始首先执行的是语句1,即就是给变量赋初始值,如int i=0;接下来就要执行语句2,即就是进行对表达式的判断,如i<n,如果条件为真,就执行一下循环体中的语句块1;接下来就是进行语句3,即就是对变量的一个更新,如i++;紧接着就会继续重头在进行一次判断。对于for循环来说,语句块1、2、3,均可不写,即for(;;),当这种情况下它就等同于while(1);其中,对于for循环可以使用contiun语句(结束本次的循环,进入下一次循环)和break语句(结束循环,即就是不再执行这个循环,直接执行循环后面的语句)。
#include <stdio.h>
int main()
{
int sum=0; // sum为记录1到100的累计值
for (int i=1;i<=100;i++) //int i=1为赋初始值;i<=100即就是循环的条件;i++就是对变量的更新
{
sum=sum+i;
}
printf("1到100的累计值为%d\n",sum);
}
对于后面的知识,最吸引我的就是函数有关的内容,对于函数来说,其一般形式为: 返回值类型 函数名(函数参数)
{
语句块1;
}
例如:求两个数10和20的最大值
#include<stdio.h>
int Max(int a, int b)
{
int c=a>=b?a:b;
return c;
}
int main()
{
printf(“%d”,Max(10,20));
return 0;
}
对于这个函数来说,其中的a和b都是形式参数(函数定义或者声明时的参数称为形式参数或者形参),而10和20称为实参(调用函数时给的参数称为实际参数或者实参)。并且当实参传递给形参的时候,形参是实参的一份临时拷贝,所以对形参的修改并不影响实参的值。其中对于一些比较长但是有一定规律的参数,我们采用递归的方法,如斐波那契数列:1.1.2.3.5.8.13...,我们就采用递归的方法去求它的第n项:
#include<stdio.h>
int Fibon(int n)
{
int f1=1;
int f2=1;
if(n==1||n==2)
{
printf(“1”);
}
for(int i=3;i<=n;i++)
{
int fn=Fibon(n-1)+Fibon(n-2);
}
}
int main()
{
printf(“%d”,Fibon(8));//即就是求斐波那契额数列的第八项
return 0;
}
接下来就是数组的相关问题,首先就是一维数组,其一般表达形式为:类型名数组名[元素个数],例如:int arr[12];其中对于数组来说数组是采用下标来进行访问的,并且下标是从零开始;数组的计算:比如要求一个数组arr的大小,方法为:int sz=sizeof(arr)/sizeof(arr[0])。接下来就是二维数组,其一般表达式为:类型名 数组名[表达式1][表达式2],其中表达式1指的是行的个数,表达式2指的是列的个数,例如arr[3][4]表示的就是一个三行四列的二维数组,并且其中的行数是可以省略的,但是列数不能省略。并且对于字符数组来说,字符数组结束的标志就是:‘\0’,并且字符串处理函数时包含在头文件#include<string.h>。
对于一些常见的字符串函数如下:
(1)puts函数:输出字符串的函数
用法:puts(字符数组);
char str[]={"china\nbeijing"};
puts(str);
输出结果为:
china
beijing
(2)gets函数:输入字符串的函数
用法:gets(字符数组);
gets(arr);
(3)strcat函数:字符串连接函数
用法:strcat(字符数组1,字符数组2);
printf("%s",strcat(str1,str2));
(4)strcpy和strncpy函数:字符串复制函数
用法:
strcpy(字符数组1,,字符数组2); 将字符数组2复制到字符数组1中去。
strncpy(字符数组1,,字符数组2,n);将字符数组2中最前面的n个字符复制到字符数组1中,取代字符数组1中最前面的n个字符.其中n时不大于字符数组中原有字符个数(不包括结束标志符\0)。
(5)strcmp函数:字符串比较函数
strcmp(字符串1,字符串2);
当字符串1=字符串2时返回0,当字符串1>字符串2时返回正数,当字符串1<字符串2时返回负数。
(6)strlen函数:测量字符串长度的函数
strlen("china"); //值是5,不包含结束标志符\0
(7)strlwr函数:将字符串中的大写字母转换为小写字母
strupr函数:将字符串中的小写字母转换为大写
还有就是关于类型转换的问题,主要是强制转换的问题:
(float) a; //将变量 a 转换为 float 类型
(int)(x+y); //把表达式 x+y 的结果转换为 int 整型
(float) 100; //将数值 100(默认为int类型)转换为 float 类型
比如:
#include <stdio.h>
int main(){
int sum = 103; //总数
int count = 7; //数目
double average; //平均数
average = (double) sum / count;//将int类型的数转换为double类型
printf("Average is %lf!\n", average);
return 0;
}
这就是一个需要强制转换的例子
最后以几个比较有意思的例题来结束此次读书笔记:
- 打印华氏温度与摄氏温度转换表,要求按照从300度到0度的顺序
#include <stdio.h>
#include <stdlib.h>
int main()
{
float fahr, celsius; //定义华氏,摄氏温度
float lower, upper, step; //定义最低,最高温度,温度阶梯
lower = 0.0;
upper = 300.0;
step = 20.0;
fahr = upper;
//for循环输出温度对照
for (fahr = upper; fahr >= lower; fahr = fahr - step) {
celsius = (5.0/9.0) * (fahr - 32.0);
printf("%6.0f %18.1f\n", fahr, celsius);
}
return 0;
}
- 利用函数实现温度转换
#include <stdio.h>
#include <stdlib.h>
#define LOWER 0//宏变量
#define UPPER 300
#define STEP 20
float change(float f) //定义了一个名为change的函数
{
float c;
c = (5.0/9.0) * (f - 32.0);
return c;
}
float change(float a);//函数的声明
int main()
{
float fahr;//参数要重新定义
for (fahr = LOWER; fahr <= UPPER; fahr = fahr + STEP){
printf("%3.0f %6.1f\n",fahr,change(fahr));
}
return 0;
}
啊啊最终对于《C程序设计语言》整本书的学习,我认为不论学习什么语言,重要的办法就是用它去编写代码,因为只有这样才能更好的理解其中的意思。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)