10 第6章 数组与指针— 指针
指针和数组的关系

指针和数组的关系
指针和数组是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语言中是紧密相关的,数组名本质上就是一个指向数组第一
个元素的指针。
我们可以通过指针访问数组中的元素,并通过加减运算实现对数组的遍
历。
在实际编程中,使用指针可以提高程序的效率和灵活性。
使用指针可以避免对数组名
的重复引用,从而减少程序的存储空间和运行时间开销。
但是,指针操作也比较容易出现指针越界、空指针等错误,因此在使用指针时需特别
注意,避免出现不必要的错误。
教材课后题答案-第6章_指针习题答案

习题解答一、单项选择题1.若定义了int n=2, *p=&n, *q=p;则下面【】的赋值是非法的。
A.p=qB. *p=*qC. n=*qD. p=n【答案】D2.若定义了double *p, a;则能通过scanf函数给输入项读入数据的程序段是【】。
A.p=&a; scanf(“%1e”,p);B. *p=&a; scanf(“%1f”,p);C. p=&a; scanf(“%f”,p);D. p=&a; scanf(“%1f”,a);【答案】C3.若定义了int a[10], i=3, *p; p=&a[5];下面不能表示为a数组元素的是【】。
A.p[-5]B. a[i+5]C. *p++D. a[i-5]【答案】D4.若有如下定义:int n[5]={1,2,3,4,5},*p=n;则值为5的表达式是【】。
A.*+5B. *(p+5)C. *p+=4D. p+4【答案】C5.设变量b的地址已赋给指针变量ps,下面为“真”的表达式是【】。
A.b==&psB. b==psC. b==*psD. &b==&ps【答案】C6.设有以下定义和语句:int a[3][2]={1,2,3,4,5,6},*p[3];p[0]=a[1];则*(p[0]+1)所代表的数组元素是【】。
A.a[0][1]B. a[1][0]C. a[1][1]D. a[1][2]【答案】C7.若定义了char *str=”Hello!”;下面程序段中正确的是【】。
A.char c[ ], *p=c; strcpy(p,str);B.char c[5], *p; strcpy(p=&c[1],&str[3]);C.char c[5]; strcpy(c,str);D.char c[5]; strcpy(p=c+2,str+3);【答案】B8.若有下面的程序段,则不正确的fxy函数的首部是【】。
《C++语言程序设计》第6章 数组 指针与字符串

• 可以只对部分元素初始化
• 例如:static int a[3][4]={{1},{0,6},{0,0,11}};
• 列出全部初始值时,第1维下标个数可以省略
• 例如:static int a[][4]={1,2,3,4,5,6,7,8,9,10,11,12}; • 或:static int a[][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
其中数组a的存储顺序为:
a00 a01 a02 a03 a10 a11 a12 a13 a20 a21 a22 a23
12
二维数组的初始化
• 将所有初值写在一个{}内,按顺序初始化
• 例如:static int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
• 分行列出二维数组元素的初值
cout << "Moving the point to (" << newX << ", " << newY << ")" << endl; x = newX; y = newY; }
例6-3 对象数组应用举例
//6-3.cpp #include "Point.h" #include <iostream> using namespace std;
int main() {
cout << "Entering main..." << endl;
数组和指针的区别

数组和指针的区别数组和指针是C语言中非常重要的两个概念,它们在编写程序时起着极其重要的作用。
虽然它们在某种程度上非常相似,但它们之间也存在着很多的差异,下面我们就来分析一下它们的区别。
1. 定义方式数组是由一组具有相同类型的数据元素所组成的有序集合,每个元素具有相同的数据类型,可以通过下标在数组中访问对应的元素。
在C中,定义一个数组可以使用以下语句:```int arr[10];```这个语句定义了一个名为arr的整型数组,这个数组有10个元素。
而指针是一个变量,它存放了一个内存地址,这个地址与它存储的数据类型有关。
在C中,定义一个指针可以使用以下语句:```int *p;```这个语句定义了一个名为p的指针,这个指针指向一个整型变量。
2. 内存分配数组在定义时要求需要一定的内存空间来存储数组元素,因此在定义时就已经确定了内存空间的大小,且数组的大小不可改变。
例如,如果定义一个大小为10的数组,则它的大小就是10,无论实际使用时需要存储的元素个数是多少,数组的大小都不会改变。
而指针在定义时只需要分配一个指针变量所需的内存空间,该指针可以在程序运行时动态地分配内存,因此指针所指向的内存空间大小不确定,需要在运行时根据需要动态地分配或释放空间。
3. 访问方式在数组中,可以通过数组的下标来访问数组中具体的元素,下标从0开始,最大下标为数组大小减1。
例如,访问arr数组中的第三个元素可以写成:arr[2]。
而对于指针,可以通过指针变量所指向的地址来访问该地址所对应的值。
例如,访问p指针所指向地址上的整型变量可以写成:*p。
4. 传递方式在函数调用时,数组可以通过值传递或指针传递来传递数组的值。
如果数组作为参数传递给函数时,实际上传递的是该数组的地址,即使数组非常大,也不会导致栈溢出。
而对于指针,只能通过指针传递方式来传递指针变量的值,在函数内部可以通过指针来修改该指针所指向的地址所存储的值,因此指针可以用来传递地址或修改变量的值。
第6章C语言

float
*point;
定义了一个指向浮点型数据的指针变量point,即point是一个 用于存放浮点型变量地址的变量。
6.1.2 指针变量的定义与初始化
在此定义中,基类型声明了该指针变量所指向的 实体的类型。如:一个指向float类型的指针变量,它 的基类型应该为float型;一个指向int类型的指针变 量,它的基类型应该为int型。“*”是一个标识,用 以说明该变量是一个具有指针类型的变量。对于指针 变量的变量名的命名也应该尽量做到“见名知义”。 需要注意的是,指针变量名为“point”,而非 “*point”。
第6章
指针
山东大学电气工程学院
第6章Байду номын сангаас指针
指针是C语言中一个非常重要的概念,它对于变量的引用、数组 的处理、字符串的操作、函数参数的调用及函数间数据的处理、 结构体的应用和文件的操作等等都起着相当重要的作用。正确的 运用指针不仅可以提高程序的执行效率,简化操作过程,而且可 以处理复杂的数据操作,实现动态的数据结构,完成形式多样的 参数传递以及灵活的修改形参与实参的数值。但是需要警惕的是, 因为指针的运用如此的灵活,以至于经常会出现一些意想不到的 错误和结果。甚至在某些情况下,错误的运用指针,会使程序受 到非常严重的破坏。因此可以说,正确的理解和运用指针是衡量 能否成功的编写高质量C程序的标准。
6.1.3 与指针有关的运算符
在C语言中有三个与指针有关的运算符: 1、“&”运算符 此运算符称为取地址运算符。通过取地址运算符“&”可以获得 一个变量的地址。“&”为单目运算符,运算方向为从右向左结合, 直接作用于一个变量前,表示该变量的地址。 例如: int x=10,*p1;
理解C语言(一)数组、函数与指针

理解C语⾔(⼀)数组、函数与指针1 指针⼀般地,计算机内存的每个位置都由⼀个地址标识,在C语⾔中我们⽤指针表⽰内存地址。
指针变量的值实际上就是内存地址,⽽指针变量所指向的内容则是该内存地址存储的内容,这是通过解引⽤指针获得。
声明⼀个指针变量并不会⾃动分配任何内存。
在对指针进⾏间接访问前,指针必须初始化: 要么指向它现有的内存,要么给它分配动态内存。
对未初始化的指针变量执⾏解引⽤操作是⾮法的,⽽且这种错误常常难以检测,其结果往往是⼀个不相关的值被修改,并且这种错误很难调试,因⽽我们需要明确强调: 未初始化的指针是⽆效的,直到该指针赋值后,才可使⽤它。
int *a;*a=12; //只是声明了变量a,但从未对它初始化,因⽽我们没办法预测值12将存储在什么地⽅int *d=0; //这是可以的,0可以视作为零值int b=12;int *c=&b;另外C标准定义了NULL指针,它作为⼀个特殊的指针常量,表⽰不指向任何位置,因⽽对⼀个NULL指针进⾏解引⽤操作同样也是⾮法的。
因⽽在对指针进⾏解引⽤操作的所有情形前,如常规赋值、指针作为函数的参数,⾸先必须检查指针的合法性- ⾮NULL指针。
解引⽤NULL指针操作的后果因编译器⽽异,两个常见的后果分别是返回置0的值及终⽌程序。
总结下来,不论你的机器对解引⽤NULL指针这种⾏为作何反应,对所有的指针变量进⾏显式的初始化是种好做法。
如果知道指针被初始化为什么地址,就该把它初始化为该地址,否则初始化为NULL在所有指针解引⽤操作前都要对其进⾏合法性检查,判断是否为NULL指针,这是⼀种良好安全的编程风格1.1 指针运算基础在指针值上可以进⾏有限的算术运算和关系运算。
合法的运算具体包括以下⼏种: 指针与整数的加减(包括指针的⾃增和⾃减)、同类型指针间的⽐较、同类型的指针相减。
例如⼀个指针加上或减去⼀个整型值,⽐较两指针是否相等或不相等,但是这两种运算只有作⽤于同⼀个数组中才可以预测。
机械工业出版社c语言各章节编程题参考答案(书中有)

else if((a*a+b*b==c*c)||(a*a+c*c==b*b)||(b*b+c*c==a*a))printf(“This is a
if(b>c){temp=b;b=c;c=temp;}
if(c>d){temp=c;c=d;d=temp;}/*d已经为最大的数*/
if(a>b){temp=a;a=b;b=temp;}
if(b>c){temp=b;b=c;c=temp;}/*c已经为次大的数*/
if(a>b){temp=a;a=b;b=temp;}/*a已经为最小的数*/
printf(“ *** ”);
printf(“ ***** ”);
printf(“ *** ”);
printf(“ * ”);
}
3参考答案
#include <stdio.h>
main()
case 3:
case 5:
case 7:
case 8:
case 10:
case 12: day=31; break;
case 4:
case 6:
case 9:
}
结束
5 解答:
S0:i=0;
S1:判断gi是否大于80,若大于转S3;
S2:i=i+1;
S3:打印i,gi
S4:若i<10,返回S1否则继续执行。
6 解答:求两个整数的最大公约数、最小公倍数
第06章 指针

17
高 级 语 言 程 序 设 计 与 应 用 教 程
6.3 指针和地址运算
1、指针变量的加、减运算(移动运算) 将指针变量的原值加上n个
它指向的变量所占用的内存 指针可以参与加法和减法运算,但其加、减的含义绝对 单元字节数。 不同于一般数值的加减运算。如果指针p是这样定义的: ptype *p;,并且p当前的值是ADDR,那么:
第 六 章
指 针
学习指针是学习C语言中最重要的一环, 能否正确理解 和使用指针是我们是否掌握C语言的一个标志,可以说不懂 C语言中的指针就不懂什么是C语言。
2
高 级 语 言 程 序 设 计 与 应 用 教 程
本章学习重点
指针的概念 指针变量的定义、初始化和引用 指针的运算 指针与一维数组 指针与二维数组 指针与字符串 指针作为函数的参数
第 六 章
指 针
3
高 级 语 言 程 序 设 计 与 应 用 教 程
6.1 指针与地址
1、内存地址──内存中存储单元的编号 教学楼
存储地址
内存
存储 单元
0 …... 2000 2001
601 501
602 502
50
2002 注意:内存单元的地址与内存单元中的数据是 401 402 两个完全不同的概念。 2003 存储单元有
指针变量p 2000 指针变量q 2000
第 六 章
…...
指 针
12
高 级 语 言 程 序 设 计 与 应 用 教 程
指针变量赋值的几种错误方法: 例 int *p = &a; int a;
变量a的定义在后,对a的引 用超出了a的作用域
第 六 章
注意:一个指针变量只能指向同类型的变量如果给指针赋 例 int a; 值时,=号右边的指针类型与左边的指针类型不同,则需要 int *pi = &a; pc不能指向非字符型变量 进行类型强制转换。 char *pc = &a; int a; 赋值语句中,被赋值的指针 例 int int *pi; a; 变量p的前面不能再加“*” int *p; 说明符 char *pc; *p = &a; pi = &a; //pi指向a 不允许直接把一个数(或任 pc = (char *)pi; //pc也指向了a,即pi和pc的值都是a的地址 例 int *p; 何其他非地址类型的数据) p = 2000; 赋值给指针变量
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
说
明
(5)其中的“初值”通常是“&普通变量名”、“&数组元素名” 或“数组名”,这个普通变量或数组必须在前面已定义。 这个普通变量或数组可以是在本语句的前面出现的定义 语句中定义的,也可以是在本定义语句中出现的,但必须是 对应指针变量前出现
说
明
(6)一个定义语句中,可以只给部分指针变量赋初值
例:指针变量的定义和初始化 int a; int *p=&a,*p3; float f1, f[10], *p1=&f1, *p2=f;
* (指针变量+0) 或 * 指针变量 * (指针变量-k) * (指针变量+k)
1、用指向一维数组的指针变量处理数组元素
● 当指针变量指向首地址后,对下标为i的数组元素引用 有下列四种方法:* (指针变量+i) * (数组名+i) 指针变量[i] 数组名[i] 前两种引用数组元素的方法采用“指针运算符”,称为 “指针法” 后两种引用数组元素的方法采用“下标运算符([])” 称为“下标法”
运算对象 (1)变量 (2)数组元素 (1)指针变量 (2)变量的地址 (3)数组元素的 地址
运算结果 对象的地址 指针变量所 指向的变量 或数组元素 的值
结合性 自右向左
单目 前缀
指针 (间接 取地址运算符(&)
运算对象:已定义过的变量或数组的元素 不能是数组名、常量 运算结果:运算对象的地址 例如: 定义:变量a、数组b[10],则&a、&b[0]、&b[9]均合法 代表:变量a的地址 数组元素b[0]的地址、数组元素b[9]的地址 而&b则是非法的
(1)指针变量和整数的算术运算
上述运算规则组成的式子称为表达式,这种表达式的类 型是“地址型”,所以上述规则组成的表达式常称为“地址型表 达式”或“指针型表达式”,简称为“指针表达式”
(1)指针变量和整数的算术运算 例如:定义整型数组a[10],整型指针变量pa 执行pa=a 假定数组a的首地址为2000 则,下列表达式的运算结果: 执行pa=pa+5后 pa指向数组元素a[5],pa的地址值将为 2000+5*2=2010,其中的“2”是整型数 占用的单元数 再执行pa--后 pa将指向数组元素a[4],pa的地址值将为 2010-1*2=2008
例:用指针方法按从小到大的顺序输出三个整数
main( ) { int a,b,c; int *pa=&a,*pb=&b,*pc=&c,*p; scanf (“%d,%d,%d”,pa,pb,pc); if (*pa>*pb) { p = pa; pa = pb; pb = p; } if (*pa>*pc) { p = pa; pa = pc; pc = p; } if (*pb>*pc) { p = pb; pb = pc; pc = p; } printf (“%d<=%d<=%d\n”,*pa,*pb,*pc); }
(三)
指针运算符(*)
运算对象:已赋值的指针变量,不能是普通变量 变量的地址 数组元素的地址
运算结果:指针所指向的内存单元的内容
(三)
例如
指针运算符(*)
定义:变量a、数组b[10]、指针变量p 执行:“p=&a”,即p已指向了a,则*p代表变量a 执行:“p=&b[3]”,即p已指向了数组元素b[3],则*p就 代表数组元素b[3] 注意:当指针变量的值为数组的首地址,“* 指针变量” 也是正确的,它代表数组的第一个元素。例如,执行了 “p=b”,即 p已指向了数组b,则*p就代表数组元素b[0]
1、用指向一维数组的指针变量处理数组元素
引用方式一:当指针变量指向数组首地址
引用“数组元素[0]” 引用“数组元素[i]”
* (指针变量+0) 或 * 指针变量 * (指针变量+i)
1、用指向一维数组的指针变量处理数组元素
引用方式二:当指针变量指向下标为i的数组元素
引用“数组元素[i]” 引用“数组元素[i-k]” 引用“数组元素[i+k]”
1、内存单元和地址
内部存储器是由多个内存单元组成的,每个内存单元 有自己独有的地址,称为内存单元地址
2、变量与地址
程序中可以用变量来存放各种数据,因此每个变量都 需要分配连续的内存单元
由于数据类型的不同,每个变量需要分配的内存单元 数目也不同
2、变量与地址
当一个变量只占用一个内存单元时,内存单元的地址 就是变量的地址
(1)指针变量和整数的算术运算 ++指针变量 “指针变量中的地址+指针变量类型占用单元 数”对应的地址,此后,指针变量将指向下一 个数组元素 注意:指针变量本身的值已经发生了变化 --指针变量 “指针变量中的地址-指针变量类型占用单元 数”对应的地址,此后,指针变量将指向上一 个数组元素 注意:指针变量本身的值已经发生了变化
3、数组与地址
例如:有一条定义语句“int a[3]={1,2,3};”,分配的内存单元 如图3所示,而记录下来的数组与地址对照表如图4所示。
地址 内存单元 3000 3001 3002 3003 3004 3005 1 2 3 图3 数组名 a 整型数组元素a[0] 整型数组元素a[1] 整型数组元素a[2] 数组与地址对照表 数据类型 整型 图4 长 度 3 首地址 3000
(三)&和*的运算优先级
· &、*和自增、自减等单目运算符是同级别的
· 所有单目运算符的结合性均为自右向左
(三)&和*的运算优先级
在混合使用运算符时,要注意分清它们的运算对象和运 时的结合性。 例如,设有变量a、指针变量pa,且pa已经指向a,则
*&a 正确的 相当于“*(&a)”,&a是变量a的地址,*(a地址)代表变量a &* a 错误的 相当于“&(*a) ”,因为a不是合法运算对象,所以* a不正确 *&pa 正确的 相当于“*(&pa)”, &pa是pa的地址,*(pa地址) 代表指针变量 &*pa 正确的 相当于“&(*pa)”,*pa代表变量a,&(变量a)代表a的地址
3、数组与地址
当一个数组元素只占用一个内存单元时,内存单元的地 址就是该数组元素的地址 当数组元素占用若干个连续的内存单元时,最前面一个 单元的地址就是该数组元素的地址 当一个数组占用连续的若干个内存单元时,最前面的单 元地址称为数组的首地址,也是第一个数组元素的地址
3、数组与地址
每个数组元素的地址可以通过下列公式求得: 数组元素a[i]的地址=数组首地址+i×数组元素的数据类 所占用单元数 对源程序进行编译时,每遇到一个数组,按其类型和 度分配内存单元,同时记录数组名、数据类型、数组长度、 数组首地址。
6.2.2 指针变量的定义、初始化和引用
(一) 指针变量的定义和初始化
1、指针变量的定义和初始化格式 数据类型 *指针变量名 [=初值] ; 例如: int *p = &i ;
2、功能:定义指向特定数据类型的变量或数组的若干 个指针变量,同时给这些指针变量赋初值。
说
明
(1)指针变量名的命名原则同标识符,前面必须有“*”号 (2)在一个定义语句中,可以同时定义普通变量、数组、 指针变量 (3)定义指针变量时的“数据类型”可以选取任何基本数据类 型,也可以选取以后介绍的其它数据类型。 这个数据类型不是指针变量中存放的数据类型,而是它将 要指向的变量或数组的数据类型
4、指针和变量 —— 指针变量
地址也是一种值,也可以存储在一个变量中 由于地址是一种特殊的数据类型,所以存放地址的变量与存放字符型、 整型、实型数据的变量不同,是特定类型的变量 存放地址的变量像一个指针,指向要存取值的变量,所以将这种变量 称为“指针变量” 先通过指针变量获得变量的地址,再到相应地址中访问变量的方式, 称为“间接寻址(访问)方式”
6.3 指针与数组
6.3.1 指向一维数组的指针 6.3.2 指向多维数组的指针
6.3.1
指向一维数组的指针
1、用指向一维数组的指针变量处理数组元素
2、指向一维数组的指针变量的运算
1、用指向一维数组的指针变量处理数组元素
当指针变量已指向数组后,就可以用指针变量处理 数组中的每个元素。
处理数组元素的关键是引用数组元素,引用数组元 素的方法与指针指向数组的方式有关:
当变量占用连续的若干个内存单元时,最前面一个单 元的地址就是该变量的地址
2、变量与地址
例如,int i=3, j=5 ; float f ; 分配的内存单元如图1所示 记录下来的变量与地址对照表如图2所
2001 2002 2003 2004 2005 2006 2007 2008
3 5
整型变量i 整型变量j
C语言规定:
① 变量地址只能利用“取地址”运算符“&”通过运算获得 运算对象:变量或数组元素名 运算结果:对应变量或数组元素的地址 例如:变量i的地址应写成表达式“&i” 数组元素a[1]的地址 “&a[1]” ② 数组的首地址就是数组名,不必利用取地址运算符通过 运算获得 例如定义了数组a,这个a在程序中可以直接使用,代 表该数组的首地址,也是数组元素a[0]的地址。 所以“a”和“&a[0]”的作用是相同的。
指
6.2 指针的概念 6.3 指针与数组 6.4 字符串的指针
针
*6.5 指针数组和指向指针的指针
6.2 指针的概念
6.2.1 地址与指针的概念 6.2.2 指针的定义、初始化与引用
6.2.1 指 针 概 述
指针是一种数据类型 所谓指针,就是存放数据的内存地址 指针变量是一种变量,该变量中存放的数据就是指针类型 的数据 对一个变量或数组元素来说,可以通过变量名或数组名 标]来引用,也可以通过指针变量来引用,但需要事先将指 针变量“指向”变量或数组,所谓“指向”就是将变量或数组 地址存放到指针变量中