C函数实现 - 使用Pointer vs without Pointer

时间:2012-08-23 10:17:57

标签: c pointers

我刚刚开始使用C,从来没有处理过我以前用过的语言中的指针,所以我想知道如果只是修改一个字符串,哪种方法更好。

指针串与正常。

此外,如果您想提供有关何时使用指针的更多信息。当我发现函数“normal”甚至会修改传递的字符串,并在main函数中更新而没有返回值时,我感到很震惊。

#include <stdio.h>

void pointerstring(char *s);
void normal(char s[]);

int main() {
    char string[20];
    pointerstring(string);
    printf("\nPointer: %s\n",string);
    normal(string);
    printf("Normal: %s\n",string);
}

void pointerstring(char *s) {
    sprintf(s,"Hello");
}
void normal(char s[]) {
    sprintf(s,"World");
}

输出:

Pointer: Hello
Normal: World

4 个答案:

答案 0 :(得分:7)

在函数声明中,char []char *是等效的。具有外层数组类型的函数参数被转换为等效的指针类型;这会影响调用代码和函数体本身。

因此,使用char *语法会更好,否则您可能会感到困惑并尝试例如获取外层固定长度数组类型参数的sizeof

void foo(char s[10]) {
    printf("%z\n", sizeof(s));  // prints 4 (or 8), not 10
}

当您传递一个声明为函数指针的参数(并且指针参数未声明为const)时,您明确地赋予该函数权限以修改指针所指向的对象或数组。

答案 1 :(得分:5)

C中的一个问题是数组是二等公民。在几乎所有有用的情况下,其中 将它们传递给函数时,数组会衰减到指针 (从而丢失它们的大小信息)。

因此,无论您将数组作为T* arg还是T arg[] - ,后者仅仅是前者的同义词 ,这一点没有区别。两者都是指向string中定义的main()变量的第一个字符的指针,因此两者都可以访问原始数据并可以对其进行修改。


注意:C始终传递参数每个副本。在这种情况下也是如此。但是,当您传递一个指针(或一个衰减到指针的数组)时,复制的是地址,以便所引用的对象可以通过其地址的两个不同副本访问。

答案 2 :(得分:1)

使用指针Vs无指针

1)我们可以直接将局部变量引用(地址)传递给新函数来处理和更新值,而不是将值发送到函数并从函数中返回值。

使用指针

...
int a = 10;
func(&a);
...

void func(int *x);
{
   //do something with the value *x(10)
   *x = 5;
}

没有指针

...
int a = 10;
a = func(a);
...

int func(int x);
{
   //do something with the value x(10)
   x = 5;
   return x;
}

2)全局变量或静态变量具有生命期范围,局部变量仅具有函数的范围。如果我们想要创建用户定义的范围变量,则意味着需要指针。这意味着如果我们想创建一个应该在某些n个函数中具有范围的变量,在第一个函数中为该变量创建一个动态内存并将其传递给所有函数,最后在第n个函数中释放内存

3)如果我们想要将成员函数与成员变量一起保存在sturucture中,那么我们可以使用函数指针。

struct data;

struct data
{
    int no1, no2, ans;
    void (*pfAdd)(struct data*);
    void (*pfSub)(struct data*);    
    void (*pfMul)(struct data*);
    void (*pfDiv)(struct data*);
};

void add(struct data* x)
{
   x.ans = x.no1, x.no2;
}
...
struct data a;
a.no1 = 10;
a.no1 = 5;
a.pfAdd = add;
...
a.pfAdd(&a);
printf("Addition is %d\n", a.ans);
...

4)考虑一个data的结构s非常大。如果我们想将这个结构的变量发送到另一个函数,最好发送作为参考。因为这会减少为新函数创建的激活记录(堆栈)大小。

使用指针 - 在函数func的激活记录(堆栈中)中仅需要4字节(32位m / c)或8字节(64位m / c)

...
struct data a;
func(&a);
...

没有指针 - 在函数s的激活记录(堆栈中)中需要func个字节。考虑到ssizeof(struct data)这是非常大的价值。

...
struct data a;
func(a);
...

5)我们可以用指针改变常量变量的值。

...
const int a = 10;
int *p = NULL;
p = (int *)&a;
*p = 5;
printf("%d", a); //This will print 5
...

答案 3 :(得分:0)

除了其他答案之外,我对“字符串”操纵函数的评论(字符串=零终止字符数组):总是返回字符串参数作为返回值。

所以你可以使用函数程序或函数,比如printf("Dear %s, ", normal(buf));