我不确定我是否正确地说了这个标题,但基本上。我想知道是否有一种方法可以使用参数中的指针从hey函数添加到buff数组中,为什么它会起作用呢?
BUF [100]。 例如:
int main(){
char buf[100];
hey("320244",buf);
printf("%s", buf);
}
void hey(char* s, char* result){
/*
some code that appends to result using pointers
do some stuff with s and get the result back in buf without using return.
*/
}
答案 0 :(得分:2)
我已经修改了一些评论代码: -
#define LEN 100 //Use a macro instead of error prone digits in code
void hey(char* s, char* result); //Fwd declaration
int main(){
char buf[LEN] = {0}; //This will initialize the buffer on stack
hey("320244",buf);
printf("%s", buf);
hey("abc", buf); //Possible future invocation
printf("%s", buf);
}
void hey(char* s, char* result){
if(strlen(result) + strlen(s) < LEN ) //This will check buffer overflow
strcat(result, s); //This will concatenate s into result
else
//Do some error handling here
}
答案 1 :(得分:2)
让我们做正确的事情,并使用结构来描述动态分配的,按需增长的字符串:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
struct mystring {
char *ptr; /* The actual string */
size_t len; /* The length of the string */
size_t max; /* Maximum number of chars allocated for */
};
#define MYSTRING_INIT { NULL, 0, 0 }
如果我们想要向struct mystring
追加一些东西,我们定义一个函数,该函数接受一个指向函数可以修改的结构的指针。 (如果它只需要一个char指针而不是一个结构,那么它需要一个char **
;一个指向char指针的指针。)
void mystring_append(struct mystring *ms, const char *s)
{
const size_t slen = (s) ? strlen(s) : 0;
/* Make sure ms points to a struct mystring; is not NULL */
if (!ms) {
fprintf(stderr, "mystring_append(): No struct mystring specified; ms == NULL!\n");
exit(EXIT_FAILURE);
}
/* Make sure we have enough memory allocated for the data */
if (ms->len + slen >= ms->max) {
const size_t max = ms->len + slen + 1;
char *ptr;
ptr = realloc(ms->ptr, max);
if (!ptr) {
fprintf(stderr, "mystring_append(): Out of memory!\n");
exit(EXIT_FAILURE);
}
ms->max = max;
ms->ptr = ptr;
}
/* Append. */
if (slen > 0) {
memmove(ms->ptr + ms->len, s, slen);
ms->len += slen;
}
/* We allocated one char extra for the
string-terminating nul byte, '\0'. */
ms->ptr[ms->len] = '\0';
/* Done! */
}
(s) ? strlen(s) : 0;
表达式使用?:
条件运算符。实质上,如果s
为非NULL,则表达式的计算结果为strlen(s)
,否则计算结果为0
。你可以用
size_t slen;
if (s != NULL)
slen = strlen(s);
else
slen = 0;
代替;我更喜欢简洁的const size_t slen = (s) ? strlen(s) : 0
形式。 (const
告诉编译器slen
变量不会被修改。虽然它可能有助于编译器生成更好的代码,但它主要是对其他程序员slen
的暗示通过这个函数具有这个特殊的值,所以他们不需要检查它是否可以在某处修改。它有助于长期编码维护,所以这是一个非常好的习惯。)
通常,函数会返回成功或错误。为了便于使用,mystring_append()
不会返回任何内容。如果有错误,它会向标准输出打印一条错误消息,并停止该程序。
最好创建一个释放此类结构所使用的动态内存的函数。例如,
void mystring_free(struct mystring *ms)
{
if (ms) {
free(ms->ptr);
ms->ptr = NULL;
ms->len = 0;
ms->max = 0;
}
}
通常,您也会看到初始化函数,例如
void mystring_init(struct mystring *ms)
{
ms->ptr = NULL;
ms->len = 0;
ms->max = 0;
}
但我更喜欢先前定义的MYSTRING_INIT
之类的初始化宏。
您可以在以下程序中使用上述内容:
int main(void)
{
struct mystring message = MYSTRING_INIT;
mystring_append(&message, "Hello, ");
mystring_append(&message, "world!");
printf("message = '%s'.\n", message.ptr);
mystring_free(&message);
return EXIT_SUCCESS;
}
注意:
当我们声明结构类型的变量(而不是指向结构的指针,即没有*
)时,我们在变量名和字段名之间使用.
。在main()
中,我们有struct mystring message;
,因此我们使用message.ptr
来引用message
结构中的字符指针。
当我们将变量声明为指向结构类型的指针时(如在函数中,在变量名称之前使用*
),我们在变量名和字段之间使用->
名称。例如,在mystring_append()
中我们有struct mystring *ms
,因此我们使用ms->ptr
来引用ms
变量指向的结构中的char指针。
动态内存管理并不困难。 realloc(NULL, size)
相当于malloc(size)
,free(NULL)
是安全的(什么都不做)。
在上面的函数中,我们只需要跟踪当前长度,以及为字段ptr
指向的动态缓冲区分配的字符数,并记住字符串需要终止nul字节, '\0'
,不计入其长度。
上面的函数只为附加字符串重新分配了足够的内存。实际上,通常会分配额外的内存,以便将所需的重新分配数量保持在最低水平。 (这是因为与其他操作相比,内存分配/重新分配功能被认为是昂贵的,或者速度很慢。)但这是另一个场合的主题。
如果我们希望函数能够修改调用者范围中的变量(即任何类型,甚至是结构) - 上例中struct mystring message;
中的main()
- - ,该函数需要获取指向该类型变量的指针,并通过指针修改该值。
address-of运算符&
获取某个变量的地址。特别是,上面示例中的&message
计算为指向struct mystring
的指针。
如果我们使用struct mystring *ref = &message;
撰写struct mystring message;
,则message
是struct mystring
类型的变量,而ref
是指向message
的指针}; ref
属于struct mystring *
类型。
答案 2 :(得分:0)
如果我理解正确你的意思是以下
#include <string.h>
//...
void hey(char* s, char* result)
{
strcpy( result, s );
}
这是一个示范程序
#include <stdio.h>
#include <string.h>
void hey( const char* s, char* result);
int main(void)
{
char buf[100];
hey( "320244", buf );
printf( "%s\n", buf );
return 0;
}
void hey( const char* s, char* result )
{
strcpy( result, s );
}
它的输出是
320244
如果数组buf
已经存储了一个字符串,那么你可以向它添加一个新的字符串。例如
#include <string.h>
//...
char buf[100] = "ABC";
strcat( buf, "320244" );
考虑到函数hey应该在使用之前声明,并且根据C标准,函数main应声明为
int main( void )