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)返回参数不同,看如下测试程序以及输出:
输出:
(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循环中的执行顺序:
编译成汇编:gcc -S for_test.c
查看汇编代码:
很清晰的看到,
先对整数赋值,条件判断,for体执行,变量递增。
功能:拷贝一定长度内存内容到指定的内存;
区别:当内存发生局部重叠的时候,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体执行,变量递增。
相关文章推荐
- 总结四:Linux与时间相关的常用命令
- 悟空学Linux专栏----第16篇
- 悟空学Linux专栏----第15篇
- linux内存映射--mmap
- centos svn备份
- Linux文件系统 软链接 硬链接
- centos引导项的重建
- linux基础命令
- Linux中查看和杀死进程
- linux双网卡绑定
- linux双网卡绑定
- Windows下登录UNIX或Linux服务器主机的软件
- wrapper 部署linux跟window
- Linux内核目录结构
- Linux系统新手学习的11点建议
- rpm安装找不到.so库文件(linux动态库连接的相关知识)
- Linux下安装配置Nexus
- 解决(Linux)Fedora10下ping: unknown host www.baidu.com
- 【编译打包】teamtalk 在CentOS 7 上的安装 推荐
- linux中输出调试信息