指针数组及指向一维数组的指针讲解
专题7 数组和指针的应用
例1. 写出结果: main() { int *p1, a[10]={1,2,3,4,5,6,7,8,9,10} ; p1=a; printf(“%d ”,*p1); printf(“%d ”,*p1++); printf(“%d ”, *(p1+3)); printf(“%d ”,*++p1); printf(“%d ”,(*p1)++); printf(“%d ”,*p1--); printf(“%d ”,*p1); } 例2.若有定义语句:double x[5]={1.0,2.0,3.0,4.0,5.0},*p=x;则错误引用x数 组元素的是[08年9月] A)*p B)x[5] C)*(p+1) D)*x
[C] D) aa+1
(3)通过指针变量来表示数组中各元素的地址
可以定义一个指针变量来存放数组的指针或数组元素的指针,且指针变 量的基类型就是定义数组时的类型 int *p,a[10]; for(p=a,k=0; k<10;k++) p++; 将数据写入数组元素中几种方式: (1)for(p=a,k=0; k<10;k++) { scanf(“%d”,p); p++; } 进一步简化: (2)for(p=a,k=0; k<10;k++) scanf(“%d”,p++); 再进一步简化: (3)for(p=a,p-a<10; p++) scanf(“%d”,p); 以上三种写法是等价的,要掌握,能看懂。
2、 通过指针变量来引用一维数组元素 当指针变量指向数组中的某个数组元素时,可以通过“*”来访问其所 指向变量的数据。
指针和数组的关系
指针和数组的关系
指针和数组是C语言中非常重要的概念,理解它们对于编写高效程序和避免常见错误
至关重要。
指针和数组的关系可以说是紧密相连的,因为数组名本质上就是一个指针。
在C语言中,数组名表示一个指向该数组第一个元素的指针,也就是数组的起始地址。
因此,如果我们定义一个数组a,那么&a和a是等价的,都表示数组第一个元素的地址。
例如,定义一个整型数组a:
int a[5] = {1, 2, 3, 4, 5};
我们可以通过数组名a访问数组中的元素。
例如,a[0]表示数组中的第一个元素,即1。
在C语言中,数组名本身是一个常量,即不能对其进行修改。
但是,我们可以使用指
针来访问数组中的元素,这就需要对指针进行加减运算来实现。
我们可以定义一个指向数组a的指针p,然后通过指针访问数组中的元素。
例如,*p
表示指针p所指向的数组的第一个元素,即1。
我们可以通过p++将指针p指向数组中的下一个元素,例如*p++表示指向数组中的第二个元素,即2。
因此,数组名和指针在C语言中是紧密相关的,数组名本质上就是一个指向数组第一
个元素的指针。
我们可以通过指针访问数组中的元素,并通过加减运算实现对数组的遍
历。
在实际编程中,使用指针可以提高程序的效率和灵活性。
使用指针可以避免对数组名
的重复引用,从而减少程序的存储空间和运行时间开销。
但是,指针操作也比较容易出现指针越界、空指针等错误,因此在使用指针时需特别
注意,避免出现不必要的错误。
《c++程序设计》第7章 指针
(1)取地址运算符&: 取出变量的内存首地址
(2)指针变量的赋值: 指针变量=&变量;或指针变量=指针变量;
3.指针变量的引用
指针运算符* :通过指针变量间接访问变量对应存储单元内容。
【例7.1】定义指针变量
p、p1、q,并将变量a的 地址赋给p、p1,输出a、 p、p1、*p、*p1的值。
【例7.3】指针变量的自加、自减、加n和减n运算。例程
3.指针变量的关系运算
指针变量的关系运算是指针变量值的大小比较,即 对两个指针变量内的地址进行比较,主要用于对数组元 素的判断。
【例7.4】用指针变量求一维实型数组元素和,并输出数组每个元 素的值及数组和。 例程
4.指针运算符的混合运算与优先级
指针数组
例如,指针数组的定义: int *pi[4];
表示定义了由4个整型指针元素pi[0]、pi[1]、pi[2]、pi[3]组成的整型指针数组。 char *pc[4];
表示定义了由4个字符型指针元素pc[0]、pc[1]、pc[2]、pc[3]组成的字符型指针数组。 (3)指针数组元素的引用 【例7.15】用指针数组输出字符串
3.数组元素的引用
对一维数组a[ ]而言,当p=a时: ①第i个元素地址:&a[i]= p+i=a+i。 ②第i个元素值:a[i]= *(p+i) =*(a+i)=p[i]。
一维数组的第i个元素有四种方式引用: a[i]、*(p+i) 、*(a+i)、p[i]。
用数组指针的四种方法求一维数组中的最大值的方法为: 方法一:使用*(a+i)访问a[i] 方法一:用指针变量名p代替数组名a,即用 p[i]代替a[i] 方法二:移动指针变量p++,用*p访问a[i] 方法三:使用*(p+i)访问第 i个元素a[i]
一维数组与指针
一维数组与指针1 关于数组元素地址的说明:一维数组在内存储单元中是连续存放的。
数组名a代表数组的首地址即a[0]的地址,&a[0],是一个地址常量,是数组存储单元最开头第一个字节的地址。
既然是一个地址值就可以给指针变量Int a[5],*pa=a; (数组名即数组首地址赋给指针变量,指针变量指向数组首个元素)Int a[5],*pa=&a[0];(遇上面等价)。
Int a[5],*pa=&a[3];2 数组元素的引用(1)引用各个数组元素的地址值:①通过使用数组名定义一个数组a[5] 则a代表&a[0] a+1,a+2,a+3,a+4 依次代表&a[1],&a[2],&a[3],&a[4]。
这里要注意,a的值为地址值,且a为一个地址常量,是一个常量,不能用来赋值,自加自减等。
a+n的计算规则是地址值的计算规则,即当前地址值(可以用十进制表示)加上n乘以数组元素的数据类型所占的字节数,代表数组元素a[n]。
可以通过循环语句和scanf语句来将输入的数存放到一位数组中,即Int a[5];F0r(i=0;i<5;i++)Scang(“%d”,a+i);②通过指针如int a[5],*pa=a; 等价于int a[5],*pa=&a[0];Int a[5],*pa;For(pa=a,i=0;i<5;i++)Scanf(“%d”,pa++);或者For(pa=a,i=0;i<5;i++){Scanf(“%d”,pa);pa++;}或者For(pa=a;pa-a<5;pa++)Scanf(“%d”,pa);(2)引用各个数组元素所在的存储单元或存储单元里面的值①通过对数组名取内容运算符*即*(a+i)。
即a[0]可以用*(a+0)或者*a来引用,a[1]可以用*(a+1)来引用,一次类推。
可以逐个输出数组元素的值For(i=0;i<4;i++)Printf(“%d”,*(a+i);②通过对指针变量取内容运算*(p+i)③通过数组名后面跟下标即a[i]④通过指针变量后面跟下标pa[i],这里有个前提即pa使数组名a的地址及pa=a;3 总结:(1)引用数组元素的方式有:*(a+i) *(p+i) a[i] p[i](前提是p=a)(2)引用数组各个元素地址的方式有:a+i ,p+i ,&a[i] , &p[i](前提是p=a)(3)注意a与p的区别,a是不可变的,而p中的地址是可以改变的,所以a++,a+=3,a=p,p=&a,都是非法的。
C语言指针数组介绍定义指针数组输入输出指针数组
C语言指针数组介绍定义指针数组输入输出指针数组C语言中,指针数组是一种特殊的数组类型,其中数组的每个元素都是一个指针。
指针数组允许我们存储和操作一组指针,以及通过指针访问和操作内存中的数据。
本文将介绍指针数组的定义、输入输出和常见用途。
1.定义指针数组定义指针数组的语法如下:```数据类型*数组名[大小];```其中,`数据类型`是指针指向的数据类型,`数组名`是指针数组的名称,`大小`是指针数组的大小(即元素个数)。
举个例子,如果想定义一个包含5个整型指针的指针数组,可以这样做:```int *ptrArray[5];```这个定义表示`ptrArray`是一个包含5个整型指针的数组。
输入指针数组的常见方式是使用循环结构逐个为数组元素赋值,可以使用`scanf`函数进行输入。
```for (int i = 0; i < size; i++)scanf("%d", &ptrArray[i]);```输出指针数组的常见方式是使用循环结构逐个打印数组元素的值,可以使用`printf`函数进行输出。
```for (int i = 0; i < size; i++)printf("%d\n", *ptrArray[i]);```注意这里要使用`*`操作符来访问指针指向的值。
3.指针数组的常见用途指针数组在程序设计中具有广泛的应用。
下面是一些常见的用途:-字符串数组:可以通过定义一个指针数组来存储一组字符串,每个元素都是一个指向字符串的指针。
```char *stringArray[5] = {"Hello", "World", "C", "Language", "Pointer"};```-函数指针数组:可以使用指针数组来存储不同函数的指针,以便在运行时根据需要调用特定的函数。
数组与指针
此外,还可通过算术元运算对指针进行移动, 此外,还可通过算术元运算对指针进行移动,来达到引用 其他数组元素的目的。 其他数组元素的目的。 a[0] p p &a[0] *p a[0] a[1] p+1 p+1 &a[1] *(p+1) a[1] a[2] P+2 p+2 &a[2] *(p+2) a[2] a[3] P+3 p+3 &a[3] *(p+3) a[3] a[4] p+4 p+4 &a[4] *(p+4) a[4]
a[0] a[1] a[2] a[3] a[4]
a
a a+1 a+2 a+3 a+4
a a+1 a+2 a+3 a+4
&a[0] &a[1] &a[2] &a[3] &a[4]
*a *(a+1) *(a+2) *(a+3) *(a+4)
a[0] a[1] a[2] a[3] a[4]
例3: main() { int a[5],*p,i; for(i=0;i<5;i++) scanf(“%d”,a+i); for(i=0;i<5;i++) printf(“%d”,*(a+i)); }
a[1] a[1][0] a[1][1] a[1][2]
此处, 的值与 的值与a[0]的值相同,但是基类型不同。a是二级 的值相同, 此处,a的值与 的值相同 但是基类型不同。 是二级 指针, 是一级指针。 指针,a[0]是一级指针。 是一级指针 a &a[0][0] a[0] 因此,以下赋值语句是错误的: 因此,以下赋值语句是错误的:p=a; a &a[0] a+1 &a[1] a+i &a[i] *(a+i) a[i]
指针指向数组的两种赋值方法
指针指向数组的两种赋值方法指针是C语言中非常重要的概念,它可以让我们更加灵活地操作内存中的数据。
在C语言中,数组也是非常重要的数据结构,它可以让我们更加方便地存储和操作一组数据。
在本文中,我们将介绍两种指针指向数组的赋值方法,分别是指针数组和数组指针。
一、指针数组指针数组是指一个数组,其中的每个元素都是一个指针。
这个指针可以指向任何类型的数据,包括数组。
下面是一个指针数组的定义:```int *arr[10];```这个定义表示一个包含10个元素的数组,每个元素都是一个指向int类型数据的指针。
我们可以通过下标来访问数组中的元素,例如:```arr[0] = (int *)malloc(sizeof(int) * 10);```这个语句表示在arr数组的第一个元素中分配了10个int类型的空间。
我们可以通过指针来访问这个空间中的数据,例如:```*(arr[0] + 1) = 10;```这个语句表示将arr数组的第一个元素中的第二个int类型空间的值设置为10。
我们也可以使用下标来访问这个空间中的数据,例如:```arr[0][1] = 10;```这个语句和上面的语句是等价的。
指针数组的优点是可以方便地存储和操作一组指针,例如我们可以使用一个指针数组来存储一组字符串:```char *strs[3] = {"hello", "world", "c language"};```这个语句表示定义了一个包含3个元素的指针数组,每个元素都是一个指向char类型数据的指针。
我们可以通过下标来访问数组中的元素,例如:```printf("%s\n", strs[0]);```这个语句表示输出strs数组的第一个元素,也就是字符串"hello"。
二、数组指针数组指针是指一个指针,它指向一个数组。
这个数组可以是任何类型的数据,包括指针。
指针数组
有关指针的数据类型和指针运算的小结 (1) )
一、有关指针的数据类型的小结 int I; 定义整型变量I 定义整型变量 int *p; p为指向整型数据的指针变量 为指向整型数据的指针变量 int a[n]; 定义整型数组a,它有n个元素 定义整型数组 ,它有 个元素 int *p[n]; 定义指针数组 ,它由 个指向整型数据的指针数 定义指针数组p,它由n个指向整型数据的指针数 据组成 int (*p)[n]; p为指向含 个元素的一维数组的指针变量 为指向含n个元素的一维数组的指针变量 为指向含 int f(); f为带回整型函数值的函数 为带回整型函数值的函数 int *p(); p为带回一个指针的函数,该指针指向整型数据 为带回一个指针的函数, 为带回一个指针的函数 int(*p)(); p为指向函数的指针,该函数返回一个整型值 为指向函数的指针, 为指向函数的指针 int **p; p是一个指针变量,他指向一个指向整型数据的指 是一个指针变量, 是一个指针变量 针变量
对指针变量 q , p 的定义: 的定义: int *q ; int **p;
指 向 指 针 的 指 针 (2) )
2、定义形式: 、定义形式: char **p;
p的前面有两个 号。*运算符的结合性是从左到右, 的前面有两个*号 运算符的结合性是从左到右, 的前面有两个 运算符的结合性是从左到右 **p相当于 相当于*(*p),显然 是指针变量的定义形式。 是指针变量的定义形式。 相当于 ,显然*p是指针变量的定义形式
一、指向指针的指针(二重指针)的概念 指向指针的指针(二重指针) 1、定义:指向指针数据的指针变量,简称为指向指针的指 、定义:指向指针数据的指针变量, 此指针中存放的是另外一个指针的地址。 针,此指针中存放的是另外一个指针的地址。 已知三个变量 a, q , p , 其中 为 int 型,p , q 为指针变量 其中a p a602 p=&q ; **p 为 a *p 为 q q ff3d a602 q=&a ; *q 为 a a 21 ff3d
数组指针的定义
数组指针的定义数组指针是一种特殊的指针类型,它可以指向数组的首地址。
在程序设计中,数组指针常常被用于处理数组的操作。
本文将从数组指针的定义、用途、操作等方面进行阐述,以帮助读者更好地理解和应用数组指针。
一、数组指针的定义数组指针是指向数组的指针变量,它可以存储数组的首地址。
在C 语言中,数组名就是一个指向数组首元素的指针,因此可以将数组名赋值给指针变量,这样指针变量就指向了数组的首地址。
例如,int arr[5]; int *p = arr; 这里,p就是一个指向arr数组的指针变量。
二、数组指针的用途数组指针在程序设计中有着广泛的应用,它可以用来实现数组的传递、访问和操作。
首先,数组指针可以作为函数参数,在函数中通过指针对数组进行修改,实现数组的传递和操作。
其次,数组指针还可以通过指针运算来访问数组的元素,例如通过*(p+i)的方式来访问数组的第i个元素。
此外,数组指针还可以用于动态内存分配和多维数组的处理等方面。
三、数组指针的操作使用数组指针时,可以通过指针运算来遍历数组的元素。
例如,可以使用指针变量p来遍历数组arr的所有元素,通过不断递增指针的值来访问数组的每个元素。
同时,可以使用指针变量p来修改数组的元素值,通过*p = value的方式来改变数组的元素值。
此外,还可以通过指针的比较来判断数组的边界,避免越界访问。
四、数组指针的注意事项在使用数组指针时,需要注意一些细节。
首先,数组指针的类型必须与指向的数组类型一致,否则会导致类型不匹配的错误。
其次,需要注意数组指针的初始化和赋值,确保指针变量指向有效的数组地址。
此外,还需要注意指针的引用和解引用的方式,以及指针的空指针判断和释放等问题。
五、总结数组指针是一种重要的指针类型,它可以用于实现数组的传递、访问和操作。
通过数组指针,我们可以方便地对数组进行遍历、修改和处理。
在程序设计中,熟练掌握数组指针的使用方法对于提高代码的效率和可读性非常重要。
指针与数组
3.通过一个行指针变量引用二维数组的元素
定义一个由m个元素组成的一维数组的指 针变量的一般形式:
类型标识符 (*指针变量名)[m];
注意:*p两侧的圆括号不可缺少。 例如:假若有语句 int a[2][3], (*p)[3]; p=a;
则:⑴ p是一个指向由3个整型元素组成的一 维数 组的指针变量。
方法ain() { int a[10]={54,65,8,2,3,56,8,21,57,98},i;
for(printf("\n"),i=0;i<10;i++) printf("%4d",*(a+i)); }
方法三:用指针变量指向数组元素
main() { int a[10]={54,65,8,2,3,56,8,21,57,98},*p,i;
⑵ p指向a数组,p+1指向数组a的下一行首地 址,a和p的基类型相同,则a数组中任意元 素a[i][j]还可以如下表示: *(p[i]+j) 、*(*(p+i)+j) 、(*(p+i))[j] 、p[i][j]
例:使用行指针变量访问数组元素。
main() {
float fa[5][10], (*pf)[10]=fa; int i,j; for(i=0; i<5; i++)
C语言程序设计
指针与数组
1.1 一维数组的指针
数组的指针 :是数组的起始地址。
数组元素的指针 :是数组元素的地址。 当指针变量指向数组或数组元素时,它就是指 向数组的指针变量。
C规定: ⑴数组名代表数组的首地址(起始地址),
也就是第一个元素的地址。
⑵当指针变量p指向数组时,p+1指向数组 的下一个元素。假设一个整型元素占两 个字节,p+1是使p的地址加2个字节。
【C语言】-指向一维数组元素的指针
【C语⾔】-指向⼀维数组元素的指针本⽂⽬录说明:这个C语⾔专题,是学习iOS开发的前奏。
也为了让有⾯向对象语⾔开发经验的程序员,能够快速上⼿C语⾔。
如果你还没有编程经验,或者对C语⾔、iOS开发不感兴趣,请忽略前⾯我们已经学习了指针,如果指针存储了某个变量的地址,我们就可以说指针指向这个变量。
数组及其数组元素都占有存储空间,都有⾃⼰的地址,因此指针变量可以指向整个数组,也可以指向数组元素。
⼀、⽤指针指向⼀维数组的元素1// 定义⼀个int类型的数组2int a[2];34// 定义⼀个int类型的指针5int *p;67// 让指针指向数组的第0个元素8 p = &a[0];910// 修改所指向元素的值11 *p = 10;1213// 打印第⼀个元素的值14 printf("a[0] = %d", a[0]);输出结果:,说明已经通过指针间接修改了数组元素的值,跟指向⼀个普通int类型变量是⼀样的。
由于数组名代表着数组的⾸地址,即a == &a[0],因此第8⾏代码等价于:// 让指针指向数组的第0个元素p = a;内存分析图如下,⼀个指针变量占⽤2个字节,⼀个int类型的数组元素占⽤2个字节⼆、⽤指针遍历数组元素1.最普通的遍历⽅式是⽤数组下标来遍历元素1// 定义⼀个int类型的数组2int a[4] = {1, 2, 3, 4};34int i;5for (i = 0; i < 4; i++) {6 printf("a[%d] = %d \n", i, a[i]);7 }输出结果:2.接下来我们⽤指针来遍历数组元素先定义⼀个指针,指向数组的第⼀个元素// 定义⼀个int类型的数组int a[4] = {1, 2, 3, 4};// 定义⼀个int类型的指针,并指向数组的第0个元素int *p = a;p的值是a[0]的地址,因此,现在我们利⽤指针p只能访问数组的第0个元素a[0],⽤*p就可取出a[0]的值1。
指针与数组
#include <stdio.h>
int main()
{ int a[6],i,s,*p;
printf("Please input data:\n");
for(i=0; i<6; i++ )
scanf("%d", &a[i] );
s=0;
for(p=a; p<a+6; p++) s+=*p ;
printf(“s=%d\n”,s);
8
指针与数组
❖指针运算:
指针类型的数据,除了间接引运算、赋值运算 p 2000
等操作外,当指针指向数组时,指针可以做
加减整数、指针相减及指针比较运算。
▪ 1.指针与整数的加、减运算
• 如果指针p是指向数组中的某个元素,加
p+3 2012
上整数n后,新指针p+n指向后续的第n个
a数组
1 2 3 4 5
a[0] a[1] a[2] a[3]
a[4]
元素。
a[5]
▪ 2.指针相减运算
a[6]
• 两个指向同个数组的同类型指针作相减运
a[7]
算,其绝对值表示它们之间相隔的元素数 目。
p+92036
a[8] a[9]
▪ 3.指针之间作关系运算
• 两个相同类型指针可作关系运算比较指针
大小。例8.5程序循环控制是通过 p<a+6
– 行指针a+2,转化为元素指针*(a+2),指向第3行第一个元素,即 a[2][0]。
– 行指针a+i,转化为元素指针*(a+i)+j,指向第i+1行第j+1一个元素, 即a[i][j]。
计算机二级等级考试C语言关于指针的讲解
如果有: 则内存情况如图8-1 如果有:int a=5;则内存情况如图 则内存情况如图 所示。 所示。 •a是存储单元(即变量)的名字, 是存储单元(即变量)的名字, • 5是存放在存储单元中的内容, 是存放在存储单元中的内容 是存放在存储单元中的内容, •存储单元的地址是2000。 存储单元的地址是 存储单元的地址 。
注意: 注意:
p++; /* 相当于 相当于p=p+1; */ 等价于*(p++) 特殊表达式: 特殊表达式: 不等价于(*p)++ *p++; 和 *p--; 先取用对象(*p),然后 自加减 自加减1 先取用对象( ,然后p自加减 ++*p;与 *++p; 完全相同 与 --*p;与*--p;完全相同 , 与 完全相同 这四种形式都是p先自加减 ,然后再取用对象 这四种形式都是 先自加减1,然后再取用对象 先自加减
本章考点
指针与指针变量的概念。 指针与指针变量的概念。 指针变量的运算。 指针变量的运算。 一维数组的地址、指向一维数组的指针及其应用。 一维数组的地址、指向一维数组的指针及其应用。 二维数组的地址、指向二维数组的指针及其应用。 二维数组的地址、指向二维数组的指针及其应用。 指针数组的概念及其应用。 指针数组的概念及其应用。 用指针表示字符串。 用指针表示字符串。 指针变量作为函数参数。 指针变量作为函数参数。 指向指针的指针变量及其应用。 指向指针的指针变量及其应用。 命令行参数的基本概念。 命令行参数的基本概念。
b[i] &b[i][0] 代表第 行0列元素的地址 代表第i行 列元素的地址 列元素的地址.
b b+1 b+2 则:b *b *(b+i)
指针二维数组的各种表示
指针二维数组的各种表示指针是C语言中的一种数据类型,它存储了一个变量的地址。
而二维数组是由多个一维数组组成的数据结构。
在C语言中,我们可以使用指针来表示二维数组。
本文将介绍指针二维数组的各种表示方法,包括指针数组、数组指针和指针的指针。
一、指针数组指针数组是一种由指针组成的数组,每个指针指向一个一维数组。
我们可以使用指针数组来表示二维数组。
假设有一个二维数组arr,它有m行n列,我们可以定义一个指针数组来表示它。
```cint *ptr[m];```这里ptr是一个指针数组,它有m个元素,每个元素都是一个指针,指向一个一维数组。
我们可以通过给每个指针赋值来初始化指针数组。
```cfor(int i=0; i<m; i++){ptr[i] = arr[i];}```二、数组指针数组指针是指向数组的指针,我们可以使用数组指针来表示二维数组。
假设有一个二维数组arr,它有m行n列,我们可以定义一个数组指针来表示它。
```cint (*ptr)[n];```这里ptr是一个数组指针,它指向一个有n列的一维数组。
我们可以通过给数组指针赋值来初始化它。
```cptr = arr;```三、指针的指针指针的指针是指向指针的指针变量,我们可以使用指针的指针来表示二维数组。
假设有一个二维数组arr,它有m行n列,我们可以定义一个指针的指针来表示它。
```cint **ptr;```这里ptr是一个指针的指针,它指向一个指针数组。
我们可以通过给指针的指针赋值来初始化它。
```cptr = (int **)malloc(m * sizeof(int *));for(int i=0; i<m; i++){ptr[i] = arr[i];}```四、比较与应用通过以上的介绍,我们可以看到指针数组、数组指针和指针的指针都可以用来表示二维数组。
它们各有优缺点,适用于不同的场景。
指针数组比较灵活,可以动态改变指针的指向,适用于需要频繁修改二维数组的情况。
指向数组的指针
如: int *ap(int x,int y)
{
......
}
表示 ap 是一个返回指针值的指针型函数,它返回的指针指向一个整型变量。
下例中定义了一个指针型函数 day_name ,它的返回值指向一个字符串。
该函数中定义了一个静态指针数组 name 。 name 数组初始化赋值为八个字符串,
#include <stdio.h>
main(){
int i;
char *day_name(int n);
printf("input Day No:\n");
scanf("%d",&i);
if(i<0) exit(1);
printf("Day No:%2d-->%s\n",i,day_name(i));
"Sunday"};
return((n<1||n>7) ? name[0] : name[n]);
}
在C语言程序设计中,无论规模多大的程序及复杂性如何,最终都要落实到每个小型函数的编写工作上。因此,C语言程序设计的基础工作是
函数的设计和编号,掌握C语言函数的特点及函数调用时参数变化的情形,无疑是一个很重要的编程基本技术。
如 int(*p)() 和 int *p() 是两个完全不同的量。 int(*p)() 是一个变量说明,
说明 p 是一个指向函数入口的指针变量,该函数的返回值是整型量,
(*p) 的两边的括号不能少。 int *p() 则不是变量说明而是函数说明,
说明 p 是一个指针型函数,其返回值是一个指向整型量的指针,
C语言程序设计第八章 指针的使用
第八章指针的使用【学习目标】本章将详细介绍在C语言中如何使用指针。
学习要点包括如下几点:(1)掌握指针和指针变量的概念,了解指针变量的特点以及直接访问数据和间接访问数据的原理。
(2)掌握指针变量的定义、赋值方法及指针运算符的使用,熟练运用指针访问简单变量。
(3)熟悉指针和一维数组的关系,掌握指向一维数组的指针变量的定义方法,熟练使用指针变量访问一维数组元素。
(4)了解指针与字符串的关系,能熟练使用指针处理字符串。
(5)熟练掌握用指针变量作函数的参数时函数的定义和调用方法、数组名作函数的参数用法。
(6)指向指针的指针的运用。
【学习导航】本章的在整个课程中的位置如图5-1所示。
图8-1 本章学习导航在本书的第一章介绍C语言有一个灵活性的特点,那么它的灵活性具体体现在哪里呢?其实就是指针。
指针是C语言的精华部分,通过利用指针,我们能很好地利用内存资源,使其发挥最大的效率。
有了指针技术,我们可以描述复杂的数据结构,对字符串的处理可以更灵活,对数组的处理更方便,使程序的书写简洁,高效。
8.1 地址和指针指针是C语言的一种数据类型,类似于整型、字符型等。
既然指针也是一种类型,那么也可以定义该类型的变量,称为指针变量。
指针变量和其他类型的变量的区别是:指针变量存储的是地址。
所以要学好指针,就一定要明白数据在内存中是如何存储的。
计算机所有数据都是存储在存储器里,系统的内存可看作编了号的小房间,如果要取房间的东西(读取数据)就需要得到房间编号。
地址就是内存区中对每个字节的编号。
下面通过两个整型变量来说明。
整型变量x、y(基本整型需4个字节)在内存中的存储如图8-2所示(假设内存编号是从2000开始)。
把变量所占用的存储单元首字节的地址作为变量的地址。
C语言中利用取地址运算符“&”获取变量的存储地址。
例如,&c将返回c的首地址;&x将返回x的首地址。
2000H2004H2008H2012H...图8-2 变量x和y在内存中的存储图8-2中2000H和2004H就是内存单元的地址。
指针数组和指向指针的指针
char *country[]={"China", "United States", "Japan", "Franch", "Britain"};
int i; stringsort(country,5); /*输出结果*/ for(i=0;i<5;i++) printf("%s\n", country[i]); }
char *str[3]; char **p; int i; str[0] = "Hello"; str[1] = "Bye"; str[2] = "To be or not to be"; p = str; for(i=0;i<3;i++)
puts(*(p+i)); }
1.2 指向指针的指针(续)
类型名 * 数组名[常量表达式];
int * p[4];
p[0]
3
p[1]
8
p[2]
p[3]
0
指针数组和指向指针的指针(续)
【例7-23】将若干字符串按字母顺序(由小到大)输出。
/*程序7-27*/ #include <stdio.h> #include <string.h> #define N 5 void main() {
1000 1004 1008 1012 1016
2000 3000 4000 5000 6000
1.2 指向指针的指针
❖ 指针数组作为数组,当然也可以通过指针的方式来访问其中的 元素。
【例7-24】通过指针访问指针数组 /*程序7-28*/ #include <stdio.h> void main() {
指针数组及指向一维数组的指针讲解
一、指针数组及指向一维数组的指针(数组指针)讲解1、数组指针(也称行指针)定义 int (*p)[n];()优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长。
也就是说执行p+1时,p要跨过n个整型数据的长度。
如要将二维数组赋给一指针,应这样赋值:int a[3][4];int (*p)[4];//该语句是定义一个数组指针,指向含4个元素的一维数组。
p=a;//将该二维数组的首地址赋给p,也就是a[0]或&a[0][0] p++;//该语句执行过后,也就是p=p+1;p跨过行a[0][]指向了行a[1][]所以数组指针也称指向一维数组的指针,亦称行指针。
2、指针数组定义 int *p[n];[]优先级高,先与p结合成为一个数组,再由int *说明这是一个整型指针数组,它有n个指针类型的数组元素。
这样赋值是错误的:p=a;只存在p[0]、p[1]、p[2]...p[n-1],而且它们分别是指针变量可以用来存放变量地址。
但可以这样 *p=a; 这里*p表示指针数组第一个元素的值,a的首地址的值。
如要将二维数组赋给一指针数组:int *p[3];int a[3][4];for(i=0;i<3;i++)p[i]=a[i];这里int *p[3] 表示一个一维数组内存放着三个指针变量,分别是p[0]、p[1]、p[2]所以要分别赋值。
这样两者的区别就豁然开朗了,数组指针只是一个指针变量,似乎是C语言里专门用来指向二维数组的,它占有内存中一个指针的存储空间。
指针数组是多个指针变量,以数组形式存在内存当中,占有多个指针的存储空间。
还需要说明的一点就是,同时用来指向二维数组时,其引用和用数组名引用都是一样的。
比如要表示数组中i行j列一个元素:*(p[i]+j)、*(*(p+i)+j)、(*(p+i))[j]、p[i][j]优先级:()>[]>*例1、下列给定程序中,函数fun()的功能是:从N个字符串中找出最长的那个串,并将其地址作为函数值返回。
拓展知识7-3 指向一维数组的指针变量
拓展知识7-3 指向一维数组的指针变量一级指针变量可以指向普通变量、一维数组元素;二级指针变量可以指向一级指针变量,还可以指向一维数组。
指向一维数组的指针变量定义的一般形式:数据类型(*变量名)[常量表达式];定义中的一对圆括号不能省,否则将变成定义指针数组。
该定义是定义一个指向含有常量表达式的值个元素的一维数组的指针变量,指向一维数组的指针变量是一个二级指针变量。
【示例1】int (*p)[3];定义了一个指向含有3个元素的一维数组的指针变量p,p只能指向含有3个元素的一维数组。
【示例2】int a[4][3],b[3][4],(*p)[3];则正确的赋值语句是:A. p=a[3];B. p=b[3];C. p=a;D.p=b;解析:数组a作为一维数组有4个元素a[0],a[1],a[2],a[3],每一个元素都是含有3个元素的一维数组;数组b作为一维数组有3个元素b[0],b[1],b[2],每一个元素都是含有4个元素的一维数组;变量p是一个指向含有3个元素的一维数组的指针变量。
选项A是把二维数组a的元素a[3]的值,即&a[3][0]赋给了指针变量p,使p 指向了a[3][0],a[3][0]是一个二维数组元素,而不是含有3个元素的一维数组,所以,选项A是错误的;选项B中的b[3]已超出数组b的范围,所以,选项B也错误的;选项C是把二维数组a的值,即&a[0]赋给了指针变量p,使p指向了a[0],而a[0]是一个含有3个元素的一维数组,所以,选项C是正确的;选项D是把二维数组b的值,即&b[0]赋给了指针变量p,使p指向了b[0],而b[0]是一个含有4个元素的一维数组,所以,选项D也错误的。
因此,正确的赋值语句是选项C。
一维数组和指针的关系
数组名是一个指针常量,表示数组第一个元素的的起始地址。
如 int a[5]; a表示数组第一个元素a[0]的起始地址&a[0]。
引用数组元素的方法:一引用数组元素的方法①用数组下标引用数组元素 数组a中元素用下标表示为: a[0] a[1] a[2] a[3] a[4]②用指针引用数组元素 数组a中元素用下标表示为: int *p = a; *p, *(p+1), *(p+2), *(p+3), *(p+4)数组和指针的关系:二数组和指针的关系①既然p是指向数组第一个元素起始地址的指针,可以用*(p+i)表示数组中第i+1个元素,a也是指向数组第一个元素的指针啊,那么能不能用*(a+i)表示第i+1个元素呢? 可以的,可以用printf 打印 *(a+i)的值验证②反过来,a是指向数组第一个元素起始地址的指针,可以用a加数组下标引用数组元素,如a[3],p也是指向数组第一个元素起始地址的指针,能不能用p加数组下标引用数组元素? 也是可以的,可以用printf 打印 p[0], p[1]....的值验证PS:由上得,数组名a和指针p是一样的。
实际上编译时,数组元素a[i] 就是当作 *(a+i)去处理的,先通过数组名a找到数组的首地址,然后首地址 a+i 得到元素a[i]的地址, 再然后通过*(a+i)得到第i个元素的内容。
所以:数组的第i个元素直接写成*(a+i)的形式直接取得值,效率不就提升了吗。
省去编译器先通过数组名a 找到数组的首地址,然后首地址 a+i 得到元素a[i]的地址, 再然后通过*(a+i)得到第i个元素的内容。
指向数组的指针的自增:三指向数组的指针的自增 int a[5]; int *p = a; 可以 ++p 递增指针p指向下一个数组元素,然后用*p取得元素的值。
能不能用a++或者++a把指针指向下一个数组元素?不能!!!开头就说过,数组名是指向数组首元素的指针常量。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一、指针数组及指向一维数组的指针(数组指针)讲解
1、数组指针(也称行指针)
定义 int (*p)[n];
()优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长。
也就是说执行p+1时,p要跨过n个整型数据的长度。
如要将二维数组赋给一指针,应这样赋值:int a[3][4];int (*p)[4];
//该语句是定义一个数组指针,指向含4个元素的一维数组。
p=a;
//将该二维数组的首地址赋给p,也就是a[0]或&a[0][0] p++;
//该语句执行过后,也就是p=p+1;p跨过行a[0][]指向了行a[1][]
所以数组指针也称指向一维数组的指针,亦称行指针。
2、指针数组
定义 int *p[n];
[]优先级高,先与p结合成为一个数组,再由int *说明这是一个整型指针数组,它有n个指针类型的数组元素。
这样赋值是错误的:p=a;只存在p[0]、p[1]、p[2]...p[n-1],而且它们分别是指针变量可以用来存放变量地址。
但可以这样 *p=a; 这里*p表示指针数组第一个元素的值,a的首地址的值。
如要将二维数组赋给一指针数组:
int *p[3];
int a[3][4];
for(i=0;i<3;i++)
p[i]=a[i];
这里int *p[3] 表示一个一维数组内存放着三个指针变量,分别是p[0]、p
[1]、p[2]所以要分别赋值。
这样两者的区别就豁然开朗了,数组指针只是一个指针变量,似乎是C语言里专门用来指向二维数组的,它占有内存中一个指针的存储空间。
指针数组是多个指针变量,以数组形式存在内存当中,占有多个指针的存储空间。
还需要说明的一点就是,同时用来指向二维数组时,其引用和用数组名引用都是一样的。
比如要表示数组中i行j列一个元素:
*(p[i]+j)、*(*(p+i)+j)、(*(p+i))[j]、p[i][j]
优先级:()>[]>*
例1、下列给定程序中,函数fun()的功能是:从N个字符串中找出最长的那个串,并将其地址作为函数值返回。
#include <string.h>
#include <stdio.h>
#define N 4
#define M 50
char *fun(char (*q)[M])
{ int i; char *p;
p=*q;
for(i=0; i<N; i++)
if (strlen(p)<strlen(*(q+1)))
q=*(q+1);
return p;
}
main( )
{
char str[N][M]={“pingpong”,”basketball”,
”field hockey”,”softball”};
char *longest;
int i;
longest=fun(str);
printf(“\nThe longest string:\n”);
puts(longest);
}
例2、下列给定程序中,函数fun()的功能是:从N个字符串中找出最长的那个串,并将其地址作为函数值返回。
#include <string.h>
#include <stdio.h>
char *fun(char **q,int n)
{ int i; char *p1;
p1=*q;
for(i=0; i<n; i++)
if (strlen(p1)<strlen(*(q+i)))
p1=*(q+i);
return p1;
}
main( )
{
char *p[]={“pingpong”,”basketball”,
”field hockey”,”softball”};
char *longest;
int i;
longest=fun(p,4);
printf(“\nThe longest string:\n”);
puts(longest);
}
注意:①数组指针:int (*p)[4]; p适应于指向二维数组的数组名,类型匹配。
也就是说二维数组名作为函数的实参时,形参必须定义为数组指针。
②指针数组:int *p[4]; 指针数组名作为函数的实参时,形参必须定义为指向指针的指针。
这样类型才匹配。
二、一维数组名与二维数组名的区别
定义的时候一维数组名有一个[],而二维数组名有两个。
如一维数组a[N],二维数组a[N][N].对于一维数组a[N]来说,a(或者&a[0])就是数组首地址(即a[0]的地址),a+1就是a[1]的地址。
而对于二维数组a[][]来说,a(或者a[0]或者&a[0][0])是它的首地址,a+1(或者a[1]或者&a[1][0])就是a[1][0]的地址。
但要注意对于二维数组a[][]来说,虽然a(或者a[0]或者&a[0][0])是它的首地址,但a和a[0]的指向是不同的,也就是指针类型不一样,a[0]是竖指针,而a是横指针。
例3、写出下面程序输出的结果:
main()
{int a[4]={1,2,3,4},b[4][4]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
printf("%d,%d\n",*a,*(a+1));
printf("%d,%d\n", a[0],a[1]);
printf("%d,%d\n",a,a+1);
printf("%d,%d\n",*b,*(b+1));
printf("%d,%d\n",**b,**(b+1));
printf("%d,%d\n",*(*b+1),*(*(b+1)+1));
printf("%d,%d\n",*b[0],*(b[0]+1));
getch();
}
例4、写出下面程序输出的结果:
main()
{int *p1,(*p2)[4],a[4]={1,2,3,4},b[4][4]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
p1=a; p2=b;
printf("%d,%d\n",*a,*(a+1));
printf("%d,%d\n", a[0],a[1]);
printf("%d,%d\n",*p1,*(p1+1));
printf("%d,%d\n", p1[0],p1[1]);
printf("%d,%d\n",a,a+1);
printf("%d,%d\n",p1,p1+1);
printf("%d,%d\n",*b,*(b+1));
printf("%d,%d\n",**b,**(b+1));
printf("%d,%d\n",*p2,*(p2+1));
printf("%d,%d\n",p2[0],p2[0]+1);
printf("%d,%d\n",**p2,**(p2+1));
printf("%d,%d\n",*(*b+1),*(*(b+1)+1)); printf("%d,%d\n",*(*p2+1),*(*(p2+1)+1));
printf("%d,%d\n",*b[0],*(b[0]+1));
printf("%d,%d\n",*p2[0],*(p2[0]+1)); getch();
}。