- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
这是在 C 中计算数组长度的众所周知的代码:
sizeof(array)/sizeof(type)
但我似乎无法找出作为参数传递给函数的数组的长度:
#include <stdio.h>
int length(const char* array[]) {
return sizeof(array)/sizeof(char*);
}
int main() {
const char* friends[] = { "John", "Jack", "Jim" };
printf("%d %d", sizeof(friends)/sizeof(char*), length(friends)); // 3 1
}
我假设数组作为常量指针按值复制到函数参数并引用它应该解决这个问题,但这个声明是无效的:
int length(const char**& array);
我发现将数组长度作为第二个参数传递是冗余信息,但为什么 main
的标准声明是这样的:
int main(int argc, char** argv);
请解释是否可以在函数参数中找出数组长度,如果可以,为什么main
中会有冗余。
最佳答案
sizeof
仅在将其应用于原始数组时才能计算出数组的长度。
int a[5]; //real array. NOT a pointer
sizeof(a); // :)
但是,当数组衰减为指针时,sizeof 将给出指针的大小而不是数组的大小。
int a[5];
int * p = a;
sizeof(p); // :(
正如您已经聪明地指出的那样,main 接收数组的长度作为参数 (argc)。 是的,这是出于必要而不是多余的。 (好吧,这有点多余,因为 argv 很方便地被空指针终止,但我离题了)
关于为什么会发生这种情况,有一些推理。我们怎样做才能让 C 数组也知道它的长度?
第一个想法是在将数组传递给函数时不要让数组退化为指针,并继续在类型系统中保持数组长度。这样做的坏处是您需要为每个可能的数组长度设置一个单独的函数,而这样做并不是一个好主意。 (Pascal 做到了这一点,有人认为这是它“输给”C 的原因之一)
第二个想法是将数组长度存储在数组旁边,就像任何现代编程语言所做的那样:
a -> [5];[0,0,0,0,0]
但是你只是在幕后创建了一个不可见的 struct
并且 C 哲学不赞成这种开销。也就是说,自己创建这样的结构通常是解决某些问题的好主意:
struct {
size_t length;
int * elements;
}
您可以考虑的另一件事是 C 中的字符串如何以 null 终止而不是存储长度(如在 Pascal 中)。要存储长度而不用担心限制,需要 高达 四个字节,这是一个难以想象的昂贵数量(至少在当时是这样)。人们可能想知道数组是否也可以像那样以 null 终止,但是您将如何允许数组存储 null?
关于c - 函数参数中的数组长度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8269048/
C语言sscanf()函数:从字符串中读取指定格式的数据 头文件: ?
最近,我有一个关于工作预评估的问题,即使查询了每个功能的工作原理,我也不知道如何解决。这是一个伪代码。 下面是一个名为foo()的函数,该函数将被传递一个值并返回一个值。如果将以下值传递给foo函数,
CStr 函数 返回表达式,该表达式已被转换为 String 子类型的 Variant。 CStr(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CSng 函数 返回表达式,该表达式已被转换为 Single 子类型的 Variant。 CSng(expression) expression 参数是任意有效的表达式。 说明 通常,可
CreateObject 函数 创建并返回对 Automation 对象的引用。 CreateObject(servername.typename [, location]) 参数 serv
Cos 函数 返回某个角的余弦值。 Cos(number) number 参数可以是任何将某个角表示为弧度的有效数值表达式。 说明 Cos 函数取某个角并返回直角三角形两边的比值。此比值是
CLng 函数 返回表达式,此表达式已被转换为 Long 子类型的 Variant。 CLng(expression) expression 参数是任意有效的表达式。 说明 通常,您可以使
CInt 函数 返回表达式,此表达式已被转换为 Integer 子类型的 Variant。 CInt(expression) expression 参数是任意有效的表达式。 说明 通常,可
Chr 函数 返回与指定的 ANSI 字符代码相对应的字符。 Chr(charcode) charcode 参数是可以标识字符的数字。 说明 从 0 到 31 的数字表示标准的不可打印的
CDbl 函数 返回表达式,此表达式已被转换为 Double 子类型的 Variant。 CDbl(expression) expression 参数是任意有效的表达式。 说明 通常,您可
CDate 函数 返回表达式,此表达式已被转换为 Date 子类型的 Variant。 CDate(date) date 参数是任意有效的日期表达式。 说明 IsDate 函数用于判断 d
CCur 函数 返回表达式,此表达式已被转换为 Currency 子类型的 Variant。 CCur(expression) expression 参数是任意有效的表达式。 说明 通常,
CByte 函数 返回表达式,此表达式已被转换为 Byte 子类型的 Variant。 CByte(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CBool 函数 返回表达式,此表达式已转换为 Boolean 子类型的 Variant。 CBool(expression) expression 是任意有效的表达式。 说明 如果 ex
Atn 函数 返回数值的反正切值。 Atn(number) number 参数可以是任意有效的数值表达式。 说明 Atn 函数计算直角三角形两个边的比值 (number) 并返回对应角的弧
Asc 函数 返回与字符串的第一个字母对应的 ANSI 字符代码。 Asc(string) string 参数是任意有效的字符串表达式。如果 string 参数未包含字符,则将发生运行时错误。
Array 函数 返回包含数组的 Variant。 Array(arglist) arglist 参数是赋给包含在 Variant 中的数组元素的值的列表(用逗号分隔)。如果没有指定此参数,则
Abs 函数 返回数字的绝对值。 Abs(number) number 参数可以是任意有效的数值表达式。如果 number 包含 Null,则返回 Null;如果是未初始化变量,则返回 0。
FormatPercent 函数 返回表达式,此表达式已被格式化为尾随有 % 符号的百分比(乘以 100 )。 FormatPercent(expression[,NumDigitsAfterD
FormatNumber 函数 返回表达式,此表达式已被格式化为数值。 FormatNumber( expression [,NumDigitsAfterDecimal [,Inc
我是一名优秀的程序员,十分优秀!