arrays - 如何修复函数 a3 以获得我的输出
问题描述
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char null;
static char a3[](char a[], int start, int length)
{
if(length < 0 || start < 0 || start + length -1 >= sizeof(a))
{
return null;
}
char sub[] = new char[length];
for (int i=start, j=0; j<length; i++, j++)
{
sub[j] = a[i];
}
return sub;
}
int main()
{
char a[]= {'a', 'b','c'};
int start = 0;
int length = 3;
printf("%d\n", a3(a, start,length));
return 0;
}
我想编写一个接受字符数组、从零开始的起始位置和长度的函数。它应该返回一个字符数组,其中包含从输入数组的起始字符开始的长度字符。该函数应对起始位置和长度进行错误检查,如果任一值不合法,则返回 null。当我构建它给我以下错误“错误:在'{'令牌|之前预期'=',',',';','asm'或'属性'”。我不知道如何解决这个错误。谁能帮我 ??
解决方案
数组类型的值不能传递给函数、从函数返回或分配给数组类型的对象。但是,指向数组元素的指针可以传递给函数或从函数返回。因此,函数的原型a3
应该是这样的:
static char *a3(char a[], int start, int length)
数组类型的函数参数会自动调整为指针类型,并将指向数组的第一个元素。因此上面的原型等价于:
static char *a3(char *a, int start, int length)
该函数无法确定数组的大小,因为数组参数实际上只是一个指针。sizeof(a)
函数中的表达式a3
等价于sizeof(char *)
数组的长度,与数组的长度无关。需要以其他方式告知函数数组的长度,可能使用另一个参数:
static char *a3(char *a, int a_len, int start, int length)
然后测试正确参数的代码可以是这样的:
if (length < 0 || start < 0 || start + length > a_len)
{
return NULL;
}
请注意,这NULL
是一个空指针常量,返回值将是一个类型为 的空指针值char *
。这比将变量的值转换为null
不char *
进行强制转换的现有代码更可取。
如果您在函数或块中创建具有自动存储类的数组或其他变量,则在到达函数或块的末尾时它不再存在。因此,如果函数返回指向此类变量的指针,则该指针将无效。调用者不能使用它来访问变量的内容,因为它不再存在。因此,该函数应该使用内存管理函数,例如malloc
或calloc
为对象分配存储空间并返回指向该存储空间的指针。存储在该地址上持续存在,直到free
被调用以释放存储,或被realloc
调用以更改其大小。
现有代码使用 C++new
运算符为 array 创建存储sub
,但 C 不支持。C 等效项是声明sub
为指针并使用malloc
或calloc
分配存储。(calloc
还将返回的内存块的所有字节设置为 0。):
char *sub = malloc(length * sizeof(char));
或者:
char *sub = calloc(length, sizeof(char));
请注意,sizeof(char)
根据定义,它是 1,因此上面可以简化为:
char *sub = malloc(length);
或者:
char *sub = calloc(length, 1);
分配内存是可能的,也可能是malloc
失败calloc
的(对于分配少量内存的小程序来说不太可能),在这种情况下它们返回一个空指针。该函数应检查并返回错误:
if (sub == NULL)
{
return NULL;
}
main
使用说明printf
%d
符打印返回值的位置出错a3()
。说明%d
符需要一个类型的值int
(在默认参数 Promotions之后),所以我不知道 OP 期望在那里打印什么。
将它们放在一起并更改main
函数以打印合理的内容,我们有以下内容:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static char *a3(char a[], int a_len, int start, int length)
{
if(length < 0 || start < 0 || start + length > a_len)
{
return NULL;
}
char *sub = malloc(length);
if (sub == NULL)
{
return NULL;
}
for (int i=start, j=0; j<length; i++, j++)
{
sub[j] = a[i];
}
return sub;
}
int main(void)
{
char a[]= {'a', 'b','c'};
int a_len = 3;
int start = 0;
int length = 3;
char *sub = a3(a, a_len, start, length);
if (sub == NULL)
{
printf("Error\n");
exit(EXIT_FAILURE);
}
for (int i = 0; i < length; i++)
{
printf("%c", sub[i]);
}
printf("\n");
free(sub); // free the storage returned by a3()
return 0;
}
可以进行各种改进。例如,a
参数 ofa3
可以更改为const char *a
(或const char a[]
因为将调整为const char *a
),以表明它不修改 指向的内容a
。
推荐阅读
- c# - 如何使用 FakeItEasy 伪造商业图书馆的非虚拟成员?
- javascript - 当元素数量增加时,水平滚动条裁剪左侧元素
- windows - 名为“groups.*”的文件会使每个编辑器崩溃
- jmeter - 我们如何将 xml 中创建的不记名令牌传递到 2 nd api 中,该 api 放置在 jmeter 的另一个线程组中
- r - dplyr:聚合连续日期时间
- swift - 这个 var 声明中的括号是什么意思?
- postgresql - SQL 聚合总和产生意外输出
- go - 更新 vendored 库中的文件
- graphql - 在graphql上使用vuex-orm的部分突变?
- java - .antMatchers("/swagger-ui.html").permitAll() 不起作用