【问题标题】:regarding toupper() using pointer arithmetic关于使用指针算法的 toupper()
【发布时间】:2015-09-13 15:33:41
【问题描述】:

我在尝试理解 toupper() 函数时遇到了一个有趣的问题。请在下面找到代码: 这里的问题在于输出中我总是 missing 我输入字符串的第一个字符。

请纠正我的错误。我在谷歌上做了太多关于这个之后发布这个。

void UpperString()
{

    char arr [10];
    memset(arr, 0x00, sizeof(arr));
    strcpy(arr, "abcd");
    char *ptr = arr;
    char *temp = ptr;
    printf("Before Upper String - %s\n",ptr);
    while(*ptr++ = toupper(*ptr))
    {
        printf("ptr - %s\n",ptr);
        printf("FULL - %s\n",temp);
    }
    printf("After Upper String - %s\n",temp);
    return;
} // UpperString()

输出

Before Upper String - abcd
ptr - bcd
FULL - Bbcd
ptr - cd
FULL - BCcd
ptr - d
FULL - BCDd
After Upper String - BCD

【问题讨论】:

  • 我认为你在 *ptr++ = toupper(*ptr) 中有未定义的行为:你正在阅读 ptr(在 *ptr 中,函数参数)并且你正在修改 ptr(在 ptr++ ),并且中间没有序列点。
  • 这段代码在C程序员之间的竞争中是goog,但bau i普通代码应该有很好的控制效果。在同一个地方内联的操作太多

标签: c pointers increment


【解决方案1】:
while(*ptr++ = toupper(*ptr))

这条线有问题。您倾向于在单个执行行中多次更改ptr 的值,从而调用未定义的行为

C99 §6.5:“2.在前一个和下一个序列点之间,对象的存储值最多只能通过表达式的评估修改一次。此外,应仅读取先验值以确定要存储的值。”

在另一行增加。

while(*ptr= toupper(*ptr)){
// your code
...
ptr++;

}

【讨论】:

  • 嗨,艾米,感谢您的回复。我明白了你的意思,但相同的代码如何在一个处理器中按预期工作,但在其他处理器中却没有
  • @sakthi 你的意思是它在一个系统上工作而不是在另一个系统上工作?这可能是未定义行为的副作用。在 UB 中,输出可以是任何东西,甚至可能是我的电话号码 :)
【解决方案2】:

你问理解toupper(),但你代码中的问题与这个函数无关。

while(*ptr++ 

*p++ 具有“来自地址的值并在工作后递增 ptr”的含义,因此如果第一个 nr 为 0,则使用单元格,但 PTR 递增

toupper(*ptr)) 右侧从已经高级的指针'b'中读取一个字母,制作'B'并将设置在单元格a

这是没有问题的相同代码:

void UpperString()
{

   char arr [10];
   memset(arr, 0x00, sizeof(arr));
   strcpy(arr, "abcd");
   char *ptr = arr;
   char *temp = ptr;
   printf("Before Upper String - %s\n",ptr);
   while(*ptr = toupper(*ptr))
   {
      printf("ptr - %s\n",ptr);
      printf("FULL - %s\n",temp);
      ptr++;
   }
   printf("After Upper String - %s\n",temp);
  return;
} 

【讨论】:

  • 为什么下来?准确告诉您是否有费用
  • 你的英文几乎看不懂,而且你给出的解释是错误的:C不会从左到右评估表达式。
  • 也许评估顺序是可导入的(在编译器之间),但是你如何描述交换 a i b
  • ...我不明白你刚刚写的什么。
  • @melpomene 也许代码更国际化 :) 如果 C 代码有问题和/或不可读的下马口哨
【解决方案3】:

C 中的规则是同一变量只能在一次操作中修改一次,并且仅用于确定先前的值。参考:C99 草案 n1256 中的 6.5 表达式 §2:在前一个和下一个序列点之间,对象应具有其存储值 通过表达式的评估最多修改一次。此外,先验值 应为只读以确定要存储的值

在同一语句中,您更改了ptr 的值,但也在toupper(*ptr) 中使用它:这两个操作没有排序,您会得到未定义的行为。

你应该写:

while(*ptr = toupper(*ptr)) /* Ok ptr is unchanged, and *ptr is read to compute value to store */
{
    printf("ptr - %s\n",ptr);
    printf("FULL - %s\n",temp);
    ptr += 1;   /* Ok ptr is changed here but not use elsewhere */
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-03
    • 1970-01-01
    • 1970-01-01
    • 2013-11-16
    • 1970-01-01
    相关资源
    最近更新 更多