一维数组与指针:
指向一维数组的指针变量:
数组元素的指针就是数组元素的地址,可以用一个指针变量指向一个数组元素
int main() {
int a[10] = {2,4,6,8,10,12,14,16,18,20};
int *p;
p = &a[0];//把a数组中第一个元素的地址赋值给p指针变量
int *q;
q = a;//理解:将a[0]的地址赋给q
return 0;
}
使用指针访问数组的元素:
如果指针变量p的初值为&a[0],则:
1.p + i和a + i就是数组元素a[i]的地址,或者说,他们指向a数组中序号为i的元素
2.*(p + i)或*(a + i)是p + i或a + i所指的元素的值,即a[i]的值
练习:
//一维数组的指针练习
//数组元素赋值,遍历
//
#include <stdio.h>
int main() {
int arr[5],i;
int *p = arr;
printf("请输入五个数字:");
for ( i = 0;i < 5;i++) {
scanf("%d",p + i);
}
for (int j = 0;j < 5;j++) {
printf("%d\n",*(p + j));
}
return 0;
}
指针带下标的使用(少用,但要知道):
指向数组元素的指针变量也可以带下标,如p[i].p[i]被处理成*(p +i),如果p是指向一个整形数组的元素a[0],则p[i]代表a[i],但要搞清楚p当前值是什么,比如p指向a[3],则p[2]代表的是a[5]
举例:
#include <stdio.h>
int main() {
int arr[5] = {1,2,3,4,5};
int *p = arr;//将arr[0]的值赋值给p变量,输出
printf("%d\n",*(p+2));//输出的数是多少取决于赋值的首元素是多少
//下面使用p[i]带角标的用法
printf("%d\n",p[2]);//输出为3
//不过尽量少用这种方法,容易写错
return 0;
}
#include <stdio.h>
int main() {
int a[5] = {10,20,30,40,50};
int *p = a;
//遍历数组
for (int i = 0;i < 5;i++) {
printf("%d\n",*(p + i));//或者这里直接用p[i]的格式,但自己可能会写错
}
return 0;
}
&数组名的使用:
复习举例:
#include <stdio.h>
int main() {
int arr[5] = {0};
int *p = arr;
printf("%p\n",p);
printf("%p\n",&p);
return 0;
}
注意:
printf("%p\n",a);//a表示a[0]的地址
printf("%p\n",&a);//&a表示a这个数组的地址,而a这个数组的地址恰好是a[0]的地址
printf("%p\n",a + 1);//a + 1:表示a[1]元素的地址
printf("%p\n",&a + 1);//&a + 1 表示的是a这个数组后面一个数组的地址
二维数组与指针:
在形式上是二维数组,但在实际存储中还是一维数组
a[0][0]的地址可以用a[0]来表示
a[0][1]的地址可以用a[0]+1来表示
a[0][2]可以用a[0]+2表示,以此类推
a为二维数组名,指向一维数组a[0],相当于&a[0][0]
a+i为二维数组名,指向一维数组a[i],相当于&a[i][0]
举例:
#include <stdio.h>
int main() {
int arr[][4] = {
{1,2,3,4},
{5,6,7,8},
{9,10,11,12}
};
printf("%d\n",arr[0][0]);//1
printf("%p\n",&arr[0][0]);//获取a[0][0]元素对应的地址
printf("%p\n",arr[0]);//获取a[0][0]的地址
printf("%p\n",arr);//获取一维数组 a[0]的地址
printf("%p",&arr);//获取二维数组arr的地址
return 0;
}

/*讨论:使用数组名,表示数组中各个相关元素的地址和值
*前提:
*&a,二维数组a的地址名
*a,获取a[0]的地址名
*a[0] 获取a[0][0]的地址名
*
*
*
*
*讨论1:a[0][0]相关的
*a[0][0]的地址:&a[0][0],a[0],*a
*a[0][0]的值:a[0][0] *(a[0]),*(*a))
*
*
*讨论2: a[1]相关的
*a[1]的地址;&a[1],a+1,
*
*讨论3:a[1][0]相关的
*a[1][0]的地址:&a[1][0],a[1],*(a+1)
*a[1][0]的值:a[1][0],*(a[1]),*(*(a+1))
*
*
*讨论4:
*a[1][2]相关的:
*a[1][2]的地址:&a[1][2],a[1]+2,*(a+1)+2
*a[1][2]的值:a[1][2],*(a[1]+2),*(*(a+1)+2)
*
*
*
**/
获取元素值的三种表示方法:
a[i][j]下标法
*(a[i]+j)用一维数组名
*(*(a+i)+j)用二维数组名
使用和指针变量访问::
对于a数组中的任一元素a[i][j]:
地址表示:p+i*N+j
值表示:*(p+i*N+j)或者p[i*N+j]
举例:
#include<stdio.h>
int main() {
int b[4][3] = { //b[M][N]
{10,20,30},
{40,50,60},
{100,110,120}
};
int *p = b[0];//p是b[0][0]元素的地址
//则元素b[1][2]对应的地址,元素为
printf("%p\n",p + 1*3+2);
printf("%d",*(p + 1*3+2));
return 0;
}
举例1:
//二维数组中使用指针变量的操作
//使用指针变量访问二维数组,求二维数组的最大值
#include <stdio.h>
int main() {
int a[3][4] = {
{10,20,30,40},
{50,60,70,80},
{120,11,100,90}
};
//传统方式1:
把首元素的地址赋给指针变量p,并定义首地址为最大值
int max = a[0][0];
int i,j;
通过循环,利用指针变量访问数组中的元素并找出最大值
for (i =0;i < 3;i++) {
for (j = 0;j<4;j++) {
if (a[i][j] > max) {
max = a[i][j];
}
}
}printf("最大值是:%d\n",max);
//方式二:
int max = a[0][0];
int *p = &a[0][0];
int i,j;
for (i =0;i < 3;i++) {
for (j = 0;j<4;j++) {
if (max < *(p + i*3+j)) {
max = *(p + i*3+j);
}
}
}
printf("最大值是:%d\n",max);
//方式3:使用单个for循环
int *q,zuidazhi =a[0][0];
for (q = a[0];q < a[0] + 3*4;q++) {
if (zuidazhi < *q) {
zuidazhi = *q;
}
}
printf("zuidahzhi是:%d",zuidazhi);
return 0;
}
指针数组:
数组指针和指针数组:
数组指针:
当一个指针变量里存放一个数组的首地址时,此指针变量称为指向数组的指针变量,简称数组指针
数组指针是指针
整形指针:int*pint,能够指向整形数据的指针
浮点型指针:float*pf,能够指向浮点型数据的指针
数组指针:能够指向数组的指针
指针数组:
数组是用来存放一系列相同类型的数据,所以也能用来存放指针,这种用来存放指针的数组被称为指针数组,它要求存放在数组中指针的数据类型一致
指针数组是数组
指针数组的使用:
格式:
数据类型 * 指针数组名[大小]
举例:
int *arr[5];
arr是一个数组,有五个元素,每一个元素都是一个整形指针,需用下标来区分。
举例1:
#include <stdio.h>
int main() {
//如何定义一个指针数组
int a,b,c,d,e;
a = 1;
b = 2;
c = 3;
d = 4;
e = 5;
int *arr[] = {&a,&b,&c,&d,&e};//定义一个int类型的指针数组
//通过遍历的方式,取出该数组中每一个值
for (int i =0;i < 5;i++) {
printf("%d ",*arr[i]);
}
return 0;
}
举例2:
#include <stdio.h>
int main() {
int line1[] = {1,2,3,4};
int line2[] = {5,6,7,8};
int line3[] = {9,10,11,12};
//定义一个指针数组,保存三个一维数组地址
int *arr[3]= {line1,line2,line3};
//遍历该数组
for (int i = 0; i < 3; i++) { //该循环用来遍历指针数组
for (int j = 0; j < 4; j++) { //该循环显示的是内层的,也就是三个一维数组中每个元素的地址
printf("%d \n",*(arr[i] + j));
}
}
return 0;
}
字符数组和字符指针变量:
一个字符串,可以用一维字符数组表示,也可以使用字符指针表示
1.字符数组由若干个元素组成,每个元素放一个字符
2.字符指针变量中存放的是地址(字符串/字符数组的首地址),不是将字符串放到字符指针变量中
举例:
#include<stdio.h>
int main() {
char str[] = {"hello world"};
char *p = {"hello world"};//把首元素的地址赋值给p这个指针变量
printf("%p",p);//输出首元素的地址
printf("%s",p);//输出的是hello world
return 0;
}
两个方式的区别;
对已声明的字符数组,只能一一对各个元素赋值,不能声明后重新赋值
比如:
char str[14];
str[0] = 'i';//这是对的
str = "hello,world"//这是错的
指针变量是一个变量,可以多次重新赋值
比如:char *pstr = “hell”;
pstr = “hello tom”;//这是对的
一个字符数组,因为他有确定的内存地址,所以字符数组名是一个常量,而定义一个字符指针变量时,它在指向某个确定的字符串数据的情况下,也可以多次赋值
举例:
#include <stdio.h>
int main() {
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int *p = arr;
printf("%d\n",p[1]);//2
printf("%d\n",*(p + 1));//2
p[1] = 50;
printf("%d\n",p[1]);//50
printf("%d\n",arr[1]);//50
int num = 30;
p = #
printf("%d\n",*p);//30
printf("%d\n",p[0]);//30
return 0;
}
char arr[6] ="hello";
arr[1] = 'm';//错误,已经声明数组中的元素不可以再更改
字符串数组的表示
字符串可以用一维字符数组或字符指针变量两种方式表示。
如果一个数组的每个成员都是一个字符串,则构成了字符串数组,字符串数组有两种表达方式:
1,二维字符数组。
2,字符指针数组
方式1:使用二维字符数组
char fruit[][7] = {
"apple", "banana", "orange", "grape", "peach", "pear"
};
char weekdays[7][10] ={
"Monday"
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday"
};
字符串数组,一共包含7个字符串,所以第一维的长度是7,其中,最长的字符串长度是10(还有一个
\0占位符),所以第二维的长度同意设为10
方式2:使用字符指针数组表示字符串数组
举例;
int main() {
char *weekdays[7] ={
"Monday"
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday"
};
这个字符串数组,其实是一个一维数组,成员就是7个字符指针,每个指针指向一个字符串
练习:
#include <stdio.h>
int main() {
char *arr[4] = {"三国演义"
,"红楼梦",
"水浒传",
"西游记"};
for (int i = 0; i < 4; i++) {
printf("%s ",arr[i]);
}
return 0;
}
拓展:指向固定长度数组的指针变量
定义一个整形指针变量指向一维数组,一维数组的每个元素包含m个元素
定义格式:
(*标识符)[一维数组元素个数];
例如:
定义一个指针变量p,它指向包含4个元素的一维数组
int(*p)[4];
说明:p先和*结合,说明p是一个指针变量,指向一个大小为4的整形数组
注意:此时定义的是一个指针变量,并非是一个指针数组。(*p必须放在括弧内,否则就成了定义指针数组)


举例:

指针与数组详解
5321

被折叠的 条评论
为什么被折叠?



