是18岁才开始接触编程的, 之前对此说是一无所知也未尝不可, 这个专业在我看来可有, 亦可无, 我喜欢的是医学和文学, 可惜我的执着并不能打败现实.
那就这样接受现实吧!
我的英语算不上好, 能认识几个单词, 这对于编程构不成很大的威胁, 但是这也是致命的弱点, 我最开始接触的语言是汉语, 随后是英语, 再就是 python, C语言, 但是真正系统的学习的机器语言只有C语言, 这门语言是那么吸引人, 当自己一步步写出能够有一点点用的代码的时候, 那种自豪感是任何东西都无法替代的, 虽然我还在成长路上蹒跚, 但我绝不倒退.
自我鼓励的话太多了, 可是每当身陷命运沼泽无法自拔的时候, 这些自我鼓励总能带我走出来.
自我总结了不少关于 c语言基础的东西, 可能用不到, 但是这都是心血, 是一步步走过来的脚印, 和见证.
c语言应用时遇到的一些问题以及注意事项:
注意事项:
1.以下函数在调用时须注明头文件:#include <string.h>
.puts 函数为 输出 字符串的函数;
.gets_s 函数为 输入 字符串的函数;要接受两个变量!
.strcat 函数为 字符串的 连接 函数;(猫函数)
.strcpy 函数为 字符串的 复制 函数;(cpy copy函数)用法:strcpy(str1,str2),将 str2 复制到 str1
.strcnpy 同上 用法:strcnpy(str1,str2,n),n 为要从 str2 中复制到 str1 中元素的个数 从 0 到 n-1
.strcmp 函数为 字符串的 比较 函数;(用于判定两个字符串是否相等,若等,值为 0)用法:strcmp(str1,str2)[ == 0 ?]
.strlen 函数为 测量(length)字符串长度 的函数;用法:strlen(str)
.strupr 函数为 转换小写字母为大写字母 的函数;
.getch 函数为 接受一个字符:并不显示在终端上,直接被接受,甚至不需要回车
.getchar 函数为 接受一个字符
2.以下函数为自定义函数:
.void length() //求整数的长度
{
int m,n,i = 1;
scanf_s("%d",&m);
n = m;
while(n / 10 != 0)
{
n = n / 10;
i = i + 1;
}
}
关于第七章的一些事项:
在第七章中,很多概念的理解以及一些变量的门道需要掌握,这一章的东西比较简单,但也很难,所以就要好好消化一下。
此章需要阅读三遍以上。
知识点的总结:
1.调用函数的目的:使代码模块化,简洁。
2.定义函数
例:
int max(int x,int y)//定义的形式参数,做形式用,储存空间是临时开辟的;
{
int z; //定义的局部变量,只能在函数内部使用;
z = (x > y) ? x : y;
return (z); //int型函数要求必须有返回值;
}
3.函数的调用:被调用的函数在被使用时需要在调用函数中进行声明!
4.函数的定义与声明:
函数的定义:指将函数的名称,类型,参数,函数体都写出来义工使用的代码;
函数的声明:将函数的名称,类型,参数(类型)写出来表示在此处可能被调用,做出的先行性说明;
5形式参数和实际参数之间的关系:
形式参数:作为函数体中的一个虚拟变量,在函数执行时由程序临时开辟存储空间以供其使用,
执行玩函数后其存储空间被释放,在函数执行时参与运算。
实际参数:作为变量被存储在存储空间中,在需要被使用的时候把值交给相应的形式参数进行计算。
关系:什么时候形参的改变会引起实参的变化?答案是 当形参指向实参的地址时,形参的变化会引起实参的变化!
其中值得注意的是,单个字符的形参并不指向地址,因此想通过形参来改变实参的值,要用到指针!
但是如数组这种本身就代表了他的地址的形参,可以直接对实参的内容进行操作!
6.函数的返回值:在魔方阵一案中,作者并没有在主函数中写上返回的函数!因此在这里猜测主函数里可以没有返回函数!
7.函数的递归调用:对这个环节还是理解不是很透彻,因此这几页需要花费大力气来看
8.数组作为函数参数:这里的应用在前面已经相当熟练,值得注意的是,数组作为函数参数有时候会比较麻烦
但是在某些案例中能起到出其不意的妙用,因此需对准症状来选择方法。
9.局部变量和全局变量:这一节也是需要花费力气来理解的内容!
至此,第七章的内容就要告一段落啦,还希望自己多多加油,及时复习巩固,这样才会不断提高呐!
给自己点个赞咯!
第八章 指针 ---C语言的精华所在
这一章是 C 语言的最根本所在, 其中的很多用法千变万化, 经过一个月的摸索使用终于得以了解了一些常见的用法
首先要讲一讲个人对指针的理解:
通俗来讲, 指针就是地址, 做一个简单的比喻, "地址" 就是一个 "人" 的住宅位置,我们通过对 "地址" 的访问来对 "人" 进行操作
赋值上 理解为 把一个 "包裹" 通过邮递的方法邮寄到 该 "人" 的 "地址"
规范来讲 就是 把 某值 赋给 某变量
我们还有一个访问利器 指针, 这是一个可以随时访问 "人" 的地址的家伙 , 在此把它形象为 "楼管".
"楼管" 可以随时访问 "人" 的 "地址" 并且对 "人" 进行一些必要的 "教育"
//顺带一提, "楼管" 自身也是有地址的, 那么我们可以上访请求到 "楼管" 的上级 "小区管理员",
这样我们就可以 假借 "小区管理员" 的手腕来对 "楼管" 进行访问了
模块一:
c 语言里把 地址 形象化为 指针,其中 指针变量 是指向 地址/指针 的变量(在此就不再强调地址和指针叫法的区别了)
指针变量 指向的 变量 的 基类型 必须与自身的 基类型一致
ex:
int a = 0;
int * p;
p = &a;
此处 a 是整型变量,它的变量类型是 (int), 它的基类型是 (int), 它的值为 0;
p 则是指针变量 它的变量类型是 (int *), 它的基类型是 (int), 它的值为 变量 a 的地址;
想要对 变量 a 进行操作, 那么利用指针 在其变量名之前 加上 * 就可以实现.
模块二:
指针变量做函数参数
ex:
void swap(int * p1, int * p2);
这里用了两个指针变量做函数的参数
模块三:
利用指针进行引用:
(1):引用数组:
在数组里, 定义一个指针可以访问到所有数组元素, 但每次只能访问一个元素
但是 指针被允许对自身的加减,因此 在许多地方也可以对指针自身进行加减来实现对元素的逐个访问
指针的加减在此不做过多阐述, 以后会对其进行一个专题类别的整理.
(2):使用数组名做函数的参数
void fun(int arr[], int, n);
(3)指针对多维数组的访问:
在此处 觉得应该对这个知识点进行一个个人看法的扩展:
对于维度来说, 在二维数组里面, 既可以用一个指针对其进行每个元素的访问,
也可以建立一个一维指针数组分别对二维数组的每一行/或列进行访问.
在此处仅仅讨论使用 "点指针" 的访问方式.
在此处又要讨论到另外一个专题 <二维数组的地址详解>以及<指针对二维数组的访问>
/*第一排第一个即是排长又是士兵*/
/*
行 起始地址表示方法: a &a[i] a[i] a + i
行 首列地址表示方法: * a &a[i][0] a[i] *(a + i) + 0 * (a + i)
元素 地址表示方法: &a[i][j] *(a + i) + j a[i] + j
元素的值的 表示方法: * &a[i][j] / a[i][j] * (*(a + i) + j) * (a[i] + j) * (a[0] + n)
*/
此处并不过多赘述, 以后有时间再来对其进行一个系统的管理.
(4):指针对字符串的"访问"
特别提示: 指针对字符串的访问并非是把字符串每个元素的地址都存储到指针变量里,
而是把 字符串的 首元素地址 储存到指针变量中(原理是字符串的空间是连续的)
(5):字符指针 做函数参数
模块四:
指向函数的指针,这里并没有做过多的深究, 暂且理解为通过指针实现对函数的访问;
返回指针值的函数,这里暂且也不多说, 理解为 一个函数的返回值为 指针 即可.
模块五:
指针数组 和 多重指针(意会即可)
模块六:
动态内存分配和指向他的指针
1 malloc 开辟动态内存 (这个在建立链表的时候会用到)
用法 malloc(unsigned int size)//括号里应为开辟内存的大小
2 calloc 开辟动态内存
用法 calloc(unsigned n, unsigned size)//括号里的意思为 开辟 n 个 大小为 size 的空间
3 realloc 重新分配已经开辟的空间
用法 p = malloc(20); realloc(p,50);
4 free 释放已经开辟的空间
用法 p = malloc(20); free(p)
最终总结 : 主函数也是有参数的 void mian(int argc, char const * argv[])
具体细节再慢慢补充.毕竟要学习 python 了 哈哈哈
第九章 用户建立自己的数据类型
深度的理解一下这个章节的名字:
我们学习接触的最多的类型 如下 : int, char, float......等等
现在 随着一些简单的学习过程的告一段落, 我们会遇到更多的难以解决的问题,因此, 在现实生活中
c 语言提供了 用户自我数据类型的构建,我们可以把数据规模化 整体化 板块化;
这样既利于用户自己的使用, 也给服务端对数据的管理提供了极大的方便.
(1) 建立自己的结构体类型:
struct $ //数据名
{
/* 类型 */
}(变量表列);
(2) 共用体类型
union $ //数据名
{
/* 类型 */
}(变量表列);
(3) 枚举类型:
enum $ //数据名
{
/* 元素成员 */
}
扩展章节:
一:链表的建立 修改 删除 增加 输出 录入 复刻;
这一章节是我很感兴趣的部分, 在数据结构这一课程上会有具体讲解.
二:用 typedef 声明新类型名
理解 根据 coder 自身的代码习惯 将旧的类型名用新的类型名替代 实现代码习惯的移植.
方式:
typedef int Integer //将 int 类型 用 Integer 代替
typedef floa Real //同理
这两节需要花费时间好好看看.
(其中提到的 Fortran 语言也需要有所了解)
好了,第九章也就此告一段落了, 向着第十章进发吧!
第十章 对文件的输入和输出
一:
什么是文件:
文件有不同的类型 在程序设计中 主要用到两种文件:
程序文件:源文件(后缀.c) 目标文件(后缀.obj) 可执行文件(.exe)
数据文件:供程序运行时读取的数据.(这一节应该好好读一读)
文件名:
文件标识包括三部分:
1 文件路径;
2 文件名主干;
3 文件后缀.
文件的分类:
数据文件可分为两类:
ASCLL文件:又被称作文本文件;
二进制文件:又被称作映像文件.
文件缓冲区:
缓冲文件系统是指系统自动为在内存区的每一个正在使用的文件开辟一个文件缓存区
从内存向磁盘输出数据必须先送到内存中的缓存区 装满缓存区之后再一起送到磁盘
文件类型的指针:
文件类型为 FILE
二:打开与关闭文件
打开:
方式 : 用 fopen("file1", "r")
常用下面的方式打开文件:
if((fp = fopen("file","r")) == NULL)
{
printf("Can't open this file!\n");
exit(0);
}
关闭:
方式 : fclose(fp);
文件的操作方式:
表列如下:
文件使用方式 | 含义 如果指定文件不存在
r (只读) | 为了输入数据, 打开一个已经存在的文本文件 出错
w (只写) | 为了输出数据,打开一个文本文件 新建文件
a (追加) | 向文本文件尾部添加数据 出错
rb (只读) | 为了输入数据,打开一个二进制文件 出错
wb (只写) | 为了输入文件,打开一个二进制文件 新建文件
ab (追加) | 向二进制文件尾部添加数据 出错
"r +" (读写) | 为了读和写,打开一个文本文件 出错
"w +" (读写) | 为了读和写,建立一个新的文件 新建文件
"a +" (读写) | 为了读和写,打开一个文本文件 出错
"rb +" (读写) | 为了读和写,打开一个二进制文件 出错
"wb +" (读写) | 为了读和写,建立一个新的二进制文件 新建文件
"ab +" (读写) | 为读写打开一个二进制文件 出错
三:按一定顺序读取文件
读写一个字符的函数:
fgetc fgetc(fp) 从 fp 指向的文件读入一个字符 读取成功,带回所读的字符,失败则返回文件结束标志 EOF(即 -1 )
fputc fputc(ch, fp) 把字符 ch 写入到 fp指向的文件中 输出成功,返回值为输出的字符;输出失败同上.
读写一个字符串的函数:
fgets(str, n, fp): 从 fp 指向的文件读入一个长度为 n - 1 的字符串, 存放到字符串 str 中,
成功返回 str 的地址, 失败则返回 NULL;
fputs(str, fp): 把字符串 str 所指向的字符串写入到 fp 所指向的文件中,输出成功返回 0;否则返回非 0 值.
用格式化的方法读取文本文件:
fprintf(文件指针, 格式字符串, 输出表列) fprintf(fp, "%d, %6.2f",i, f);
fscanf(文件指针,格式字符串, 输入表列) fscanf(fp,"%d, %f",i, f);
用二进制的方式向文件读写一组数据:
fread(buffer, size, count, fp):
fwrite(buffer, size, count, fp);
其中 buffer 为一个地址 用来存放从文件读入的数据的存储区域的地址 / 要把此处的存储区域的数据向文件输出
size 是要读写的字节数;
count 要读写多少个数据项;
fp 指向被读写的文件
四:随机读取文件(待看)
五:文件读写时的错误检测(待看)