本文主要讲解本人在开发过程中遇到的一些不同平台的差异的问题,已经使用的注意事项
BUFSIZ
此参数定义在stdio.h
中,在 win 中有 512 个字节,在 linux 中有 8192 个字节。
__VA_ARGS__ 是一个可变参数的宏,很少人知道这个宏,这个可变参数的宏是新的C99规范中新增的,目前似乎只有 gcc 支持。
实现思想就是宏定义中参数列表的最后一个参数为省略号(也就是三个点)。
- Linux
1
2
3
4
5
6
7
8
9
int main() {
int b = 1;
print_variable("%d=%d", b, 1);
print_variable2("hel\n");
return 0;
}注意:在
print_variable2
中可以发现,使用__VA_ARGS__
时多了两个##
。
此处是为了防止只传一个参数的时候,print_variable2
会编译出错。
其中##
的作用就像是将,
删除一样,具体原因未知。
#
将参数转换为字符串。此处转换为字符串有两层含义:
- 如果传递的是带有值的变量名,那么字符串就是指变量名。
- 如果传递的是简单类型值,那么字符串的就是指简单类型转换为字符串的值。
- Linux 结果为:
1
2
3
4
5
6
7
8
int main() {
int b = 1;
P(b);
P(1);
return 0;
}1
2b:1
1:1
##
将宏定义中的参数变成字符串连在一起。
- Linux 结果为:
1
2
3
4
5
6
7
8
9
10
11
12
int main()
{
int a = 1, b = 2;
char* ab = "Hello";
printf(STR(a));
printf("\n");
printf(FUNC(a, b));
return 0;
}1
2a
Hello
C 中 AF_xxx 与 PF_xxx的区别
除了在 Unix/Linux 中存在一定区别外(在不同的版本中这两者有微小差别。对于 BSD,是 AF,对于 POSIX 是 PF。),其实是一样的。
只是在使用的时候,设置 socket 的时候使用 PF_xxx,设置 addr 的时候使用 AF_xxx。
例如:
1 | int sockfd = socket(PF_LOCAL, SOCK_STREAM, 0); |
errorno 简述
在 Linux 中 api 函数发生异常时,一般会将 errno 变量(需 #include<errno.h>
)赋一个整数值,用于推测出错原因。
由于不可能每次都去查询 errno.h 中的解释,可以通过以下的函数获取错误信息。
Linux
perror()
: 用来将上一个函数发生错误的原因输出到标准错误(stderr),参数s 所指的字符串会先打印出,后面再加上错误原因 字符串char *strerror(int errno)
: 将错误代码转换为字符串错误信息,可以将该字符串和其它的信息组合输出到用户界面。例如1
fprintf(stderr,"error in CreateProcess %s, Process ID %d",strerror(errno),processID)
int strerror_r(int errnum, char *buf, size_t n)
: 将错误代码转换为字符串信息,并存储到大小为 n 大小的 buf 中。printf("%m", errno)
Win
perror()
: 与 Linux 同。errno_t strerror_s(char * buf,rsize_t bufsz,errno_t errnum)
: 使用方式与strerror_r
相同。- 其它相同
printf 自动连接字符串
目前在 Linux 与 Win 都测试了,printf 函数可以实现直接连接两个字符串。如下所示:
1 | printf("hello"",error %d", 1); |