C-指针,阵列和弦
#c #指针 #字符串 #arrays

指针是C和C ++中最令人困惑的概念之一,在此博客文章中,我们将容易理解此概念。


#types和内存

当我们声明vaialbe或暂时存储任何数据时,计算机将为此变量或数据保留内存,并且将存储该变量或数据在保留空间中。

我们将用来理解指针的内存结构表示的示例是

Image description

仅放置该地址以使其易于理解,通常将其放在十六进制中,变量是名称,值是已分配的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;

Image description

int这个示例我们创建了L的地址为6。

char l;

l = 'A';

Image description

我们将值'A'分配给了变量l,但是字节不会容纳字母'A',它将容纳ASCII代码,即65(MAN ASCII)。

Image description

intfloat案例中,我们使用4个字节。

int n;  

n = 8;

Image description

和操作员

当我们想找到变量的地址时,我们使用&ocerator。

示例

Image description

Image description

修饰符%p用于打印地址


#存储内存地址

到目前为止,我们学会了如何将角色,十进制和漂浮在变量中。

我们还学会了如何使用&操作员获取变量的地址。

指针只是内存中数据的地址。
指针变量是存储该数据地址的变量。

声明指针变量

VARIBALE_TYPE *VARIABLE_NAME

示例

char *p;

Image description

Image description

指针变量保存其他变量数据的地址
指针变量的大小为8个字节
指针变量有自己的变量地址

Image description

示例

int n;
int *p; 

n = 10;
p = &n; 

Image description

现在n的地址为3,n的地址为&n,因此我们存储了n的地址。

在此示例中,n的地址为3,然后p的值为3,它保留n。

的地址

Image description

Image description

Image description


#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内存表示为

Image description

Image description

删除*p = 20后,内存看起来像

Image description

Image description

Image description

Image description


#Functions参数按值传递

我们在C功能博客文章中介绍了传递函数中参数的两种方式。

  • 按值传递:传递变量的副本。

  • 通过参考:将指针传递到变量。

通过值:此方法仅复制主函数中变量的值,而另一个函数中所做的更改不会影响主函数中的值,因为它只是一个复制。

示例

Image description

在执行i = 20;之前,内存布局看起来像

Image description

Image description

执行i = 20;后,内存布局将看起来像

Image description

Image description

娱乐完成后执行变量i,并且内存布局看起来像

Image description

Image description

使用指针从函数进行修改。

Image description

在功能娱乐之前,内存布局看起来像

Image description

Image description
当我们调用函数趣味时,p的值存储在一个名为i的新变量中。

Image description

Image description

由于我存储相同的内存地址,因此指向相同的地址,因此P和我现在指向n。因此,当我们执行行 *i = 20时;我们修改了N和N的值现在容纳20。

Image description

Image description

当我们留下功能乐趣时,变量我被破坏了,但我的价值仍然20

Image description

Image description


#arrays

C中的数组是连续的存储区域,它们具有相同类型的许多值,并且数组的所有元素具有相同的类型。

声明数组

TYPE ARRAY_NAME[ARRAY_SIZE];

分配值
TYPE ARRAY_NAME[ARRAY_SIZE] = {ELEMENTS}

示例

int arr[5];

arr [0]将访问第一个元素,arr [1]第二个元素,依此类推。

在此示例中,计算机将为5个整数保留一个连续的空间。

Image description

Image description

内存布局看起来像

Image description


#pointers vs数组

数组不是指针,它们不容纳内存地址,但是数组的名称是数组的第一个元素的地址。

示例

Image description

Image description

因此,为什么在表达式中使用数组a时,该数组类型会自动将其隐式转换为指针到元素类型(数组类型decay)。

在两种情况下,此规则有两个例外:

  • sizeof()操作员

示例

Image description

Image description

  • &操作员

示例

Image description

Image description

#pointers算术

我们可以使用其他方法为 *(var + x)访问数组的元素,其中var是数组的名称,x是(x + 1)element。

示例

Image description

Image description

内存是布局

Image description


#strings

字符串实际上是由null字符'\ 0'''\ 0'终止的一维字符。

TYPE STRING_NAME[SIZE] = {ELEMENT}

示例

Image description

Image description

您可能会注意到我们使用了一个大小为6的数组,这是因为在C中,字符串以字符'\ 0'结束(ASCII值= 0)。

Image description


#C程序的会员布局

C程序的内存布局包含五个段:

  • 堆栈段

  • 堆段

  • bss(由符号启动的块)

  • ds(数据段)

  • 文本段

每个段都有自己的读,写和可执行的权限。如果程序试图以不允许的方式访问内存,则分割故障,这是一个常见的问题,会导致程序崩溃。

Image description

堆栈

堆栈包含来自函数,返回值的局部变量,每个函数都有一个堆栈帧。
该堆栈包含一个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; 
}

Image description

提示:NULL用于指针,这是没有地址的指示器,'\ 0'是ins for strings