好的,我不会给你一个一对一的指针指南(我不打算写一本书),但这里是基于你的假设/问题的快速指南:
- “
int *pInt
:这是结构中的 int 类型数组”
它可能pInt
是一个指向整数的指针。它不必是一个数组。数组是指针,但指针并不总是数组。没错,数组当然是数组,但是在 C 中访问它的方式是通过数组变量或指针。此处清楚地解释了
差异
基本上:一个数组是一个连续的内存块,一个数组变量经常(嗯,总是保存我上面链接到的页面上列出的 3 种情况)衰减成一个指针。阅读为什么和如何,以清楚地了解指针和数组之间的差异和相似之处。
如果您了解为什么以下片段之一是不允许的,而另一个是不允许的,那么您就在那里:
char *str = "Read only";
printf("%c\n", str[2]);//prints a from (0=>r, 1=>e, 3=> a...)
str[2] = 'q';//ILLEGAL
//BUT:
char str[] = "Read only";
str[2] = 'q';//perfectly legal...
printf("%c\n", str[2]);//prints q!
为什么是这样?简单的。在这两种情况下,literall"Read only"
都存储在只读存储器中。不同之处在于,通过将此字符串分配给指针(char *str
),我们将只读内存地址分配给变量,因此我们无法更改它指向的内存(这就是只读的意思)。
在第二种情况下,字符串字面量存储在同一个只读内存中,但是因为我们将它分配给一个数组,所以它的值被复制到新分配的堆栈内存中,我们可以对其进行写入。
因此,指针指向内存中的一些数据块。该内存可以是可写的,也可以是不可写的,内存地址可以是数组的一部分的地址,也可以是单个 int(就像您的情况一样),您甚至可以拥有指向多个指针的指针,并且每个这些指针本质上可以指向内存中的不同位置(即不是连续的块)。
无论如何,考虑一下:
int i = 123;
int arr[3] = {1,2,3};//array
int *iPtr = &i;//iPtr contains the mem address of i
printf("%d\n", *iPtr);//prints 123
iPtr = arr;//iPtr points to the same as arr (note no & operator)
printf("%d\n", *iPtr);//prints 1
//now probably a mindfuck for you now, but:
printf("%d\n", *(iPtr+1));//prints 2!
int
最后一点只是为了显示指针是什么:它是内存中的一个位置,大到足以容纳+1
一个指着。在内存中,这可能看起来像这样:
| 0x0f0 | 0x0f2 | 0x0f4 | 0x0f6 | //mem address
| *iPtr | iPtr + 1 | iPtr + 2 | iPtr + 3 | //access via pointer
这就是为什么指针可能很危险的原因。在上面的代码中,iPtr
指向 3 个整数中的第一个(在arr
数组中定义),但是如果我访问*(iPtr+4)
,我正在访问超出范围的内存。您正在访问未声明/初始化的内存,或由其他人拥有的内存。这可能并且可能会导致意外的行为......但我已经看到这用于获得一些额外的随机化......
- "
newStruct *createMyStruct
: 一个名为 createMyStruct 的函数。createMyStruct 是一个指向 newStruct 并创建 newStruct 副本的指针。"
你把我弄丢了,这是一个函数定义。该函数确实被调用createMyStruct
了,它返回一个指向该类型的指针newStruct
。就是这样,就像int some_function()
一个返回 int 的函数
- "
newStruct *pStruct
: pStruct 与 createMyStruct (?) 相同"
不,pStruct
是指向 a 的指针newStruct
,并且pStruct
是函数参数,而不是函数createMyStruct
。
免费通话时:
free
当您不再需要它们时,您可以调用存储在从堆分配的内存中的变量。如果它们超出范围,您将无法再释放它们,因此当您仍然有一个指向它的变量时,您必须释放内存,但您不应该释放您稍后在程序中可能需要的任何内容:
char *str = calloc(11, sizeof(char));
free(str);
//I can't use str here anymore
但:
int main()
{
void some_function();
some_function();
//I can't free str here, mem-leak immanent!
return 0;
}
void some_function()
{
char *str = calloc(11, sizeof(char));
//do stuff, but no calls to free
}
在这种情况下,free(str);
应该是some_function
. 如果some_function
是的话char *some_function()
,我们会这样写:
int main()
{
char *return_val = NULL;
char *some_function();
return_val = some_function();
printf("%s was returned by some_function\n", return_val);
//the allocated memory is accessible here
//And it has to be freed before main returns, so:
free(return_val);//deallocate!
return 0;
}
char *some_function()
{
char *str = calloc(11, sizeof(char));
//do stuff, but no calls to free
return str;//return char pointer
}
它以 结尾return str
,那么您必须调用free
该main
函数,因为它有一个指向已分配内存的指针。
就是这样,简而言之...