C初始化函数中的字符数组,或者我应该将其作为参数传递

时间:2014-02-05 12:21:06

标签: c arrays function char c99

我有一个函数需要一个char指针,就像这个:

void func(char *string);

我希望以这种方式更改传递的char数组:

func(“用户”) - >你好,用户!

解决此任务的更好方法是什么?

选项#1; - >使用其他字符数组 - > temp(将被声明一次)

void func(char *string, char *temp){
    sprintf(temp, "Hello, %s!", string);
}

并在临时使用后

选项#2; - >使用temp作为局部变量(应该每次在函数体中声明)

void func(char *string){
    char temp[512];
    sprintf(temp, "Hello, %s!", string);
    sprintf(string, "%s", temp);
    // or strcpy(string, temp); string[strlen(temp)]=0;
}

问题是经常调用函数。第二种选择是否会显着降低性能?还有其他选择可以解决这个问题吗?

5 个答案:

答案 0 :(得分:2)

第一种选择是两者中较好的选择。如果与字符串文字一起使用,第二个将调用未定义的行为,因为您无法覆盖它们。当然,无论如何它都没有任何意义,你期望如何改变被覆盖的文字?

当然,对于输入字符串,缓冲区溢出保护和正确const会更好:

void func(const char *string, char *out, size_t out_max)
{
  snprintf(out, out_max, "Hello, %s!", string);
}

到目前为止,大多数系统都应该有snprintf()

答案 1 :(得分:0)

另一种方式是:

获取大小为"Hello! User" + 1的字符串,并使用"Hello! "

进行初始化

char string[20] = "Hello! ";(让)

然后每次都在string + 7处输入。 (7的长度为"Hello! "

scanf("%s", string + 7);

如果您想在此之后的任何时间使用"User"字符串,那么string + 7将始终指向它。

答案 2 :(得分:0)

性能没有太大差别,部分原因是因为它是一个小函数,并且因为编译器知道如何优化这些类型的东西,一般来说最好的做法是声明它一次。由于您不知道用户名将需要多长时间,因此您必须进行一些内存分配。我建议做这样的事情:

void func(char* name) {
   char* hello = "Hello! ";
   //allocate memory for the whole string
   char* tmp = (char*)malloc(sizeof(char)*(strlen(name)+strlen(hello)+1));
   //construct the string
   strcpy(tmp, hello);
   strcat(tmp, name);
   //print it
   printf("%s\n", tmp);
   //discard of the space you used
   free(tmp);
}

这样你就可以确保你有足够的内存和性能,我认为printf是那里最慢的操作。

答案 3 :(得分:0)

你已经有几个选择;但既然你说你真的想要最高性能的解决方案,也许以下是有用的 - 你创建一个不断重复使用的单个函数(而不是硬编码模板字符串,你传递它;这样你只有一个这样的功能,而不是每个可能输出的一个功能)。我很确定带有snprintf参数的%s函数在一个不太合适的编译器上执行类似于memcpy的操作,所以这应该尽可能高效。无论如何,产生输出到屏幕的工作远远慢于生成字符串的工作。请记住,从长远来看,易于维护的代码将始终是正确的选择。

有两种方法可以做到这一点 - 你可以像这样创建一个实际的函数:

void create_output(char* subThis, char* intoThis, char* outputThat, int n){
    snprintf(outputThat, n, intoThis, subThis);
}

或者您可以使用#define将一个名称别名替换为另一个名称。这样做的好处是,您可以在封面下使用snprintf时使用更自然的参数顺序:

#include <stdio.h>

#define MAX_OUT 100
#define create_output(a,b,c,d) snprintf((c),(d),(b),(a))

//void create_output(char* subThis, char* intoThis, char* outputThat, int n)

int main(void) {
    char username[]="Fred";
    char template[]="Hello %s";
    char output[MAX_OUT];

    create_output(username, template, output, MAX_OUT);
    // and show that it works:
    printf("%s\n", output);
}

如果保持输出缓冲区始终可用于此目的,您甚至可以简化用户的生活:在下面,#define使用逗号运算符执行snprintf函数但返回指向结果的指针OUTPUT - 这是一个只定义一次的全局范围的缓冲区。这可能看起来有点像黑客,但它以尽可能高效和灵活的方式生成您要求的功能(最小的开销 - 很多工作在编译时完成)。

#include <stdio.h>

#define MAX_OUT 100
char OUTPUT[MAX_OUT];

#define create_output(a,b) (snprintf(OUTPUT,MAX_OUT,(b),(a)), OUTPUT)

// apparent prototype:
// char* create_output(char* subThis, char* intoThis)
// it returns a pointer to the location where the string is stored

int main(void) {
    char username[]="Fred";
    char template[]="Hello %s";
    char *output;

    output = create_output(username, template);
    // and show that it works:
    printf("%s\n", output);
}

答案 4 :(得分:0)

void func(const char *string, char *outbuff){
    const char *p = "Hello, ";
    while(*p)
        *outbuff++ = *p++;
    p = string;
    while(*p)
        *outbuff++ = *p++;
    p = "!";
    while(*outbuff++ = *p++);
}