C语言-学习心得(1)

时间:2022-09-08 16:22:21


记得在大学学习C++的时候,对指针这种类型特别害怕。因为虽然我知道指针是指向内存地址的一种变量,变量本身

有自身的内存(在32位系统中指针变量占4个字节),而这4个字节存放的数据是个地制值,这个地制值是你真正要操

作的内存,但是在使用的时候,总会这样或者那样的错误。直到我在出来实习后,我才知道我在那些地方存在盲区,

导致我在使用指针的时候总会出错。导致这些盲区的原因很多,如老师仅仅教基础的,甚至连基础的都没有讲解完,

又或者学校的这个专业不强和学习氛围不好,又或者学校没有一些编程知识钻研很深的老师,又或者学校的教材不

好等等。尽管我知道这些理由都很牵强,可人都喜欢找借口,我也一样。

     

直到我出来实习后,我才找到自己在C++方面的很多盲区。这得益于当时阅读了钱能的《C++程序设计》,这本书虽然

不大,对某些知识点也没有很深入的讲解,但是该书可以说是“麻雀虽小,却五脏俱全”,同时在某些知识点上讲得

很深入很精辟。最让我佩服的是,这本书让我感受到C++是一门艺术,这是难能可贵的。


下面是我扫盲后总结出来的要点:


1、数据类型与内存

1.1、对编程来说,在计算机体系中,最重要的硬件是CPU、寄存器和内存,最重要的软件是操作系统和编译器

 操作系统:

对应用开发程序员来说,应用的开发总是基于操作系统,对系统开发程序员来说,开发更多可能是基于裸

机。但不论何种开发,最终都是0、1的指令,这些指令能够控制硬件的工作。

只是基于操作系统的应用开发是基于操作系统的API,而操作系统的API完成对底层硬件操作的封装。

编译器:

  程序员编写的代码,最终都会翻译成01指令,这项工作是由编译器来完成的。我们总是习惯了编译、连接、

运行,而很少去考虑编译器怎么翻译。我们知道编译器也是一个软件,但是我们却很少知道编译器的翻译

原则(原理)。的确,我们不了解编译器,也能开发出很优秀的应用。但是了解一些编译器的知识,总是

有助于我们理解一些东西。如为什么编程语言中会有整型、浮点型、结构体、枚举等等数据类型,为什么

整型、浮点型可以进行加减乘除的操作。

为编译器已经对这些基本数据类型已经设置为默认,只要编译器在翻译过程中,遇到了int,就翻译成

对应对四个字节的内存空间,并且对于int类型的操作,也对应翻译成对这四个字节的内存空间的操作。

  当然对数据类型编译原理绝对不会那么简单,只是最终都是对内存、寄存器的操作。

  CPU、寄存器、内存:

  硬件的工作主要依赖于CPU的运转。CPU厂商在生产CPU时,就对外提供了一套指令集,这套指令集能够控制

  CPU的工作。一直想找个时间到CPU生产厂商官网上下载一份文档回来看看,只求了解就好了。只可惜一直没

有去做这件事情。

1.2、编程语言的数据类型是计算机内存的逻辑抽象


1.3、编程语言的基本数据类型是由编译器完成计算内存的抽象,这段抽象代码由编译器完成


1.4、编程语言的非基本数据类型,如结构体、联合体、枚举、类等的计算机内训的抽象由程序员完成,

当然其中这些复杂的数据类型里面必然是由基本数据类型组合而成,最终复杂数据类型也交由编译器完成。


1.5、数据类型的内存逻辑抽象是指该类型与特定大小的内存块捆绑,如基本数据类型int,定义int var;

由于int 类型的大小占4个字节(在32位系统上),那么变量var实际对应着4个字节的内存块,操作这个var,

就是对应的内存块进行读写操作。


1.6、数据类型与特定大小的内存块捆绑后,获得仅仅是该内存块的首地址(第一个字节)。如int var;变量var获

得的仅仅是对应4个字节的首地址,即4个字节中的第一个字节。但由于编译器识别到var是非指针数据类型,

对var的操作是对整个所占内存块的操作。又如short int * siNumPtx = new short int;

此时*siNumPtx的访 问跟var无异。可是当 *((int*)siNumPtx)访问后就有差别了,

此时已经非法访问无权限访问的内存了。此时 你是否发现siNumPtx仅仅获得的是首地址,

当你告诉编译器要按照(int*)这种类型的内存进行块访问时,此 时的内存块已经从2个字节变成了4个字节。

这就是指针的魅力,十足的*访问任何内存的权力,但过度的 权力如果不加以约束,终成*。


1.7、数据类型不仅仅是与内存存在捆绑关系,也规定了对内存的块的操作。如基本数据类型int,

存在着与4个字节的内存块的捆绑关系,也规定了加减乘除等操作,这些基本数据类型的操作

已经由编译器完成。而对复杂数据类型的操作则是由程序员完成,当然这些封装的操作也

肯定调用基本数据类型的操作。

C语言-学习心得(1)