目录
- 前言
- 一.指针基础
- (1)概念理解
- (2)地址运算符和间接运算符
- 二.字符指针与字符数组
- (1)字符数组
- (2)字符指针
- (3)数组与指针联系
- 三.指针变量的使用
- (1)赋值
- (2)解引用
- (3)取址
- (4)指针与整数相加
- (5)递增指针
- (6)指针减去一个整数
- (7)递减指针
- (8)指针求差
- (9)指针比较
前言
许多人认为指针时c语言学习中最难攻克的部分,我们将逐一对指针的性质,指针与数组的关系,指针与函数的关系,二级指针,指针与多维数组进行解释。
本篇blog建议收藏后多次食用,反复观看,切莫动怒。
目录
一.指针基础
(1)概念理解
什么是指针?指针是一个值为内存地址的**变量**
普通的变量可以用 int,char,long,float,double等来声明变量类型
和普通的变量x,y,一样,指针也需要声明变量类型;
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
int*dog;//dog是指向int类型变量的指针
char*cat;//cat是指向char类型变量的指针
float*along,*zhao;//along和zhao都是指向float类型变量的指针;
}
声明的意思是dog,cat,along,zhao,都是指针
而*dog是int类型, *cat是char类型 , *along是float类型
接下来我们来区分“指针变量”和“变量的指针’两个概念
指针变量变量的值是地址,是储存指针的变量
变量的指针就是变量的存储地址
指针变量的定义形式如:数据类型 指针名
如上面的定义,指针变量名为 dog,cat,along。而不是dog、*cat、*along
(2)地址运算符和间接运算符
地址运算符 &
&后跟一个变量名,&给出该变量的地址,
例如我们经常调用的scanf函数,就是在一个地址上存储变量;从而达到
变量赋值的目的
而在平时使用时,&可以给出一个变量的地址
例如
//声明了一个普通变量 dog
int dog;
//声明一个指针变量,指向变量 dog的地址
int *p;
//通过取地址符&,获取 a 的地址,赋值给指针变量
p = &dog;
//通过间接寻址符,获取指针指向的内容
printf("%d", *p);//最后输出的结果就是变量dog的地址
dog的地址由一个无符号整数表示,但指针并不是整数类型
注:指针实际上是一个新类型,不是整数类型
间接运算符 *
间接运算符后跟一个指针变量或者地址时,*可以给出存储在指针指向
地址上的值
示例
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
int*dog;//dog是指向int类型变量的指针
char*cat;//cat是指向char类型变量的指针
float*along;//along和zhao都是指向float类型变量的指针;
int a=34;
int b=66;
dog=&a;
printf("%d\n",*dog);
printf("%d\n",*&b);
//输出结果为34/66
}
##(3)简单实例理解
给定变量x,y,交换它们的值
void main(){
//声明两个普通变量
int x, y;
//声明两个指针变量
int *px, *py;
//声明一个临时变量,用于交换
int t;
//输入两个值,赋值给 x、y
scanf("%d", &x);
scanf("%d", &y);
//给指针变量 px、py 赋初值(关联变量 x、y)
px = &x;
py = &y;
//利用指针来对比 x、y 的值,如果 x 的值比 y 的值小,就交换
if(*px < *py){
//交换步骤,其中*px == x、*py == y
t = *px;
*px = *py;
*py = t;
}
printf("x = %d, y = %d", *px, *py);
}
加减运算
//定义三个变量,假设它们地址为连续的,分别为 4000、4004、4008
int x, y, z;
//定义一个指针,指向 x
int *px = &x;
//利用指针变量 px 加减整数,分别输出 x、y、z
printf("x = %d", *px); //因为 px 指向 x,所以*px = x
//px + 1,表示,向前移动一个单元(从 4000 到 4004)
//这里要先(px + 1),再*(px + 1)获取内容,因为单目运算符“*”优先级高于双目运算符“+”
printf("y = %d", *(px + 1));
printf("z = %d", *(px + 2));
赋值运算
int *pa, *pb, *pc, a = 10;
//赋予某个变量的地址
pa = &a;
//相互赋值
pb = pa;
//赋值具体的地址
pc = 4000;
关系运算
pa > pb 表示 pa 指向的存储地址是否大于 pb 指向的地址
pa == pb表示 pa 和 pb 是否指向同一个存储单元
pa == 0 和 pa != 0 表示 pa 是否为空指针
//定义一个数组,数组中相邻元素地址间隔一个单元
int h[2] = {1, 3};
//将数组中第一个元素地址和第二个元素的地址赋值给 pa、pb
int *pa = &h[0], *pb = &h[1];
int *pc = &h[0];
int *pt;
//则 pb > pa
if(pb > pa){
printf("pb 指向的存储地址大于 pa 所指向的存储地址\n");
}
//pc 和 pa 都指向 h[0]
if(pc == pa){
printf("pa 和 pc 指向同一个地址\n");
}
//pn 没有初始化
if(pt == NULL || pt == 0){
printf("pn 是一个空指针\n");
}
二.字符指针与字符数组
(1)字符数组
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char a[] = "along";
printf("%s", a);
(2)字符指针
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
char *a={"zhao along is an old longer "} ;//定义一个字符串a
printf("%c\n",*a);
printf("%c\n",*(a+3));
printf("%c\n",a[0]);
printf("%c",a[3]);//由结果可以看出*a==a[0],*(a+3)==a[3]
printf("%s\n",a);
}
(3)数组与指针联系
由上文字符指针例子中可以看出指针是可以当作数组使用的,
注:字符指针方式区别于字符数组方式,字符数组不能通过数组名自增操作,但是字符指针是指针,可以自增操作。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
//定义字符数组 a 和 b,给 x 赋初值
char a[] = "zhao along is an old longer", b[100];
//定义字符指针,指向 b
char *p = b;
int i;
//循环赋值
for(i = 0; a[i] != '\0'; i++){
*(p + i) = a[i];
}
//在当 i 等于 a 的长度(a 的长度不包含'\0')时,
//i 继续自增,此时判断 a[0] != '\0'不符合,跳出循环,则 i 比 a 长度大 1
*(p + i) = '\0';
//输出字符串,因为p指向 b,所以输出结果是一样的
printf("p = %s\n, b = %s\n", p, b);
}
三.指针变量的使用
(1)赋值
利用&将变量的地址赋给指针
(2)解引用
*运算符给出指针指向地址上储存的值
(3)取址
&取址
(4)指针与整数相加
#include<stdio.h>
int main()
{
int *a;
int x[10]={4,5,6,4,9,4,6,4,456,};
a=x;
printf("%d\n",*a);
printf("%d\n",*(a+4));
printf("%d",x[4]);
}
自己悟,太简单,没法解释
(5)递增指针
#include<stdio.h>
int main()
{
int *a;
int x[10]={4,5,6,4,9,4,6,4,456,};
a=x;
printf("%d\n",*a);
a++;
printf("%d",*a);
}
递增指向数组元素的指针,即a++,因此a++相当于a的值加上4;
为什么是4?——自己悟
运行上面的代码就可以理解递增的概念了
(6)指针减去一个整数
和指针与整数相加一样,不说了哈
(7)递减指针
和递增指针一样,也不说了哈;
(8)指针求差
#include<stdio.h>
int main()
{
int *a1,*a2,*a3;
int h[]={4,5,6,9,8,7,2,3,1,56};
a1=&h[6];
a2=&h[2];
printf("%d",a1-a2);
}
上面代码的输出结果为4,意思是a1和a2相差四个int ,而不是4个字节,
注:进行指针求差时两个指针必须指向同一个数组;
(9)指针比较
注:两个指针必须指向同一类型的值才可以用关系运算符进行比较
。
。
。
。
。
本次指针基础内容到此结束,较为简单
,指针进阶马上就到,(指针进阶难度较大)