zoukankan      html  css  js  c++  java
  • 附录一 再论指针和数组

                附录一

    附录一

    再论指针和数组

    再论指针和数组

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                    预习检查

    链表单元有哪几个部分组成

    如何申请链表单元,及释放链表单元

    实现单链表插入的基本语法

    简述一下快速排序基本理论要点

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                                                                 课程目标

    本章概述

    重点

    难点

    指针与数组什么时候相同 C语言为什么把数组参数当作指针 C语言的多维数组,及如何创建动态数组。

    本章目标

    掌握指针什么时候和数组相同,以为容易混淆的原因

    掌握多维数组的内存布局。

    使用指针向函数传递多维数组参数

    使用指针返回多维数组

    使用指针创建和使用动态数组

    指针和数组混淆的原因

    指针传递多维数组参数

    指针和数组混淆的原因

    创建和使用动态数组

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                 本章结构

    再论指针和数组

    再论指针和数组

    怎样使用数组

    怎样使用数组

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

    指针与数组不相同

    指针与数组不相同

    指针与数组相同

    指针与数组相同

    指针运算 指针运算

    指针数组和数组指针

    指针数组和数组指针

    函数指针和指针函数

    函数指针和指针函数

                      1 再论指针和数组 指针与数组的不相同

    指针与数组的相同

    怎样使用指针

    指针运算

    函数指针和指针函数

    指针数组和数组指针

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                    1.1 指针与数组的不相同 数组和指针是如何访问的

    数组访问指针数据

    使声明与定义相匹配

    数组和指针的其他区别

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                             1.1.1数组和指针是如何访问的

    申明区别

    extern int *x; -》声明x是个int型的指针

    extern int y[] -》y是个int型数组,长度尚未确定

    地址和内容的区别

    在这个上下文环境里 ,符号x的含义是x所 代表的地址。

    在这个上下文环境里, 符号Y的含义是Y所代表 的地址的内容。

    这被称为左值。

    这被称为右值。

    左值在编译时可知,

    右值直到运行时才知。

    左值表示存储结果的

    如无特别说明, 右值

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

    地方。 表示Y的内容

    X=Y

                                                        1.1.1数组和指针是如何访问的

    数组下标引用特点

    例:

    A

    运行步骤:

    地址在编译时可知

    直接进行操作

    数组:char a[9]=“abedefgh”; ... 取值:c=a[i]

    9980

    +1 +2 +3 +4 ... +i

    编译器符号表具有一个地址9980 嵌入式家园 www.embedclub.com

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

    1. i的值,将它与9980相加 2. 取地址(9980+i)的内容。

                                                       1.1.2 数组访问指针数据 指针访问特点

    B

    运行步骤:

    例:

    必须首先在运行时取得它的当前

    间接进行操作

    指针:char *p 取值:c=*p

    5081

    4642

    5081

    1. 取地址4624的内容,就是‘5081’ 2. 取地址5081的内容。

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git编译器符号表有一个符号p,它的

    地址为4624 git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                                            1.1.2 数组访问指针数据 数组访问指针特点

    C

    运行步骤:

    例:

    对内存进行直接的引用转化为间接引用

    数组:char a[9]=“abedefgh”; ... 取值:c=a[i]

    5081

    +1 +2 +3 ... +i

    4642

    5081

    1. 取地址4624的内容,即‘5081’2. 取得i的值,并将它与5081相加。 3. 取地址[508l+i]的内容。

    5081+i

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git编译器符号表有一个符号p,它的

    地址为4624 git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                          1.1.2 数组访问指针数据

    指针访问特点

    char *p=“abcdefgh”;...p[3] -》 d char a[]=”abcdefgh”; ...a[3] -》 d

    访问特点

    取得符号表中P的地址,提取存储于此处的指针。 把下标所表示的偏移量与指针的值相加,产生一个地址。 访问上面这个地址,取得字符。

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                            1.1.3 数组和指针的其他区别

    保存数据的地址

    指针 数组 保存数据

    间接访问数据,首先取得指针的内容

      ,把它作为地址,然后从这个地

      址提取数据。

    直接访问数据,a[I]只是简单地以a*1为地址取得 数据

    如果指针有一个下标[I],就把指针的 内容加上I作为地址,从中提取数 据

    通常用于动态数据结构 相关的函数为malloc(),free()

    通常用于存储固定数目且数据类型相同的元素。

    隐式分配和删除

    自身即为数据名

    通常指向匿名数据

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                     1.2 指针与数组的相同

    什么时候指针与数组相同 混淆的原因

    数组和指针规则 为什么C语言把数组形参当作指针 数组与指针归纳总结

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                                   1.2.1 什么时候指针与数组相同 数组运用特性

    数组声明

    外部数组(external array)的声明 数组的定义

    函数参数的声明

    运用特性 作为函数参数的数组名可以通过编译器转换为指针 使用数组时,数组可以写成指针 ,可以互换

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                          1.2.1 什么时候指针与数组相同 数组与指针

    编译器处理时是不同的 一个数组就是一个地址 一个指针就是一个地址的地址

    在运行时的表示形式也是不一样的 可能产生不同的代码

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                1.2.2 数组和指针混淆的原因 分析:

    char my _array[10]

    char* my_ptr ;

    ...

    j = strlen(my_array);

    J = strlen(my_ptr);

    printf(”%s %s”,my_ptr,my_array);

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                1.2.2 数组和指针混淆的原因 数组和指针是相同的规则

    表达式中的数组名(与声明不同)被编译器当作一个指向该数组第一个元素 的指针1。

    下标总是与指针的偏移量相同

    在函数参数的声明中,数组名被编译器当作指向该数组第一个元素的指

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                   1.2.3 数组和指针规则

    “表达式中的数组名”就是指针 C语言把数组下标作为指针的偏移量 “作为函数参数的数组名”等同于指针

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                                                 1.2.3.1 “表达式中的数组名就是指针

    数组下标的引用

    一个指向数组的起始地址的指针加上偏移量” 下标值的步长调整到数组元素的大小

    整型数的长度是4个字节,那么a[i+1]和a[i]在内存中的距离就是4(而不是1)

    例:访问a[i]: int a[10];

    int*p; Int i=2 ;

    p = a;

    访问数组第i个元素的三张方式 p = a;

    p = a+i; *p;

    p[i];

    *(p+i);

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                               1.2.3.1 “表达式中的数组名就是指针 数组的引用不能用指向该数组第一个元素的指针规则

    数组作为sizeof()的操作数一显然此时需要的是整个数组的大小,而不是 指针所指向的第一个元素的大小。

    使用&操作符取数组的地址。 数组是一个字符串(或宽字符串)常量初始值。

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                 1.2.3.2 C语言把数组下标作为指针的偏移量 数组访问模式分析

    数组访问

    for(i=0;i<10;i++)

    [R2]装入R3

    A[i]=0;

    如果需要,对R3的步长进行调整把 R1+R3

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

    把左值(a)装入Rl(可以提到循环外)

    把左值(i)装入R2(可以提到循环外)

    的结果装入R4中 把0存储到[R4]

                                 1.2.3.2 C语言把数组下标作为指针的偏移量 数组访问模式分析

    p=a;

    把左值(i)装入R2(可以提到循环外)

    指针备选方案1

    for(i=0;i<10;i++)

    [R2]装入R3

    p[i]=0;

    把左值(p)装入R0(可以提到循环外)

    [R0]装入Rl(可以提到循环外)

    如果需要,对R3的步长进行调整

    R1+R3的结果装入R4中 嵌入式家园 www.embedclub.com

    0存储到[R4]。 git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                 1.2.3.2 C语言把数组下标作为指针的偏移量 数组访问模式分析

    p=a;

    把左值(i)装入R2(可以提到循环外)

    指针备选方案1

    for(i=0;i<10;i++)

    [R2]装入R3

    *p++=0;

    把左值(p)装入R0(可以提到循环外)

    [R0]装入Rl(可以提到循环外)

    如果需要,对R3的步长进行调整

    R1+R3的结果装入R4中 嵌入式家园 www.embedclub.com

    0存储到[R4]。 git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                 1.2.3.2 C语言把数组下标作为指针的偏移量 数组访问模式分析

    p=a;

    指针备选方案2

    [R0]装入Rl *(p+i)=0; 0存储至U[R1]

    for(i=0;i<10;i++)

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

    P所指对象的大小装入R5 (可以提到循环外)

    把左值(p)装入Rl(可以提到循环外)

    R5+R1的结果装入Rl Rl存储到[R0]

                                     1.2.4 为什么C语言把数组形参当作指针 数组运用特性

    数组声明

    外部数组(external array)的声明 数组的定义

    函数参数的声明

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                    1.2.4 为什么C语言把数组形参当作指针

    出于效率的考虑 ???

    传值调用与传址调用

    C语言形参特性 非数组形式的数据实参均以传值形式

    拷贝整个数据

    拷贝整个数组,在时间上还是在内存空间上的开销都非常大

    所有的数组在作为参数传递时都转换为指向数组起始

    地址的指针,而其他的参数均采用传值调用

    函数的返回值绝不能是一个函数数组,而只能是指向

    数组或函数的指针

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                1.2.4 为什么C语言把数组形参当作指针 例:

    展示了对一个下标形式的数组形参进行访问所需要的几个步骤。

    Func(char p[]); ... c=p[i]

    Func(char *p); ... c=p[i] 编译器符号表显示p可以取址,从堆栈指针sp偏移14个位置运行时

    步骤1:从sp偏移14个位置找到函数的活动记录,取出实参。 步骤2:取i的值,并与5081相加。 步骤3:取出地址(508+i)的内容。

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                          1.2.4 为什么C语言把数组形参当作指针 数组,指针实参的一般用法

    调用时的实参

    类 型

    通常目的

    func(&my_int); func(my_int_ptr); func(my_int_array);

    一个整型数的地址

    指向整型数的指针

    整型数组

    一个int参数的传址调用

    传递一个数组 func(&my_int_array[i]) 一个整型数组某个元素的地址 传递数组的一部分

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

    传递一个指针

                    1.2.5 数组与指针归纳总结 用a[i]这样的形式对数组进行访问总是被编译器“改写”或解

    释为像*(a+1)这样的指针访问。 指针始终就是指针。它绝不可以改写成数组。

    在特定的上下文中,也就是它作为函数的参数(也只有这 种情况),一个数组的声明可以看作是一个指针。作为函数 参数的数组(就是在一个函数调用中)始终会被编译器修改 成为指向数组第一个元素的指针。

    当把一个数组定义为函数的参数时,可以选择把它定义为

    数组,也可以定义指针。不管选择哪种方法,在函数内部

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git事实上获得的都是一个指针。

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git定义和声 必须 配

                   1.3 怎样使用数组

    多维数组

    向函数传递一个多维数组

    从函数返回一个数组

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                    1.3.1 多维数组

    多维数组特性

    多维数组内存布局

    如何分解多维数组

    如何对数组进行初始化

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                    1.3.1.1 多维数组特性

    定义和引用多维数组惟一的方法就是使用数组的数组 注意:a[i][j][k] 与 a[I,j,k] 多维数组看作是一种向量

    多维数组的定义

    声明一个10×20的多维字符数组 char carrot[10][20];

    或者声明一种看上去更像“数组的数组”形式: typedef char vegetable[20];

    vegetable carrot[10];

    不论哪种情况,访问单个字符都是通过carrot[i][j]的形式, 编译器在编译时会把它解析为*(*(carrot+i)+j)的形式

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                                                      1.3.1.2 多维数组的内存布局

    多维数组内存布局 pea[1][2]的内存表示:线性存储 表达式为:*(*(pea+i)+j)

    Pea[1][2]

    ‘a’

    ...

    Pea[0] 嵌入式家园Peaw[1w]w.embedcluPbe.cao[o1m] git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

    Pea[0] [1] [2] [3]

    ‘a’

    Pea[1]

                                                             1.3.1.3 如何分解多维数组

    分解特点:

    多维数组是如何分解为几个单独的数组的

    多维数组每一个单独的数组都可以看作是一个指针

    不能把一个数组赋值给另一个数组

    多维数组分解

    int apricot[2][3][5] sizeof(apricot) 区域

    sizeof(apricot[i]) sizeof(apricot[i][j]) sizeof(apricot[i][j][k])

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                           1.3.1.4 如何对数组进行初始化 嵌套的花括号进行初始化多维数组

    如1

    short cantaloupe[2][5]={ {10,12,3,4,一5}, {31,22,6,0,-5}, };

    如2

    int rhubarb[][3]={{0,0,0},{1,1,1},};

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                          1.3.1.4 如何对数组进行初始化 建立指针数组进行初始化多维数组

    如1

    char vegetables[ ][9] = { “carrot”,

    只有字符串常量才可以初始化指

    针数组

    “celery”, “corn”, “cilantro”,

    指针数组不能由非字符串的类型

    如2 “crispyfriedpatatoes”}

    int *weights[]={ {1,2,3,4,5},

    char *vegetables[]= { “carrot”,

    };

    “celery”,

    “corn”,

    “cilantro”,

    嵌入式家园 www.embedclub.com

    “crispy fried patatoes” }

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

    直接初始化

    {6,7}, {8,9,10}

                      1.3.1.4 如何对数组进行初始化 建立数组进行初始化多维数组

    如:

    int row_1[]={1,2,3,4,5,-1}; /*1是行结束标志*/ int row_2[]={6,7,-1};

    int row_3[]={8,9,10,-1};

    int *weight[]=

    {

    row_1,

    row_3 };

    row_2,

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                       1.3.2 向函数传递一个多维数组 方法1

    例子

    模式:my_function(int my_array[10][20]);

    特点: 最简单的方法

    作用最小的

    int a[3][3] =

    };

    {3, 3, 3}

    Func(a[3][3]);

    int a[3][3] =

    Main() {Main()

    {{

    {1, 1, 1},

    {

    ......

    };

    ......

    {1, 1, 1},

    ......

    // 函数调用

    {2, 2, 2},

    {2, 2, 2},

    {3, 3, 3}

    // 函数调用 Func(a[3][3]);

    // 函数定义 // 函数定义

    ...... 上海嵌{......} -开发板商城 http://embedclub.taobao.com/

    嵌入式家园 www.embedclub.c}omvoid Func(int array[3][3]); }

    void Func(int array[3][3]);

    { ...... }

                                  1.3.2 向函数传递一个多维数组 方法2

    模式:my_function(int my_array[][20]) ; 例:

    方法3 (指针传递模式) 模式:my_function(char **my_array)

    int a[3][3] = {int a[3][3] =

    Main() {Main()

    };

    {3, 3, 3}

    // 函数调用 Func(a);

    {

    {1, 1, 1},

    };

    Func(a);

    {1, 1, 1},

    {

    ......

    {2, 2, 2},

    ......

    // 函数调用

    {2, 2, 2},

    {3, 3, 3}

    // 函数定义 // 函数定义

    ......

    嵌入式家园 www.embedclub.com

    void Func(int **array); } void Func(int **array);

    }

    { ...... }

    上海嵌{......} -开发板商城 http://embedclub.taobao.com/

    ......

                            1.3.3 从函数返回一个数组

    怎样返回一个数组

    例:

    一个指向任何数据结构的指针

    一个指向数组的指针

    int(*pal())[20]; int(*pal())[20] {

    }

    return pear;

    嵌入式家园 www.embedclub.com

    /*声明一个指向包含20int元素的数组的指针*/ int(*pear)[20];

    pear=calloc(20,sizeof(int)); if(!pear)longjmp(error,1);

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                阶段小节

      数组在什么时候和指针相同

      数组与指针混淆原因是什么

      数组当作函数传递的好处是什么   如何向一个函数传递一维数组

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                    1.4 指针运算

    什么是间接引用

    最多可以使用几层指针

    void指针与空指针 指针运算

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                            1.4.1 什么是间接引用

    间接引用: 指向变量或内存中的对象的指针 指针就是对对象值的间接引用

    一个间接引用的例子

    #include <stdio.h> Int main()

    {

    int i;

    int * p ; i = 5;

    p=&i; /* now *p==i */

    /* %PisdescribedinFAQVII.28*/

    printf("i=%d, p=%P , * p= %d " , i, P , *p);

    *p=6; /* sameasi=6 */

    printf("i=%d, p=%P , * p= %d " , i, P , *P);

    return0; /* seeFAQXVI.4 */}

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

    }

                                       1.4.2 最多可以使用几层指针

    一个指针时最多可以包含几层间接引用

    至少可以有12层 如:

    不要使用两层以上的指针

    int i=0;

    int * ip0l

    = &d;

    = &ip01;

    int ** ip02

    int ***ip03

    = &ip02; = &dp03;

    int **** ip04

    int ***** ip05

    = &ip04;

    最多可以使用多少层指针而不会使程序变得难读

    int ****** ip06 = &ip05;

    int ******* ip07 = &ip06;

    程序运行时最多可以有几层指针

    无限层

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                  1.4.2 最多可以使用几层指针 例:一个有无限层间接引用的循环链表

    /*Would run forever if you didn't limit it to MAX */ # include <stdio. h>

    struct circ_list

    {

    # define MAX 20 main()

    {

    char value[ 3 ];

    struct circ_list * next; };

    int i = 0;

    struct circ_list while (i <=MAX)

    *p = suffixes;

    struct circ_list suffixes[ ] = { "th",&.suffixes[1],/* Oth */

    {

    printf("%ds% ", i, p->value); + +i;

    p = p->next;

    "st",&.suffixes[2],/* 1st */

    "nd",&suffixes[3],/* 2nd */

    "rd",&suffixes[4],/* 3rd */

    "th", &.suffixes[ 5 ], / * 4th * /

    } }

    "th",&.suffixes[6],/* 5th */

    "th",&suffixes[7],/* 6th */

    "th",&suffixes[8],/* 7th */

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git"th", &suffixes[9],/* 8th */

    "th",&suffixes[0],/* 9th */};

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                   1.4.3 void指针与空指针

    什么是空指针 什么是void指针 NULL总是被定义为0吗

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                1.4.3.1 什么是空指针 空指针

    并不指向任何对象指针

    值是NULL , NULL可能是0,0L或(void*)0 绝对不能间接引用一个空指针

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                1.4.3.1 什么是空指针 空指针的用法

    用空指针终止对递归数据结构的间接引用

    用空指针作函数调用失败时的返回值

    用空指针作警戒值

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                                          1.4.3.2 什么是void指针

    void指针 通用指针或泛指针

    不属于任何类型

    常常用作函数指针

    内存操作

    内存操作 例子

    char *strepy(char‘strl,const char *str2);

    char *strncpy(char *strl,const char *str2,size_t n); void *memcpy(void *addrl,void *addr2,size_t n);

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                       1.4.3.3 NULL总是被定义为0吗 NULL与 0

    NULL不是被定义为0,就是被定义为(void *)0

    if(/* ... */) {

    p=NULL; }

    else {

    p=/* something else */; }

    /* ... */ if(p==0)

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                   1.4.4 指针运算

    两个指针可以相减吗

    把一个值加到一个指针上意味着什么

    两个指针可以相加吗

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                    1.4.4.1 两个指针可以相减吗 如果两个指针向同一个数组,它们就可以相减,其为

    结果为两个指针之间的元素数目

    如果两个指针不是指向一个数组,它们相减就没有意 义

    指针相减的结果是某种整类型的值

    ptrdiff_t

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                  1.4.4.1 两个指针可以相减吗 指针的相减运算

    # include <stdio. h> # include <stddef.h> struct stuff

    {

    main ( ) {

    char name[l6]; };

    * p8 = &-array[8];

    diff = p8-p0;

    addr.diff = (char * ) p8 - (char * ) p0;

    struct stuff array [] = {

    };

    printf ("p0 + 8 = %P (same as p8) ", (void* ) (p0 + 8)); return0; /* seeFAQXVI.4 */

    { "The" }, { "quick" },

    { "brown" }, { "fox" },

    { "jumped" }, { "over" }, { "the" }, { "lazy" }, {"dog." }, {""}

    addr_diff); printf ("p8-8 = %P " , (void*) (p8-8));

    }

    struct stuff

    struct stuff

    ptrdiff_t

    ptrdiff_t

    printf ("&array[0] = p0 = %P " , (void* ) p0);

    printf ("&. array[8] = p8 = %P " , (void* ) p8) ;

    printf ("The difference of pointers is %ld " , (long) diff) ; printf ("The difference of addresses is %ld " , (long)

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

    * p0 = &.array[0];

                  1.4.4.2 把一个值加到一个指针上意味着什么 当把一个整型值加到一个指针上后,该指针指向的位

    置就向前移动了一段距离

    这段距离对应的字节数等于该值和该指针所指向的对

    象的大小的乘积

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                           1.4.4.3 两个指针可以相加吗 两个指针是不能相加的

    如:

    p=(p+p2)-p1;

    正确的语句应该是: p=p+(p2-p1); 对此例来说,使用下述语句更好: p+=p2-p1;

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                   1.5 函数指针和指针函数

    指针函数

    函数指针

    函数指针的用法

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                             1.5.1 指针函数 定义:

    指带指针的函数,即本质是一个函数

    语法:

    返回类型标识符 * 返回名称(形式参数表) { 函数体 }

    特点:

    返回类型可以是任何基本类型和复合类型

    返回一个指针变量的值

    可以把整个函数看成一个变量

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                       1.5.1 指针函数 例子:

    #include “stdio.h” float *find(); main()

    {

    函数定义:

    }

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

    static float score[][4]={{60,70,80,90}, {56,89,34,45},

    /*定义指针函数*/

    float * find(float(*pionter)[4],int n)

    {

    {34,23,56,45}};

    float *pt;

    float *p;

    int i,m;

    printf("Enter the number to be found:"); scanf("%d",&m);

    printf("the score of NO.%d are: ",m); p=find(score,m);

    for(i=0;i<4;i++)

    pt=*(pionter+n); return(pt);

    printf("%5.2f ",*(p+i));

    }

                                             1.5.2 函数指针 定义:

    指向函数的指针变量 语法:

    数据类型标志符 (*指针变量名)(参数)

    特点:

    是指针变量

    指向类型为函数

    可用该指针变量调用函数

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                   1.5.2 函数指针 例子:

    函数定义:

    void main() {

    /*定义函数*/

    int max(int x,int y) {

    }

    int (*ptr)();

    int a,b,c;

    ptr=max;

    scanf("%d,%d",&a,&b); c=(*ptr)(a,b); printf("a=%d,b=%d,max=%d",a,b,c);

    return(x>y?x:y); }

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                      1.6 函数指针的用法

    定义函数指针类型

    // 定义一个原型为int Fun( int a );的函数指针 typedef int (*PTRFUN) ( int aPara );

    函数指针变量的定义

    PTRFUN pFun; // pFun 为函数指针变量名

    int (*pFun2) ( int a ); // pFun2也是函数指针变量名

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                     1.6 函数指针的用法

    函数指针作为函数的参数传递

    定义回调函数

    使用回调

    int CallBack( int a ){ return ++a;

    }

    定义回调者函数

    void Caller( PTRFUN cb ) // void Caller( int (*cb) ( int ) ) // 也可这样申明 {

    }

    int nPara = 1;

    int nRet = cb( nPara );

    void Test(){

    Caller( CallBack ); // 直接使用回调函数

    PTRFUN cb = CallBack; // int (*cb) ( int ); cb = CallBack;

    int nRet1 = cb( 99 ); // nRet1 = 100;

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

    }

                阶段小节

      指针在什么时候可以实现相加减   空指针与void指针

      指针函数的申明和赋值   函数指针的传递和调用   指针数组的定义和初始化

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                  本章总结

    再论指针和数组

    再论指针和数组

    深入具体的讲述指针的运算

    指针与数组不相同

    指针与数组不相同

    指针与数组相同

    指针与数组相同

    讲述了指针和数组的相同点,

    以及分析他们之间的混淆原因

    怎样使用数组

    怎样使用数组

    简单讲述了多维数组,并深入

     讲述数组和函数的应用

    指针运算 指针运算

    函数指针和指针函数

    函数指针和指针函数

    了解指针函数和函数指针的区

    别,并深入讲述函数指针的用

          法

    指针数组和数组指针

    指针数组和数组指针

    了解指针数组和数组指针的区

          别

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

    本节主要讲述了指针和数组

      的互访及其区别

                                                              实验项目

    题目

    写一个排序函数,要求实用两种参数传递模式。并采用函数指针

    调用模式实现的排序函数,并输入排序的最终结果

    实验目的

    回顾上章节的排序算法应用;

    数组的参数传递和数组及指针互用操作;

    函数指针的实现和调用;

    实验分析

    定义排序函数,采用传指针和传数组两种方式; 用typedef定义函数指针;

    调用函数指针;

    输出最终的排序结果;

    git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

  • 相关阅读:
    flowable的多人会签和一票否决
    排序
    Java数组的三种打印方式
    CF446B DZY Loves Modification(优先队列)
    2019CCPC哈尔滨 Interesting Permutation(思维)
    2019沈阳网络赛 Fish eating fruit (换根dp)
    AcWing287 积蓄程度(换根dp)
    CF1358E Are You Fired?(前缀和+贪心)
    android android studio error
    cocos2D-X 打包
  • 原文地址:https://www.cnblogs.com/askDing/p/5443713.html
Copyright © 2011-2022 走看看