嵌入式笔记(一)

指针详解

c语言指针真正精髓的地方在于指针可以进行加减法,这一点极大的

提升了程序的对指针使用的灵活性,同时也带来了不小的学习负担。

正是因为c语言指针可运算,才奠定了如今c语言的地位。

一、指针

内存,作为计算机的存储核心,可以想象为一片广阔的仓库,其中整齐排列着无数大小统一、等距分布的存储单元。每个单元,即我们所说的“格子”,容量恰好为一字节,这是数据存储的基本元。为了让这个庞大的存储空间易于管理和访问,我们赋予了每个存储单元一个独一无二的编号,这就是内存地址。通过这个地址,无论是数据的存储还是检索,都能够精准而迅速地定位到具体的存储单元。想象一下,这就如同在一个图书馆中寻找一本书。每本书都有一个特定的索引号,通过这个索引号,读者可以轻松地在书架上找到所需的书籍。同样,在计算机的内存中,每个数据字节都拥有一个明确的"索引号",即内存地址,使得数据的存取变得井然有序。

通过这种方式,内存不仅成为了一个存储数据的场所,更成为了一个高效、可快速访问的信息中心。这种编号系统,使得内存的每一个“格子”都能够在需要时迅速被定位和访问,极大地提升了计算机处理数据的效率和速度。

内存地址是计算机世界中的邮政编码,它确保每一份数据都能被精确投递到正确的存储单元。在这个数字化的宇宙里,程序就像是邮递员,它们依赖这些地址来检索和分发信息。当程序需要访问内存中的某个数据片段时,它必须先找到那个独一无二的内存地址,然后才能取出或存入数据。

二、指针的初始化

①初始化为NULL: 将指针初始化为NULL(在C中)是一种安全的做法,可以避免未定义行为或野指针问题。

②初始化为具体的内存地址: 如果已经知道要指向的内存地址,可以直接将指针初始化为该地址。

③使用动态内存分配: 使用malloc(C)分配内存,并初始化指针指向这块新分配的内存。

④初始化为数组或字符串的地址: 指针可以初始化为数组或字符串的第一个元素的地址。

初始化为函数的地址: 指针可以指向函数,这在回调函数或函数指针数组中非常有用。

三、指针的运算

实际上指针运算只要掌握指针数据类型的差别,根据所占字节计算指针的步长即可。

四、指针与数组

  • 指针是一个变量,可以改变其指向的地址。
  • 数组名是一个常量,指向数组的第一个元素,且类型固定。

五、指针与字符串

C 语言中字符串并非像其它语言一样,将其设置为基本数据类型,而是构建于数组之上,并在数组末尾添加\0表示结尾,这也是为什么数组和字符串经常成对出现的原因。

六、函数指针

函数指针是C语言中一种特殊类型的指针,它指向一个函数的入口地址。使用函数指针可以在程序中动态地调用不同的函数,实现回调机制、多态性以及事件驱动编程等高级特性。

函数指针的定义--函数指针可以指向任何返回类型和参数列表的函数,其基本语法如下:

return_type (* pointer_name)(parameter_list);

注意事项

  • 确保函数指针的类型与指向的函数签名匹配。
  • 函数指针可以是NULL,在使用前应检查其是否已经被初始化。
  • 不同编译器可能对函数指针的表示方式有所不同,特别是在内存对齐方面。

七、NULL 指针

NULL指针是一个特殊的指针值,用于表示没有指向任何内存地址或对象的指针。在C语言标准中,NULL被定义为一个空指针常量,其值通常为整数0或宏定义为0的宏。其次,当我们使用 free 函数释放堆内存时,也应该将指针指向为 NULL,防止出现内存访问错误。

八、对复杂指针的解释

1. 指向指针的指针(多级指针)

指向指针的指针,即一个指针变量存储的是另一个指针变量的地址。这在处理多维数组、动态内存分配或实现某些数据结构(如链表、树)时非常有用。

int value = 10;
int *ptr = &value; // ptr是一级指针
int **ptr_to_ptr = &ptr; // ptr_to_ptr是指向一级指针的二级指针
2. 指针数组

指针数组是存储多个指针的数组。每个数组元素都是一个指针,可以指向不同的数据类型。

int arr1[5] = {1, 2, 3, 4, 5};
int arr2[5] = {6, 7, 8, 9, 0};
int *array_of_ptrs[] = {arr1, arr2}; // 存储数组arr1和arr2的地址
3. 函数指针数组

函数指针数组存储了指向具有相同签名的函数的指针。这允许程序根据不同的条件调用不同的函数。

void function1() { printf("Function 1\n"); }
void function2() { printf("Function 2\n"); }
void (*functionArray[])() = {function1, function2};
4. 指针的指针的应用
  • 多维数组的模拟:使用指针的指针可以模拟多维数组的内存布局。

  • 动态数据结构:如链表、树等,其中每个节点可能包含指向其他节点的指针。

  • 传递大型数据结构:通过传递指向大型数据结构的指针,而不是整个结构本身,可以减少内存消耗和提高效率。

5. 指针和动态内存分配

在C语言中,指针常用于动态内存分配。使用malloccalloc分配内存时,返回的是一个指向分配内存的指针。

int *dynamicArray = (int *)malloc(5 * sizeof(int)); // 分配一个整型数组

6. 指针与结构体

结构体中可以包含指针,指向其他数据或结构体,这在创建复杂数据类型时非常有用。

struct Node {
    int data;
    struct Node *next;
};

struct Node *createNode(int data) {
    struct Node *newNode = malloc(sizeof(struct Node));
    newNode->data = data;
    newNode->next = NULL;
    return newNode;
}

7. 指针的指针的注意事项

  • 确保在使用多级指针时正确地初始化每一级指针。
  • 在使用指针数组时,注意数组的大小和指针的生命周期。
  • 使用动态内存分配时,要记得释放分配的内存,避免内存泄漏。

 以上是我对指针的总结,欢迎对嵌入式感兴趣或者想要转行嵌入式的各位伙伴一起交流讨论! (私信看到就会回复) 同时为大家提供免费资料,欢迎大家私信dd我!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值