我的设置:gcc-4.9.2,UTF-8环境.
以下C程序以ASCII格式运行,但不以UTF-8格式运行.
创建输入文件:
echo -n '?????? ???' > /tmp/????
Run Code Online (Sandbox Code Playgroud)
这是test.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 10
int main(void)
{
char buf[SIZE+1];
char *pat = "?????? ???";
char str[SIZE+2];
FILE *f1;
FILE *f2;
f1 = fopen("/tmp/????","r");
f2 = fopen("/tmp/?????","w");
if (fread(buf, 1, SIZE, f1) > 0) {
buf[SIZE] = 0;
if (strncmp(buf, pat, SIZE) == 0) {
sprintf(str, "% 11s\n", buf);
fwrite(str, 1, SIZE+2, f2);
}
}
fclose(f1);
fclose(f2);
exit(0);
}
Run Code Online (Sandbox Code Playgroud)
检查结果:
./test; grep -q ' ?????? ???' …Run Code Online (Sandbox Code Playgroud) 在 libc 中有两个函数可以将系统时间转换为日历时间 -gmtime和localtime,但只有localtime反函数 - mktime。为什么 没有反函数gmtime,如果不应该有,为什么gmtime存在?
wint_t使用默认情况下已在编译器中定义的事实,在wchar.hvia 内设置type .所以要改变stddef.h__WINT_TYPE__
typedef unsigned int wint_t;
Run Code Online (Sandbox Code Playgroud)
成
typedef wchar_t wint_t;
Run Code Online (Sandbox Code Playgroud)
我们可以在开头使用以下代码 wchar.h
#undef __WINT_TYPE__
#define __WINT_TYPE__ wchar_t
#define WEOF (-1)
Run Code Online (Sandbox Code Playgroud)
但是这条评论表明这样做"打破了C++重写的兼容性".
您不能在不破坏ABI兼容性的情况下更改typedef的现有定义(例如wint_t)(即使您具有相同的大小和签名,因此C语言与ABI兼容,更改C++重整的基础类型中断兼容性).
那么,为什么这个typedef无法改变,什么是"兼容C++ mangling"?
char的签名不是标准化的.因此有signed char和unsigned char类型.因此,使用单个字符的函数必须使用可以包含signed char和unsigned char的参数类型(此类型被选择为int),因为如果参数类型是char,我们将从编译器获取类型转换警告(如果-Wconversion在这样的代码中使用):
char c = 'ÿ';
if (islower((unsigned char) c)) ...
warning: conversion to ‘char’ from ‘unsigned char’ may change the sign of the result
Run Code Online (Sandbox Code Playgroud)
(这里我们考虑如果islower()的参数类型为char会发生什么)
而没有明确的类型转换使其工作的事情是自动升级char到int.
此外,wchar_t引入的ISO C90标准没有说明任何具体的表示wchar_t.
glibc引用的一些引用:
定义
wchar_t为合法是合理的char
如果
wchar_t定义为必须定义char类型wint_t,则int由于参数提升.
因此,wchar_t可以很好地定义为char,这意味着必须应用宽字符类型的类似规则,即,可能存在wchar_t积极的实现
,并且可能存在wchar_t否定的实现.由此可以得出必须存在unsigned wchar_t和signed wchar_t类型(出于同样的原因,因为有 …
我的设置:perl 5.20.2
正如预期的那样,使用以下代码就地更改文件:
echo abc > test.txt
perl -i -ne 's/b/x/;print' test.txt
Run Code Online (Sandbox Code Playgroud)
但是在这里,打印输出stdout并清空文件.为什么?
echo abc > test.txt
perl -i -ne 's/b/x/;push@a,$_;END{print for @a}' test.txt
Run Code Online (Sandbox Code Playgroud) 为什么在gcc中编译以下代码不会产生任何类型不匹配警告?-1是int类型,并f()期望类型为char:
void f(char c) {}
int main(void)
{
f(-1);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
即使我们明确指定了类型,也没有警告:
void f(unsigned char c) {}
int main(void)
{
f((signed int)-1);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
什么是好奇:如果我们指定超出范围的值,则打印警告:
void f(char c) {}
int main(void)
{
f(65535);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
warning: overflow in implicit constant conversion
gcc版本6.1.1
要发送字母“a”,HID 设备会发送以下扫描代码:00 00 04 00 00 00 00 00。
与字符“a”对应的值是<AC01>(在 中找到/usr/share/X11/xkb/symbols/us)。根据/usr/share/X11/xkb/keycodes/evdev,<AC01>通过按钮代码映射到38(这是我们必须从设备获取的)。
evtest /dev/input/event#显示代码30。为什么?
prog2不退出CTRL+D。为什么然后prog1退出CTRL+D?更奇怪的是,信号处理程序不执行任何操作,尽管它以某种方式影响最终结果......
下面两个程序的区别仅在于prog1.c sigaction()使用了in,以及prog2.c signal()使用了in:
@@ -39,10 +39,7 @@
/* read from loopback tty */
if (cpid > 0) {
/* this is the strange part */
- struct sigaction sa;
- sa.sa_handler = child_handler;
- sa.sa_flags = 0;
- sigaction(SIGCHLD, &sa, NULL);
+ signal(SIGCHLD, child_handler);
struct termios tty;
tcgetattr(fd, &tty);
Run Code Online (Sandbox Code Playgroud)
每个程序都只是打开一个环回 tty 并将其自身分成两个进程,其中一个进程从 tty 读取响应,另一个进程将数据写入 tty 设备。然后将从环回tty虚拟设备接收到的数据输出到控制终端。
编译prog1并prog2使用-lutil选项。启动每个程序并输入hello<CTRL+D>. 这会产生以下输出:
$ ./prog1 …Run Code Online (Sandbox Code Playgroud) 创建此x.c测试文件:
int main(void)
{
char x[2] = {3};
return x[2];
}
Run Code Online (Sandbox Code Playgroud)
然后运行
gcc x.c; ./a.out; echo $?
Run Code Online (Sandbox Code Playgroud)
结果是:64。
为什么64?
顺便说一句,为什么如果我们使用
return x[1];
Run Code Online (Sandbox Code Playgroud)
我们得到0?为什么{3}也没有初始化x[1]?