我是C语言的菜鸟,我发现我的程序表现得很奇怪:
代码如下:
#include <stdbool.h>
#include <string.h>
#include <conio.h>
#include <stdio.h>
char * p(char arg[] , char sym[] , int i , bool rv) {
char head[i],w[i];
strncpy(head,arg,i); head[i] = "\0";
int l;
for (l = 0 ; l <= (int)(strlen(sym) / i) ; l++) {
strncpy(w,sym+l*i,i); w[i] = "\0";
if (strcmp(head,w) == 0) {
if (rv) { return head; } else {
char v[strlen(arg) - i];
strcpy(v,arg+i);
v[strlen(arg)-i] = "\0";
return v;
};
};
};
return arg;
}
int main() {
printf(p("/parameter","+-\\/",1,false));
getch();
}
主要问题是该函数的返回值是随机生成的代码的“字符串”,或者仅仅是空。
预计/
返回return h;
,parameter
返回return v;
。
另一个问题是,在编译程序时没有发现错误,但是一堆警告告诉function returns address of local variable
和assignment makes integer from pointer without a cast
。
另一方面,return arg;
非常安静,不会发出任何错误。 (如果您不相信,请尝试更改p("/parameter","+-\\/",1,false)
中的代码。)我做错了什么?
该功能的使用:
p(“ argument_passed_to_check ”,“ 符号接受到_be_at_the_front ”,“ separate_for_each _
i
_字符”,“ return_header_instead_of_parameter”)
预期结果:
p("-argue","/\\-",1,false)
返回argue
p("/help","me",1,false)
返回/help
p("/help","me",1,true)
返回(null)
p("--parameter","--++",2,false)
返回parameter
p("--parameter","--++",2,true)
返回--
我要寻求帮助的摘要:
除return arg
外,其他返回部分都很奇怪:return head;
给出了随机字符; return v;
完全不返回任何内容。如何让它们按预期效果工作?
为什么会有那些警告?
答案 0 :(得分:3)
由于head
被定义为char head[i]
,因此它的最后一个元素是head[i-1]
。尝试访问head[i]
具有C标准未定义的行为。
由于w
被定义为char w[i]
,因此它的最后一个元素是w[i-1]
。尝试访问w[i]
具有C标准未定义的行为。
由于v
被定义为char v[strlen(arg) - i]
,因此它的最后一个元素是v[strlen(arg) - i - 1]
。尝试访问v[strlen(arg) - 1]
具有C标准未定义的行为。
由于w
是在不带extern
或static
的括号括起来的语句块内定义的,因此它具有与该块关联的自动存储持续时间,因此仅存在而函数是block。执行return
语句后,w
不再存在(在C的抽象机中)。语句return w;
尝试返回指向w
的第一个元素的指针(因为在此用法中,数组会自动转换为指向其第一个元素的指针)。执行此return
语句后,指针将变为无效。
由于v
是在不带extern
或static
的括号括起来的语句块内定义的,因此它具有与该块关联的自动存储持续时间,因此{{1} }仅在执行语句时存在。执行v
后,该块的执行结束,返回的指针变为无效。
return v;
是一个字符,但是head[i]
是包含一个字符的字符串,因此"\0"
是不正确的分配。该字符串将被转换为指向其第一个元素的指针,从而导致尝试将指针分配给head[i] = "\0";
。这是一个约束违例,您的编译器应对此发出警告。在char
和w[i] = "\0";
中会发生相同的问题。正确的代码应为v[strlen(arg)-i] = "\0";
(将head[i] = '\0';
的大小固定为包含元素head
之后)。
补救措施包括:
head[i]
一样),在调用方提供的数组内创建字符串,或使用具有静态存储持续时间的数组。如果使用第一个选项,即动态创建的数组,则应为要释放的空间做好准备(例如,调用者在完成处理后将它们传递给malloc
)。您应该避免使用具有静态存储持续时间的数组,因为它的使用有限且麻烦(例如,每个定义只存在一个这样的数组,而每个调用者可能想要多次调用一个函数,而每个调用者都想要自己的独立数据) 。