简体   繁体   English

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

[英]C Function implementation - with Pointer vs without Pointer

I've just started to work with C, and never had to deal with pointers in previous languages I used, so I was wondering what method is better if just modifying a string. 我刚刚开始使用C,并且从来没有处理过我以前用过的语言中的指针,所以我想知道如果只是修改一个字符串,哪种方法更好。

pointerstring vs normal. 指针串与正常。

Also if you want to provide more information about when to use pointers that would be great. 此外,如果您想提供有关何时使用指针的更多信息,那将是很棒的。 I was shocked when I found out that the function "normal" would even modify the string passed, and update in the main function without a return value. 当我发现函数“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");
}

Output: 输出:

Pointer: Hello
Normal: World

In a function declaration, char [] and char * are equivalent. 在函数声明中, char []char *是等效的。 Function parameters with outer-level array type are transformed to the equivalent pointer type; 具有外层数组类型的函数参数被转换为等效的指针类型; this affects calling code and the function body itself. 这会影响调用代码和函数体本身。

Because of this, it's better to use the char * syntax as otherwise you could be confused and attempt eg to take the sizeof of an outer-level fixed-length array type parameter: 因此,最好使用char *语法,否则可能会混淆并尝试获取外层固定长度数组类型参数的sizeof

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

When you pass a parameter declared as a pointer to a function (and the pointer parameter is not declared const ), you are explicitly giving the function permission to modify the object or array the pointer points to. 当您将声明为指针的参数传递给函数(并且指针参数未声明为const )时,您将显式赋予函数权限以修改指针指向的对象或数组。

One of the problems in C is that arrays are second-class citizens. C中的一个问题是阵列是二等公民。 In almost all useful circumstances, among them when passing them to a function, arrays decay to pointers (thereby losing their size information). 在几乎所有有用的情况下, 它们传递给函数时,数组会衰减到指针 (从而丢失它们的大小信息)。

Therefore, it makes no difference whether you take an array as T* arg or T arg[]the latter is a mere synonym for the former . 因此,无论是将数组作为T* arg还是T arg[]都没有区别 - 后者仅仅是前者的同义词 Both are pointers to the first character of the string variable defined in main() , so both have access to the original data and can modify it. 两者都是指向main()定义的string变量的第一个字符的指针,因此它们都可以访问原始数据并可以对其进行修改。


Note: C always passes arguments per copy . 注意:C始终为每个副本传递参数。 This is also true in this case. 在这种情况下也是如此。 However, when you pass a pointer (or an array decaying to a pointer), what is copied is the address , so that the object referred to is accessible through two different copies of its address. 但是,当您传递一个指针(或一个衰减到指针的数组)时,复制的是地址 ,因此所引用的对象可以通过其地址的两个不同副本访问。

With pointer Vs Without pointer 用指针Vs没有指针

1) We can directly pass a local variable reference(address) to the new function to process and update the values, instead of sending the values to the function and returning the values from the function. 1)我们可以直接将局部变量引用(地址)传递给新函数来处理和更新值,而不是将值发送到函数并从函数返回值。

With pointers 用指针

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

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

Without pointers 没有指针

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

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

2) Global or static variable has life time scope and local variable has scope only to a function. 2)全局变量或静态变量具有生命期范围,局部变量仅具有范围的功能。 If we want to create a user defined scope variable means pointer is requried. 如果我们想要创建用户定义的范围变量,则意味着需要指针。 That means if we want to create a variable which should have scope in some n number of functions means, create a dynamic memory for that variable in first function and pass it to all the function, finally free the memory in nth function. 这意味着如果我们想创建一个应该在n个函数中具有范围的变量,则在第一个函数中为该变量创建一个动态内存并将其传递给所有函数,最后释放第n个函数中的内存。

3) If we want to keep member function also in sturucture along with member variables then we can go for function pointers. 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) Consider a structure data which size s is very big. 4)考虑尺寸s非常大的结构data If we want to send a variable of this structure to another function better to send as reference. 如果我们想将这个结构的变量发送到另一个函数,最好发送作为参考。 Because this will reduce the activation record(in stack) size created for the new function. 因为这会减少为新函数创建的激活记录(堆栈)大小。

With Pointers - It will requires only 4bytes (in 32 bit m/c) or 8 bytes (in 64 bit m/c) in activation record(in stack) of function func 使用指针 - 在函数func激活记录(堆栈中)中只需要4字节(32位m / c)或8字节(64位m / c)

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

Without Pointers - It will requires s bytes in activation record(in stack) of function func . 没有指针 - 它将需要函数func激活记录(在堆栈中)中的s个字节。 Conside the s is sizeof(struct data) which is very big value. 考虑到ssizeof(struct data) ,这是非常大的值。

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

5) We can change a value of a constant variable with pointers. 5)我们可以用指针改变常量变量的值。

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

in addition to the other answers, my comment about "string"-manipulating functions (string = zero terminated char array): always return the string parameter as a return value. 除了其他答案,我对“字符串”操纵函数的评论(字符串=零终止字符数组):总是返回字符串参数作为返回值。

So you can use the function procedural or functional, like in printf("Dear %s, ", normal(buf)); 所以你可以使用函数procedural或functional,比如printf("Dear %s, ", normal(buf));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM