这可能吗?[指向字符数组C的指针]

这可能吗?[指向字符数组C的指针],c,arrays,pointers,char,C,Arrays,Pointers,Char,这可能吗 size_t calculate(char *s) { // I would like to return 64 } int main() { char s[64]; printf("%d", calculate(s)); return 0; } 我想编写一个函数来计算main()中声明的字符数组的大小。是的,如果s的数组末尾有一个特定的字符,那么这是可能的。例如,您可以将s[63]=125设置为0到62之间的每一个字符都不是125,您可以执行F

这可能吗

size_t calculate(char *s)
{
    // I would like to return 64
}

int main()
{
    char s[64];

    printf("%d", calculate(s));

    return 0;
}

我想编写一个函数来计算
main()

中声明的字符数组的大小。是的,如果
s
的数组末尾有一个特定的字符,那么这是可能的。例如,您可以将
s[63]=125
设置为0到62之间的每一个字符都不是125,您可以执行For循环,直到找到125并返回数组的大小


否则,这是不可能的,因为函数参数中的
s
只是指向数组的指针,因此
sizeof(s)
内部的
calculate
将只返回您的机器指针大小,而不是人们期望的64。

在静态声明的
char[]
上,您可以使用操作符
sizeof
,在本例中返回64

printf("%d", sizeof(s));
在动态声明的
char*
上,无法获取分配内存的大小


动态数组是通过
malloc
和friends获得的。所有其他的都是静态声明的,您可以对它们使用
sizeof
,只要您在声明数组的相同范围内使用它(例如,在您的例子中使用相同的函数)。

这通常是通过C中的宏来完成的,例如:

#define ARRAY_SIZE(x) (sizeof(x)/sizeof(*x))

这是否是一个好主意是一个完全不同的问题。

您的函数
calculate()
,仅给定指针参数
s
,无法计算数组的大小。数组的大小不在指针中编码,也不可从指针访问。如果它被设计为以null结尾的字符串作为参数,它可以确定该字符串的长度;当然,
strlen()
就是这样做的。但是,如果它想知道有多少信息可以安全地复制到数组中,就必须告诉它数组有多大,或者假设有足够的空间

正如其他人指出的那样,
sizeof()
操作符可以在数组定义可见的函数中使用,以获取数组的大小。但在无法查看数组定义的函数中,无法有效地应用
sizeof()
运算符。如果数组是一个全局变量,其定义(不是声明)在写入
calculate()
的作用域(可见)中,因此不是函数的参数,则
calculate()
可以指示大小


这就是为什么很多很多C函数使用一个指针和一个长度。缺少信息是为什么C有点容易被人误用并产生“缓冲区溢出”错误,代码试图将一加仑的信息放入一品脱罐中。

不幸的是,单凭指针值无法确定相应数组中有多少个元素。您或者需要在数组中使用某种类型的哨兵值(如用于字符串的0终止符),或者需要单独跟踪它

您可以使用
sizeof
运算符获取数组中的字节数或元素数:

char arr[64];

size_t size = sizeof arr;                 // # of bytes in arr
size_t count = sizeof arr / sizeof *arr;  // # of elements in arr
但是,这仅适用于
arr
是数组类型的情况;如果您试图在功能中执行此操作

 size_t calculate(char *s)
 {
   return sizeof s;
 }

它将返回指针值的大小(以字节为单位),而不是相应数组对象的大小

否。
char*x
char x[]
只创建指向内存位置的指针。指针不包含有关内存区域大小的任何信息


但是,
char*x=“Hello”
占用6个字节(包括终止的null),并且
strlen(x)
将返回5个字节。这依赖于字符串末尾的null字符,strlen仍然对底层缓冲区一无所知。所以strlen(“Hello\000There”)仍然是5。

您可以使用“de”
sizeof
函数。这只在静态声明x时有效。对于动态声明的数组,需要将长度保存在单独的变量中。@Rick Rainer:什么是静态声明的数组?它适用于
静态
数组、全局数组、自动数组和可变长度数组。它只在数组的定义可见的情况下才起作用——并且显然无法用函数的数组(即指针)参数生成有用的答案——如问题中所述。它不能用于动态分配的数组(使用
malloc()
或亲戚创建)。(对不起,尼古拉),宏观经济并不是问题的解决方案。人们只是在早上紧张起来:)否决投票是不公平的。:)这个想法对于x来说很好,因为它是“charx[];”@乔纳森·莱夫勒:见上图。有一个很好的解释:“char x[64];”char*x;“您可以对非静态数组定义应用
sizeof()
,并获取数组的大小。它适用于静态数组(内部和外部函数)、全局数组、自动数组和VLA(可变长度数组)。它只在数组的定义(而不是声明)是可见的情况下起作用——并且显然无法用函数的数组(即指针)参数生成有用的答案——如问题中所述。它不能用于动态分配的数组(使用malloc()或亲戚创建)。好的-你说得对。问这个问题的人会理解你的非标准术语吗?如果你解释它的意思,那么它可以帮助他们理解你的答案。