C 我向函数传递了错误的数组长度。为什么我没有得到一个错误?

C 我向函数传递了错误的数组长度。为什么我没有得到一个错误?,c,C,我是一个初学者,我正在学习c大约20天。我一直在用Youtube做这件事。我看到一个视频,其中告诉我,如果一个数组被传递给一个函数,那么第二个变量应该是数组的长度。我觉得这不对,我尝试了下面给出的代码 #include <stdio.h> #include <conio.h> void name(int[], int); int main() { int arr[] = {1,2,3}; name(arr, 5); getch(); r

我是一个初学者,我正在学习c大约20天。我一直在用Youtube做这件事。我看到一个视频,其中告诉我,如果一个数组被传递给一个函数,那么第二个变量应该是数组的长度。我觉得这不对,我尝试了下面给出的代码

#include <stdio.h>
#include <conio.h>

void name(int[], int);

int main() {
    int arr[] = {1,2,3};
    name(arr, 5);
    getch();
    return 0;
}

void name(int a[], int i) {
    printf("%d", i);
}
它没有给我任何错误。那么,这是正确的吗?我的意思是,第二个变量对于数组的长度真的是必要的吗?

我没有给我任何错误?不,在这种情况下,编译器不会产生任何错误,因为您只是传递大于数组元素的元素值No,但如果name函数尝试访问绑定外的元素,则会导致未定义的行为。例如

#include <stdio.h>
#include <stdio.h>
#include <conio.h>
void name(int[], int);
int main() {
    int arr[] = {1,2,3},ele;
    ele = sizeof(arr)/sizeof(arr[0]);
    name(arr, ele);
    getch();
    return 0;
}

void name(int a[], int ele) {
    printf("no of element in array : %d\n", ele);
    for(int row =0; row<ele; row++) {
      printf("%d\n",a[row]);
    }
}
正确的步骤是找到数组中元素的编号,存储到一个变量中,并将该变量传递给函数,而不是某个随机数。例如

#include <stdio.h>
#include <stdio.h>
#include <conio.h>
void name(int[], int);
int main() {
    int arr[] = {1,2,3},ele;
    ele = sizeof(arr)/sizeof(arr[0]);
    name(arr, ele);
    getch();
    return 0;
}

void name(int a[], int ele) {
    printf("no of element in array : %d\n", ele);
    for(int row =0; row<ele; row++) {
      printf("%d\n",a[row]);
    }
}

这里有一些混淆:在C中,数组作为指向其第一个元素的指针传递给函数。因此,函数不会自动接收有关数组元素数的任何信息。如果需要此信息,则必须以其他方式传递:

数组大小可以在函数规范中固定。在这种情况下,由程序员来确保传递到此函数的数组在每个调用点都具有预期的大小,以便函数可以假定其数组参数具有正确的大小。 数组大小可以从其内容推断出来:例如,C字符串是以空字节结尾的字符数组,一个零值字符通常写为“\0”,实际上是C中的int。指向第一个字符的指针足以处理整个字符串。 数组大小可以作为额外参数传递给函数。同样,程序员有责任根据函数规范传递数组的实际大小。例如,fgets将流的内容读入char数组。必须向它传递它可以更改的最大数组元素数,最多为数组大小:

char buf[128];
int lineno = 1;
while (fgets(buf, sizeof buf, stdin)) {
    printf("%d\t%s", buf);
}
请注意,数组大小可以计算为sizeofarray/sizeof*数组,sizeofchar的定义为1

下面是一个修改后的示例:

#include <stdio.h>
#include <conio.h>

void output(int *a, int length) {
    int i;
    for (i = 0; i < length; i++) {
        printf("%d\n", a[i]);
    }
}

int main() {
    int arr[] = { 1, 2, 3 };
    output(arr, sizeof(arr) / sizeof(*arr));
    getch();
    return 0;
}

取决于函数试图实现的名称。这里数组的长度不是五,而是三,我知道是三。但是为了得到一个错误,我试了五次。你通常想要传递长度,但没有什么强迫你这么做;从逻辑上讲,传递错误的长度是不正确的,但在您的例子中,实际上并没有使用它来索引数组,因此代码只是奇怪,没有错。如果传递的长度大于数组的实际大小,且函数尝试使用这些索引,则这是未定义的行为,但只要不在数组外建立索引,代码就有效,如果大小不匹配,则不一定正确。编译器将无法检测此错误,因为您只是将值传递给函数。当您尝试在函数中使用该值访问数组时,您将遇到未定义的行为。我认为您是对的。非常感谢。