# 嵌入式C语言3--指针


5. 指针(指针变量,内存地址)。

指针就叫内存地址。变量里面记录的内存地址
语法: 数据类型 * 变量名;

    int a =10;
    int *p = &a;   // 标记p里存放的是内存地址。
        // *p 解引用运算,获取指针里面的值。
    *p = 200;  // 给a重新赋值200
    printf("%d\n", *p);      // 打印200.

指针变量占用的大小,根数据类型无关,根编译器有关。32位占4字节。64位系统占8字节。
给指针变量赋值的时候,不能把一个数值赋值给指针变量。
利用 *(借用运算符),可以查询数据,存储数据。

5.1 指针的作用:

  • 操作其他函数中的变量。 利用指针交换a、b的指针。
  • 函数返回多个值。
  • 函数的结果和计算的状态分开。
void getMaxAndMin(int arr[], int len, int* max, int* min){
    *max = arr[i];
    *min = arr[i];
}

int max = arr[0];
int min = arr[0];
getMaxAndMin(arr, len, &max, &min); //   

6. 指针高级

6.1 指针的运算。

int * p = 0x001; // 指针中数据类型的作用:获取字节数据的个数。
步长:指针移动依次的字节个数(看实际占用几个字节,int4字节)。
p+N; p-N; 往后或往前移动N个步长。

有意义的操作:

  • 指针跟整数进行加、减操作(每次移动N个步长)
  • 指针跟指针进行减操作(间隔步长数)

6.2 野指针,悬空指针

野指针:指针指向的空间未分配;
int *p2 = p1+10; // 野指针

悬空指针:指针指向的空间已分配,但是被释放了。

int *method() {
    int num =10;
    int *p = #
    return p;
}
int *p3 = method();
printf("%p\n", p3);
printf("%d\n", *p3);

总结:野指针,悬空指针 都可能导致数据异常。

6.3 void *p; 不代表任何类型。

特点:无法获取数据,无法计算,但是可以接受任意地址。
不同类型的指针之间,是不能互相赋值的。但是 void * 是特殊情况。
void *p3 = p1;
void *p4 = p2;

作用:swap数据,不限定数据类型。让它更有通用性。

void swap(void *p1, void *p2, int len) {
    // 把void类型,转char类型的。
    char* pc1 = p1;
    char* pc2 = p2;
    char temp = 0;
    
    // 以字节为单位,一字节一字节的交换。len字节的长度。
    for(int i=0; i<len; i++) 
    {
        temp = *pc1;
        *pc1 = *pc2;
        *pc2 = temp; // 交换字节中的数据。
        
        pc1++;
        pc2++;
    }
}
int c = 100;
int d = 200;
swap(&c, &d, 4); // 4是int 占据的字节数。

6.4 二级指针,多级指针。

指针数据类型:跟指向空间中,数据的类型是保持一致的。
二级指针:指向指针的指针。
int a; int* a; // 指针 int** a; // 二级指针。

int a = 10;  int b=20;
int* p = &a; // 定义一级指针
int** pp = &p; // 定义二级指针

*pp = &b; // 作用1:利用二级指针,修改一级指针里面记录的内存地址。
printf("%d\n", *pp); // 作用2:利用二级指针获取到变量中记录的数据。

6.5 数组和指针。

指向数组的指针,叫做数组指针。方便的操作数组中的各种数据。

include <stdlib.h>

include <time.h>

随机数
srand(time(NULL));
int num = rand() ;

// 生成一定范围的随机数。
int num = rand()%17 + 7; //7~24
int num = rand()%42+ 8; // 8~49
int num = rand()%100 +1;// 1~100

数组:

就是一个容器,可以用来存储同种数据类型的多个值。
数组作为参数传递的时候,传递的是数组的首地址。

int len = sizeof(arr)/ sizeof(arr[0]);
void printArr(int arr[], int len) {
for(int i=0;i<len;i++){
printf("%d\n", arr[i]);
}
}

// 利用数组的指针,遍历数组。

int main() {
    int arr[] = {1,5,4,3,2}; // 升序排序。
    int len = sizeof(arr)/sizeof(int);
    
    int* p1 = arr; // 数组的首地址。
    for(int i=0; i<len; i++) {
        printf("%d\n", *(p+i));
    }
}

6.6 数组指针的细节。

  • arr参与计算时,会退化为指向第一个元素的指针。指向数组的首地址。
    特殊情况:
  • sizeof 运算的时候,不会退化,arr还是整体;
  • &arr 获取地址的时候,不会退化。
    步长 = 数据类型 * 数组长度, // 每+1处理,跨越整个数组。比如二维数组遍历的场景。
    printf("%d\n", &arr +1); // 5*4=20

6.7 索引遍历数组。

int arr[m][n] ={{}, {}, {}}; // m是二位数组的长度;n是一维数组的长度

int arr1[3] = {1,2,3}; // 先定义一维数组。在放入到二维数组中。
int* arr[3] = {arr1, arr2, arr3}; // 存放不同长度的数组。
int len1 = sizeof(arr1) / sizeof(int);// 先计算数组长度,保存到长度数组中。
int lenArr[3] = {len1, len2, len3};  // 数组长度数组。
    
for(int i=0; i<3; i++) {
    for(int j=0; j<lenArr[i]; j++) {
        printf("%d", arr[i][j]);
    }
    printf("\n");
}   

6.8 指针遍历数组。

int (*p)[5] 二维数组里面的指针。
*p

int main() {
    int arr[3][5] = {
        {1,2,3,4,5},
        {11,22,33,44,55},
        {111,222,333,444,555},
    }; 
    // 二维数组里面存储的是一维数组 Int[5]
    int (*p)[5] = arr; // 数组指针:指向数组的指针。  步长为int*5(20字节)
    for(int i=0; i<3; i++) {
        // 遍历一维数组
        for(int j=0;j<5;j++) {
            printf("%d ", *(*p+j));
        }
        printf("\n");
        p++; // 移动二维数组的指针
    }
}

// 第二种格式。二维数组中存放的是内存地址。

int arr1[3] = {1,2,3,4,5};
int* arr[3] = {arr1, arr2, arr3}; // 指针数组:存放指针的数组。
int ** p = arr;
for(int i=0; i<3; i++) {
    // 遍历一维数组
    for(int j=0;j<5;j++) {
        printf("%d ", *(*p+j));
    }
    printf("\n");
    p++; // 移动二维数组的指针
}

6.9 函数和指针。

利用函数指针,动态的调用函数。灵活。

void method1() {
    printf("method1\n");
}
int method2(int num1, int num2) {
    printf("method2\n");
    return num1 +num2;
}
int main() {
    // 1.定义指针,指向两个函数。
    void (*p1)() = method1; // 指针p1指向method1.
    void (*p2)(int, int) = method2;
    // 2.利用函数指针,去调用函数
    p1();
    int result = p2(10, 20);
}

// 函数指针的使用。灵活使用。注意:只有形参完全相同,且返回值完全一样的函数,才能放到函数指针数组中。

int add(int num1,int num2) {
    return num1+num2;
}
int subtract(int num1,int num2) {
    return num1-num2;
}
int mutipy(int num1,int num2) {
    return num1*num2;
}
int divide(int num1,int num2) {
    return num1/num2;
}
int main() {
    // 定义数组,装4个函数的指针。函数指针数组。
    int (*arr[4])(int, int) = {add,subtract, mutipy,divide};
    int num1 = 10;
    int num2 = 20;
    int choose = 2;
    // 根据用户的选择,调用不同的函数。
    int res = (arr[choose -1])(num1, num2); // 函数的指针。
    printf("%d\n", res);
}

----End----

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,761评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,953评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,998评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,248评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,130评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,145评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,550评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,236评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,510评论 1 291
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,601评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,376评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,247评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,613评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,911评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,191评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,532评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,739评论 2 335

推荐阅读更多精彩内容