【问题标题】:C char array pointer confusionC char 数组指针混淆
【发布时间】:2021-11-18 06:44:03
【问题描述】:

我写了以下c代码:

#include <stdio.h>
#include <stdlib.h>

void func1(char *arr){
    printf("%d\n",arr[0]);
    printf("%d\n",arr[1]);
    return;
}

int main () {
    char a[6] = "hello";
    printf("%p\n",a);
    printf("%p\n",&a);
    func1(a);
    return 0;
}

当我执行这段代码时,我得到以下输出

0x7fff5a7323e2
0x7fff5a7323e2
104
101

以下是我的疑问:

  1. 为什么arr[1] 的值小于arr[0],这些值是多少?
  2. 假设给定 0 到 1073741823 是有效的内存范围,我们必须检查传递给 func1 的数组是否在有效范围内,然后如何检查。

【问题讨论】:

  • printfa 的类型为char *&amp;a 的类型为pointer-to-array-of char[6](正式类型char (*)[6] )。它们的地址相同,但类型不同。
  • 打印指针值实际上是您应该转换值的情况之一 (printf("%p\n", (void *) a);)

标签: arrays c c-strings


【解决方案1】:

1.为什么arr[1] 的值小于arr[0],这些值是多少?

printf("%d\n",arr[0])printf("%d\n",arr[1]) 将打印这些位置的字符的十进制值,因为您的字符 encoding is ASCII 的十进制值 e (arr[1]) 是 101 并且十进制值 h ( arr[0]) 是 104,你可以查看链接表。


2.假设我们给定 0 到 1073741823 是有效的内存范围,我们必须检查传递给 func1 的数组是否在有效范围内,那么如何检查。

在这种情况下,由于它是一个字符串,你知道它会在数组的末尾有一个哨兵空字节,所以你可以使用:

// initially arr will be pointing to the first element of the array
while(*arr != '\0'){ // will evaluate to false when the string ends
     
    //do stuff...
    arr++;

}

还有其他方法,例如,将数组的大小作为第二个参数传递:

void func1(char *arr, int size){...}

和电话:

func1(a, sizeof a / sizeof *a);

这在您的数组不是空终止数组时更有用,否则您总是可以使用哨兵来表示数组结束,缺点是在大多数情况下,您需要自己添加它们。


注意printf("%p\n", a) 的行为是未定义的,你应该有printf("%p\n", (void*)a)

【讨论】:

    【解决方案2】:

    对于第二部分,您可以将十六进制地址转换为十进制并与提供的范围进行比较。

    【讨论】:

      【解决方案3】:

      您需要了解printf 的格式化字符串。 printf("%d\n",arr[0]); 期望在输出中打印一个整数。 但是在 C 中,字符可以根据其在内存中的编码值被视为整数。例如,根据 ASCII 编码,104 代表“h”。而101代表“e”。 为您的阵列分配的内存由系统管理,您不应该检查它们是否在有效范围内。但您始终可以将它们视为整数并使用简单的比较运算符。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-02-11
        • 1970-01-01
        • 2010-09-25
        • 2011-09-04
        • 2016-11-08
        • 1970-01-01
        • 2021-01-26
        相关资源
        最近更新 更多