为什么C和C ++编译器在从未强制实施时允许函数签名中的数组长度?

为什么C和C ++编译器在从未强制实施时允许函数签名中的数组长度?

这是我在学习期间发现的:

#include<iostream>using namespace std;int dis(char a[1]){
    int length = strlen(a);
    char c = a[2];
    return length;}int main(){
    char b[4] = "abc";
    int c = dis(b);
    cout << c;
    return 0;}

所以在变量中int dis(char a[1])[1]似乎什么都不做,根本不起作用
,因为我可以使用a[2]。就像int a[]char *a。我知道数组名称是一个指针,以及如何传达一个数组,所以我的谜题不是这个部分。

我想知道的是为什么编译器允许这种行为(int a[1])。或者它有其他我不知道的含义?


牧羊人nacy
浏览 827回答 3
3回答

12345678_0001

这是将数组传递给函数的语法的怪癖。实际上,无法在C中传递数组。如果您编写的语法看起来应该通过数组,那么实际发生的是传递指向数组第一个元素的指针。由于指针不包含任何长度信息,因此[]实际上忽略了函数形式参数列表中的内容。允许这种语法的决定是在20世纪70年代做出的,并且自从......以来引起了很大的混乱。

慕桂英4014372

忽略第一个维度的长度,但需要额外维度的长度以允许编译器正确计算偏移量。在下面的示例中,foo函数传递指向二维数组的指针。#include&nbsp;<stdio.h>void&nbsp;foo(int&nbsp;args[10][20]){ &nbsp;&nbsp;&nbsp;&nbsp;printf("%zd\n",&nbsp;sizeof(args[0]));}int&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){ &nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;a[2][20]; &nbsp;&nbsp;&nbsp;&nbsp;foo(a); &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0;}[10]忽略第一个维度的大小;&nbsp;编译器不会阻止你索引结束(请注意,正式需要10个元素,但实际只提供2个元素)。但是,第二个维度的大小[20]用于确定每一行的步幅,这里,形式必须与实际匹配。同样,编译器也不会阻止您索引第二个维度的末尾。从数组基址到元素的字节偏移量由下式args[row][col]确定:sizeof(int)*(col&nbsp;+&nbsp;20*row)请注意,如果col >= 20,那么您将实际索引到后续行(或整个数组的末尾)。sizeof(args[0]),80在我的机器上返回sizeof(int) == 4。但是,如果我尝试接受sizeof(args),我会得到以下编译器警告:foo.c:5:27:&nbsp;warning:&nbsp;sizeof&nbsp;on&nbsp;array&nbsp;function&nbsp;parameter&nbsp;will&nbsp;return&nbsp;size&nbsp;of&nbsp;'int&nbsp;(*)[20]'&nbsp;instead&nbsp;of&nbsp;'int&nbsp;[10][20]'&nbsp;[-Wsizeof-array-argument] &nbsp;&nbsp;&nbsp;&nbsp;printf("%zd\n",&nbsp;sizeof(args)); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;^foo.c:3:14:&nbsp;note:&nbsp;declared&nbsp;herevoid&nbsp;foo(int&nbsp;args[10][20]) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;^1&nbsp;warning&nbsp;generated.在这里,编译器警告它只会给出数组已经衰减的指针的大小而不是数组本身的大小
打开App,查看更多内容
随时随地看视频慕课网APP