指针(一)

一、指针

  1. 指针是内存中一个最小单元的编号,也就是地址
  2. 平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量

总结:指针就是地址,口语中说的指针通常指的是指针变量

地址指向该变量单元。因此,将地址形象化的称为“指针”。
意思是通过它能找到以它为地址的内存单元

指针是个变量,存放内存单元的地址(编号)
指针变量:我们可以通过&(取地址操作符)取出变量的内存其实地址,把地址可以存放到一个变量中

指针是一个地址
指针变量是存放地址的变量

例如:

int main()
{
	int a = 10;//在内存中开辟一块空间
	int*p = &a;//对变量a,取出它的地址,可以使用&操作。
	//将a的地址存放在p变量中,p就是一个指针变量,类型为int*
	return 0;
}

一个内存单元是一个字节,一个字节给一个对应的地址

  1. 指针是用来存放地址的,地址是唯一标识一块地址空间的。
  2. 指针的大小在32位平台是4个字节,在64位平台是8个字节。

二、指针变量和指针类型

1.指针变量

一般形式:
类型名 *指针变量名;

引用指针变量时,可能有3种情况:

  1. 给指针变量赋值

例如:p=&a;
指针变量p的值是变量a的地址,p指向a

  1. 引用指针变量指向的变量

若以及执行p=&a;则
printf(“%d”,p);
作用是:以整数形式输出指针变量p所指向的变量a的值
若执行
p=1;
表示将整数1赋给p当前所指向的变量a,即a=1

  1. 引用指针变量的值

printf(“%o”,p);
作用:以八进制数形式输出指针变量p的值,若p指向了a,就是输出了a的地址,即&a

运算符

  1. &——取地址运算符。&a是变量a的地址
  2. *——指针运算符(或称“间接访问”运算符),*p代表指针变量p指向的对象

2.指针类型

指针类型决定了指针进行解引用的时候,能访问的空间大小
int *p; *p能够访问4个字节
char *p; *p能够访问1个字节
double *p;*p能够访问8个字节

例如:

#include<stdio.h>
int main()
{
	printf("char=%d\n",sizeof(char*));
	printf("short=%d\n", sizeof(short*));
	printf("int=%d\n", sizeof(int*));
	printf("double=%d\n", sizeof(double*));
	return 0;
}

结果:
char=4
short=4
int=4
double=4

例如:

#include<stdio.h>
int main()
{
	int a = 0x11223344;
	int * pa = &a;
	char* pc = &a;
	printf("%p\n", pa);
	printf("%p\n", pc);
	return 0;
}

结果:
00EFFA00
00EFFA00

在这里插入图片描述
指针类型决定了:指针走一步走多远(指针的步长)
intp;p+1–>4
char
p;p+1–>1
double*p;p+1–>8
指针的类型决定了指针向前或者向后走一步有多大距离(单位:bety字节)
在这里插入图片描述
指针的类型决定了,对指针解引用的时候有多大的权限(能操作几个字节)char * 的指针解引用只能访问一个字节
int *的指针的解引用能访问四个字节
在这里插入图片描述

char* 类型的指针是为了存放 char 类型变量的地址。
short* 类型的指针是为了存放 short 类型变量的地址。
int* 类型的指针是为了存放 int 类型变量的地址。

3.指针变量作为函数参数

函数的参数可以是指针类型

作用:将一个变量的地址传送到另一个函数中

例如:对输入的两个整数按大小顺序输出。

#include<stdio.h>
int main()
{
	void swap(int *p, int *p2);
	int a, b;
	int *p_1, *p_2;
	printf("请输入两个整数:");
	scanf("%d,%d", &a, &b);
	p_1 = &a;
	p_2 = &b;
	if (a < b)
		swap(p_1, p_2);
	printf("max=%d,min=%d\n", a, b);
	return 0;
}
void swap(int *p1, int *p2)
{
	int temp;
	temp = *p1;
	*p1 = *p2;
	*p2 = temp;
}

结果:
请输入两个整数:5,9
max=9,min=5

  • *p1就是a,是整形变量。但 *temp是指针变量temp所指向的变量
  • p1是指针变量,应该等于地址,p1=&a

函数的调用只可以得到一个返回值,而使用指针变量作参数,可以得到多个变化了的值。

三、数组指针

数组指针指向的是数组,那数组指针中存放的应该是数组的地址,能够指向数组的指针
例如:

#include <stdio.h>
int main()
{
    int arr[10] = {1,2,3,4,5,6,7,8,9,0};
    int (*p)[10] = &arr;//把数组arr的地址赋值给数组指针变量p
    return 0;
}

arr表示的是数组的首地址
&arr 表示的是数组的地址
整形指针: int * pint; 能够指向整形数据的指针。
浮点型指针: float * pf; 能够指向浮点型数据的指针

1.数组元素的指针

数组元素的指针就是数组元素的地址
引用数组元素可以用下标法(如:a[3]),也可以是指针法——通过指向数组元素的指针找到所需元素

程序中的数组名不代表整个数组,只代表数组首元素的地址。
例如:
p=a;
作用:把a数组的首元素的地址赋给指针变量p

int *p=&a[0];等价于int *p;p=&a[0];等价于int *p=a;

int (*p)[10];

  • p先和*结合,说明p是一个指针变量,然后指着指向的是一个大小为10个整型的数组。所以p是一个指针,指向一个数组,叫数组指针。
  • 注意:[ ]的优先级要高于号的,所以必须加上()来保证p先和结合。

2.引用数组元素时指针的运算

在指针已指向一个数组元素时

  1. p+1指向同一数组中的下一个元素,p-1指向同一数组中的上一个元素
  2. 若p的初值为&a[0],则p+i和a+i就是数组元素a[i]的地址,或者说,他们指向a数组序号为i的元素
  3. *(p+i)或 *(a+i)是p+i或a+i所指向的数组元素,即a[i]
  4. 若指针变量p1和p2都指向同一数组中的元素,若执行p2-p1,结果是p2-p1的值(两个地址之差)除以数组元素的长度

两个地址不能相加,p1+p2是无实际意义的

3.通过指针引用数组元素

引用一个数组元素,可以用两种方法:

  1. 下标法:a[i]形式
  2. 指针法:*(a+i)或 *(p+i)。其中a是数组名,p是指向数组元素的指针变量,其初值p=a。

例如:

int main()
{
	int a[10];
	int i;
	printf("请输入10个整数:");
	for (i = 0; i < 10; i++)
	{
		scanf("%d", &a[i]);
	}
	for (i = 0; i < 10; i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");
	return 0;
}

结果:
请输入10个整数:0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9

分析情况:

  1. p++;*p;

p++使p指向下一元素a[1],然后再执行*p,则得到下一个元素a[1]的值

  1. *p++;

等价于*(p++),先引用p的值,实现*p的运算,然后再使p自增1

  1. *(p++)与 *(++p)作用不同

*(p++)是先取 *p值,然后使p+1
(++p)是先使p+1,然后取 p
例如:
p=a;
输出
(p++),得到a[0]的值
输出
(++p),得到a[1]的值

  1. ++(*p)

表示p所指向的元素值加1
注意:是元素的值加1,而不是指针p的值加1
例如:
p=a;
++(*p)相当于++a[0],若a[0]=3;
执行++(*p)后,a[0]=4;

  1. 若p指向a数组中第i个元素a[i],则:
    *(p - -)相当于a[i - -],先对p进行“ * ”运算(求p所指向的元素的值),在使p自减
    *(++p)相当于a[++i],先使p自加,在进行“ * ”
    *(- - p)相当于a[- - i],先使p自减,在进行“ * ”

4.用数组名作函数参数

以变量名和数组名作为函数参数的比较

实参类型变量名数组名
要求形参的类型变量名数组名或指针变量
传递的信息变量的值实参数组首元素的地址
通过函数调用能否改变实参的值不能改变实参变量的值能改变实参数组的值

当用变量名作为函数参数时传递的是变量的值,当用数组名作为函数参数时,由于数组名代表的是数组首元素地址,因此传递的是地址,所以要求形参为指针变量。

实参数组名代表一个固定的地址,或者说是指针常量,但形参数组名并不是一个固定的地址,而是按指针变量处理

在函数调用进行虚实结合后,形参的值就是实参数组首元素的地址。在函数执行期间,可以再被赋值

实参用数组名,形参可以是数组名,也可用指针变量名

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值