深度剖析指针------1

众所周知,指针是c语言的灵魂所在,也是c语言的难点所在,很多人在学习这部分的时候都感到非常困难,然而只要你静下心来慢慢“品尝”,你会发现,指针非常的灵活C语言之精髓!!

指针是什么?这个问题听起来真的不陌生,可能你自己都常常问你自己指针到底是什么?
---------指针就是地址,地址就是指针


我们可以把计算机内存用一个方块来模拟,把这个方块切成若干个,每一块大小为一个字节(八个比特位),每一块用一个数来标识(地址),当我们想找到某一块时只需要知道这一块的标识数(地址),由于这个标识数(地址)具有很强的指向性,所以我们称它为指针。

那么“指针变量”又是什么呢,指针变量是我们定义的一个变量,这个变量用来存放指针
实际上,我们不要去纠结这两个名词,我们把指针变量一般就叫指针,区分它们并没有实际意义。
 


一、字符指针

	char ch = 'a';
	char* p =&ch;
	printf("%c", *p); 

图中的p就是一个字符指针,下面来看另一种常用字符指针
 

	char* p = "i love you";
	printf("%s\n", p);

这里的p也是一个字符指针,那么这个指针到底是啥?如果我们直接用%p打印出p,我们将得到一个地址,那麽这个地址到底是谁的地址呢?对,他就是首字符的地址,在这里即是i的地址
下面来看一道经典例题

	char str1[] = "i love you";
	char str2[] = "i love you";
	char* str3 = "i love you";
	char* str4 = "i love you";
	if (str1 == str2)
		printf("1 and 2 is same\n");
	if (str3 == str4)
		printf("3 and 4 is same\n");

输出结果为:3 and 4 is same
那为什么会这样呢?
因为这里的str3和str4指向的是同一个字符串,c/c++会把字符常量单独放到一个区域(字符常量区),当要用到他们时,就可以用指针解引用来使用它们。理所当然,这里的str3和str4不能再被更改否则会报错。  str1和str2都是数组,在C语言中,两个数组的地址(数组名)怎么可能相等呢,编译器不可能给他们开辟在同一个地址空间,所以这里肯定不一样呗!!!


二、指针数组和数组指针


很显然,指针数组是数组,    数组指针是指针
那他们的用途分别是什么呢?
指针数组:
定义:

	int* arr1[10];   //存放整形指针 
	char* arr2[10];   //存放字符指针 

这里指针数组不再过多介绍,我们前面有一篇文章专门介绍了指针数组和数组指针,里面还有一些经典例子。

数组指针:
定义:

	int (*p1)[10]; 
	char (*p2)[10];

这里就有一些小伙伴开始搞不清楚数组指针和指针数组的写法,真的很像耶✌!!这里有一个小诀窍来辨别他们:我们得知道[ ]的优先级高于 * ,所以没加括号时会与[ ]先结合,那麽他就是一个数组(指针数组),而括号括起来后,他就是一个指针(数组指针);

知识法宝:定义一个数组arr,区别arr和&arr
有人会一本正经的回答,它两不就一样嘛!确实,他俩的值都一样,但意义却大不相同,你需要切记:数组名“永远”代表数组首元素的地址除1. 用sizeof求取它的长度  2.取地址数组名这两种特殊情况外)。而&arr代表这个数组的地址。
你可以打印出 arr+1 和 &arr+1 的值,他们的值是不会相同的!!
下面看这几条语句:

	int arr[10] = {0};
	int (*p1)[10]; 
	int (*p2)[8] = &arr;      //警告 (纬度应该一致) 
	p1 = &arr;
	p1 = arr;                 //警告  (应该取该数组的地址,而不是首元素的地址) 

好了,那么数组指针一般的用途到底是啥?我们看下面的代码:

#include<stdio.h>
void print(int (*p)[3], int row, int col);
int main()
{
	int arr[2][3] = {{2,3,4},{5,6,7}};
	print(arr, 2, 3);
	return 0;
} 
void print(int (*p)[3], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for(j = 0; j < col; j++)
		printf("%d ", p[i][j]);
		printf("\n");
	}
}

结果为:

这是数组指针的一个典型运用,用它来传参多维数组,这里该怎样使用它来传参呢?
切记下面的话:

数组 传参 会 降维“指向其内部元素”指针

当多维数组传参时,用数组名接收时,只能省去离数组名最近的那个纬度;
 


三、指针传参:

一级指针传参
可以用来接收一维数组、一级指针等等,这里比较简单,不再过多介绍

二级指针传参:

下面看一段代码:

#include<stdio.h>
void test(char** p)
{
	printf("lalala\n");
}
int main()
{
	char c = 'b';
	char* pc = &c;
	char** ppc = &pc;
	char* arr[10];
	test(&pc);
	test(ppc);
	test(arr);
	return 0;
}

该代码体现了几种二级指针的传参(该代码无警告无错误)

 

猜你喜欢

转载自blog.csdn.net/eternal_yangyun/article/details/83755429