asi*_*s07 8 c c++ arrays parameters char-pointer
我是 C 编程新手。我知道char *和char[]数组是不同的。然而,当涉及到函数参数时,您可以扣除char[]to 。char *所以函数声明可能是相同的。
但是我如何知道该函数是否专门需要一个char数组,而不是char *通过查看签名(声明)?
例如,如果我使用库头文件并且函数如下。我如何知道要通过哪一项?
// somelib.h
void foo(char *bar);
Run Code Online (Sandbox Code Playgroud)
因为如果函数正在修改bar参数并且我传递 a char *,它将出现段错误。这是针对 C 的,但是对于 C++ 来说也是一样的吗?
Bar*_*mar 13
如果函数修改数组,则应声明参数char *。如果它不修改数组,则应该声明该参数const char *。
当声明参数时,const char *传递字符串文字是安全的。否则,您应该将数组或指针传递给使用malloc()(在 C 中)或new(在 C++ 中)动态分配的内存。
在 C++ 中,如果尝试将文字传递给不带const修饰符的参数,则会出现编译错误,因为字符串文字是const. 但由于历史原因,C 中的字符串文字类型是 non- const,即使修改它们会导致未定义的行为,因此不会出现错误(但有些编译器会产生警告)。
作为函数参数
我知道
char *和char[]数组不同
虽然char *和char[]是不同的类型,但作为函数和函数参数,它们并没有什么不同,因为所有声明为数组的函数参数都被调整为指向该数组元素的指针。因此,char[]函数参数被编译器调整为char *。此调整仅适用于函数参数,不适用于其他上下文。
但是,我如何通过查看签名(声明)来知道该函数是否特别需要 char 数组还是 char * ?
需要 char 数组的函数就是需要char *. 我想您的意思是问如何知道函数是否期望/要求将char *指向数组的元素。而且,也许数组是否需要以 null 终止,或者具有最小大小。
答案是单看签名是无法得知的。
我怎么知道要通过哪一项?
通过阅读描述该函数功能的文档。如果没有文档,则阅读该函数的实现。如果也没有实现,那么您可以尝试对二进制文件进行逆向工程。如果您不知道该函数的作用,则不应调用它。
因为如果函数正在修改 bar 参数并且如果我传递 char *,它将出现段错误。
我想你的意思是该函数修改指向的一个或多个字符。在这种情况下,修改指针本身应该没问题。
如果其元素所指向的数组char *是可修改的,则将其传递给修改该数组的函数不应导致段错误。如果数组是 const,则不应将其传递到修改数组的函数中。
当用作函数参数时,char *x和char x[]完全相同。在许多其他情况下,情况并非如此。
char *x对于描述为(or )的参数,char x[]函数不可能知道调用者实际传递的内容。调用者可能传递了一个数组(该数组作为指向该数组第一个元素的指针传递)。它可能已经传递了&vwherev是类型的变量char。它可能已经通过了其他事情。
该函数所能做的就是做出假设,并继续执行该假设。它可能假设它传递的是单个地址char,并且仅修改该地址char。或者,它可能假设已传递了一个 1000 的数组char,并修改所有这些字符。该函数可能会假设(正如标准 C 字符串函数在很多情况下所做的那样)调用者已传递一个以 nul 结尾的数组(可以具有任意长度的数组,但末尾由数值char为零的标记标记) 。该函数可能使用另一个参数来指定数组的长度(因此依赖于调用者传递了有效数组和正确长度的假设)。
无论做出什么假设,如果调用者传递的内容与函数假设的内容不同,函数就有可能出现未定义的行为(例如访问或覆盖不存在的字符)。
对于调用者(或试图编写代码来调用该函数的程序员)来说,情况是相同的。只有两种方法可以知道什么可以安全地传递给函数。
一些风格指南鼓励函数作者使用char *x被视为单个地址的参数char,以及char x[]需要数组的函数。对于编译器来说,这没有什么区别。许多程序员并不遵守这些准则。
您阅读了文档。如果不使用像 Agda 这样的证明语言,类型系统将永远无法完全描述函数的契约。在 C 语言中,请阅读文档。
在 C++ 中,你永远不应该使用char*. 需要字符串的函数应该采用std::string. 需要修改字符的函数应该使用 a char&,并且在极少数情况下,您需要一个不是有效字符串的字符数组,std::vector<char>应该使用 a 。在现代 C++ 中,从来没有将原始指针用作公共函数参数的用例。
| 归档时间: |
|
| 查看次数: |
1145 次 |
| 最近记录: |