项目中遇到的问题小结
在做一个项目时,程序的要求是:将数据以32位存入文件中,因为在32位机上操作习惯了,所以直接将数据类型设置为 int 型,结果在测试数据的时候,发现数据好长,检查了一下,程序的结构,没有发现什么逻辑上的错误,偶然间一个同学问我:怎么查看本机内核的版本,我说你用: uname -a 看一下,对呀,我怎么忘记了这个命令,检查一看,原来我的机子是 64 位的,原来问题出在这里了!
简单小结一下这次的问题:
1) 整型是 C语言的基本类型之一,int 是整型变量的基本类型,整型变量还有短整型(short int)和长整型(long ing),它们在内存中所占的字节数是不一样的,在32位机上short int占两个字节,即16位,而整型和长整型占用4字节32位(但是有的微机上是:短整型和整型都是16位,长整型32位),这个可以通过 sizeof 来计算;
2) 默认的情况下 一般是有符号的,只有在指明了 unsigned 时,才是无符号的,还有一点要特别声明一下,就是如果你定义的是 unsigned 类型的,那么在 printf 时,你觉得没有错误,但是打印的数据就是有错误,那么请仔细检查,在printf 时格式应该是:
printf("data is:%u\n" , data);
当你定义了 unsigned 时,数据的范围已经改变了,而 %d 打印的是有符号的,所以……
3) 既然是32位机的,那么我需要32位的应该怎么定义呢,其实,内核已经给我们设置好了,在头文件中就有这样的定义,大家可以查看 /usr/include/stdint.h 和 linux/types.h 中的相关定义,所以在做项目时应该避免使用像 int 之类的,也是便于可移植,取而代之像 uinit32_t。
总结:
在项目时,这些都是很容易被疏忽的,所以小小的总结一下!
其实还有一些小问题,可是经常在我们做程序设计时将其忽略,所以这些问题还是值得注意的
在编写面向过程的程序时,程序的逻辑性很重要的!以下是一些简单的小结
NULL检查
下面是一个程序小片段
点击(此处)折叠或打开
char *str = NULL;
memset(str, 0, sizeof(str));
if(str == NULL) {
program 1;
} else {
program 2;
}
预想的结果是,这个程序回去执行 program 1,但是却犯了一个致命的错误,原因是错误的理解
memset函数的用途,这个函数的用途是将指定的空间清零,即\0\0\0\0…;
所以这里不可以用 NULL 来判断
所以在初始化的时候一定要特别注意这些细节上的问题,或者说是好好理解一些函数的用法!
总结一下防止以后在犯类似的错误!!
多命令行参数的检查--dbase=:
我们要分离开IP 和 PORT,如果是你,你会怎么检查呢!但是有点是很明白的,在解析的时候,我们会通过 *pos!='\0',来判断,如果是解析port,那么这样是可以的,但是如果是在解析IP呢!
IP:192.168.200.100
PORT: 0-65535
这样的话,就相当的复杂了, 从简单的一种检查方式:
*s_name!=':' && *s_name!='\0'
这样就么有问题了吗, 从简单的 0.0.0.0 - 255.255.255.255
如果用户输入的是 --dbase=2555.255.2555.1000:655350
好了,这样的话,上面的检查是不是还有问题,所以可以在检查的时候加上一个变量(i++),通过这个就可以防止用户输入的参数超过预期的IP的范围,其实还有一些问题,就先到这儿吧!
数组
1) 对于二维数组 先行后列相较于先列后行要快很多,并且务必注意边界检查
C语言常见编程提示
1)C语言提供的字符串sprintf/vsprintf/strcpy/strcat/等函数很容易导致内存越界,谨慎操作
2)数组循环操作时防止越界操作
3)memcpy memcpy拷贝时,先调用memset清空缓冲区,当涉及敏感信息时及时调用memset清0
4)memcpy拷贝的是无结构的内存,没有规定指针的长度, 也不在缓冲区末尾强制加'\0',最终可能使用了结尾的垃圾数据
性能和优化
- 使用局部变量激励频繁使用且需要计算的值;
- 减少循环次数,展开循环体,减少函数的调用次数
- 频繁使用的代码使用高效的算法
- 边界值检查,检查除数为0的情况
- 字节序:字节序是大端还是小端取决于CPU而非架构
函数使用
strlen这个函数计算的是字符串的长度,以末尾的 '\0' 为结束标志,判断是否已经到字符串尾,计算的长度不包含结尾的 '\0'
宏定义
#pragma pack(1) / #pragma() 默认的是4字节对齐方式
4万+

被折叠的 条评论
为什么被折叠?



