snprintf
这个函数的返回值确实蛋疼,网上大多数说是“返回预期要写入的字符串长度”,那还有失败小于0的情况啊?
其实,这样理解是比较好的:
什么时候写入成功?只有返回值 大于等于0,且小于长度限制n
因为snprintf最多copy n-1个字符,之后会在后面加入,所以实际正常下,写入的长度最多是n-1,那当然是小于n
strncat,strncpy
strcpy是从开始0位开始覆盖,而strcat是从当前buf字符结束处开始覆盖,最多copy n个,遇到结束copy。所以对于strncat要注意一般是strncat(buf, dest, BUF_SIZE - strlen(buf) - 1)
关键是涉及字符串安全结束的问题:
strcatstrcpysnprintf 在coyp的dest字符串远小于n的时候,都会将剩余的buf填充为0。
只是snprintf最多copy n-1个,而strcat、strcpy最多copy是n个,这样第n个除非恰好是0,否则,需要代码自己讲第n位写为0.
所以一般有两种写法:
1)总是在函数结束,将buf 第n为显式设为0,输入的n或n-1都无所谓,是否之前清空了也无所谓(显示设为0,可能之前已经copy了一个,)
#ifndef STRCPY
#define STRCPY(d,s) do{ strncpy(d, s, sizeof(d)-1); d[sizeof(d)-1]=0; }while(0)
#endif
2)先保证buf全部为空,输入时n-1即可,这样代码比较清晰简单。
sizeof
这个其实是关键字,是在编译时展开的
特别要注意一定要用原型定义去计算size,特别注意的是指针指向的只能是指针的大小。
所以一般我们数组作为函数参数,必须带上大小。否则,可以传入数组指针:
int test(char (*p)[5])
{
printf("->>>>>>>>>%d
", sizeof(*p));
return 0;
}
int main()
{
char a[5]={'A','B','C','D'};
char (*p)[5] = &a;
test(p);
//或者用test(&a) 也可以
}
这里如果是二维数组int a[][5],则为 char (*p)[5] = a;不用再给a取地址。
引用
指针可以来回换着指多个对象,当然也可以改。但引用最好不要这样做,很别扭,加const吧。
int a = 10;
int c = 20;
const int &b = a;
//b = c; 通过此把a的值就修改为c的值了,const可以避免
printf("a = %d, c = %d
", a, c);
数组及指针
这是一个老的话题了,指针我们一定先要清楚其三要素:地址、指向的地址、类型,
而解引用p就是取指向地址内存的值
类型会影响指针的偏移,包括指针类似数组直接取下标p[i],等价于((p+i))