传递字符串
为什么我们传递“const char *”???,如果我知道这意味着传递指向 char 类型常量变量的指针。但是 __filename like "hello.txt" 是字符串类型,而不是字符类型。
C 没有“字符串类型”。在 C 中,字符串是 char 的数组,其结尾由空字符(值为零的字符)标记。尽管在像fopen("myfile", "r") 这样的调用中,我们使用"myfile" 作为参数,但数组"myfile" 会自动转换为指向其第一个元素的指针。它的第一个元素是char,所以这个指针是char *。
这来自 C 标准中的一条规则,在 C 2018 6.3.2.1 3 中,它表示任何类型为“type”的表达式都将转换为指向其第一个元素的指针,除非:
- 表达式是
sizeof 或一元& 的操作数,或者
- 是用于初始化数组的字符串文字(如
char x[] = "abc";)。
const 在一个参数中
参数具有const char * 类型的事实并不意味着我们必须传递指向const 的指针。我们可以将一个普通指针传递给char、char *,它会自动转换为const char *。这表明该函数会将字符视为const。换句话说,该函数只会读取字符;它不会修改它们。
(从技术上讲,const char * 类型的指针可以合法地转换为char * 并用于修改指向的对象,只要这些对象最初不是用const 定义的。但这是一些东西用于特殊情况。在参数中使用const 的普通函数定义不会这样做。)
__restrict 在一个参数中
-- 我也很困惑,这个*是属于__restrict还是__filename,这个__restrict和我们在C99中声明普通C函数时使用的关键字restrict一样吗?
__restrict 用于某些 C 头文件中,表示无意义(在为旧版本的 C 编译时)或 restrict(在为现代版本的 C 编译时)。例如,在 Apple 随其开发人员工具分发的标头中,<stdio.h> 包含一个标头,该标头以这种方式定义 __restrict:
#if __STDC_VERSION__ < 199901
#define __restrict
#else
#define __restrict restrict
#endif
编译器根据它正在编译的 C 版本定义(或省略定义)__STDC_VERSION__(可以使用命令行开关选择,例如-std=c17)。然后上面的语句定义了__restrict,这样restrict在编译非常旧的C版本时不使用,但在编译现代版本时使用。
fseek 的偏移量
为什么在...fseek...等其他函数原型中传递“long int __off”而不是指针?
off 参数指定磁盘或其他存储上的文件中的偏移量。它不是主存中某物的地址,所以它不是指针。它是从文件开头开始的字节数,所以它是一个数字。