C语言的琐碎记录——读《C和指针》

1. 关于数组长度

数组可以指定长度然后初始化,也可以由编译器自动根据初始化内容计算数组长度

int vector[5] = {1, 2, 3, 4, 5};//指定长度初始化
int vector[] = {1, 2, 3, 4, 5, 6};//自动计算数组长度

对于字符形式,可以直接指定初始化,也可以使用字符串的方法初始化

//1
char message1[] = {'H', 'e', 'l', 'l', 'o'};
//2
char message2[] = "Hello";
char *message3 = message1;

注意message1和message2的内容是不一样的,1的方式长度为5,2的方式长度为6,多了一个'\0',下边的这种初始化方式其实经常被用到。

对于下面的这种类型其实是可以看做字符串,库函数里有标准获取字符串长度的函数strlen(),但是得到的结果是5,不包括最后的结束符'\0',也就是说你把它看做字符串时,统计字符长度strlen只统计字符个数。

统计数组的长度并没有标注库函数,C语言惯用的获取数组长度采用下面的宏定义

#define ARRAY_LEN(array)    \
(sizeof(array)/sizeof(array[0]))

这里将message2传进去得到的结果是6,可以使用message1计算,但不能将message3传进去。

 2.关于多维数组作为函数参数

假设要调用一个矩阵:

int matrix[3][10];
...
func(matrix);

这里参数matrix的类型是指向包含10个整形元素的数组的指针,func的原型可以是以下的任一种:

void func(int (*mat)[10]);
void func(int mat[][10]);

其中第二维长度必须声明,使用下面的声明是不正确的:

void func(int **mat);//mat是指向整形指针的指针

3. 关于size_t

stddef.h定义size_t是一个无符号整形,很多函数返回的是size_t类型,比如strlen,注意其是无符号的

if(strlen(x) >= strlen(y)) ...
if(strlen(x) - strlen(y) >= 0) ...

以上两个表达式是不一样的,第二条语句结果永远为真,如果使用第二种方式注意强转为int可消除问题。

4.字符串函数的一些问题

常用的字符串函数都是“不受限制”的,即只通过寻找字符串结尾的'\0'字节来判断它的长度,比如:

a.   strcpy、strcat必须保证目标字符数组的空间足以容纳源字符串,否则出错

b.   strcmp的返回结果有三种:小于、等于、大于,判断是否相等的比较好的判断风格如下:

if(0 == strcmp(a, b))

     注意比较的字符串参数必须以'\0'结尾。

上面的问题在库函数有长度受限的字符串函数:

strncpy、strncat、strncmp,这些是安全的字符串函数,防止长字符串从它们的目标数组溢出,自己使用的时候尽量使用这些函数,避免大量调试工作,

其中要注意strncpy,如果源串大于目标串的长度,目标的结果将不会以'\0'结束。为了保证是一个完整的串,可以使用下面的方法:

char buffer[BSIZE];
...
strncpy(buffer, name, BSIZE);
buffer[BSIZE-1];

name可以容于buffer的时候,最后的赋值语句没有作用;但当name太长超过BSIZE大小时,最后的赋值语句可保证buffer中是字符串。可以考虑把后面两句自己打包为一个宏进行调用。





posted @ 2012-03-28 14:03  寒山月  阅读(215)  评论(0编辑  收藏  举报