指针是C和C ++中最令人困惑的概念之一,在此博客文章中,我们将容易理解此概念。
#types和内存
当我们声明vaialbe或暂时存储任何数据时,计算机将为此变量或数据保留内存,并且将存储该变量或数据在保留空间中。
我们将用来理解指针的内存结构表示的示例是
仅放置该地址以使其易于理解,通常将其放在十六进制中,变量是名称,值是已分配的ASCII编号。
。根据变量的类型,计算机将在内存中保留不同的空间。
1 byte = 8 bits, each bit being 0 or 1
-
char = 256不同的值= 2^8 = 8位= 1字节
-
int = 4294967296不同的
value = 2^32 = 32 bits = 4 byte
-
float = 4294967296不同的值= 2^32 = 32位= 4字节
您可以使用sizeof
操作员检查变量类型的大小。
示例
当我们声明char
类型的l
时。
char l;
int这个示例我们创建了L的地址为6。
char l;
l = 'A';
我们将值'A'
分配给了变量l
,但是字节不会容纳字母'A'
,它将容纳ASCII代码,即65(MAN ASCII)。
在int
和float
案例中,我们使用4个字节。
int n;
n = 8;
和操作员
当我们想找到变量的地址时,我们使用&ocerator。
示例
修饰符
%p
用于打印地址
#存储内存地址
到目前为止,我们学会了如何将角色,十进制和漂浮在变量中。
我们还学会了如何使用&
操作员获取变量的地址。
指针只是内存中数据的地址。
指针变量是存储该数据地址的变量。
声明指针变量
VARIBALE_TYPE *VARIABLE_NAME
示例
char *p;
指针变量保存其他变量数据的地址
指针变量的大小为8个字节
指针变量有自己的变量地址
示例
int n;
int *p;
n = 10;
p = &n;
现在n的地址为3,n的地址为&n,因此我们存储了n的地址。
在此示例中,n的地址为3,然后p的值为3,它保留n。
#dereferencing
删除性是一种使用指示值存储在其指向的内存地址的值的方式。
我们使用 *解雇操作员来解释值。
首先 *有两个功能
-
在声明中使用。例如,
int *p;
-
用于删除。例如,
*p = 20;
示例
int n;
int *p;
n = 11;
p = &n;
*p = 20;
现在:
-
p == &n
拥有n 的地址
-
*p == n
指向n 的值
现在让我们使用内存表示。
打破此示例。直到零件n = 11和p =&n = 7内存表示为
删除*p = 20
后,内存看起来像
#Functions参数按值传递
我们在C功能博客文章中介绍了传递函数中参数的两种方式。
-
按值传递:传递变量的副本。
-
通过参考:将指针传递到变量。
通过值:此方法仅复制主函数中变量的值,而另一个函数中所做的更改不会影响主函数中的值,因为它只是一个复制。
示例
在执行i = 20;
之前,内存布局看起来像
执行i = 20;
后,内存布局将看起来像
娱乐完成后执行变量i,并且内存布局看起来像
使用指针从函数进行修改。
。在功能娱乐之前,内存布局看起来像
由于我存储相同的内存地址,因此指向相同的地址,因此P和我现在指向n。因此,当我们执行行 *i = 20时;我们修改了N和N的值现在容纳20。
当我们留下功能乐趣时,变量我被破坏了,但我的价值仍然20
#arrays
C中的数组是连续的存储区域,它们具有相同类型的许多值,并且数组的所有元素具有相同的类型。
声明数组
TYPE ARRAY_NAME[ARRAY_SIZE];
分配值
TYPE ARRAY_NAME[ARRAY_SIZE] = {ELEMENTS}
示例
int arr[5];
arr [0]将访问第一个元素,arr [1]第二个元素,依此类推。
在此示例中,计算机将为5个整数保留一个连续的空间。
内存布局看起来像
#pointers vs数组
数组不是指针,它们不容纳内存地址,但是数组的名称是数组的第一个元素的地址。
示例
因此,为什么在表达式中使用数组a
时,该数组类型会自动将其隐式转换为指针到元素类型(数组类型decay)。
在两种情况下,此规则有两个例外:
-
sizeof()
操作员
示例
-
&
操作员
示例
#pointers算术
我们可以使用其他方法为 *(var + x)访问数组的元素,其中var是数组的名称,x是(x + 1)element。
示例
内存是布局
#strings
字符串实际上是由null字符'\ 0'''\ 0'终止的一维字符。
TYPE STRING_NAME[SIZE] = {ELEMENT}
示例
您可能会注意到我们使用了一个大小为6的数组,这是因为在C中,字符串以字符'\ 0'结束(ASCII值= 0)。
#C程序的会员布局
C程序的内存布局包含五个段:
-
堆栈段
-
堆段
-
bss(由符号启动的块)
-
ds(数据段)
-
文本段
每个段都有自己的读,写和可执行的权限。如果程序试图以不允许的方式访问内存,则分割故障,这是一个常见的问题,会导致程序崩溃。
堆栈
堆栈包含来自函数,返回值的局部变量,每个函数都有一个堆栈帧。
该堆栈包含一个LIFO(首先是最后一次)结构,在调用时将函数变量推到堆栈上,返回时函数变量会从堆栈中弹出。
了解LIFO如何检查堆栈数据结构。
#include <stdio.h>
int main(void)
{
int data; //local variable stored in stack
return 0;
}
堆
堆用于在运行时分配内存和由Malloc,Calloc,Free等内存管理功能管理的堆区域
#include <stdio.h>
int main(void)
{
char *pStr = malloc(sizeof(char)*4); //stored in heap
return 0;
}
BSS(非初始化的数据段)
它包含所有非初始化的全局和静态变量。
#include <stdio.h>
int data1;
// Uninitialized global variable stored in BSS
int main(void)
{
static int data2;
// Uninitialized static variable stored in BSS
return 0;
}
ds(初始数据段)
它包含显式初始化的全局和静态变量,并且该段可以进一步分类为初始化的读取区域和初始化的读取区域。
#include <stdio.h>
int data1 = 10 ;
//Initialized global variable stored in DS
int main(void)
{
static int data2 = 3;
//Initialized static variable stored in DS
return 0;
}
文本
文本段包含编译程序的二进制文件,他的文本段是一个仅阅读段,可防止程序被意外修改。
#include <stdio.h>
int main(void)
{
return 0;
}
提示:
NULL
用于指针,这是没有地址的指示器,'\ 0'是ins for strings