指针和数组
使用指针能使程序更高效,指针还能有效的处理数组,数组表示法其实是在变相的使用指针 好 开始学习 GO
指针和数组
数组名是数组元素的首地址
int a[3];
a==&a[0]; //数组名表示数组元素的首地址
- 1
- 2
#include<stdio.h>
#define SIZE 5
int main()
{
int dates[SIZE];
int *pt1;
long a[SIZE];
long *pt2;
printf(" %s %s\n","int","long");
for(int i=0;i<SIZE;i++)
printf(" + %d: %10p %10p\n",i,pt1+i,pt2+i);
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
在C中,指针+1指的是增加一个储存单元
对于数组而言,表示下一个元素的地址
指针加1,指针的值递增它所指向类型的大小(以字节为单位)
假设a是整型数组,下面这样是✔
a+1==&a[1]; //相同的地址
*(a+2)==a[2]; //相同的值
- 1
- 2
可以看到数组和指针就好像是好基友
,咳咳,可以使用指针表示数组的元素和获取数组元素的值
注意:间接运算符 * 的优先级高于算术运算符+
*(a+2); //a的第三个元素的值
*a+2; //a的第一个元素的值加2
- 1
- 2
学到这,我们在写代码时可以选择数组表示
和指针表示
,我们可以用指针表示数组,反过来,也可以用数组表示指针,在使用以数组为参数的函数时应注意
函数数组和指针
假设有需求,需要一个处理数组的函数,该函数返回数组中的所有元素之和
思路:
通过循环一次读入数组数据迭代计算求和,需要掌握宏定义,自定义函数,以及数组和循环结构
函数原型:
//函数原型
int sum(int arr[],int n);
- 1
- 2
函数定义:
//函数定义
int sum(int arr[],int n)
{
int total = 0;
for(int i=0;i<10;i++)
total+=arr[i];
return total;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
函数调用:
//函数调用
int answer = sum(sd,SIZE);
- 1
- 2
完整代码:
#include<stdio.h>
#define SIZE 10
int sum(int arr[],int n);
int main(void){
int sd[SIZE] = {10,20,30,40,50,60,70,80,90,100};
int answer = sum(sd,SIZE);
printf("%d\n" ,answer);
printf("%zd",sizeof sd);
return 0;
}
int sum(int arr[],int n)
{
int total = 0;
for(int i=0;i<10;i++)
total+=arr[i];
return total;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
使用指针形参
使用函数处理数组,必须要知道何时开始,何时结束。除了上面的方法传参,我们还可以传递两个指针,第一个指针指向数组的开始处,第二个指针指向数组的结束处。比如下面:
#include<stdio.h>
#define SIZE 10
int sum(int *start,int *end);
int main()
{
int a[SIZE]={10,20,30,40,50,60,70,80,90,100};
int b=sum(a,a+SIZE);
printf("%d\n",b);
return 0;
}
int sum(int *start,int *end){
int a=0;
while(start<end){
a+=*start;
start++;
}
return a;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
指针操作
C可以对指针进行什么操作呢,我们来学习一些基本的指针操作
1.赋值:可以把地址赋给指针。例如:使用数组名,地址运算符&的变量名,另一个指针等进行赋值。
地址应该与指针的类型兼容,就是说int型的地址给int型的指针,C99/C11已经强制不允许类型不兼容
int a[3]={1,2,3};
int *ptr,*ptr1;
ptr=a;
ptr1=&a[1];
- 1
- 2
- 3
- 4
这就是把整型数组a的首地址赋值给整型指针ptr,把整型数组a的第二个地址赋值给整型指针ptr1
2.解引用和取值:*运算符给出指针指向地址上储存的值
解引用:
#include<stdio.h>
int main(){
int a[3]={1,2,3};
int *ptr,*ptr1;
ptr=a;
ptr1=&a[1];
printf("%d\n",*ptr);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
取值:和所有变量一样,指针变量也有自己的地址和值。对与指针来说,&运算符给出指针值的地址,
#include<stdio.h>
int main(){
int a[3]={1,2,3};
int *ptr,*ptr1;
ptr=a;
ptr1=&a[1];
printf("ptr1=%p,*ptr1=%d,&ptr1=%p\n",ptr1,*ptr1,&ptr1);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
这里用到的三个参数ptr1指的是指针所在的地址,*ptr1解引用指针所指向的值,&ptr1指针所指向的值的地址
3.递增递减指针:数组元素的指针可以让指针移动至数组的下一个元素。递减当然就是再回去了
int a[]={1,2,3};
int ptr1;
ptr1=&a[1];
ptr1++;//让指针移动至数组的下一个元素a[2],即递增四个字节
ptr--;//让指针移动至数组的上一个元素a[1],即递减四个字节
- 1
- 2
- 3
- 4
- 5
4.指针求差:可以计算两个指针的差值,可以用一个指针减去另一个指针得到一个整数,或者用一个指针减去一个整数得到另一个指针
注意:千万不要解引用未初始化的指针
int *pt1;//未初始化的指针
*pt=5;//严重错误
- 1
- 2
这把5储存在了pt指向的位置,但是pt未初始化,其值是一个随机值,幸运点没什么问题,或者会擦写数据或代码,甚至导致系统的崩溃。
切记:创建一个指针时,系统只分配了储存本身的内存,并未分配储存数据的内存,因此,在使用指针之前,必须先用已分配的地址初始化它
int a[3];
int *pt1,*pt2;
- 1
- 2
基于这些操作,C程序员创建了指针数组,函数指针,指向指针的指针数组,指向函数的指针数组等
文章来源: blog.csdn.net,作者:周棋洛ყ ᥱ ᥉,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/m0_53321320/article/details/118737434
- 点赞
- 收藏
- 关注作者
评论(0)