嵌入式C语言实战开发详解(四)

一、内存管理

1、你的数据放哪里?

 

栈空间:局部变量、函数形参、自动变量(调用后释放)

堆空间:mallocrealloccalloc分配空间

数据段:bss:保存未初始化的全局变量

        rodata:常量

        .data(静态数据区):全局变量、static修饰变量(程序结束后释放)

2、内存的分配方式

(1)从全局数据区分配

(2)在栈上创建

(3)在堆上创建

3、常见的内存错误及对错

(1)内存分配未成功,却使用了它

(2)内存分配虽然成功,但是尚未初始化就引用它

(3)内存分配成功并已经初始化,但操作越过了内存的边界

(4)忘记了释放内存,造成了内存泄漏

(5)释放了内存却继续使用它

4、段错误的调试方法

详情请戳网址:

http://blog.csdn.net/wzhcalex/article/details/51866913

 

二、函数

函数:(1)维护性好,函数要有独立的功能

     (2)迭代开发

     (3)复用性好

函数的调用:

  通过函数名找到函数的入口地址

  给形参分配内存空间

  传值:把实参变量对应的空间的值传给形参

  执行函数体里的语句

  函数返回并释放空间

 

函数的三要素:函数名、函数形参、函数返回值

 

1、函数名(自注释性--可读性)

    1、 一定要写函数声明!

        命名函数名要形成自己的风格!

        命名函数名要体现功能

        动词+名词:get_userinsert_user

        陌生词语不要进行缩写

        先写调用,再写实现

2、函数名也是指针常量,保存函数存放的地址,即函数的入口地址

2、函数参数的传递

1)传参要用对应的类型来接

2)代码示例:

#include<stdio.h>

 

void swap_int(int *left,int *right)

{

    int temp;

    temp = *left;

    *left = *right;

    *right = temp;

 

}

int main()

{

    int left = 5;

    int right = 6;

 

    printf("before swap:left = %d\tright = %d\n",left,right);

 

    swap_int(&left,&right);

 

    printf("after swap:left = %d\tright = %d\n",left,right);

 

    return 0;

}

 

如果只是传值而不是传地址的话,函数返回释放空间,则right、left的值并没有发生交换

这就引来了一个问题:什么时候传值,什么时候传地址呢?

读(不修改)实参变量对应的内存空间的值时,传实参变量名

写(修改)实参变量对应的内存空间的值时,传实参变量的地址(上示例代码即为传地址)

3)传入参数&传出参数:

如果函数接口有指针参数,既可以把指针所指向的数据传给函数使用(称为传入参数),也可以由函数填充指针所指的内存空间,传回给调用者使用(称为传出参数)

代码示例:


 

 

(4)主函数的形参:(命令行参数)

#include<stdio.h>

#include<stdlib.h>

 

int main(int argc,char *argv[])

{

    if(argc != 2)

    {

        printf("please input a param!\n");

exit(1);

    }

 

    printf("argc = %d\n",argc);

 

    int i;

 

    for(i = 0; i < argc; i++)

    {

        printf("argv[%d] = %d\n",i,atoi(argv[i]));

    }

    

    return 0;

}

 

 

3、函数返回值

(1)不能返回局部变量的地址:局部变量存放于栈空间,函数调用后就释放了

(2)exit1):结束整个程序,头文件为:#include<stdlib.h>

     1:是返回给用户

     通常用来做异常处理,判断哪个exit( )退出,用打印信息的方法

     echo $?

 

(3)return 0:返回给操作系统,标志主函数结束

            是规范要求,能够提高操作系统的运行效率,如果不写return 0系统要检查是否是正常退出等等

 

4、企业级函数编写

(1)函数的编码规范:

1、对所调用函数的错误返回码要仔细、全面地处理。

2、防止将函数的参数作为工作变量。

说明:将函数的参数作为工作变量,有可能错误地改变参数内容,所以很危险。对必须改变的参数,最好先用局部变量代之,最后再将该局部变量的内容赋给该参数。

3:函数的规模尽量限制在200行以内。

说明:不包括注释和空格行。

4、一个函数仅完成一件功能。

5、为简单功能编写函数。

说明:虽然为仅用一两行就可完成的功能去编函数好象没有必要,但用函数可使功能明确化,增加程序可读性,亦可方便维护、测试。

6、不要设计多用途面面俱到的函数。

说明:多功能集于一身的函数,很可能使函数的理解、测试、维护等变得困难。

7、尽量不要编写依赖于其他函数内部实现的函数。

说明:此条为函数独立性的基本要求。由于目前大部分高级语言都是结构化的,所以通过具体语言的语法要求与编译器功能,基本就可以防止这种情况发生。但在汇编语言中,由于其灵活性,很可能使函数出现这种情况。

8、避免设计多参数函数,不使用的参数从接口中去掉。

说明:目的减少函数间接口的复杂度。

9、检查函数所有参数输入的有效性。

(2)函数入口参数检查

比如:void * find_string(char *src,char *head,char *tail)

{

if(src == NULL || head == NULL || tail == NULL )

{

    printf(“the param is error!”)

exit(1);

}

}

(3)函数返回值异常处理

详情见上述exit( )

 

5、函数指针、函数指针数组

(1)函数指针

#include<stdio.h>

 

int add(int a,int b)

{

    return a+b;

}

 

int main()

{

    int num1 = 5;

int num2 = 6;

    

int (*p_func)(int,int);

p_func = add; //函数入口地址,倾向于此种

//p_func = &add;整个函数的地址

 

int result = p_func(num1,num2);

 

    printf("result = %d\n",result);

    

    return 0;

}

 

(2)回调函数

#include<stdio.h>

 

int add(int a,int b)

{

    return a+b;

}

int sub(int a,int b)

{

    return a-b;

}

int mul(int a,int b)

{

    return a * b;

}

int cal(int (*p_func)(int,int),int a,int b)

{

    return p_func(a,b);

}

 

int main()

{

    int num1 = 5;

int num2 = 6;

 

int i;

 

    

    int (*func_array[3])(int,int);

    func_array[0] = add;

    func_array[1] = sub;

    func_array[2] = mul;

 

    for(i = 0; i < 3; i++)

    {

        printf("result = %d\n",func_array[i](num1,num2));

    }

    

    return 0;

}

 

回调函数:回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。

 

6、可变参数

未完待续

  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
嵌入式web服务器boa框架的基础上, 使用C语言cgi, 或者Python脚本, 结合HTML + javascript + ajax 的嵌入式web系统的开发实例 html 中使用javascritp + ajax 从C语言生成的cgi文件的get, set 一些值. boa服务器的相关配置参数说明: http://www.cnblogs.com/liuweiqiang/p/3859130.html boa安装包文件名: boa-for-hi3516a.tar.gz boa.conf 文件的保存路径: cat /etc/boa/boa.conf boa可 执行文件的路径: /usr/local/bin/boa, 可以设置为: 系统启动的时候, 这个进程自动启动 boa.conf 文件的重要参数 保存html文件的目录 DocumentRoot /www 可以将这个目录, 设置为samb共享文件夹的目录, 方便修改调试 修改完成以后, 肯定要重启boa进程的 保存python脚本, 或者C语言cgi文件的目录 ScriptAlias /cgi-bin/ /var/www/cgi-bin/ 说明: cgi-bin/ 后面的斜杠, 一定要加上 可以将这个目录, 设置为samb共享文件夹的目录, 方便修改调试 修改完成以后, 肯定要重启boa进程的 html文件文件中, 调用python脚本的时候, 指定的路径, 需要有: /cgi-bin, 比如: var url = "/cgi-bin/getuser.py"; 这个是python 或者 var url = "/cgi-bin/output.cgi"; 这个是C语言 说明: 如果发现, html文件, 修改了, 可是在浏览器中, 查看html源代码的时候, 这个代码, 还是旧的, 那么可以通过清空"IE浏览器", "360浏览器"的浏览记录 以上, javascript 可以调用python 同样, 也可以调用C语言生成的cgi文件(其实, 就是可执行文件) C语言 + Html 例子 C语言 CGI实例 http://blog.csdn.net/ajrm0925/article/details/8810342 http://blog.csdn.net/liang890319/article/details/6277900 http://blog.csdn.net/gnefniu/article/details/42432657 上传文件: http://blog.csdn.net/yu_xiang/article/details/7996670 查找文件 find . -type f -name "boa.conf" -print -mount find . -type f -name "boa" -print -mount 嵌入式web服务器boa的配置和使用 嵌入式web服务器boa的配置文件为boa.conf, 在boa-0.94.13目录下面,复制该文件到文件 系统的/etc/boa目录下面,打开boa.conf,修改为如下内容: Port 80 User root Group root ErrorLog /dev/console AccessLog /dev/null ServerName SoftEmbed.com DocumentRoot /www DirectoryIndex index.html KeepAliveMax 1000 KeepAliveTimeout 10 MimeTypes /etc/mime.types DefaultType text/plain CGIPath /bin:/usr/bin:/usr/local/bin ScriptAlias /cgi-bin/ /www/cgi-bin/ 几个重要配置参数如下: DocumentRoot: 存放html文档的主目录; DirectoryIndex: 默认返回的html文档; ScriptAlias:cgi脚本虚拟路径对应的实际路径,/www/cgi-bin/为cgi脚本存放的实际路径; 其他配置选项的意义请参考相关资料。 复制boa可执行文件到/usr/sbin目录中, 启动boa进程 重新制作文件系统,系统启动后,在客户端浏览器上输入开发板的ip 地址,例如: http://192.168.0.218, 就可以看到显示的测试网页了,如下图所示 CGI getenv函数的参数详解: http://www.cnblogs.com/ser0632/p/5498228.html s = getenv("环境变量名"); 取得环境变量内容 putenv改变或增加环境变量 int putenv(const char * string); setenv(改变或增加环境变量) http://www.jb51.net/article/71940.htm
宋宝华嵌入式 C/C++语言精华文章集锦 C/C+语言 struct 深层探索 ............................................................................2 C++中 extern "C"含义深层探索........................................................................7 C 语言高效编程的几招...............................................................................11 想成为嵌入式程序员应知道的 0x10 个基本问题 .........................................................15 C 语言嵌入式系统编程修炼...........................................................................22 C 语言嵌入式系统编程修炼之一:背景篇 ............................................................22 C 语言嵌入式系统编程修炼之二:软件架构篇 ........................................................24 C 语言嵌入式系统编程修炼之三:内存操作 ..........................................................30 C 语言嵌入式系统编程修炼之:屏幕操作 ..........................................................36 C 语言嵌入式系统编程修炼之五:键盘操作 ..........................................................43 C 语言嵌入式系统编程修炼之六:性能优化 ..........................................................46 C/C++语言 void 及 void 指针深层探索 .................................................................50 C/C++语言可变参数表深层探索 .......................................................................54 C/C++数组名与指针区别深层探索 .....................................................................60 C/C++程序员应聘常见面试题深入剖析(1) ..............................................................62 C/C++程序员应聘常见面试题深入剖析(2) ..............................................................67 一道著名外企面试题的抽丝剥茧 ......................................................................74 C/C++结构体的一个高级特性――指定成员的位数 .......................................................78 C/C++中的近指令、远指针和巨指针 ...................................................................80 从两道经典试题谈 C/C++中联合体(union)的使用 ......................................................81 基于 ARM 的嵌入式 Linux 移植真实体验 ................................................................83 基于 ARM 的嵌入式 Linux 移植真实体验(1)――基本概念 ...........................................83 基于 ARM 的嵌入式 Linux 移植真实体验(2)――BootLoader .........................................96 基于 ARM 的嵌入式 Linux 移植真实体验(3)――操作系统 ..........................................111 基于 ARM 的嵌入式 Linux 移植真实体验(4)――设备驱动 ..........................................120 基于 ARM 的嵌入式 Linux 移植真实体验(5)――应用实例 ..........................................135 深入浅出 Linux 设备驱动编程 .......................................................................144 1.Linux 内核模块..............................................................................144 2.字符设备驱动程序 ...........................................................................146 3.设备驱动中的并发控制 .......................................................................151 4.设备的阻塞与非阻塞操作 .....................................................................157
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值