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

用指针访问数组的方法一、指针与数组的关系。
1.1 指针就像是数组的导航员。
数组在内存里是一块连续的空间,就像住在公寓里的一排房间。
而指针呢,就好比是房间的钥匙或者说是指向这些房间的路标。
它能准确地找到数组里的每个元素,这就跟你拿着钥匙能打开对应的房间门一样。
咱们可以把数组想象成一群小伙伴排着队,指针就可以指出哪个是排头,哪个是排尾,还能找到中间的小伙伴。
1.2 从本质上来说,数组名其实就是一个指针常量。
这就像是一个固定的地址标签,它指向数组的第一个元素。
就好比你家的门牌号,永远指着你家这个“元素”所在的位置。
而且,这个指针常量是不能被修改的,就像你不能随便更改你家的门牌号一样。
二、用指针访问数组元素。
2.1 简单的访问方式。
咱们先定义一个数组,比如说int arr[5] = {1, 2, 3, 4, 5};再定义一个指针,int p = arr; 这里的arr就相当于把数组的首地址给了指针p。
现在如果我们想访问数组的第一个元素,就可以用p,这就像是通过钥匙打开了第一个房间。
如果我们想访问第二个元素呢,那就可以让指针p指向下一个元素,也就是p++,然后再用p来获取这个元素的值。
这就好像你沿着走廊走到下一个房间,再用钥匙打开门看看里面有啥。
2.2 灵活的遍历。
通过指针来遍历数组那是相当方便的。
我们可以写一个简单的循环,像这样:for (int p = arr; p < arr + 5; p++) { printf("%d ", p); }。
这个循环就像是一个小机器人,从数组的开头沿着指针这个“导航路线”一直走到结尾,把每个房间里的东西(元素的值)都展示出来。
这就好比是你沿着一排房间一个一个地查看里面的情况,一个都不落下。
2.3 指针运算的妙处。
指针的运算在访问数组的时候可是很有讲究的。
比如说,p + 2,这里可不是简单的数学加法,它实际上是让指针向后移动两个元素的位置。
这就像是你一下子跳过两个房间,直接到第三个房间的门口。
浅谈数组和指针

的地 址 。 设 i和j 以及 p 都 是 指 针 变量 , 用 它 们
指 向 有 关 元 素。 i的 出 值 为x , j 的 出 值 为
x + n 一 1 , 使 i与j交换就是 使a [1]与a 【j]交换
V o id
in v
(in t
’
×
in
t
,
n
)
J ( ) { / in t
te
m
p i.
0 3 7 9 6 7 5 4 2 ,
.
11
,
,
.
,
,
,
.
,:
( p r in t f
“the
o
r ig
in a
l
a
rra
y :kn
)”
:
f o r (i= 0 :i< 1 0 :i+ + )
( ㈤ p r in tf
% d “
”
,a
:
( p r in t f
) m “
”
.
in v
n
(a
10
.
):
p r in t f (“ T h e a r r a y h a s b e e n in v e rt e d :~n )”
—
p r in tf (“ t h e o r ig in a l a r r a y :~ ” ):
fo r (_- O:i< 1 0 :i+ + )
p
r in tf (“ % d
”
,a
[i])
p r in tf (“ Ⅵ ” ):
m a in ()
f 【 】={ } in t i a 1 0 ,
指针修改值和数组的关系

指针修改值和数组的关系指针是C语言中的一种特殊数据类型,它存储的是内存地址,而不是实际的数据值。
通过指针,我们可以直接修改内存中的值,这在很多情况下都非常有用。
特别是在处理数组时,指针的这一特性更是发挥了巨大的作用。
在数组中,每个元素都是一个变量,有自己的内存地址。
如果我们有一个指向数组元素的指针,那么我们可以通过这个指针来修改数组中的值。
这是因为指针指向的是数组元素的内存地址,当我们修改指针所指向的值时,就相当于直接修改了数组中的值。
下面是一个简单的例子:```c#include <stdio.h>int main() {int array[5] = {1, 2, 3, 4, 5};int *ptr = array; // 指向数组首元素的指针printf("原始数组:\n");for(int i = 0; i < 5; i++) {printf("%d ", array[i]);}printf("\n");*ptr = 10; // 修改指针指向的值printf("修改后的数组:\n");for(int i = 0; i < 5; i++) {printf("%d ", array[i]);}printf("\n");return 0;}```这段代码中,我们首先定义了一个包含5个整数的数组`array`,然后定义了一个指向`array`首元素的指针`ptr`。
我们通过`ptr`修改了数组的首个元素,从1变成了10。
运行这段代码,你会看到原始数组和修改后的数组的输出结果。
需要注意的是,指针的修改必须合法,否则可能会导致未定义的行为。
比如,我们不能随意修改一个我们没有权限访问的内存地址的值,这可能会导致程序崩溃或者数据损坏。
数组与指针
此外,还可通过算术元运算对指针进行移动, 此外,还可通过算术元运算对指针进行移动,来达到引用 其他数组元素的目的。 其他数组元素的目的。 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"。
二、数组指针数组指针是指一个指针,它指向一个数组。
这个数组可以是任何类型的数据,包括指针。
函数参数数组与指针的区别
函数参数数组与指针的区别
在C语言中,函数参数可以是数组类型或指针类型。
它们之间的
主要区别在于数组参数在函数内部被看作一个本地的数组,而指针参
数在函数内部只是一个指向实际数组的地址。
对于数组参数,函数可以通过数组名获取数组的大小,但是数组
名无法修改。
在函数内部,数组参数可以直接使用,而不需要使用指
针运算符。
同时,对数组参数进行修改会改变实际数组的值。
相反,指针参数可以通过指针运算符进行操作,可以用来访问整
个数组或指向数组中的一个元素。
但指针参数没有数组参数那样方便,因为它不提供数组大小信息,需要通过其他方法或额外参数获得。
总的来说,数组参数可以看作特殊的指针参数,它们在函数调用
时具有不同的语法和语义。
如果函数需要使用数组的长度或修改实际
数组的值,则应使用数组参数;如果函数仅需要访问数组中的值,则
可以使用指针参数。
C语言中“指针和数组等价” 到底是什么意思
C语言中“指针和数组等价”到底是什么意思
在C 语言中对数组和指针的困惑多数都来自这句话。
说数组和指针“等价”不表示它们相同, 甚至也不能互换。
它的意思是说数组和指针的算法定义可以用指针方便的访问数组或者模拟数组。
特别地, 等价的基础来自这个关键定义:
一个T 的数组类型的左值如果出现在表达式中会蜕变为一个指向数组第一个成员的指针(除了三种例外情况);结果指针的类型是T 的指针。
这就是说, 一旦数组出现在表达式中, 编译器会隐式地生成一个指向数组第一个成员地指针, 就像程序员写出了&a[0] 一样。
例外的情况是, 数组为sizeof 或&操作符的操作数, 或者为字符数组的字符串初始值。
作为这个这个定义的后果, 编译器并那么不严格区分数组下标操作符和指针。
在形如a[i] 的表达式中, 根据上边的规则, 数组蜕化为指针然后按照指针变量的方式如p[i] 那样寻址, 如问题6.2 所述, 尽管最终的内存访问并不一样。
如果你把数组地址赋给指针:
p = a;
那么p[3] 和a[3] 将会访问同样的成员。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
scanf("%d", &a[i]); // ?
printf("逆序输出:\n"); for(i=9;i>=0;i--)
printf(“%d\n”, *(p+i)); }
2. 一维数组与指针(8)
一维数组名作为实参(例6.20)
#include <stdio.h> #define M 100 void fun(int *x, int *y, int *z, int n) { int i;
1. 指向数组的指针变量的定义(3)
short a[4]; int *p; p=&a[0]; 或 p=a;
1. 指向数组的指针变量的定义(4)
例6.18 #include <stdio.h> void main() { int *p1,*p2,*p3,*p4;
int a[10]={1,2,3,4,5,6,7,8,9,10}; p1=&a[0]; p2=p1; p3=&a[5]; p4=&a[10]; // ? }
第6章 地址和指针(二)
主要内容: 1. 指向数组的指针变量的定义 2. 一维数组与指针 3. 二维数组与指针
1. 指向数组的指针变量的定义(1)
数组 (1)所分配的内存单 元连续。
(2)数组名对应于数 组的首地址,是一个 常量指针。
1. 指向数组的指针变量的定义(2)
数组指针变量的定义 short a[4]; int *p; //定义指针变量p p=&a[0]; //将数组的首地址赋给指针变量p 或 p=a;
2. 一维数组与指针(3)
例6.19 (1)使用数组名+下标访问数组元素
#include <stdio.h> void main() {
int a[10], i; for(i=0; i<10; i ++)
scanf("%d", &a[i]);
printf("逆序输出:\n"); for(i=9; i>=0; i--)
2. 一维数组与指针(9)
printf("数组b中的值为:"); for(i=0; i<5; i++) printf("%d ", b[i]); printf("\n");
fun(a,b,c,5);
printf("数组c中的值为:"); for(i=0; i<5; i++)
printf("%d ", c[i]); printf("\n"); }
printf("逆序输出:\n"); for(i=9; i>=0; i--)
printf("%d\n", p[i]);
2. 一维数组与指针(5)
例6.19 (3)使用数组名的指针法访问数组
#include <stdio.h> void main() { int a[10],i,*p;
p=a; for(i=0;i<10;i++)
for(i=0; i<n; i++) z[i]=x[i]+y[i];
} void main() { int i, a[M]={1,3,5,7,8}, b[M]={2,3,4,5,8},c[M];
printf("数组a中的值为:"); for(i=0; i<5; i++)
printf("%d ", a[i]);
(4)a[i] *(a+i)
for(n=0; n<=4; n++) change(&x[n]);
for(n=0; n<=9; n++) printf("%d ", x[n]);
}
3. 二维数组与指针(1)
• 二维数组的地址
对于一维数组:
a
(1)数组名a表示数组的首地址,
也是元素a[0]的地址
(2)数组名a是地址常量
(3)a+i是元素a[i]的地址
scanf("%d", &a[i]);
printf("逆序输出:\n"); for(i=9;i>=0;i--)
printf(“%d\n”, *(a+i));
2. 一维数组与指针(6)
例6.19 (4)使用指针变量的指针法访问数组
#include <stdio.h> void main() { int a[10],i,*p;
p=a; for(i=0;i<10;i++)
scanf("%d", &a[i]);
printf("逆序输出:\n"); for(i=9;i>=0;i--)
printf(“%d\n”, *(p+i));
2. 一维数组与指针(7)
思考:将输入语句scanf()的参数也改成 指针的方式?
#include <stdio.h> void main() { int a[10],i,*p;
printf("%d\n", a[i]); }
2. 一维数组与指针(4)
例6.19 (2)使用指针变量的下标法访问数组
#include <stdio.h> void main() { int a[10], i ,*p;
p=a; for(i=0; i<10; i++)
scanf("%d", &a[i]);
2. 一维数组与指针(1)
如果数组指针变量p已经指向数组中的 某个元素,则p+1指向下一个元素
若有 int a[10], *p=a; 则p+i和a+i(0≤i ≤ 9) 均指向a中的第i个元素,或者说p+i和 a+i的值就是元素a[i]的地址
2. 一维数组与指针(2)
*(p+i)或*(a+i)(0≤i ≤ 9)表示元素a[i]的值 也可用p[i]表示元素a[i]
数组名作为函数参数传递时,不是整个数组 传递给形参,而是只将数组的首地址传递给 形参。
2. 一维数组与指针(11)
一维数组的元素地址作为实参
#include <stdio.h> void change(int k[ ]) { k[0]=k[5]; } void main() { int x[10]={1,2,3,4,5,6,7,8,9,10}, n;
2. 一维数组与指针(10)
注意 子函数的首部可以写为: void fun(int *x, int *y, int *z, int n) void fun(int x[], int y[], int z[], int n) void fun(int x[M], int y[M], int z[M], int n)