【问题标题】:function returns a pointer函数返回一个指针
【发布时间】:2017-10-14 20:49:03
【问题描述】:

我对 C 语言相当陌生,我很难掌握所有这些指针。换句话说,取消引用运算符和 & 号运算符。我相信,在盯着它们看了一会儿之后,我开始了解它们是如何工作的。例如:

    int x = 1;            //this creates an integer variable called x and assigns one to it
    int *pointer;     //this creates a pointer variable that will point to an integer
    pointer = &x;     //now the variable pointer points to x
    *pointer = 0      //the value that pointer points to is now zero

我很确定我了解它的工作原理。
我正在阅读 Kernighan 和 Ritchie 的“The C Programming Language”,但我对他们在第 5.4 节(地址算术)中的一些代码感到困惑。我应该指出,我了解地址算术,所以我的问题与此无关。我对以下函数中的代码的问题也不是。在线搜索有关此代码的问题会产生很多帖子,其中人们不了解 if/else 语句中的代码如何运行。无论如何,我的问题是关于函数名本身。

    #define ALLOCSIZE 1000
    static char allocbuf[ALLOCSIZE];
    static char *allocp = allocbuf;

    char *alloc(int n)  /*return pointer to n charachters*/
    {
          if (allocbuf + ALLOCSIZE - allocp >=n)
             {
             allocp += n;
             return  allocp - n;
             }
          else
             return 0;
    }

再次,我理解函数中的代码,但如何理解

*alloc

工作?我知道这个函数返回一个指针。这是否意味着通过将函数名作为指针,我们将返回指向 char 类型的指针?如果是这样,它指向什么?在我之前的示例中,我们有

    int x = 1;
    int *pointer;
    pointer  = &x;

这里的变量“pointer”指向x变量。然而。在函数 alloc 中没有指向任何东西。任何帮助将不胜感激。

【问题讨论】:

标签: c function pointers


【解决方案1】:

这个函数

char *alloc(int n)  /*return pointer to n charachters*/

将返回一个指向字符的指针

这样写可能更容易理解:

char* alloc(int n)  //subtle, but this change in format can help

现在,关于指针实际指向的内容。以前,在这条线上;

#define ALLOCSIZE 1000
static char allocbuf[ALLOCSIZE];

创建了一个大小为 1000 的 char 数组。我们有一个包含 1,000 个字符的数组,名称“allocbuf”指向数组中的第一个元素。 接下来,在这一行;

static char *allocp = allocbuf;

我们创建一个指向 1,000 个字符数组 (allocbuf) 的第一个元素的指针 (allocp)。 数组和指针都是全局变量。它们可以在程序中的任何位置访问。在您发布的示例中,这些变量将在 alloc 函数中使用。

在我们继续之前,定义函数的目的是有意义的。目的是使用之前定义的 1000 个 char 数组(它可以帮助您将 char 视为单个字节)来分配内存。因此该函数将跟踪已使用的内存。并返回一个指向可以使用的大小为“n”的块的指针(如果没有足够的内存,则返回 null '0')。

不要关心这个例子中的内存是如何释放的。我重新阅读了您从中提取此示例的部分,它后来定义了一个名为“afree”的方法来释放此函数分配的内存。

该函数通过每次请求内存时将“allocp”(指向 1000 个字符的数组的指针)递增“n”(请求的大小)来跟踪已使用的内存。然后,当函数的用户请求更多内存时,它会检查以确保这些行可以满足该请求;

if (allocbuf + ALLOCSIZE – allocp >= n)
    …
else{
    return 0;
}

如果请求的大小不合适,则返回 null。该函数利用“allocp”的当前位置来确定先前调用是否有足够的内存剩余。 如果要求的尺寸合适,就会发生这种情况;

allocp += n;
return allocp – n;

它的作用是通过请求多少内存来增加“allocp”。该指针用于跟踪该函数已请求多少内存。由于该函数可以满足内存请求,因此它现在认为请求的内存正在使用中。因此,指针现在指向 1000 字符数组中未使用的第一个字符。 然后,在增加指针后,该函数通过从“allocp”的当前位置减去“n”(请求的大小)返回指向所请求内存块的第一个字符的指针。

在所有这些过程中,没有人知道这个内存的实际价值是什么。没有人知道 allocbuf[13] 或 allocbuf[314] 包含什么。这个函数只管理哪些内存是空闲的,哪些是被占用的,它并不关心内存中实际存储了什么。

如果用户像这样要求 4 个字节

char* 4bytes = alloc(4)

像这样在其中存储一个 32 位 int;

//don’t ever actually do this!!!
int* 4bytesInt = (int*)4bytes;
*4bytesInt = 2,147,483,647;

那么 allocbuf 的前四个元素包含该整数。 如果你释放内存;

afree(4bytes);

那么指针仍然有效,并且 allocbuf 的前 4 个元素仍然包含该整数。实际上并没有改变这些字节的值。 但是,如果你再次请求内存,

char* 4bytesAgain = alloc(4);

然后 alloc 将返回相同的 4 字节到“4bytesAgain”,它返回到“4bytes”!由于内存被释放,“alloc”函数可以随意重用它。所以如果你现在用一个名字来填充这四个字节;

4bytesAgain[0] = ‘C’;
4bytesAgain[1] = ‘A’;   
4bytesAgain[2] = ‘R’;
4bytesAgain[3] = ‘L’;

那么这将改变原来的“4bytes”和“4bytesInt”所指向的值。

【讨论】:

  • 谢谢。您的详细解释很有帮助。
  • “名称allocbuf 指向第一个元素”:并非如此。它为数组命名,在许多但不是所有情况下,数组的名称将衰减为指向第一个元素的指针,这就是初始化static char *allocp = allocbuf; 中发生的情况。此外,4bytes4bytesAgain 不是有效标识符。
【解决方案2】:

这只是意味着每当调用该函数时,它都会返回一个指向char的指针。

例如,当调用此函数时,您可能会看到如下内容:

char* x;
x = alloc(5);

【讨论】:

    【解决方案3】:

    char *alloc(int n) 表示alloc 是一个返回指向char 的指针的函数。在这种情况下,它是指向数组第一个元素的指针,表示alloc 预订的内存块。把* 放在alloc 旁边可能有点误导,把它想象成char* alloc(int n)

    函数名不是指针,它返回的是——就像你写int fun(int x)一样——只是这里的返回值不是int而是char *

    【讨论】:

    • 谢谢。l 您在操作员的顺序中的权利确实更清楚了。
    猜你喜欢
    • 2020-01-12
    • 2022-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-04
    • 1970-01-01
    • 2016-10-23
    • 2013-04-10
    相关资源
    最近更新 更多