当前位置: 首页 > news >正文

【嵌入式学习2】c语言重点整理

目录

## 重点掌握

1、数组

2、指针

3、结构体

4、函数

回调函数的常见用途

## 如何区分数组指针,指针数组,函数指针,结构体指针,指针偏移量


## 重点掌握

1、数组

https://blog.csdn.net/weixin_60546365/article/details/146476765

重点注意:

①数组逆置操作:

#include <stdio.h>
 
int main() {
    // 定义一个数组,同时初始化所有成员变量
    int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 
 
    int i = 0;  // 首元素下标
    int j = sizeof(a) / sizeof(a[0]) - 1;   // 尾元素下标
    int temp;
 
    while (i < j) {
        // 元素交换值
        temp = a[i];
        a[i] = a[j];
        a[j] = temp;
        // 位置移动
        i++;
        j--;
    }
 
    for (i = 0; i < sizeof(a) / sizeof(a[0]); i++) {
        printf("%d, ", a[i]);
    }
 
    return 0;
}

②数组与指针

#include <stdio.h>
 
int main() {
    int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    int i = 0;
    int n = sizeof(a) / sizeof(a[0]);
 
    for (i = 0; i < n; i++) {
        // * 和 [] 效果一样,都是操作指针所指向的内存
        // printf("%d, ", a[i]);
        printf("%d, ", *(a + i)); //a+i参考指针步长
    }
    printf("\n");
 
    // 定义一个指针变量保存a的地址
    int *p = a; 
    for (i = 0; i < n; i++) {
        // printf("%d, ", p[i]);
        printf("%d, ", *(p + i));
    }
    printf("\n");
 
    return 0;
}

2、指针

https://blog.csdn.net/weixin_60546365/article/details/146464990
①指针大小与数据类型无关:无论指针指向什么类型的数据(int、char、double等),指针本身的大小只取决于系统的位数(32位或64位)。
指针大小与系统架构相关:

  • 在32位系统上,指针大小为4字节。
  • 在64位系统上,指针大小为8字节。
  • 指针类型与数据类型的关系:虽然指针的大小与指向的数据类型无关,但在使用指针时,仍然需要确保指针类型与它所指向的数据类型匹配,以避免类型不匹配错误。

②指针加整数的含义

  • a 是一个指针,假设它指向一个数组的首地址;i 是一个整数。
  • a + i 表示将指针 a 向后移动 i 个单位。这里的“单位”是指指针所指向的数据类型大小。例如:
  • 如果 a 是一个指向 int 类型的指针,那么 a + i 表示将指针 a 向后移动 i * sizeof(int) 字节。
  • 如果 a 是一个指向 char 类型的指针,那么 a + i 表示将指针 a 向后移动 i * sizeof(char) 字节(sizeof(char) 通常为1字节)。

③野指针与空指针

  • 野指针:赋任意数值,没有意义 → 此指针指向区域未知
  • 空指针:赋值NULL,标志该指针没有任何指向

野指针不会直接引发错误,操作野指针指向的内存区域才会出问题

3、结构体

【嵌入式学习2】结构体-CSDN博客

①结构体使用:

  • 如果是结构体变量,通过 . 操作
  • 如果是结构体指针变量,通过 -> 操作

②结构体传参:

  • 传值是指将参数的值拷贝一份传递给函数,函数内部对该参数的修改不会影响到原来的变量
  • 传址是指将参数的地址传递给函数,函数内部可以通过该地址来访问原变量,并对其进行修改

4、函数

https://blog.csdn.net/weixin_60546365/article/details/146463482

回调函数:

  • 函数指针变量做函数参数,函数指针变量指向的函数就是回调函数
  • 回调函数可以增加函数的通用性,在不改变原函数的前提下,增加新功能
  • 这里定义了一个名为CallbackFunc的函数指针类型,它指向的函数返回类型为void,参数为一个int和一个char
typedef void (*CallbackFunc)(int, char);
#include <stdio.h>
 
// 定义函数,函数指针做形参
int calc(int a, int b, int (*p)(int, int)){
    // 通过函数指针变量调用函数,获取返回值
    int res = p(a, b);
    
    return res;
}
 
// 定义加法函数
int add(int x, int y) {
    return x + y;
}
 
// 定义减法函数
int sub(int x, int y) {
    return x - y;
}
 
int main() {
    int result;
 
    // 回调加法函数
    result = calc(1, 2, add);
    printf("result = %d\n", result);
 
    // 回调减法函数
    result = calc(10, 5, sub);
    printf("result = %d\n", result);
 
    return 0;
}
回调函数的常见用途
  • 事件处理

    在图形用户界面编程中,回调函数常用于处理用户的输入事件(如点击按钮、键盘输入等)。

  • 异步编程

    在异步操作(如文件读写、网络通信)完成后,通过回调函数通知调用者操作已完成。

  • 算法的扩展性

    在一些算法中,可以使用回调函数来提供自定义的处理逻辑,增强算法的灵活性。

## 如何区分数组指针,指针数组,函数指针,结构体指针,指针偏移量

数组指针:指向整个数组的指针

  • 数组指针指向的是整个数组的首地址,可以通过指针加偏移量访问数组中的元素
  • 数组指针的解引用可以得到整个数组
//这里p是一个指向包含10个int元素的数组的指针。
int arr[10] = {0};
int (*p)[10] = &arr; // p指向数组arr
printf("%d\n", (*p)[5]); // 访问数组arr的第6个元素

指针数组:数组的每个元素是指针

  • 指针数组本身是一个数组,其大小在声明时确定
  • 每个元素是一个指针,可以指向不同的变量或内存地址
//这里p是一个包含10个int指针的数组。
int a = 1, b = 2, c = 3;
int *p[3] = {&a, &b, &c}; // 指针数组p的每个元素分别指向a、b、c
printf("%d\n", *p[1]); // 输出b的值

函数指针:指向函数的指针

  • 函数指针可以指向函数,通过函数指针可以调用函数
  • 函数指针的类型必须与它指向的函数的类型一致
//这里p是一个指向返回值为int,参数为两个int的函数的指针
int add(int x, int y) {
    return x + y;
}
int (*p)(int, int) = add; // p指向函数add
printf("%d\n", p(3, 4)); // 通过函数指针调用函数,输出7

结构体指针:指向结构体变量的指针

  • 结构体指针可以通过指针访问结构体中的成员
  • 结构体指针的解引用可以得到整个结构体
//这里p是一个指向struct Student类型的结构体变量的指针
struct Student {
    int id;
    char name[20];
};
struct Student s = {1, "Alice"};
struct Student *p = &s; // p指向结构体变量s
printf("%d %s\n", p->id, p->name); // 访问结构体成员

指针偏移量:通过指针加偏移量访问内存中的数据

  • 指针偏移量通常用于访问数组中的元素或结构体中的成员
  • 偏移量的计算基于指针的类型和步长
int arr[5] = {1, 2, 3, 4, 5};
int *p = arr; // p指向数组arr的首地址
printf("%d\n", *(p + 2)); // 通过指针偏移量访问数组的第3个元素,输出3

相关文章:

  • Shiro漏洞攻略
  • c#处理算数溢出的情况
  • 【Android】我们是如何优化安卓应用大小至10MB以下的
  • 如何进行文件操作
  • 【QT】Qt creator快捷键
  • Ftrans飞驰云联受邀参加“2025汽车零部件CIO年会“并荣获智象奖
  • 【python】OpenCV—Hand Detection
  • Packaging Process
  • 【随手记】支持多模态输入的 AI Chatbot App
  • 抓包软件【Fiddler】
  • .Net SSO 单点登录方式
  • 软考笔记——操作系统
  • SAP GUI Script for C# SAP脚本开发快速指南与默认主题问题
  • 2、稳定排序二——插入排序
  • 注册中心之Nacos相较Eureka的提升分析
  • JavaScript中的宏任务和微任务
  • Spring框架漏洞攻略
  • MyBatis-Flex、MyBatis-Plus 与 Fluent-Mybatis 的比较分析
  • FastStoneCapture下载安装教程(附安装包)专业截图工具
  • 环境评价分析中土地利用现状图的制作方法
  • 国铁集团:全国铁路旅客发送量连续3天同比增幅超10%
  • 海港负国安主场两连败,五强争冠卫冕冠军开始掉队
  • 安徽两位新任地级市政府党组书记亮相
  • 十四届全国人大常委会举行第四十四次委员长会议
  • 宁波市纪委监委通报4起违反中央八项规定精神典型问题
  • 北京银行一季度净赚超76亿降逾2%,不良贷款率微降