2017-10-14 140 views
3

我对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; 

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

+0

但'char * allocp' **是一个指针,它指向'allocbuf'。 “missing”'&'在这里解释[数组名称是一个指针吗?](https://stackoverflow.com/questions/1641957/is-an-array-name-a-pointer) –

回答

0

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

函数名不是一个指针,它返回的是 - 就像你会写int fun(int x) - 除了这里的返回值不是int而是char *

+0

Thank you.l Your按照运营商的顺序,这样做确实使它更加清晰。 – EFiore

+0

不客气,我经历了同一本书;) – atru

0

这只是说,无论何时调用函数,它都会返回一个指向char的指针。

例如,当这个函数被调用,你可能会看到这样的事情:

char* x; 
x = alloc(5); 
2

此功能

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的字符数组。我们有一个包含1,000个字符的数组,名称'allocbuf'指向数组中的第一个元素。 接下来,在这条线上;

static char *allocp = allocbuf; 

我们为1,000个char数组(allocbuf)的第一个元素创建一个指针(allocp)。 数组和指针都是全局变量。他们可以在程序中的任何地方访问。在你发布的例子中,这些变量将被用在alloc函数中。

在我们继续之前,定义函数的用途是有意义的。目的是使用先前定义的1000个char数组(它可以帮助您将char看作单个字节)来分配内存。所以这个函数会跟踪已经使用了什么内存。并返回一个指向可以使用的大小为'n'的块的指针(如果没有足够的内存,则返回空值'0')。

不要关心在这个例子中如何释放内存。我重读了你从这个例子中拉出来的部分,它后来定义了一个叫做'afree'的方法来释放这个函数分配的内存。

每次请求存储器时,该函数都会追踪'alloc'(指向1000个字符的数组的指针)'n'(请求的大小)所使用的内存。然后,当函数的用户请求更多的内存时,它会检查以确保这些行可以满足请求;

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

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

allocp += n; 
return allocp – n; 

这是做什么是增加'allocp'无论多少内存被请求。该指针用于跟踪该功能请求了多少内存。由于该功能可以满足内存请求,因此它现在认为所请求的内存正在使用中。因此,指针现在指向1000 char数组中未使用的第一个字符。 然后,在增加指针后,该函数返回一个指向内存块的第一个char的指针,该指针是通过从'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”那它返回“4字节”!由于内存被释放,'alloc'函数可以自由地重用它。所以,如果你现在用这个名字填充这四个字节,

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

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

+0

谢谢。你的详细解释会帮助你很多。 – EFiore

+1

“allocbuf”指向第一个元素“:不是。它命名数组,在许多情况下(但并非所有情况下),数组的名称将衰减为指向第一个元素的指针,这是在初始化“static char * allocp = allocbuf;'中发生的情况。另外,“4bytes”和“4bytesAgain”不是有效的标识符。 – aschepler