C:如果我理解为0和'\0';同样,当我写int my_array={0};,编译器如何知道数组的大小;?

C:如果我理解为0和'\0';同样,当我写int my_array={0};,编译器如何知道数组的大小;?,c,initialization,C,Initialization,我试图创建一个函数,使用指针将数组复制到另一个数组中。我想添加以下条件:如果目标数组较小,则循环必须中断 所以基本上它是工作的,但是如果我按如下方式初始化目标阵列,它就不工作了: int dest_数组[10]={0} 据我所知,它用int 0填充数组,int 0相当于'\0'(空字符)。所以我的问题是: 在这种情况下,计算机如何知道阵列大小或何时结束 (如何比较作为参数传递的数组?) 在C语言中,不可能从本质上知道数组的长度。这是因为数组实际上只是一个连续的内存块,传递给函数的值实际上只是指向

我试图创建一个函数,使用指针将数组复制到另一个数组中。我想添加以下条件:如果目标数组较小,则循环必须中断

所以基本上它是工作的,但是如果我按如下方式初始化目标阵列,它就不工作了:

int dest_数组[10]={0}

据我所知,它用int 0填充数组,int 0相当于'\0'(空字符)。所以我的问题是:

在这种情况下,计算机如何知道阵列大小或何时结束

(如何比较作为参数传递的数组?)


在C语言中,不可能从本质上知道数组的长度。这是因为数组实际上只是一个连续的内存块,传递给函数的值实际上只是指向数组中第一个元素的指针。因此,要真正了解函数中数组的长度(而不是声明该数组的函数),必须以某种方式向函数提供该值。两种常见的方法是使用sentinel值来指示最后一个元素(类似于按照约定将空字符“\0”解释为第一个字符而不是C中字符串的一部分),或者提供另一个包含数组长度的参数

这是一个非常常见的例子:如果您编写过任何使用命令行参数的程序,那么您肯定熟悉
intmain(intargc,char*argv[])的通用定义,它使用上述第二种方法,通过
argc
参数提供
argv
数组的长度

编译器有一些方法可以解决局部变量的问题。例如,以下方法可行:

#include <stdio.h>

int main(){
    int nums[10] = {0};
    printf("%zu\n", sizeof(nums)/sizeof(nums[0]));
    
    return 0;
}
这将最终将以下内容打印到标准输出:

10
Calling other function...
2
这可能不是您期望的值,但出现这种情况是因为方法签名
int-tryToGetSizeOf(int-arr[])
在功能上等同于
int-tryToGetSizeOf(int*arr)
。因此,您将整数指针(
int*
)的大小除以单个
int
)的大小;然而,当您仍在
main()
(即数组最初定义的位置)的本地上下文中时,您将分配内存区域的大小除以内存区域被分区为的数据类型的大小(
int

将数组引用为指针时,会丢失大小信息。使用
ptr1
无法识别数组的大小,即元素的数量。您必须借助另一个变量,该变量将表示
ptr1
(或
ptr2
)引用的数组的大小

字符数组也是如此。考虑下面的内容:

char some_string[100];
strcpy(some_string, "hello");
您提到的检查
\0
(或
0
)的方法提供了驻留在
某些字符串中的字符串的元素数。它决不是指
某个字符串
中的元素数,即
100

要确定目的地的大小,必须传递另一个描述其大小的参数


还有其他方法可以识别数组的结尾,但t更容易明确地传递大小,而不是使用一些指针技巧,如将指针传递到数组的结尾或使用一些无效值作为数组中的最后一个元素。

TL/DR-您需要将数组大小作为单独的参数传递给功能。像
0
这样的哨兵值只标记序列的逻辑结束,而不是数组本身的结束

除非它是
sizeof
或一元
&
运算符的操作数,或者是用于初始化声明中字符数组的字符串文字,否则“T
的N元素数组”类型的表达式将转换(“衰减”)为“指向
T
的指针”类型的表达式,表达式的值将是数组第一个元素的地址。因此,当您将源数组和目标数组作为参数传递给
copy
时,函数实际接收的只是两个指针

没有与指针关联的元数据可以告诉它是否指向序列中的第一个对象,或者该序列的长度是1。字符串中的哨兵值(如0终止符)只告诉您一个逻辑值序列的长度,而不是存储这些值的数组的大小2

您需要向
copy
提供至少一个以上的参数,告诉它目标缓冲区有多大,因此当您到达目标缓冲区的末尾或在源缓冲区中看到
0
时,停止复制,以先到者为准


  • 数组对象也是如此-数组对象中没有运行时元数据来存储大小或其他任何内容。
    sizeof
    技巧有效的唯一原因是数组的声明在作用域中。数组对象本身不知道它有多大。
  • 这是像
    strcpy
    这样的库函数的一个问题,它只接收每个缓冲区的起始地址-如果源缓冲区中的字符数超过目标缓冲区的大小,则
    strcpy
    将爆炸到目标缓冲区的末尾,并覆盖接下来的内容。
    在C语言中,有完全数组和不完全数组的概念。您可以在初始化中使用语法糖
    arr[X]={0}
    仅用于完整数组。

    0
    不是数组结尾的标记。它知道数组的大小,因为您在这里告诉它:
    int dest_array[10]
    看看您的平台
    memcpy(…)
    源文件。值得注意的是
    10
    Calling other function...
    2
    
    int* ptr1;
    int* ptr2;
    
    char some_string[100];
    strcpy(some_string, "hello");