null程序设计技术程序设计技术C语言数据描述和C程序设计初步
结构化程序设计基础和C语言的控制结构
数组及其应用
函数与C程序结构
指针与函数
指针与数组
字符串及其应用
结构体类型和联合体类型
C语言的文件处理及其应用
位运算与枚举类型指针与数组 指针与数组 指针与数组的关系
指针数组与命令行参数
用指针构成动态数组 指针与数组的关系 指针与数组的关系 多级指针的概念
在程序设计语言中,占用连续空间的数据对象都与其所占存储区域的起始地址相关。
占用连续空间的数据对象有的表示的是线性的概念、有的表示的是平面的概念或是多维空间的概念。在计算机存储系统中对应的都是线性的连续空间区域,现在的问题是如何用表明存储系统中线性连续区域的起始地址表示的到底是几维空间的起始地址。
使用地址的不同级别来描述这些表示不同空间数据对象在存储上的首地址,其中用一级地址描述线性空间在存储上的首地址;用二级地址描述平面空间在存储上的首地址;地址就是指针,所以一级地址、二级地址、多级地址又分别称为一级指针、二级指针和多级指针。指针与数组的关系 指针与数组的关系 多级指针变量的定义
二级指针变量的定义形式如下:
[存储类别符] 数据类型符 **指针变量名;
三级指针变量的定义形式如下:
[存储类别符] 数据类型符 ***指针变量名;
更高级别的指针变量的定义形式按照上述形式类推,只需增加更多的星号即可。
int x=100,*y,**z;
y=&x;
z=&y;指针与数组的关系 指针与数组的关系 多级指针变量的引用
例6-1 多级指针变量的引用示例。
指针与数组的关系 指针与数组的关系 一维数组与指针的关系
一维数组元素与指针的关系
定义合适的指针变量后,可以使用指针变量指向数组中的任何一个数组元素。
指针与数组的关系指针与数组的关系一维数组与指针的关系
指针变量的算术运算
对于指向数组的指针变量而言,当对指针变量进行加减一个整型常量以及自增/自减运算时,实质上就是将指针变量的指向沿着数组所占据的存储区域向前和向后移动多个或者是一个数组元素的位置。int a[10]={0},*p1=a,*p2=a;
p1+=3;
*p1=100;
p2=&a[9];
p2-=3;
*p2=200;
p1--;
p2++;
*p1=1000;
*p2=2000;000000000010020002001000指针与数组的关系指针与数组的关系一维数组与指针的关系
指针变量的算术运算
对于两个同类型指针变量相减的操作,也只有在这两个指针变量指向同一连续的存储区域时才有实际意义。
两个指针变量差值的绝对值表示了两个指针之间存在着多少个它们所能够指向的数据对象,当然也可以由此计算出两个指针之间距离的字节数。
int a[10]={1,2,3,4,5,6,7,8,9,10},*p1=a,*p2=a+5; 234567891015个整型数据
(20个字节)例6-2 随机生成一个数组的所有元素,并用指针移动的方式输出这些元素值。 指针与数组的关系 指针与数组的关系 一维数组与指针的关系
一维数组与指针的关系
当定义指向数组的指针并使其指向了一个数组后,在指针没有移动的情况下(即指针始终指向数组的0号元素),对该数组某个元素(如i号元素)的地址和元素值而言分别有三种等价的表示形式:等价的地址表示形式 等价的元素表示形式 &a[i] a[i] a+i *(a+i) p+i *(p+i) 指针与数组的关系 指针与数组的关系 一维数组与指针的关系
数组名与指向数组的指针变量的区别
虽然用数组名和指针变量都可以表示数组,但它们之间有一个根本的区别:
数组名是地址常量,任何想改变其值的运算都是非法的,例如:a=p、a++等;
指针变量的值是可以改变的,例如:p=arr、p++等都是有意义的操作。
例6-3 使用不同的指针形式引用一维数组元素示例。指针与数组的关系 指针与数组的关系 一维数组与指针的关系
指向数组的指针变量作函数的参数
数组名和指向数组的指针都表示地址,作为参数传递时都表示传递某一对象地址,可根据需要混合使用;
函数的形参无论使用的是数组形式还是指针形式,本质上都是一个指针变量,在被调函数中既可以将它当作指针变量使用也可以将它当作数组名使用。
例6-4 使用选择排序法将一组数据按降序排列,要求被排序数组用随机函数生成,排序功能在自定义函数内进行实现,并且要求函数的数组类形式参数和函数中对数组的操作都使用指针变量形式。
指针与数组的关系 指针与数组的关系 二维数组与指针的关系
二维数组中的地址表示形式
一个二维数组a被认为是由若干个名字分别为: a[0]、a[1]、a[2]…、a[i]、…的一维数组组成。一维数组的名字代表了该一维数组的首地址,即该一维数组0号元素的地址,可以表示为a[i]和&a[i][0]两种等价形式。
按照地址加法的规则,一维数组a[i]的j号元素地址可以表示为a[i]+j和&a[i][j]两种等价形式。由于a[i]等价于*(a+i),所以有二维数组a的i行j列元素地址的等价表示形式:a[i]+j、*(a+i)+j和&a[i][j]。 指针与数组的关系 指针与数组的关系 二维数组与指针的关系
二维数组中i行首地址的不同级别表示形式
对于二维数组a而言,a[i] 、a+i和*(a+i)都是数组a的i行的首地址,其表示意义不同之处在于:
a+i方式将二维数组看成一个用一维数组作为元素的一维数组,指针移动的方向是按每次移动过二维数组中一行(即一个一维数组);
*(a+i)方式将数组看成若干个简单变量元素组成的。指针移动方向是每次移动二维数组中的一列(即以个元素); a+i形式指针移动方式*(a+i)形式指针移动方式每次移动过一行元素每次移动过一个元素指针与数组的关系 指针与数组的关系 二维数组与指针的关系
二维数组存储始址的表示形式
二维数组a所占存储区域的首地址有四种表示方式,它们是: a、a[0]、&a[0][0]和*a。这四种地址表示形式的地址级别是不同的,其中a表示二级地址,其地址单位是二维数组中一行数据所占据的存储单元字节数;其余三个都表示一级地址,其地址单位为一个数组元素所占据的存储单元字节数。所以,若要用指针来表示二维数组的地址关系,需要注意对应的地址级别。指针与数组的关系 指针与数组的关系 二维数组与指针的关系
指针指向特定的数组元素
设有:int a[3][4],*p=&a[2][2];
*p a[2][2]
指针指向二维数组首地址且未移动
设有:int a[3][4],*p1=a[0];
例6-5 使用不同的指针形式引用二维数组元素示例。指针与数组的关系 指针与数组的关系 指向由若干个元素组成的数组的指
程序设计中如果需要让指针的一次移动可以跨过所需要的数据对象个数,可以定义指向由若干个元素组成的一维数组的指针。定义指向由若干个元素组成的一维数组指针的一般形式为:
[存储类别符] 数据类型符 (*ptr)[常量表达式];
注:式中常量表达式的值就是指针所需要跨过的元素个数;
例: int (*ptr)[10];
定义了指针变量ptr;
指针ptr的一次移动可以移动过10个整型数据所占用的连续存储区域; 例6-6 使用指向由若干个元素组成的一维数组的指针处理二维数组。
例6-7 指向若干个元素组成的一维数组指针变量作函数形式参数(求二维数组中全部元素之和)。
指针与数组 指针与数组 指针与数组的关系
指针数组与命令行参数
用指针构成动态数组 指针数组与命令行参数 指针数组与命令行参数 指针数组
指针数组的概念
如果有一组指向同一类型数据的相关指针也可以对它们使用数组这种数据结构,每一个元素都是指针的的数组称为指针数组。
指针数组定义的一般形式为:
[存储类型] 数据类型 *数组名[常量表达式];
指针数组初始化
[存储类型] 数据类型 *数组名[常量表达式]=
{字串常量1,字串常量2,…};
指针数组与命令行参数 指针数组与命令行参数 指针数组
用指针数组组织若干同类型的数组
例:int a[4],b[5],*p[2];
p[0]=a;
p[1]=b;
用指针数组组织若干同类型的变量
例: double x,y,*p1[2];
p1[0]=&x;
p1[1]=&y;
例6-8 用一维指针数组处理二维数组示例。指针数组与命令行参数 指针数组与命令行参数 指针数组
例6-9 编制程序解决下述问题:5个学生,每人所学课程门数不同(成绩存放在一维数组中,以-1表示结束),编写程序输出他们的各项成绩。
指针数组与命令行参数 指针数组与命令行参数 命令行参数
命令行参数的概念
为了使程序运行时能从系统接收参数,C语言提供了程序在主函数中接收从命令行传递过来的实参的能力,这种参数称为命令行参数。为了接收命令行参数,在定义主函数时使其带上形式参数,其一般形式为:
void main(int argc,char *argv[])
主函数的形式参数
整型参数用于记录命令行输入的参数个数,习惯于用标识符argc表示;
指向字符的指针数组argv参数用于存放命令行上输入的各实参字符串的起始地址,即指针数组的每一个元素指向一个由命令行上传递而来的字符串。指针数组与命令行参数 指针数组与命令行参数 命令行参数
例如,若有C源程序文件为echo.cpp,则编译连接后的执行文件echo.exe,若其源文件中主函数头形式为:
void main(int argc,char *argv[]),
执行程序时命令行为:
echo file1.txt file2.txt
则参数传递的结果为:argc=3
例6-10 命令行参数的获取示例。指针数组与命令行参数 指针数组与命令行参数 命令行参数
使用命令行参数时的注意点
从命令行上带入的参数都是字符串,如果程序在功能上要求被带入的参数不是作为字符串使用,则需要在应用程序中进行合适的转换。
例6-11 编程序实现功能:在执行程序时从命令行上带入两个实型数据,在程序中求两个实数之和并输出。
指针与数组 指针与数组 指针与数组的关系
指针数组与命令行参数
用指针构成动态数组 用指针构成动态数组 用指针构成动态数组 动态数组的概念
动态数组就是可以在程序的运行过程中根据需要创建的数组数据对象。
在支持C99
标准
excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载
的C程序开发环境中,允许程序员根据在程序运行过程中提供的数组长度定义数组,亦即数组空间的分配在程序的运行过程中完成。
在不支持C99标准的C程序开发环境中,通过结合使用C语言的动态存储分配标准库函数和指针变量实现动态数组。用指针构成动态数组 用指针构成动态数组 C语言中的存储分配标准库函数
存储分配标准库函数malloc
函数原型
void *malloc(size_t size);
函数功能
在主存储器中分配由size所指定大小的存储块,返回所分配存储块在存储器中起始位置(指针)。返回指针类型为void(空类型),在应用程序中应根据需要进行相应的类型转换。如果存储器中没有足够的空间分配,即当存储分配失败时返回NULL。用指针构成动态数组 用指针构成动态数组 C语言中的存储分配标准库函数
存储释放标准库函数free
函数原型
void free( void *memblock );
函数 功能
释放由指针变量memblock指明首地址的由malloc类库函数分配的存储块,即将该块归还操作系统。
用指针构成动态数组 用指针构成动态数组 C语言中的存储分配标准库函数
重新分配存储标准库函数realloc
函数原型
void *realloc( void *memblock, size_t size );
函数功能
将以memblock值为首地址的存储块长度调整为size所指定的长度。分配成功时,若返回的新存储块首地址与由memblock确定的原首地址相同,则不需要进行原块内存放内容的拷贝;若返回的新存储块的首地址与memblock确定的原首地址不同,则需要将原块内存放内容的拷贝新分配的存储块中。
用指针构成动态数组 用指针构成动态数组 一维动态数组的建立和使用
实现一维动态数组的基本步骤
定义合适数据类型的一级指针变量。
调用C动态存储分配标准库函数按照指定的长度和数据类型分配存储。
将动态分配存储区域的首地址转换为所需要的指针形式赋值给对应的指针变量。
将指针变量名作为一维数组名操作。
例6-13 编制程序实现冒泡排序功能,程序中假定事先并不知道排序元素的个数。为了模拟数据程序中仍然要求被排序数组用随机函数生成。用指针构成动态数组 用指针构成动态数组 二维动态数组的建立和使用
实现二维动态数组的基本步骤
定义合适数据类型的二级指针变量。
按照指定的二维数组行数动态创建一维指针数组,并将其首地址赋值给二级指针变量。
以二维数组的列数为长度动态创建若干个(由行数决定)一维数组,并将其首地址分别赋值给指针数组中的对应元素。
将二级指针变量名作为二维数组名操作;
例6-14 二维动态数组的创建和使用示例。