您的位置:首页 > 运维架构 > Linux

Linux C编程中遇到问题

2015-07-10 15:01 417 查看
1、memcpy 和 memmove

功能:拷贝一定长度内存内容到指定的内存;

区别:当内存发生局部重叠的时候,memmove保证拷贝的结果是正确的,memcpy不保证拷贝的结果的正确;

函数原型:

void *memcpy(void *dst, const void *src, size_t count);

void *memmove(void *dst, const void *src, size_t count);

图形看出两者的区别:



第二种体现出两者的区别;

2、sprintf 和 snprintf

功能:格式化的数据写入某个字符串中

原型:

int sprintf( char *buffer, const char *format, [ argument] … );

int snprintf(char *str, size_t size, const char *format,[ argument] … )

(1) 如果格式化后的字符串长度 < size,则将此字符串全部复制到str中,并给其后添加一个字符串结束符('\0');

(2) 如果格式化后的字符串长度 >= size,则只将其中的(size-1)个字符复制到str中,并给其后添加一个字符串结束符('\0'),返回值为欲写入的字符串长度。

区别:(1)sprintf存在内存溢出的问题;

(2)返回参数不同,看如下测试程序以及输出:

#include <stdio.h>

int main()
{
        int ret_value = 0;
        char buffer[1024] = { 0 };
        const char *str = "1234567890";
        char buff1[1024] = { 0 };
        char buff2[1024] = { 0 };
        int len1 = 0, len2 = 0;
        int i;

        ret_value = sprintf(buffer, "%s", str);
        printf("ret_value = %d\nbuffer = %s\n", ret_value, buffer);
        ret_value = snprintf(buffer, 5, "%s", str);
        printf("ret_value = %d\nbuffer = %s\n", ret_value, buffer);
    
        len1 = snprintf(buff1, 1024, "%s", "a");
        printf("len1 = %d\n buff1 = %s\n", len1, buff1);

        len2 = sprintf(buff2, "%s", "a");
        printf("len2 = %d\n buff2 = %s\n", len2, buff2);    
        for(i = 0; i < 3; i++)
        {   
              snprintf(buff1, 1024, "%s%s", buff1, "a");
              sprintf(buff2, "%s%s", buff2, "a");
        }   
        printf("buff1 = %s\n", buff1);
        printf("buff2 = %s\n", buff2);
        return 0;
}

输出:




(3)snprintf每次会将缓存区buffer[0] =’\0’,而sprintf没有这个参数,可以参照glibc标准源码。上面用测试用例验证。

类似:strcpy() sprintf() strcat() 存在安全隐患, 其对应的安全版为:

strncpy() snprintf() strncat()



3、指针数组和数组指针

指针数组:array of pointers,即用于存储指针的数组,也就是数组元素都是指针

数组指针:a pointer to an array,即指向数组的指针

还要注意的是他们用法的区别,下面举例说明。

int* a[4] 指针数组

表示:数组a中的元素都为int型指针

元素表示:*a[i] *(a[i])是一样的,因为[]优先级高于*

int (*a)[4] 数组指针

表示:指向数组a的指针

元素表示:(*a)[i]

4、for循环中三条语句执行顺序:

看下面例子,以及汇编代码来查看for循环中的执行顺序:

#include <stdio.h>
int main()
{
        int i;
        for(i = 0; i < 10; i++)
        {
                printf("%d\n", i);
        }
        return 0;
}


编译成汇编:gcc -S for_test.c

查看汇编代码:

.file   "for_test.c"
        .section        .rodata
.LC0:
        .string "%d\n"
        .text
.globl main
        .type   main, @function
main:
        pushl   %ebp
        movl    %esp, %ebp
        andl    $-16, %esp
        subl    $32, %esp
        movl    $0, 28(%esp)
        jmp     .L2
.L3:
        movl    $.LC0, %eax
        movl    28(%esp), %edx
        movl    %edx, 4(%esp)
        movl    %eax, (%esp)
        call    printf
        addl    $1, 28(%esp)
.L2:
        cmpl    $9, 28(%esp)
        jle     .L3
        movl    $0, %eax
        leave
        ret
        .size   main, .-main
        .ident  "GCC: (GNU) 4.4.7 20120313 (Red Hat 4.4.7-4)"
        .section        .note.GNU-stack,"",@progbits


很清晰的看到,

先对整数赋值,条件判断,for体执行,变量递增。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: