为什么 strchr 采用 int 来查找 char?

2023-11-21

The strchrC 标准库中的函数寻找char在一个字符串中,但它的签名需要一个int为搜索字符。在我发现的这两个实现中,该实现投射了这个int to a char:

char *strchr(const char *s, int c) {
    while (*s != (char)c) 
        if (!*s++)
            return 0; 
    return (char *)s; 
}

char *strchr(const char *s, int c) {  
    while (*s && *s != (char)c)
       s++;
    if (*s == c)  
      return (char *)s;
    return NULL;
}

有谁知道为什么?为什么不直接拿一个char作为参数?


其原因纯粹是历史原因。请注意,在过去的 C 语言 (K&R C) 中,没有这样的东西函数原型. A strchr那时的函数将被声明为

char *strchr();

并以 K&R 风格定义为

char *strchr(s, c)
  char *s;
  char c;
{
  /* whatever */
}

然而,在 C 语言中(在 K&R C 和现代 C 语言中),如果函数声明时没有原型(如上所示),则每个函数调用中传递的参数都会受到所谓的默认参数促销。在默认参数提升下,任何小于的整数类型int (or unsigned int) 总是转换为int (or unsigned int)。 IE。当参数未声明时,每当您传递charvalue 作为参数,这个值是隐含地转换成int,并且实际上作为int。对于short. (BTW, float被转换为double默认参数促销)。如果在函数内部参数实际上被声明为char(如上面的 K&R 风格定义),它是隐含地转换回char类型并用作char函数内部。这就是它在 K&R 时代的工作原理,实际上这也是它在现代 C 语言中的工作原理,当函数没有原型或使用可变参数时。

现在,提示现代 C,它有函数原型并使用现代风格的函数定义语法。为了保留和再现“传统”功能strchr,如上所述,我们别无选择,只能声明参数strchr as an int并将其显式转换为char函数内部。这正是您在引用的代码中观察到的。这与功能完全相同strchr标准中有描述。

此外,如果您有一个已经编译的遗留库,其中strchr以 K&R 风格定义,如上所示,并且您决定为该库提供现代原型,正确的声明strchr将会

char *strchr(const char *s, int c);

because int是上述遗留实现期望物理接收的内容c。用 a 来声明它char参数将不正确。

因此,您永远不会看到“传统”标准库函数需要以下类型的参数char, short or float。所有这些函数都将使用类型参数进行声明int or double反而。

char 指针和 char 指针的标准保证背后的基本原理完全相同void *指针具有相同的表示和对齐要求。依靠此保证,您可以声明malloc as a void *-返回函数,然后将此声明与标准库的预编译遗留版本一起使用,其中malloc实际上返回了char *.


参考:C99基本原理,版本5.10

7.1.4 库函数的使用
/--/
所有库原型都是根据“扩展”类型指定的: 以前声明为 char 的参数现在写为 int。这 确保大多数库函数都可以使用或不使用 范围内的原型,从而保持向后兼容性 C89 之前的代码

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 strchr 采用 int 来查找 char? 的相关文章

  • 格式说明符%02x

    我有一个简单的程序 include
  • 捕获 .aspx 和 .ascx 页面中的异常

    问题说明了一切 请看以下示例代码 ul li li ul
  • 如何使用 openSSL 函数验证 PEM 证书的密钥长度

    如何验证以这种方式生成的 PEM 证书的密钥长度 openssl genrsa des3 out server key 1024 openssl req new key server key out server csr cp server
  • 关于逻辑/算法的想法以及如何防止线程写入 Sql Server 中的竞争

    我有以下逻辑 public void InQueueTable DataTable Table int incomingRows Table Rows Count if incomingRows gt RowsThreshold async
  • EntityHydrate 任务失败

    我最近安装了 Visual Studio 11 Beta 和 Visual Studio 2010 之后 我无法在 Visual Studio 2010 中构建依赖于 PostSharp 的项目 因此我卸载了 Visual Studio 1
  • C# 中的 Stack<> 实现

    我最近一直在实现递归目录搜索实现 并且使用堆栈来跟踪路径元素 当我使用 string Join 连接路径元素时 我发现它们被颠倒了 当我调试该方法时 我查看了堆栈 发现堆栈内部数组中的元素本身是相反的 即最近 Push 的元素位于内部数组的
  • 无法继承形状

    为什么我不能使用继承 a 的类Shapes class http msdn microsoft com en us library ms604615 28v vs 90 29 我需要延长Rectangle具有一些方法的类 但我想以与使用相同
  • 在 C++ 代码中转换字符串

    我正在学习 C 并开发一个项目来练习 但现在我想在代码中转换一个变量 字符串 就像这样 用户有一个包含 C 代码的文件 但我希望我的程序读取该文件并插入将其写入代码中 如下所示 include
  • 如何修复错误:“检测到无法访问的代码”

    我有以下代码 private string GetAnswer private int CountLeapYears DateTime startDate return count String answer GetAnswer Respo
  • 防止控制台应用程序中的内存工作集最小化?

    我想防止控制台应用程序中的内存工作集最小化 在Windows应用程序中 我可以这样做覆盖 SC MINIMIZE 消息 http support microsoft com kb 293215 en us fr 1 但是 如何在控制台应用程
  • if constexpr 中的 not-constexpr 变量 – clang 与 GCC

    struct A constexpr operator bool const return true int main auto f auto v if constexpr v A a f a clang 6 接受该代码 GCC 8 拒绝它
  • Linux 上的 RTLD_LOCAL 和dynamic_cast

    我们有一个由应用程序中的一些共享库构成的插件 我们需要在应用程序运行时更新它 出于性能原因 我们在卸载旧插件之前加载并开始使用新插件 并且只有当所有线程都使用旧插件完成后 我们才卸载它 由于新插件和旧插件的库具有相同的符号 我们dlopen
  • C# 获取数据表中所有重复行的计数

    我通过运行存储过程来填充数据集 并且从数据集中填充数据表 DataSet RawDataSet DataAccessHelper RunProcedure storedprocedureName this will just return
  • 如何防止 Blazor NavLink 组件的默认导航

    从 Blazor 3 1 Preview 2 开始 应该可以防止默认导航行为 https devblogs microsoft com aspnet asp net core updates in net core 3 1 preview
  • 在 azure blob 存储中就地创建 zip 文件

    我将文件存储在 Blob 存储帐户内的一个容器中 我需要在第二个容器中创建一个 zip 文件 其中包含第一个容器中的文件 我有一个使用辅助角色和 DotNetZip 工作的解决方案 但由于 zip 文件的大小最终可能达到 1GB 我担心在进
  • 如何在多线程应用程序中安全地填充数据并 Refresh() DataGridView?

    我的应用程序有一个 DataGridView 对象和一个 MousePos 类型的列表 MousePos 是一个自定义类 它保存鼠标 X Y 坐标 类型为 Point 和该位置的运行计数 我有一个线程 System Timers Timer
  • 如何从 Boost.PropertyTree 复制子树

    我有一些boost property tree ptree 我需要树来删除一些具有特定标签名称的元素 例如 xml 表示源ptree如下
  • 以编程方式创建 Blob 存储容器

    我有一个要求 即在创建公司时 在我的 storageaccount 中创建关联的 blob 存储容器 并将容器名称设置为传入的字符串变量 我已尝试以下操作 public void AddCompanyStorage string subDo
  • 如何从 Windows Phone 7 模拟器获取数据

    我有一个 WP7 的单元测试框架 它在手机上运行 结果相当难以阅读 因此我将它们写入 XDocument 我的问题是 如何才能将这个 XML 文件从手机上移到我的桌面上 以便我可以实际分析结果 到目前为止 我所做的是将 Debugger B
  • 声明一个负长度的数组

    当创建负长度数组时 C 中会发生什么 例如 int n 35 int testArray n for int i 0 i lt 10 i testArray i i 1 这段代码将编译 并且启用 Wall 时不会出现警告 并且似乎您可以分配

随机推荐

  • symfony2:在控制器操作内部设置表单外部的表单字段的值

    我需要设置 symfony2 表单元素的值 我使用一个doctrine2实体 一个Symfony Component Form AbstractType以及我的控制器操作中的 createForm 方法 saleDataForm this
  • iphone:如果浮点数为负数,则转换为无符号整数的浮点数将设置为 0?

    试试看 volatile float bob 344 0f unsigned int fred unsigned int bob printf d n fred 输出将为 0 显然 我希望它能够回绕 就像我从一个有符号的 int 转换为一个
  • 如何将 Sql Server 2008 DateTimeOffset 转换为 DateTime

    我希望转换一个有DATETIMEOFFSET场 下降到DATETIME字段但通过注意偏移量来重新计算时间 实际上 这将值转换为UTC eg CreatedOn 2008 12 19 17 30 09 0000000 11 00 将被转换为
  • 透明背景

    如何让背景50 透明 假设 AbsoluteLayout 的背景很暗 但您仍然可以看到它 您可以将透明主题应用于所需的活动 在 res values style xml 中创建新样式
  • Rails 5.1 中还需要 `require jquery_ujs` 吗?

    我正在我的中安装 jQuery5 1 xRails 应用程序通过jquery rails gem 在 gem 设置中 他们建议将这些行添加到application js默认情况下 require jquery require jquery
  • 使用 nginx 在同一域上提供 React 前端和 php 后端

    我有一个 React 前端和一个 Symfony 后端 我试图在同一个域上提供服务 React 前端需要提供资产 如果存在 否则需要提供回退服务index html 我想在以下情况下提供 php Symfony 应用程序 api位于请求 u
  • 了解 Spark shuffle 溢出

    如果我理解正确的话 当一个reduce任务开始收集它的输入shuffle块 来自不同map任务的输出 时 它首先将它们保存在内存中 Q1 当执行器的 shuffles 保留内存量 在内存管理更改之前 Q2 耗尽时 内存中的数据将 溢出 到磁
  • SQL:如果不存在如何更新或插入?

    我下面有一个 SQL 插入 工作正常 但是我希望它检查 DATE xxxx NAME xxxx 和 JOB xxx 是否存在 并更新 HOURS 如果存在 否则插入新行 这可以用 SQL 实现吗 INSERT INTO TABLE NAME
  • 从内部类对象获取外部类对象

    我有以下代码 我想获取创建内部类对象的外部类对象inner 我该怎么做 public class OuterClass public class InnerClass private String name Peakit public st
  • 简单的串行点对点通信协议

    我需要两个设备 PC 和微控制器 之间的简单通信协议 PC必须向微处理器发送一些命令和参数 微控制器必须传输字节数组 来自传感器的数据 数据必须是噪音保护 除了奇偶校验之外 我想我还需要一些其他的数据校正方法 有没有标准的解决方案可以做到这
  • python字典中循环(for循环)的顺序是什么[重复]

    这个问题在这里已经有答案了 我对以下内容得到的输出有点困惑 我不明白循环的执行顺序 domains de Germany sk Slovakia hu Hungary us United States no Norway for key i
  • 在 C++11 中保存随机数生成器状态

    我希望能够将随机数生成器的状态保存在 txt 文件中并将其读回 我听说在 c 11 中 可以使用 gt 运算符来完成此操作 但是 我不确定我到底该怎么做 我有一个随机数生成器 初始化如下 mt19937 myRandomGenerator
  • 允许特定标签覆盖溢出:隐藏

    我有一个 div 这是一定的height and width and overflow hidden以便剪裁特定的内部图像 不过我想要一张图片 div 弹出边界 即覆盖overflow hidden 我该怎么做呢 诀窍是保持overflow
  • 在创建时设置全屏

    我只能在 onCreate 方法中将 Activity 设置为全屏 在 setContentView 之前 有什么方法可以在 onCreate 之外设置为全屏吗 Thanks 有可能 添加此代码 go full screen WindowM
  • Android Service 多个实例

    我对 Android 服务类还是有点陌生 我知道您需要使用 startService intent 从应用程序启动服务 但是我的问题是我的服务内部有方法 我需要以意图启动服务 然后在我的活动中创建该类的对象 以便我可以调用服务的方法 问题是
  • Flutter 上用于位置设置的本机对话框

    有没有办法实现位置设置对话框 如下图所示 当应用程序需要 GPS 位置但找不到时会触发该对话框 打OK将立即打开系统 GPS 这对于用户来说似乎更方便 而不是把他们带到某个位置并手动打开 Flutter 中可以实现这样的功能吗 对话框的展开
  • JavaScript中获取对象的所有函数

    例如 Math mymfunc function x return x 1 将被视为财产 当我写时 for var p in Math proto console log p 它将被显示 但其余的数学函数不会 如何获取 Math 对象的所有
  • Facebook 身份验证和奇怪的重定向行为

    我目前正在使用 facebook connect 测试 OAuth 实现http facebooksdk codeplex com 我有一个 FacebookController 有 2 个简单的操作 称为LogOn and CallBac
  • 更改 QTreeView 的行背景颜色不起作用

    我有一个QTreeView并希望根据行的内容使用不同的背景颜色 为了实现这一目标 我导出了一个class MyTreeView from QTreeView并实现了paint方法如下 void MyTreeView drawRow QPai
  • 为什么 strchr 采用 int 来查找 char?

    The strchrC 标准库中的函数寻找char在一个字符串中 但它的签名需要一个int为搜索字符 在我发现的这两个实现中 该实现投射了这个int to a char char strchr const char s int c whil