玩转指针,手撕c语言(深入理解指针基础)

前言

许多人认为指针时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)指针比较

注:两个指针必须指向同一类型的值才可以用关系运算符进行比较






本次指针基础内容到此结束,较为简单
,指针进阶马上就到,(指针进阶难度较大)

猜你喜欢

转载自blog.csdn.net/qq_59708493/article/details/120606282