前言
⭐️感谢相遇,唤我沈七就好。
⭐️如果能和你一起进步那就太好啦。
指针变量
基本概念
指针变量:存储其他变量的指针的变量
**变量的指针:变量的地址 **
*记为 : int p = & a;
易错点
指针变量的交换
**访问 p 相当于直接访问地址所在元素,所以修改 p ,其存储地址所在的元素也会被修改
//通过改变指针的变量 间接的改变 a b 变量的值
#include<stdio.h>
void swap(int * pa ,int *pb)
{
int t;
t=*pa,*pa=*pb,*pb=t;
}
int main()
{
int a,b;
int *pa = &a,*pb = &b;
scanf("%d%d",&a,&b);
if(a<b)
swap(pa,pb);
printf("%d %d",a,b);
}
而直接修改 p 存储的地址,不会影响到其原来存储地址所在的元素的值,改变的是指针的指向
//分别指向 a b 的指针变量 变成 分别指向b a的指针变量
int main()
{
int a,b;
int *pa = &a,*pb = &b,*t;
scanf("%d%d",&a,&b);
if(a<b)
t=pa,pa=pb,pb=t;
printf("%d %d\n",a,b);
printf("%d %d",*pa,*pb);
}
注意如果要将 仅交换指针的功能 封装成函数的话,那这样只改变的是指针的指向的方法就不对了。
因为在自定义函数中接受指针变量的是形参变量,参变量只有在函数被调用时才会分配内存,
调用结束后,立刻释放内存,所以形参变量只有在函数内部有效,不能在函数外部使用。
函数指针
声明 :int (*p)(int ,int)
一维数组
指向数组的指针变量
int a[5],*p;
p = a;
p = & a[0];
数组的地址就是 数组名 或者 &+数组中第一个元素 即 &a[0]
*(p + i ) 是 a[i]
给 a 数组 赋值
for(int p = a, i = 0 ; i < 10 ; i ++, p ++)
*p = i;
打印 a 数组 的值
for(int p = a ; p <(a+10) ; p ++)
printf(“%d”,*p);
p + 1 指向 数组的下一个元素
**(p)++ 和 p++
1.变量维度
int *p = &a
*** p++ 代表的是 p 储存的 地址 + 1 ,( * p)++ 代表的是在 p 储存的地址 上的值 + 1**
2.数组维度
int a[1000]
int * p = a
p为a 的首地址 , p 即表示 a数组中的第一个元素*
*p++ 即将地址自增 表示的就是 a数组中的第二个元素
*(p+i)代表的就是a[i]的值
*(p)++ 表示a 数组中的第一个元素自加
二维数组
a [100] [100]
行指针
int (*p)[4]=a;
行指针:指的是一整行,不指向具体元素。
a &a[i] a+i
行指针+i 和这一行的元素个数和数据类型有关
数组名依然是数组的指针,只不过在二维数组里只代指行指针
用行指针输出整个二维数组
#include<stdio.h>
int main()
{
float a[4][4];
float (*p)[4]=a;//float (*p)[4]=&a[0];
for(int i = 0 ; i < 4 ; i ++)
for(int j = 0 ; j < 4 ; j ++)
scanf("%f",&a[i][j]);
for(i = 0; i < 3; i++)
for(j = 0; j < 4; j++)
printf("%d ",*(*(p + i) + j));
printf("%d ",*( p[i] + j));
return 0;
}
列指针
int * p = a [0] ;
列指针:指的是一行中某个具体元素。
*a a[i] a[i] [j] *(a+i) a[i]+j
*( a[1] + 12 )== a[0] [12]
*( *(a+1)+12)==a[0] [12]
列指针+i 只和数据类型有关
可以将列指针理解为行指针的具体元素,行指针理解为列指针的地址。
用列指针输出整个二维数组
#include <stdio.h>
int main()
{
int a[3][4]={
1,3,5,7,9,11,13,15,17,19,21,23};
int *p= a[0]; // 列指针的定义法
for(; p < a[0] + 12; p++)
printf("%d ",*p);
printf("%",*(p+i * 7 + j ))
return 0;
}
那么两个概念之间的具体转换是:
行指针*----** 列指针
& 列指针 ---- 行指针
*p = &a[0] [0]
*(p+i * 7 + j )
(*p)[7]=a
a;//代表数组首行地址,一般用a[0][0]的地址表示
&a;//代表整个数组的地址,一般用a[0][0]地址表示
*a;//代表数组a首元素地址也就是a[0]或者&a[0][0]
a[i];
代表了第i行起始元素的地址
(网上说是代表了第i行的地址,但我觉得不是,在讲数组与指针的关系时我会验证给大家看)
&a[i];代表了第i行的地址,一般用a[i][0]的地址表示
a[i]+j;//代表了第i行第j个元素地址,a[i]就是j==0的情况
&a[i][j];//代表了第i行第j个元素的地址
*(a+i);//代表了第i行首元素的地址,*a是i=0的情况
*(a+i)+j;//代表了第i行j个元素的地址
**a;//代表a的首元素的值也就是a[0][0]
*(*(a+i)+j);//代表了第i行第j个元素
配套习题
有了以上的知识储备后,在来几个配套习题加深理解~
1.编程,从键盘输入5个字符串,存入数组a中,编写程序,找出其中最大字符串并输出,要求使用指针完成。
#include<stdio.h>
#include<string.h>
int main()
{
char a[10][10],str[10];
char (*p)[10];
p = a ;
for(int i = 0 ; i < 5 ; i ++)
scanf("%s",a[i]);
strcpy(str,p[0]);
for(int i = 0 ; i < 5 ; i ++)
if(strcmp(str,p[i])<0)
strcpy(str,p[i]);
printf("%s",str);
return 0;
}
2.编程,在主函数中输入10个最长不超过20个字符的字符串,用另一个函数完成对这10个字符串降序排序,然后在主函数中再输出排序后的字符串。
#include<stdio.h>
#include<string.h>
int n;
void sort(char (*p)[20])
{
char *t;
for(int i = 1 ; i < 10; i ++)
for(int j = 0 ; j < 10- i ; j ++)
if(p[j+1]>p[j])
*t = *p[j+1], *p[j+1]=*p[j], *p[j]=*t;
}
int main()
{
char a[10][20],str[10];
char (*p)[20];
p = a ;
for(int i = 0 ; i < 10 ; i ++)
scanf("%s",a[i]);
sort(a);
for(int i = 0 ; i < 10 ; i ++)
printf("%s\n",a[i]);
return 0;
}
3.a数组是6*6的二维int型数组,其元素值由键盘输入,请编程找出二维数组a中每行的最大值,并按一一对应的顺序存入一维数组s中。即:第零行中的最大值,存入s[0]中,第一行中的最大值,存入s[1]中,……。输出每行的行号和最大值。
#include<stdio.h>
int a[6][6],s[6],b[6];
void find(int (*p)[6],int *s,int *b)
{
for(int k = 0 ; k < 6 ; k ++)
for(int i = 0 ; i < 6 ; i ++)
for(int j = 0 ; j < 6 ; j ++)
if(*(s+k)<*(*(p+i)+j))
*(s+k)=*(*(p+i)+j),*(b+k)=j;
}
int main()
{
for(int i = 0 ; i < 6 ; i ++)
for(int j = 0 ; j < 6 ; j ++)
scanf("%d",&a[i][j]);
find(a,s,b);
for(int i = 0 ; i < 6 ; i ++)
printf("行号为%d 最大值为%d \n",b[i],s[i]);
return 0;
}
4.用指针编程,输出6*6方阵a中两个对角线上元素之和。
#include<stdio.h>
#include<string.h>
int sum(int (*p)[6])
{
int s = 0;
for(int i = 0 ; i < 6 ; i ++)
s=s+*(*(p+i)+i)+*(*(p+i)+5-i);
return s;
}
int main()
{
int a[6][6];
for(int i = 0 ; i < 6 ; i ++)
for(int j = 0 ; j < 6 ; j ++)
scanf("%d",&a[i][j]);
printf("%d",sum(a));
return 0;
}
完结散花
ok以上就是对 C语言指针 的全部讲解啦,很感谢你能看到这儿。如果有遗漏、错误或者有更加通俗易懂的讲解,欢迎小伙伴私信我,我后期再补充完善。