【C语言】个人笔记

C语言笔记

1.动态内存分配

malloc动态分配与数组静态分配一个最重要的区别:
假设数组char a[10]和charp=(char)malloc(10)都是全局的。那么数组a[10]在程序运行过程会一直存在,即一直占用10个字节空间。但动态申请的可以使用free()来释放掉.等到再使用的时候重新申请.

2. malloc函数以及free函数的注意事项

void Test( void ) 
{ 
 char *str = (char *) malloc( 100 ); 
 strcpy( str, "hello" ); 
 free( str );  
 ... 
}

如果内存紧张,可能导致分配失败,此时会返回NULL,所以要对分配结果进行检查
对于free函数,需要注意的值域一点,那就是野指针,free(p)之后,需要让p=NULL。

下面的两种写法是等价的:

// calloc()分配内存空间并初始化
char *buf1 = (char *)calloc(10, 2);

// malloc()分配内存空间并用 memset()初始化
char *buf2 = (char *)malloc(10 * 2);
memset(buf2, 0, 20);

3. i++与++i效率问题

在内建数据类型的情况下,效率没有区别;
在自定义数据类型的情况下,++i效率更高!
分析1:
(在自定义数据类型的情况下)
++i返回对象的引用;
i++ 总是要创建一个临时对象,在退出函数时还要销毁它,而且返回临时对象的值时还会调用其拷贝构造函数。
分析2:
i++由于是在使用当前值之后再 +1, 所以需要一个临时变量来转储,而++i 则直接 +1,不存在临时变量的问题。
扩展:i=i+1, i+=1, i++, ++i 效率比较
++i 最快
i++ 次之,比++i多用一个临时变量
i += 1 第三,需要取地址
i = i + 1 最后,并多用一个临时变量

4. 内存泄漏

a. 什么是内存泄漏?

正规点的理解:动态开辟的空间,在使用完毕后未释放,结果导致一直占据该内存单元。直到程序结束。一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。

b. 内存泄漏的危害

①长时间运行,程序变卡,性能严重下降
②程序莫名其妙挂掉
③Out Of Memory Error错误
④乱七八糟的错误,还不易排查

c. 内存泄漏原因

①大量使用静态变量(静态变量的生命周期与程序一致。因此常驻内存(static))
②连接资源未关闭
③线程ThreadLocal的错误使用
④乱七八糟的错误,还不易排查

4. 内存溢出

a. 什么是内存溢出?

是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。内存溢出就是你要求分配的内存超出了系统能给你的,系统不能满足需求,于是产生溢出。

b. 内存溢出原因

①内存中加载的数据量过于庞大,如一次从数据库取出过多数据;
②集合类中有对对象的引用,使用完后未清空,使得JVM不能回收
③代码中存在死循环或循环产生过多重复的对象实体
④使用的第三方软件中的BUG
⑤启动参数内存值设定的过小

c. 内存溢出解决方案

第一步,修改JVM启动参数,直接增加内存。(-Xms,-Xmx参数一定不要忘记加。)
第二步,检查错误日志,查看“OutOfMemory”错误前是否有其它异常或错误。
第三步,对代码进行走查和分析,找出可能发生内存溢出的位置。

5. C语言内存模型(内存组织方式)

内存中运行着很多程序,我们的程序只占用一部分空间,这部分空间又可以细分为以下的区域:

内存分区说明
程序代码区(code area)存放函数体的二进制代码
静态数据区(data area)也称全局数据区,包含的数据类型比较多,如全局变量、静态变量、一般常量、字符串常量。其中:全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。常量数据(一般常量、字符串常量)存放在另一个区域。 注意:静态数据区的内存在程序结束后由操作系统释放。
堆区(heap area)一般由程序员分配和释放,若程序员不释放,程序运行结束时由操作系统回收。malloc()、calloc()、free() 等函数操作的就是这块内存,这也是本章要讲解的重点。 注意:这里所说的堆区与数据结构中的堆不是一个概念,堆区的分配方式倒是类似于链表。
栈区(stack area)由系统自动分配释放,存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈。
命令行参数区存放命令行参数和环境变量的值,如通过main()函数传递的值。

在这里插入图片描述
提示:关于局部的字符串常量是存放在全局的常量区还是栈区,不同的编译器有不同的实现,VC 将局部常量像局部变量一样对待,存储于栈(⑥区)中,TC则存储在静态数据区的常量区(②区)。

6. #define与const关键字区别

#define 是宏定义,它不能定义常量,但宏定义可以实现在字面意义上和其它定义常量相同的功能,本质的区别就在于 #define 不为宏名分配内存,而 const 也不为常量分配内存,怎么回事呢,其实 const 并不是去定义一个常量,而是去改变一个变量的存储类,把该变量所占的内存变为只读!

7. 一些实用代码

a.软件模拟PWM:
1. /* 控制 GPIO 输出高低电平 */
2.double freq = atof(argv[2]);     //频率,整形
3.double duty = atof(argv[3]); //占空比, double形,0-1.0
4.double delay_time = atof(argv[4]); //方波持续时间, double形,0是死循环输出方波
5.
6.int times = (int)(delay_time*freq); 
7.if(delay_time == 0)
8.{
9.    while(1)
10.    {
11.        //open LED
12.         gpio_config("value", "1");   
13.         usleep(1000000/freq*duty); //usleep以微秒为单位,所以周期=1000000us/freq
14.         //close LED
15.         gpio_config("value", "0"); 
16.         usleep(1000000/freq*(1-duty));
17.    }
18.}
19.else
20.{
21.    while(times--)
22.    {
23.        //open LED
24.        gpio_config("value", "1");   
25.         usleep(1000000/freq*duty);
26.         //close LED
27.         gpio_config("value", "0"); 
28.         usleep(1000000/freq*(1-duty));
29. 
30.    }
31.}
b.流水控制io(低电平->高电平->低电平):
1.while(1)
2. {
3. for(i=1;i<cycle;i++) //cycle是周期
4. {
5. //open gpio
6.  gpio_config("value", "1");   
7.   usleep(i*30);
8.  
9. //close gpio
10.   gpio_config("value", "0"); 
11.   usleep((cycle-i)*30);
12.  
13. }
14. 
15. for(i=cycle-1;i>0;i--)
16. {
17.        //open gpio
18.   gpio_config("value", "1");   
19.   usleep(i*30);
20. //close gpio
21.   gpio_config("value", "0"); 
22.   usleep((cycle-i)*30);
23. }
24. 
25. }
8.蜂鸣器音调频率表(Hz)
yin_1_l = 233.028   #低音1频率
yin_2_l = 261.626
yin_3_l = 293.665
yin_4_l = 329.629
yin_5_l = 369.994
yin_6_l = 415.305
yin_7_l = 466.164   #低音7频率

yin_1_m = 523.251   #中音1频率
yin_2_m = 587.33
yin_3_m = 659.255
yin_4_m = 739.989
yin_5_m = 830.609
yin_6_m = 932.328
yin_7_m = 1046.502

yin_1_h = 1174.659   #高音1频率
yin_2_h = 1318.52
yin_3_h = 1567.982
yin_4_h = 1760
yin_5_h = 2093.004
yin_6_h = 2489.016
yin_7_h = 2959.955
9.C语言.h文件为了防止头文件被重复包含,一般需要在文件的头部添加宏的判断:
#ifndef LED_H
#define LED_H
...头文件的具体内容...
#endif
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值