目的

封面长这样,讲数据结构的书挺多的,但是我觉得这一本讲的倒是挺有特色的
比较偏向嵌入式的C语言环境下讲,而不是偏向高级语言而写的。。。
立个Flag看看要读多久读完
开始于22年6月27日
挑我觉得重点或者我不太清楚的知识记录,其他我知道的就不大记录了~~

程序设计基础

数组

数组指针相关的知识

int data0[2]={1,2};
如果取数组名data0,这个数组名的类型是int[2],如果用typedef处理下,可以用它来构造二维数组

typedef int T[2];//此时T表示int[2]
T data[3];//这句话等价于int data[3][2]

实际试了试还真是这样的,如果这样写,编译器会报告警,指针类型不匹配


以下表达式是成立的

data == data[0]== &data[0] == &data[0][0]

这里这4个指针都是指向这个数组的首元素,虽然写法不一样

data是数组名,也就对应指向data[0]的指针,所以它与&data[0]含义一样
data[0]本身是由2个int值组成的数组[两列],data[0]指向data[0][0],所以data[0]与&data[0][0]含义一样
data[0]指向的对象【data[0][0]】占用1个int大小,data指向的对象占用2个int,但是&data[0]和&data[0][0]都开始于同一个地址,因此data与data[0]值相同

有点绕是吧~~~

数组指针的偏移问题

有下面这样语句
int data[3]
然后按照书上的说法有下面这些操作,他们的效果各不相同

这里会引出一个很重要的问题,对一个指针,偏移一个数,究竟会产生怎样的效果

这取决于指针所指向的对象的类型的大小

书上给出了一个很好的总结
偏移n后的地址是由data所在的地址加数据类型data所含字节数*n得到

pData±n = (char )pData±nsizeof(*pData)

将数组的地址作为形参

某几个函数的声明是这样的
void Func0(int data[10]);
void Func1(int data[ ]);
上诉函数的形参是指针,不是数组,与int *data是一样的,指向该数组的首元素的指针。
但是这样的形参的缺点就是不知道数组的长度,最好加一个长度传入
void Func2(int data[ ],size_t len);
如果考虑防止修改数组的内容,建议加个const
void Func3(const int data[ ],size_t len);

二维数组的地址做形参的问题

希望传入一个3行2列的数组作为输入参数 给一个函数
那么它的函数声明为
int sum(int data[3][2],int size)
或者
int sum(int data[ ][2],int size)
这种写法表明data是由2个int值组成的数组,但是个数不知道,也可以反映为指向int[2]的指针。

变量的存储

就是想记下它描述大小端的这段
如果有int num = 0x00000064,那么A中存放的4字节在不同的CPU里会怎样存呢


a是大端模式,b是小端模式

类型转换

有一个隐式转换的概念,这个用不好会有坑~

编译器对操作数隐式地进行自动转换,隐式类型转换将范围窄的数据类型转成更宽的数据类型

举个书上的例子
unsigned int a =9;
int b =-4,c;
c=a/b;
c的结果是0,为啥呢

因为a是unsigned int,b是int,编译器会把b隐式转换到unsigned int,由于b是带符号的,转无符号,符号位就变成了正常的有效位了,对应的-4就变成;额0xfffffffc,所以结果是0

指针变量与指针的指针

const修饰的是紧跟在它后面的单词
int * const ptr指的是一个指向int的常量指针,指针的指向不能变,但是指向的内容可修改
const int * ptr指的是一个指向int常量的指针,指针的指向能变,但是指向的内容不可修改

共性和差异化

首先找到存在的各种概念(共性)和具体的实现(可变性)。所有的概念都找到 之后,继续封装这些概念的抽象定制接口。如果将问题的共性和可变性分离开时,经过简化后

把稳定不变的相同的处理部分包含在抽象的模块中,可变性分析发现的变量由外部传递进来的参数对应

最小化的接口只包含对于接口任务非常重要的参数,同时易于维护和扩展

依赖倒置原则

高层次的模块组件独立于低层次的组件,则高层次的模块更容易重用

高层次的模块不应该依赖低层次的模块,他们应该都依赖于抽象接口
抽象接口不应该依赖于细节,细节应该依赖于抽象接口

前/后置条件

前置条件就是指该函数能够正确输出结果必须成立的条件
后置条件就是该函数完成后必须成立的条件

设计这个的初衷时在使用者和程序员之间形成一个契约

开闭原则

因为修改接口会导致用户程序的修改,所以只能扩展原有接口,不能修改或废除原有接口

对修改关闭,对扩展开放

字符串与指针

这个我用的比较少,就多记一记吧

字符的输入输出

scanf

int scanf(const char *format, …)
读取字符的时候它不会跳过空格符,它会把空格当成一个字符读入,为了解决这个问题必须在%c之前加一个空格

scanf(" %c",&ch);

读取数字的时候会跳过空格,制表符,换行符

读取字符串的时候,一次智能读取一个单次,它始终会在字符串

gets函数

char *gets(char *str)
从标准输入设备中输入若干个字符,并保存到指定的字符数组中,直到文件结束或者读到一个换行符,此时函数会把换行符丢弃,替换成一个结束符(‘\0’)
这个函数的缺陷在于,它作为被调用方,不知道数组究竟为多大,但是本身函数又没有输入参数可以传入告知数组的大小,一旦数组越界会出现不可预知的问题

所以后来的C语言标准将这个函数删除了.

puts

int puts(const char *str)
puts不会输出结束符’\0’,在输出字符串之后会多输出一个换行符

getchar和putchar

int getchar(void)
int putchar(int char)
这两个函数都是仅处理一个字符的,而且他们不是真正意义上的函数,是预处理宏
getchar会读取空格,制表符,换行符
但是也存在坑,书上有这样一段程序

char ch1,ch2;
ch1 = getchar();
ch2 = getchar();
printf("%d%d\n",ch1,ch2);

如果输入字符’a’,打印的结果是97,10.因为getchar读到了一次字符就继续执行了,97对应的是a,10对应的是回车。
键盘在结束一次输入后,会将数据存储在一个临时缓冲区里,当缓冲区里有残留数据的话,函数就会直接读走缓冲区残留的数据而不会理会键盘输入的数据。

由于输入a时按下了Enter,此时a和enter都会读入到缓冲区内,第一个getchar读走a,第二个getchar读走回车。

缓冲区

实际上C语言库中有两类缓冲:

  1. 完全缓冲IO
  2. 行缓冲IO

完全缓冲区,指的是需要完全填满缓冲区之后才刷新缓冲区。将内容发送到目的地
行缓冲区,指的是出现换行符的时候会刷新缓冲区,将内容发送到目的地

字符串常量

NUL和NULL不是同一个东西,NUL是一个char,定义为’\0’,而NULL是空指针
在声明变量的时候,如果采取数组式的写法,编译的时候就分配好内存了,如果按指针式写法,编译的时候没有为字符分配内存,到运行时的时候才分配。
char * str = “ddddd”;
char str[6]=“ddddd”;
字符串常量的引用可以参考数组的引用,使用方括号或者直接通过字符串常量本身来引用
例如可以这样写:

printf(“OK!占用的空间%d”,sizeof(“OK!”));
printf(“OK!的地址%d”,“OK!”);
printf(“%d”,“OK!”[0]);

printf

printf不会自动地在每个字符串的末尾加上一个换行符,而puts会自动地加上换行符

fgets和fputs

char *fgets(char *str, int n, FILE *stream)
int fputs(const char *str, FILE *stream)

专门针对文件版本的gets和puts,
fgets包含有限制读入字符串的长度防止溢出,读入n-1个字符,或者读到第一个换行符为止,它会存储换行符

fputs在输出中不会添加换行符

字符串处理函数

strlen函数
size_t strlen(const char *str)
返回字符串的长度,不包括NUL字符

strcat函数
char *strcat(char *dest, const char *src)
要给拼接后的字符串长度+1才能完整存放完字符串,否则会有数组溢出的问题,否则使用strncat函数

strncat函数
char *strncat(char *dest, const char *src, size_t n)
把 src 所指向的字符串追加到 dest 所指向的字符串的结尾,直到 n 字符长度为止。
不会拷贝src中的空字符与后面的字符,会在拷贝完后的字符串添加结束符

strcmp函数
int strcmp(const char *str1, const char *str2)

该函数返回值如下:

如果返回值小于 0,则表示 str1 小于 str2。
如果返回值大于 0,则表示 str1 大于 str2。
如果返回值等于 0,则表示 str1 等于 str2。

这里比较的是ASCII码的大小

strcpy和strncpy函数
char *strcpy(char *dest, const char *src)
char *strncpy(char *dest, const char *src, size_t n)
strncpy函数更安全,毕竟传入了长度,解决溢出的问题

字符串的存放方式

要么是固定长度,连续地址存储的数组形式
要么是不固定长度,随机地址存储的指针形式
char key[][6] = {“av”,“avvv”,“ad”,“advdv”,“asd”,“asd”};
char *key[6] = {“av”,“avvv”,“ad”,“advdv”,“asd”,“asd”};
各有优点

程序设计与数据结构_周立功【读书笔记】相关推荐

  1. 周立功阅读笔记-CANopen轻松入门基于DS301(一)

    周立功阅读笔记-CANopen轻松入门基于DS301(一) CANopen阅读笔记 4.CANopen的预定义报文和ID分类 5.对象字典OD(Object dictionary) 6.网络管理NMT ...

  2. 功利主义穆勒思维导图_穆勒功利主义读书笔记

    穆勒功利主义读书笔记 [篇一:从<功利主义>看穆勒之幸福论] 从<功利主义>看穆勒之幸福论 摘要:围绕穆勒<功利主义>关于幸福的论证,论文对功利主义幸 福论之逻辑进 ...

  3. 宏观经济学gdp计算方法_曼昆宏观经济学读书笔记(一):GDP、通胀率、失业率...

    最近在看曼昆的宏观经济学,作读书笔记如下,欢迎批评指正.这个系列的笔记会边读边写. 国内生产总值 国内生产总值(Gross Domestic Product,GDP)是用于衡量国内经济运行状况的指标. ...

  4. 《控制系统设计指南》_George Ellis著_部分章节读书笔记

    Attention: 强烈建议做控制的同学先通读一遍这本书 这本书写得有点像科普文的感觉,但又不失严谨和实验论证.感慨作者太强了!完全从读者的角度出发用一个一个的例子去说明概念,读完后感觉自己以前控制 ...

  5. C程序设计语言(The C Programming Language)读书笔记

    文章目录 C程序设计语言 笔记 1 导言 1.1 入门 1.2 变量与算术表达式 1.3 for语句 1.4 符号常量 1.5 字符输入/输出 1.5.1 文本复制 1.5.2 字符计数 1.5.3 ...

  6. 《认知觉醒》-周岭-读书笔记-reading_note

    认知觉醒 (豆瓣) (douban.com) 思维导图来源: https://www.zhihu.com/question/454924392/answer/2601078022 书评 书评的内容写于 ...

  7. java开头流程_【java读书笔记】——java开篇宏观把控 + HelloWorld

    学完java有一段时间了,一直没有做对应的总结,总认为有一种缺憾.从这篇博客開始,将自己平时的学习笔记进行总结归纳,分享给大家. 这篇博客主要简单的介绍一下java的基础知识,基本的目的是扫盲.原来仅 ...

  8. 【读书笔记】实战Java高并发程序设计(第2版)读书笔记

    文章目录 1.概述 1.1. 走进并行世界 1.2 java并行程序基础 1.3 jdk并发包 1.4 锁的优化以及注意事项 1.5 并行模式与算法 1.6 java 8 9 10与并发 1.7 使用 ...

  9. 《设计模式与游戏完美开发》——第六周读书笔记

    在上一周的读书笔记中我介绍了中介者模式,本周的读书笔记来介绍一下桥接模式. 前言 现在流行的游戏都是有武器的.一个游戏不可能让玩家从头打到尾都是一把''小手枪''.例如,现在特别火的<贪婪洞窟2 ...

  10. 《设计模式与游戏完美开发》——第二周读书笔记

    在上一周的读书笔记中,我介绍了设计模式的概念.目的是什么,以及最后的最重要的面向对象的七大原则,在这篇读书笔记中,我要介绍其中的一种设计模式:状态模式. PS:这本书主要是以一个小游戏<p阵地& ...

最新文章

  1. Python使用matplotlib可视化多分类变量组合下分组小提琴图、使用seaborn中的catplot函数可视化多分类变量组合下分组小提琴图(Categorical Plots)
  2. 中国科学院院士骆清铭: “看见”大脑
  3. 影响SDN和NFV部署速度的两个因素
  4. Node.js 框架
  5. 【Android 逆向】Android 进程注入工具开发 ( Visual Studio 开发 Android NDK 应用 | Visual Studio 中 SDK 和 NDK 安装位置 )
  6. #1176 : 欧拉路·一(欧拉通路的判定)
  7. 32位linux 内存占用,LINUX内存高,触发OOM-KILLER问题解决
  8. HTML中button怎么填充GIF,css3给按钮添加背景渐变动画
  9. java使用itext填充pdf模板,超简单教学,有手就行
  10. loadrunner可用许可证
  11. Python-Matplotlib可视化(6)——自定义坐标轴让统计图清晰易懂
  12. phpcms v9二级栏目生成到根目录后三级栏目无法访问的解决办法
  13. wordpress安装记录
  14. jvm学习--类加载器
  15. c语言编辑回文数,C语言实例 回文数
  16. JAVA基础语法 - 继承
  17. 什么是VBA编程语言?
  18. 我心有猛虎,细嗅着蔷薇
  19. Spring漫画学习笔记(二) 什么是BeanFactory
  20. 方框加对勾怎么输入_word里如何往方框中加对号?带方框的对号怎么弄,原来是这样的...

热门文章

  1. js移除某个样式_JS removeAttribute()方法:删除元素的某个属性
  2. 李华《灵武二孝赞并序》中之“灵武”系指何地?
  3. 用HTML搞一个汇率转换器,利用yahoo汇率接口实现实时汇率转换示例 汇率转换器...
  4. 约瑟夫环问题java_Java求解约瑟夫环问题
  5. FE - Vue 使用 XLSL 导出 excel 文件
  6. 完全免费的Windows代码签名证书(大神勿喷)
  7. ubuntu下使用CPU频率控制
  8. 树莓派python界面编程_树莓派PythonGUI学习
  9. 各场景下NetApp的数据备份推荐(Veeam+群晖NAS)
  10. 服务器高端系统恢复工具,EASEUS Todo Backup Advanced Server高级数据备份恢复工具