此函数有以下几点值得注意:
1、第一个参数中的const。一般在函数的形参中,如果我们只是希望调用者使用该参数,而不会去改变该参数内容(一般是指针指向的内容),则可以声明为const。
2、第二个参数。C语言中函数只能有一个返回值,但是有时候我们希望从函数中得到不止一个返回内容怎么办呢?只能通过参数了。一般的参数是用来向函数输入信息的,但是指针型参数可以间接用来从函数输出信息。使用时用户只需传入一个相应的指针,函数中会把需要输出的信息地址传给这个指针,这样在函数调用完成后,用户即可到endp指针处去取函数传出的值了。这就是用参数实现返回值的方式。但是要注意,在函数中千万不可把局部变量的地址传给输出型指针,因为局部变量存在栈里,函数调用结束后即释放了,传出的指针指向的内容是栈上已经被释放的部分,因此是无效的。(PS:高级语言中譬如C#有ref,out关键字,以明确指明该引用为输出型)
3、第三个参数base。要注意这个base的机制,本函数中是按照这样的理念来设计的。即如果str中有0x开头且接下来是数字则忽略用户调用时输入的base,强制为16进制。如果str不是上面情况然后才看用户输入的base。用户输入非0则使用用户指定的base,若用户输入0则自动判断是8进制还是10进制。需要强调的是:使用习惯决定理念,理念决定代码逻辑。
4、注意 if(endp)这里,在输出型参数使用中,函数内首先判断endp是否为NULL,并以此来决定是否输出这个机制来自于一个理念:这个输出参数有可能是用户关注的,也有可能是用户不在意的。这样处理可以给用户自由,即用户如果在意就传一个有效指针过来接收;如果不在意调用时直接给个NULL就行。提供服务但不强迫,这样很好。在OS的API中很多时候都有类似的技巧,请注意体会。

unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
{
    unsigned long result = 0,value;
    //对于base,首先如果*cp以0x开头且下来是数字,则一定为16进制。然后如果用户指定了一个非0的进制,则
    //遵循用户输入的进制。如果用户输入了0进制,则根据是否0开头来确定是8进制还是10进制
    if (*cp == '0') {
        cp++;
        if ((*cp == 'x') && isxdigit(cp[1])) {
           base = 16;    //如果cp是0x开头的,下面一个又是数字,那么base一定为16。
           cp++;            //此时即使用户输入了一个base,也忽略这个base而强制其为16。
        }
        if (!base) {
            base = 8;    //如果用户输入base为0,cp是0开头,接下来不是x,那么强制为8进制
        }                        
    }
    if (!base) {
        base = 10;    //如果用户输入base为0,cp是非0开头,则使用10进制。
    }
    //while循环里value<base是精髓所在。这个解析停止的条件不能是null,而应该是str中
    //第一个不是数字的字母。这个字母的范围取决于base,譬如如果是16进制那么f也算是数字。
    //而如果是8进制那么9都不算是数字了。因此解析结束的范围只能和base比较来限定。
    while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
        ? toupper(*cp) : *cp)-'A'+10) < base) {
        result = result*base + value;
        cp++;
    }
    if (endp)                          //此处if判断的作用是:用户在使用这个函数时,如果不关心endp则可以直接
        *endp = (char *)cp;    //使用null,而不必担心程序运行会出错。这种处理技巧很实用,用户可以
        return result;              //自行决定是否使用这个函数提供的参数式返回值。
}

simple_strtoul()分析的更多相关文章

  1. Android中基于CGroup的memory子系统HAL层分析-lmkd

    Android在内存管理上于Linux有些小的区别,其中一个就是引入了lowmemorykiller.从lowmemorykiller.c位于drivers/staging/android也可知道,属 ...

  2. Linux内核--网络栈实现分析(三)--驱动程序层+链路层(上)

    本文分析基于Linux Kernel 1.2.13 原创作品,转载请标明http://blog.csdn.net/yming0221/article/details/7497260 更多请看专栏,地址 ...

  3. 嵌入式Linux驱动学习之路(五)u-boot启动流程分析

    这里说的u-boot启动流程,值得是从上电开机执行u-boot,到u-boot,到u-boot加载操作系统的过程.这一过程可以分为两个过程,各个阶段的功能如下. 第一阶段的功能: 硬件设备初始化. 加 ...

  4. (转载)U-boot启动完全分析

    1.1 U-Boot工作过程 U-Boot启动内核的过程可以分为两个阶段,两个阶段的功能如下: (1)第一阶段的功能 Ø 硬件设备初始化 Ø 加载U-Boot第二阶段代码到RAM空间 Ø 设置好栈 Ø ...

  5. u-boot移植总结(四)u-boot-2010.09框架分析

    (一)本次移植是基于FL2440,板子的基本硬件: CPU 型号为S3C2440,基于ARM920T,指令集ARMV4,时钟主频400MHz SDRAM H57V2562GTR-75C 2片*32MB ...

  6. imx6 framebuffer 分析

    分析imx6 framebuffer设备和驱动的注册过程. Tony Liu, 2016-8-31, Shenzhen 相关文件: arch/arm/mach-mx6/board-mx6q_sabre ...

  7. Android 呼吸灯流程分析

    一.Android呼吸灯Driver实现 1.注册驱动 代码位置:mediatek/kernel/drivers/leds/leds_drv.c 602static struct platform_d ...

  8. G-sensor驱动分析

    重力传感器代码分析 重力传感器驱动的功能,主要是向HAL层提供IOCTRL接口,并通过input设备上报数据.芯片实际数据的读取是采用i2c协议读取原始数据,并且作为i2c设备挂载在系统上工作的. 1 ...

  9. start_amboot()函数分析

    一.整体流程 start_amboot()函数是执行完start.S汇编文件后第一个C语言函数,完成的功能自然还是初始化的工作 . 1.全局变量指针r8设定,以及全局变量区清零 2.执行一些类初始化函 ...

随机推荐

  1. HDU 5863 cjj's string game (矩阵乘法优化递推)

    题目大意:用k种字符构建两个长度为n的字符串(每种字符有无限多个),要求对应位置字符相同的连续子串最长长度为m,问方法数. 其中k,n,m是输入,n(1<=n<=1000000000), ...

  2. Regexp-Utils:基本

    ylbtech-Regexp-Utils:基本 1.返回顶部 1. /** * 管理 */ var utils = { hostUrl: "http://localhost:8023&quo ...

  3. 19.QT对话框(文件对话框,颜色对话框,字体框,自定义对话框)

    文件对话框 #include<QFileDialog> //文件对话框 void Dialog::on_pushButton_clicked() { //定义显示文件的类型 窗口标题 可供 ...

  4. BZOJ 4184 线段树+高斯消元

    思路: 线段树表示的是时间 每回最多log个段 区间覆盖 一直到叶子 的线性基 xor 一下 就是答案 一开始没有思路 看了这篇题解 豁然开朗 http://www.cnblogs.com/joyou ...

  5. 构建工具系列一--Travis-cli

    本文地址: http://www.cnblogs.com/blackmanba/articles/continuous-integration-tool-travis-cli.html或者http:/ ...

  6. 微信小程序-最新获取用户基本信息方案

    如果只是单纯的展示用户信息,那么最简单的方案就是 文档中组件: <open-data type="groupName" open-gid="xxxxxx" ...

  7. C语言“%”运算符

    C语言中运算符“%”是取余运算符,而非取模运算符.(运算符“%”在C/C++, JAVA中,为取余运算,而在Python中为取模运算) 对于一个C语言取余表达式a % b,设其值为result,有如下 ...

  8. Activity全屏沉浸状态

    public class MainActivity extends AppCompatActivity { private static final String TAG = "MainAc ...

  9. 杭电 1114 Piggy-Bank【完全背包】

    解题思路,首先很容易想到方程f[v]=min(f[v],f[v-w[i]+p[i]),因为是要求当包装满的时候(因为题目中给出的是包的质量是一定的),包里面装的钱最少,所以将f[]初始化成一个很大的数 ...

  10. Unity 围绕X、Y、Z旋转图例

    绿色:绕X 红色:绕Y 蓝色:绕Z PS:这是右手坐标系,Unity为左手坐标系 不知道啥叫左手右手?参见我的另一篇文章http://www.cnblogs.com/36bian/p/7571727. ...