B站千锋-物联网-C语言学习笔记

第一章-main函数传参

image.png

第二章-C数据类型及语句

负数存储方式:补码

image.png
image.png

格式化输出字符

image.png

第三章-数组

若干个相同类型的变量在内存中有序存储的集合

1)存储的数据类型必须是相同的
2)在内存会开辟一块连续的空间
初始化:开辟空间额同时并且给变量赋值

字符数组的定义方式

1)char c1[]={‘c’,’ ‘,‘p’,‘r’,‘o’,‘g’}
2) char c2[]=“c prog”;
用2)字符串方式赋值比用1)字符逐个赋值要多占1个字节,用于存放字符串结束标志’\0’
image.png
image.png

第四章-函数

函数是 c 语言的功能单位, 实现一个功能可以封装一个函数来实现。
定义函数的时候一切以功能为目的, 根据功能去定函数的**参数和返回值 **

在定义函数的时候, 关于函数的参数和返回值是什么情况, 完全取决于函数的功能。
使用函数的好处?
1、 定义一次, 可以多次调用, 减少代码的冗余度。
2、 使咱们代码, 模块化更好, 方便调试程序, 而且阅读方便

第五章-预处理、动态库、静态库

  1. 预处理编译
gcc -E hello.c hello.i
将.c中的头文件展开、宏展开
生成的文件是.i文件
  1. 编译
gcc -S hello.i hello.s
将预处理后的.i文件生成.s汇编文件
  1. 汇编
gcc -c hello.s hello.o
将.s汇编文件生成.o目标文件
  1. 链接
gcc  hello.o -o  hello.elf
将.o文件链接成目标文件

include 和define的区别

注意: 预处理只是对 include 等预处理操作进行处理并不会进行语法检查
这个阶段有语法错误也不会报错, 第二个阶段即编译阶段才进行语法检查。

宏的好处: 只要修改宏定义, 其他地方在预编译的时候就会重新替换

带参宏和带参函数的区别

  1. 带参宏被调用多少次就会展开多少次, 执行代码的时候没有函数调用的过程, 不需要压栈弹栈。 所以
    带参宏, 是浪费了空间, 因为被展开多次, 节省时间。
  2. 带参函数, 代码只有一份, 存在代码段, 调用的时候去代码段取指令, 调用的时候要, 压栈弹栈。 有
    个调用的过程。所以说, 带参函数是浪费了时间, 节省了空间。
  3. 带参函数的形参是有类型的, 带参宏的形参没有类型名。

选择性编译

#ifndef AAA
代码段一
#else
代码段二
#endif
和第一种互补。
这种方法, 经常用在防止头文件重复包含。

动态库静态库

一: 动态编译
动态编译使用的是动态库文件进行编译
gcc hello.c -o hello
默认的咱们使用的是动态编译方法
二: 静态编译
静态编译使用的静态库文件进行编译
gcc -static hello.c -o hello
三: 静态编译和动态编译区别
1: 使用的库文件的格式不一样
动态编译使用动态库, 静态编译使用静态库
注意:
1: 静态编译要把静态库文件打包编译到可执行程序中。
2: **动态编译不会把动态库文件打包编译到可执行程序中,它只是编译链接关系 **

image.png

第六章-指针

指令的相关概念

操作系统给每个存储单元分配了一个编号,从0x00 00 00 00~0xff ff ff ff

  1. 这个编号称为地址
  2. 指针就是地址

指针变量:是个变量,存放地址编号,32位操作系统大小占4个字节

内存是以字节为单位来存储数据的,咱们可以将程序中的虚拟寻址空间,看成一个很大的一维字符数组

  1. 字符变量 char ch,占一个字节,有一个地址编号,这个地址编号就是变量ch的地址
  2. 整型变量int a, 占4个字节,占有4个字节的存储单元,有4个地址编号,a的地址就是存储单元编号最小的编号

image.png

指针的定义方式

image.png
image.png
数组的名字就是数组的首地址,即第0个元素的地址,是个常量
image.png

指针数组:一般遇到这样的叠词,本质就是后者

是个数组,若干个相同类型的指针变量构成的集合

指针的指针

image.png
image.png
image.png

字符串和指针

image.png
image.png
image.png
在C语言里面必须先开辟空间,再初始化,C++可以开辟空间的时候初始化
image.png
image.png

数组指针

本质是个指针,指向一个数组,+1跳一个数组,主要用来传二维数组的首地址
image.png
image.png
image.png
image.png

指针和函数的关系

1)值传递:实参的值传递给形参,形参的改变影响不了实参
2)地址传递:将实参的地址传递给形参,形参的改变影响实参
image.png
image.png

指针函数:指针作为函数的返回值

image.png

函数指针-指针保存函数的地址

image.png

函数指针数组:本质是一个数组

image.png
image.png

容易混淆的指针

image.png

image.png

特殊指针void*

image.png

image.png

特殊指针NULL

image.png

第七章:动态内存申请

内存分区基础知识

1)物理内存

实实在在的存储设备,比如内存条

2)虚拟内存

操作系统虚拟出来的内存,会在物理内存和虚拟内存之间做映射
写应用程序,看到的都是虚拟地址。
image.png

3G的用户空间:当前进程所私有的

  1. 堆区:动态申请的内存
  2. 栈区:局部变量
  3. 静态全局区:静态变量,全局变量
  4. 代码区:程序代码
  5. 文字常量区:常量

image.png

1G的内核空间:一个系统中所有进程所公有的

为什么要动态申请内存

image.png
image.png

动态分配函数

image.png
free 函数(释放内存函数)

头文件:#include<stdlib.h>
函数定义:void free(void *ptr)
函数说明: free 函数释放 ptr 指向的内存。
注意 ptr 指向的内存必须是malloc、calloc、relloc动态申请的内存 
char *p=(char *)malloc(100);
free(p);
1)free 后, 因为没有给 p 赋值, 所以 p 还是指向原先动态申请的内存。 但是内存已经不能再用了,
p 变成野指针了。
2)一块动态申请的内存只能 free 一次, 不能多次 free 
 

image.png
image.png
image.png

内存泄漏

申请的内存, 首地址丢了, 找不了, 再也没法使用了, 也没法释放了, 这块内存就被泄露了。

int main(){
    char *p;
    p=(char *)malloc(100);
    //接下来,可以用 p 指向的内存了 
     p="hello world";//p 指向别的地方了
    //从此以后,再也找不到你申请的 100 个字节了。则动态申请的 100 个字节就被泄露了
    return 0;
}   
void fun(){
    char *p;
    p=(char *)malloc(100);
    //接下来,可以用 p 指向的内存了
    free(p);
} 

int main() {
    fun();
    fun();
    return 0;
} 
void fun(){
    char *p;
    p=(char *)malloc(100);
    //接下来,可以用 p 指向的内存了
} 

int main(){
    fun();
    fun();
    return 0;
} //每调用一次 fun 泄露 100 个字节 
内存泄露例2解决方法
char * fun(){
    char *p;
    p=(char *)malloc(100);
    //接下来,可以用 p 指向的内存了
    return p;
} 

int main(){
    char *q;
    q=fun();
    //可以通过 q 使用 ,动态申请的 100 个字节的内存了
    //记得释放
    free(q);
    return 0;
} 
 

**总结: 申请的内存, 一定不要把首地址给丢了, 在不用的时候一定要释放内存 **

第八章-字符串处理函数

  1. 测字符串长度函数:size_t strlen(const char *s);
  2. 字符串拷贝函数:char *strcpy(char *dest, const char *src);
  3. 字符串追加函数 :char *strcat(char *dest, const char *src);
  4. 字符串比较函数 :int strcmp(const char *s1, const char *s2);
  5. 字符查找函数:char *strchr(const char *s, int c);
  6. 字符串匹配函数:char *strstr(const char *haystack, const char *needle);
  7. 空间设定函数:void* memset(void *ptr,int value,size_t num);
  8. 字符串转换数值:int atoi(const char *nptr);
  9. 字符串切割函数:char *strtok(char *str, const char *delim);
  10. 格式化字符串操作函数:
    image.png
  11. const

image.png

第九章-结构体共用体枚举

结构体概念

image.png

结构体定义

image.png
1)结构体变量的地址编号和结构体第一个成员的地址编号相同, 但指针的类型不同
2)结构体数组的地址就是结构体数组中第 0 个元素的地址

结构体内存分配

  1. 结构体变量大小:它所有成员的大小之和。因为结构体变量是所有成员的集合。
  2. 为什么要有字节对齐?用空间来换时间, 提高 cpu 读取数据的效率

共用体

image.png
image.png
image.png

枚举

将变量的值都列举出来, 变量的值只限于列举出来的值的范围内
枚举类型也是个构造类型的, 类型定义类似结构体类型的定义。
使用枚举的时候, 得先定义枚举类型, 再定义枚举变量

第十章-文件

image.png

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值