atoi c linux 用法
2014-05-10 11:18:56 lcstrive 阅读数 571

【起因】希望对各种类型的数组进行初始化,避免野值
      【函数头文件】 疑问提示:在linux中可以在terminal中输入 "man memset"进行查询
        #include<string.h>
        void *memset(void *s, int c, size_t n);
      【使用说明】 The  memset()  function  fills  the  first  n  bytes of the memory area  pointed to by s with the constant byte c.
      【错误用法】
        int array[10];
        memset(array,1,10);//或者memset(array,1,sizeof(array)),都是不对的!
      【解释】
       之前一直不明白为什么memset这个函数的头文件是 "string.h",看完下面的内容,你就会明白了。
       memset函数使用说明中提到的是按照byte来填充。
       举例来说
       char arr[10]; memset(arr,'a',10);
       由于char只占一个字节(byte),因此函数的结果是将连续的10个字节都填充为'a'。这是我们所期待的结果!
       int arr[10];memset(arr,1,10);
       由于int占4个字节(byte),因此"1"对应的二进制(32bits下)为"00000000000000000000000000000001"(4bytes),塞到1byte(8bit)的中,高位被舍弃了。所以,填入数组中的值是"00000001"。然而总共有10*4=40个byte,却只有10个byte被填充,因此结果是"00000001……00000001**********"(前面总共10个"00000001")。因此,第一个数是"0x01010101"=16843009(10进制),数组其余部分的值则是随机值,读取出来会是很离谱的数!
       有人说,可以这样memset(arr,1,sizeof(arr));
       其实这样做,就是将数组的所有值都填充为"0x01010101",也就是int数组的初始值变为了16843009 !这确实有点出乎我们的预料!
  【正确用法】
   方法一:可以用任何值来初始化char数组!比如 memset(arr,'a',10);
   方法二:可以用"0"来初始化任何类型数组!比如 memset(arr,0,sizeof(arr));//arr可以是char或int等类型数组!
  【小结】版权所有,如有转载请注明出处:blog.csdn.net/whuslei
   不难看出为什么memset在"string.h"头文件中声明了,因为他是以byte为单位来处理的,而char正好是一个byte!
   用"0"来初始化数组时,要初始化的长度最好用sizeof(arr)来计算,这样避免出错!是不是很强大?

2012-03-27 08:52:36 jibing57 阅读数 609

大家都知道在Unix/Linux中有个man命令,可以查询常用的命令,函数。可是对于我们这样只知道用"man 函数名"来查询的人来说,会遇到很多问题,比如:

      man read,我想看的是ANSI C中stdio的read函数原型和说明,没想到出来的确是BASH命令的说明,这是怎么回事呢?

      原来read本身是man命令的一个参数,这样输入man就会以为你要使用read的功能,而不是查看read函数,那么要怎样查看read函数呢?

       答案是使用:    man 2 read 或者是man 3 read

       中间的数字是什么意思呢?是man的分卷号,原来man分成很多部分,分别是:

1 用户命令, 可由任何人启动的。

2 系统调用, 即由内核提供的函数。

3 例程, 即库函数,比如标准C库libc。

4 设备, 即/dev目录下的特殊文件。

5 文件格式描述, 例如/etc/passwd。

6 游戏, 不用解释啦!

7 杂项, 例如宏命令包、惯例等。

8 系统管理员工具, 只能由root启动。

9 其他(Linux特定的), 用来存放内核例行程序的文档。

n 新文档, 可能要移到更适合的领域。

o 老文档, 可能会在一段期限内保留。

l 本地文档, 与本特定系统有关的。

      要查属于哪一部分的,就用哪一部分的编号在命令之前。


转自:http://hi.baidu.com/sundl2268/blog/item/b6a5bbc3df930242b219a829.html

2013-12-05 11:31:27 surfacedust 阅读数 5739
  Linux内核中有很多c中使用汇编的情况,比如原子操作。内联汇编通常用下面的格式:

asm volatile("Instruction List" : Output : Input : Clobber/Modify);

        当然,或者写作如下格式(Output、Input、Clobber/Modify都是可选的),也就是三个冒号,4个部分:

asm volatile("Instruction List"

                                    : Output

                                    : Input

                                    : Clobber/Modify);

        为了理解方便,以屏蔽本地irq相关函数的代码为例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
static inline unsigned long native_save_fl(void)
{
    unsigned long flags;
  
    /*
     * "=rm" is safe here, because "pop" adjusts the stack before
     * it evaluates its effective address -- this is part of the
     * documented behavior of the "pop" instruction.
     */
    asm volatile("# __raw_save_flags\n\t"
             "pushf ; pop %0"
             : "=rm" (flags)
             : /* no input */
             : "memory");
  
    return flags;
}
  
static inline void native_restore_fl(unsigned long flags)
{
    asm volatile("push %0 ; popf"
             : /* no output */
             :"g" (flags)
             :"memory", "cc");
}
  
static inline void native_irq_disable(void)
{
    asm volatile("cli": : :"memory");
}
  
static inline void native_irq_enable(void)
{
    asm volatile("sti": : :"memory");
}

        本篇blog耗时2小时。

 

1、asm和volatile

        volatile是c的关键字,是个修饰符,用于修饰变量或者函数,意思是告诉编译器,该变量或者函数是“易变”的,编译器会在优化时做相关的考虑。驱动中常用于修饰急促器变量。Linux下c中的使用内联汇编,就是这样,需要asm()的格式,可以没有volitile,但不能没有asm。

        关于asm到底是什么?首先,它不是ANSI C关键字,c89/c99标准中没有asm关键字;asm属于“GNU C Language Extensions”,像typeof,inline等都是这种情况。

2、Instruction List

        指令序列,就是指要执行的指令汇编指令,多条指令之间使用 分隔符“;”、“\n\t”等进行联合。

        对应例子中,就是

  • "pushf;pop %0"
  • “push %0;popf”
  • "cli"
  • "sti"

        含义分别为:

  • 将EFLAGS寄存器的值压栈,再出栈给的1个变量(先这么叫吧)
  • 将第1个变量压栈,再出栈给EFLAGS寄存器
  • 禁止本地中断
  • 开启本地中断

3、Output

        指令序列执行的结果的输出,指指令执行的结果要输出到哪。Output和Input部分,通常使用下列格式:

“constraint”(variable)

        constraint为限制的意思,翻译好听点就是“修饰”,用于限制variable的。

        在例子中,只有navtive_save_fl函数有“=rm”(flags),这句还不好臆测,还得查资料(参考资料5):

  • =,表示只写,也是output必须具备的(看见=,就是output)
  • r表示寄存器
  • m表示内存
  • flags为变量名

        联合起来表示将flags变量以内存或者寄存器的方式进行操作,flags是输出。

        关于constraint:

  • a,b,c,d,S,D 分别代表 eax,ebx,ecx,edx,esi,edi 寄存器
  • r 上面的寄存器的任意一个(谁闲着就用谁)
  • m 内存
  • i 立即数(常量,只用于输入操作数)
  • g 寄存器、内存、立即数 都行(gcc你看着办)

4、Input

       Input和Output很像,就是没有“=”。Input为指令序列提供输入,在例子中,只有native_restore_fl函数有“g”(flags),g表示“Any register, memory or immediate integer operand is allowed, except for registers that are not general registers.”,表示flags可以使用寄存器、内存、立即数等方式。

        还有个问题,就是Input和Output如何与Instruction List相关联的?Instruction List中的%0,前面叫他“第一个变量”,实际上是不准确的,实际上应该叫做input/output operand,输入/输出操作数,从Output开始,0表示第一个,1就表示第二个,以此类推。从gcc3.1开始,支持直接将%0写作%[input]、%[output]。

       input和Output可以有多个变量:中间用“,”隔开。

5、Clobber/Modify

       该部分表示哪些寄存器、内存被修改,但是又没有出现在Input/Output中。通常看到的就是memory,表示汇编语句可能修改了内存,如果有变量缓存在寄存器中,需要重新读取该变量。

 

参考资料:

1、Linux 中 x86 的内联汇编

2、__asm__ __volatile__内嵌汇编用法简述

3、第 19 章 汇编与C之间的关系

4、AT&T inline Assembly Constraint

5、Assembler Instructions with C Expression Operands

6、内联汇编

7、GCC-Inline-Assembly-HOWTO

Published in and tagged , on 2013年11月24日 by
2018-03-04 10:54:44 liulijiehanwen 阅读数 24

在C语言中,goto语句不能跨越函数。setjmp和longjmp可以完成。

  1.#include "apue.h"

  2 #include <setjmp.h>

  3 

  4 static void f1(int, int, int, int);

  5 static void f2(void);

  6 

  7 static jmp_buf jmpbuffer;

  8 static int globval;

  9 

 10 //#ifdef UNMAIN

 11 int

 12 main(void)

 13 {

 14     int autoval;

 15     register int regival;

 16     volatile int volaval;

 17     static int statval;

 18     

 19     globval = 1; autoval = 2; regival =4; volaval = 4; statval = 5;

 20     if(setjmp(jmpbuffer) != 0){

 21         printf("after longjmp: \n");

 22         printf("globval = %d, autoval = %d, regival = %d,"

 23         "volaval = %d, statval = %d \n",

 24         globval, autoval, regival, volaval, statval);

 25         exit(0);

 26         }

 27     

 28 /*

 29  * change variables after setjmp, but before longjmp .

 30  */

 31 globval = 95; autoval = 96; regival = 97; volaval = 98; statval = 99;

 32 f1(autoval, regival, volaval, statval); /*never returns*/

 33 exit(0);

 34 }

 35 

 36 static void

 37 f1(int i, int j, int k, int l)

 38 {

 39 printf("in fl() \n");

 40 printf("globval = %d, autoval = %d, regival = %d,"

 41         "volval = %d, statval = %d\n", globval, i, j, k, l);

 42 f2();

 43     }

 44 static void

 45 f2(void)

 46 {

 47     longjmp(jmpbuffer, 1);

 48     }

如代码,如果要编写一个使用非局部跳转的可移植程序,则必须使用volatile属性。autoval和regival都存放在寄存器中,volatile变量则存放在存储器中。


引用:UNIX环境高级编程的7.10

注:第一次试着写自己觉得重要的内容,网上没有查到的内容。



2014-05-19 15:46:10 aysycd 阅读数 1027

    最近写了一个项目,其中用到了tar这个命令,发现在Qt中的file取得路径之后,获得的都是绝对路径,这个时候用tar打包会将绝对路径全部放进去,可以用tar temp.tar.gz file -C fileDIr来指定file的目录,这样可以在打包成文件之后内部去掉路径信息。

    同样,在解压的时候zxvf,用-C可以动态指定解压目录,比如当前在temp下,想要解压到temp目录下的hello中,可以tar zxvf -C destDir来指定解压目录。

linux c中write、read的用法

阅读数 48249

linuxc中write、read的用法·write函数1.功能将数据写入已打开的文件内2.相关函数open,read,fcntl,close,lseek,sync,fsync,fwrite3.表头文件#include4.定义函数ssize_twrite(intfd,constvoid*buf,size_tcount);5.函数说明wri

博文 来自: lyc_daniel

LINUX C例程1:open的用法

阅读数 7

/**************************************************************************Filename:open.c*Description:*Version:1.0*Created:2011年07月18日18时54分51秒*...

博文 来自: weixin_34329187

LINUX C例程1:sscanf的用法

阅读数 2

#include&lt;stdio.h&gt;#include&lt;stdlib.h&gt;#include&lt;string.h&gt;#include&lt;unistd.h&gt;intmain(intargc,char*argv[]){charbuf[100];charstr[20]="helloworld100";intnum;...

博文 来自: weixin_34348111

linux c strtok函数的用法详解

阅读数 389

用下面示例说明strtok函数的各种用法的关键点1、用strtok函数分割字符串后,原字符串被修改#include#include#include#include#include#includeintmain(){charsend_str[600]={0};charnr[10][20]={0};cha

博文 来自: lxxll

linux c sscanf和sprintf的简单用法与理解

阅读数 1992

1、intsprintf(char*str,constchar*format,.....);函数说明:根据format来转换并格式化数据,并把结果写入到str所指的字符串数组中。返回值:成功的话返回str字符串的长度,否则返回-1。在C中我们可以用这个函数很

博文 来自: xy63345411
没有更多推荐了,返回首页