c语言指针详解

雨燕双飞 提交于 2020-03-09 06:47:55

c语言指针

1.指针是什么?

在c语言中指针和其他变量没有区别,例如 int a 和 int * b,我们可以看做为变量a 与变量b,只是 a存储的是整数值,而b存储的是整数变量的地址!!划重点地址!!!

2.指针的运算

int*a ,float*b,char *c,double*d

a++ ,b++,c++, d++,

有什么区别? 已知 int 4字节 float 4个字节 char1个字节 double 8个字节

因为他们占据这些字节,而这些字节体现到内存上,

所以指针 a++ 偏移为4 ,float++偏移 4…依次类推

通过以上的结果我们可以归纳出

​ 内存的存储长度与内存里面所存储的类型有关!!!划重点

3.指针与一维数组二维数组多维数组

一维数组与指针

int a[9] = {1,2,3,4,5,6,7,8,9};

①a是什么?

a是数组首元素的地址,意思在这个数组中 a代表 首元素1所在的地址

②a的类型是什么?

因为a是首元素的地址,首元素为int类型,那么a为int *类型

③a++的含义是什么?有什么用?

a++代表往后移动四个字节,至于为啥四个字节呢 因为a是一个地址它存储的是int类型,所以在偏移四个字节后可以访问到a[1]

具体的用处可以用a++,访问数组中的值,可以用a[0] 中括号的方式访问到数组的值

④写个程序来证明上方是对的

#include <stdio.h>
int main()
{
	int a[10]={1,2,3,4,5,6,7,8,9,10};
	int *p;
	p=a;
	while(*p!=NULL)
	{
		printf("%d ",*(p++));//为什么其实写成*p++也是和这个意思相同!!方便理解
		printf("%d ",p);
	}
	return 0;
}



1 1637536 2 1637540 3 1637544 4 1637548 5 1637552 6 1637556 7 1637560 8 1637564 9 1637568 10 1637572 -858993460 1637576 1637656 1637580 19405432 1637584 1 1637588 16600016 1637592 16590192 1637596 -1423278593 1637600 19403027 1637604 19403027 1637608 3739648 1637612 262144000 1637616 1637656 1637620 请按任意键继续. . .





解析下上面的程序 首先定义一个整数型指针p 给其赋值,然后再进行循环遍历,可以通过结果看到每个值之间的地址差值为4,可以证明在内存中是按照数组元素中的类型方式来存储的!

重要的一点为什么我要多出来个p呢直接用啊不行吗! 因为数组名为常量是常指针.

二维数组与指针!扩展延伸多维数组

int a[2][3] ={{1,2,3},{456}};定义一个二行三列的二维数组

其实他们在内存中的存储是 1 2 3 4 5 6存储的和一维数组的存储过程没有不同!多维的数组也是线性排列!

①刚才说数组名是数组首元素的首地址,那么a现在是什么?

a是{1,2,3}的地址 ,首先{1,2,3}是整数数组 那么 a是数组指针!

②什么是数组指针,怎么表示?

数组指针是指向数组地址的指针,其本质为指针;

怎么表示 例如上方的二维指针表示为 int(*p)[3]

#include <stdio.h>
int main()
{
	int a[2][3]={{1,2,3},{4,5,6}};
	int (*p)[3] = a;

	printf("a的值%d\n",p);
	printf("a后移一位的值%d\n",++p);
}

a的值1638108
a后移一位的值1638120
请按任意键继续. . .

#include <stdio.h>
int main()
{
	int a[2][3]={{1,2,3},{4,5,6}};
	int (*p)[3] = a;

	printf("a[0][2]的值%d\n",*(*(p+0)+2));
	printf("a[0][2]的值%d",a[0][2]);

}



通过上方的访问方式可以看到数组的访问方法可以有以上两种方式访问 那么那两种方式呢?

一种是指针访问 一种是a[0][2]这种形式的访问方式

③在三维及其以上的数组

#include <stdio.h>
int main()
{
	int a[2][3][2] = {
		{
			{1,2},{3,4},{5,6}

	},
	{
		{7,8},{9,10},{11,12}   
	}

};
int (*p)[3][2] =a;

printf("%d",*(*(*(p+1)+1)+0));


}



打印的是9

解释上方的p {1,2},{3,4}},{5,6}

},的地址 那么 p+0 还为这个地址,然后*(p+0)后变成了数组 然后 数组名 为 {1,2}的首地址 然后+1变成了{3,4}的地址然后解引用 再取值 就得到了3

然后比较下二维数组三维数组的取值

*(*(p+0)+2)        //二维数组
*(*(*(p+1)+1)+0)  //三维数组

那么多位数组的指针取值也可以推算出来了

a[m][n][b][v]
那么可以得到多维数组 …((((p+m)+n)+b)+v)…

4.字符 字符串 与指针

①在c语言中有真正的字符串吗?

其实是没有的 只有字符 例如 char a= ‘ccccv’;

②那为啥你还提到有字符串这个词呢?

应该正确的叫法为字符数组

例如 char a[5]={‘h’,‘e’,‘l’,‘l’,‘o’};

第一个代码块
#include <stdio.h>
int main()
{
	char a[5]={'h','e','l','l','o'};
	printf("%s",a);
	
}

打印结果为 
hello烫烫烫虆<nv镊

那么

第二个代码块
#include <stdio.h>
int main()
{
	char * a ="hello";



	printf("%s\n",a);

	printf("%s\n",a+1);
	getchar();

}

运行结果
hello
ello




那么a到底是什么呢?

在第一个代码块可以得知 a是字符串 'h’的地址

在第二个 a也是首字符的地址 !!所以只是写法不同而已!!!

那为什么 char a[ 5]会出现糖糖糖那种符号呢 因为 在c语言中 字符串默认 /0结尾 他没有这样,所以在%s进行解析的时候就会出现所示的乱码现象! 而char *a 在被赋值以后是后方默认加的!

5.二级指针及其多级指针

int a = 5;

int *b =&a;

int **c = &b;

俄罗斯套娃!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!