码迷,mamicode.com
首页 > 编程语言 > 详细

附录一 再论指针和数组

时间:2016-04-28 20:08:50      阅读:334      评论:0      收藏: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

                预习检查

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

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

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

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

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\n" , i, P , *p);

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

printf("i=%d, p=%P , * p= %d\n" , 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%\n", 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)\n", (void* ) (p0 + 8)); return0; /* seeFAQXVI.4 */

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

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

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

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

}

struct stuff

struct stuff

ptrdiff_t

ptrdiff_t

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

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

printf ("The difference of pointers is %ld\n" , (long) diff) ; printf ("The difference of addresses is %ld\n" , (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:\n",m); p=find(score,m);

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

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

printf("%5.2f\t",*(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

 

附录一 再论指针和数组

标签:

原文地址:http://www.cnblogs.com/mitnick/p/5443713.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!