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


目录
  • 前言
  • 一.指针基础
    • (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 #include #include 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)地址运算符和间接运算符
【C|玩转指针,手撕c语言(深入理解指针基础)】地址运算符 &
&后跟一个变量名,&给出该变量的地址,
例如我们经常调用的scanf函数,就是在一个地址上存储变量;从而达到
变量赋值的目的
而在平时使用时,&可以给出一个变量的地址
例如
//声明了一个普通变量 dog int dog; //声明一个指针变量,指向变量 dog的地址 int *p; //通过取地址符&,获取 a 的地址,赋值给指针变量 p = &dog; //通过间接寻址符,获取指针指向的内容 printf("%d", *p); //最后输出的结果就是变量dog的地址

dog的地址由一个无符号整数表示,但指针并不是整数类型
注:指针实际上是一个新类型,不是整数类型
间接运算符 *
间接运算符后跟一个指针变量或者地址时,*可以给出存储在指针指向
地址上的值
示例
#include #include #include 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 #include #include char a[] = "along"; printf("%s", a);

(2)字符指针
#include #include #include 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 #include #include 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 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 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 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)指针比较 注:两个指针必须指向同一类型的值才可以用关系运算符进行比较





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

    推荐阅读