目录
先看个代码。
#include<stdio.h>
int main()
{
int a = 10;//int a是4个字节
int* pc = &a;//pc是创建出来存放地址的,pc是指针变量
printf("%p\n", pc);
printf("%d\n", *pc);
return 0;
}
得出结果:
指针
指针是c语言学习过程中的一个很重要,又比较难的知识点,需要我们花比较多的时间去搞懂它。
一、指针是什么?
1、指针是内存中一个最小单元的编号,也就是地址,常量。
2、口头上的指针,一般指指针变量,是用于存放内存地址的变量。(存放在指针中的值都被当做地址处理。)
(即:指针就是地址,口头上的指针通常指指针变量)
*指针的大小在32位平台是4个字节,在64位平台是8个字节。
*内存单元的指针和内容是不同的概念。就比如去银行取钱,银行账户就是指针,取出来的钱就是内容。
*指针变量的大小取决于存储一个地址需要多大的空间。
二、定义指针变量(专门存放地址)
1.定义指针的一般形式
类型说明符 *指针变量名
int* p1;
double* p2;
char* p3;
如果直接求这几个类型指针的字节,得出的结果是一样的。
#include<stdio.h>
int main()
{
int arr1[10] = { 0 };
char arr2[10] = { 0 };
double arr3[10] = { 0 };
int* p1 = &arr1;
int* p2 = &arr2;
int* p3 = &arr3;
printf("%d\n", sizeof(p1));
printf("%d\n", sizeof(p2));
printf("%d\n", sizeof(p3));
return 0;
}
得出结果:
既然如此, 我们为什么要在前面加类型说明符呢?我们继续往下看:
1.指针类型决定了:指针进行解引用操作的时候,访问几个字节(权限)。
char* 的指针解引用访问1个字节;
int* 的指针解引用访问4个字节;
double* 的指针解引用访问8个字节。
2.指针类型决定了指针的步长(向前、向后 走一步多大距离)
char*指针+1 ,意思是跳过1个字符,也就是向后走1个字节;
int*指针+1 ,意思是跳过1个整型,也就是向后走4个字节;
double*指针+1 ,意思是跳过1个double,也就是向后走8个字节。
2.两个操作符
&——取地址操作符
*——解引用操作符(通过存放地址找到指向的空间)
(这两个操作符的作用是可以理解为相互抵消的。)
#include<stdio.h>
int main()
{
int a = 10;
printf("%d\n",*(&a));
return 0;
}
输出结果跟我们设想的一样~
3.野指针
出现野指针的原因:①指针没有初始化。②指针越界访问。
三.题目实练
1、关于指针的概念,错误的是:( )
A.指针是变量,用来存放地址
B.指针变量中存的有效地址可以唯一指向内存中的一块区域
C.野指针也可以正常使用
D.局部指针变量不初始化就是野指针
【C】
A:正确,指针变量中存储的是一个地址,指向同类型的一块内存空间
B:正确,地址是唯一的,一个指针变量中只能存储一个地址。
C:野指针指向的空间时非法的,或者说该指针指向的空间已经不存在了,因此野指针不能使用
D:局部指针变量没有初始化时里面就是随机值,因此指向那个位置不一定,故将其看成是野指针。
这道题考察的就是我们对指针的一些基本概念的了解程度。
2、设已有定义:float x;则一下定义指针变量p并赋初值的语句中正确的是()。
A.float *p=1024
B.int *p=(float)x
C.float p=&x
D.float *p=&x
【D】注意要正确赋初值。
关于给指针变量赋值有两种:
(1)定义的同时赋值
int a;
int *p=&a;
(2)先定义再赋值
int a;
int *p;
p=&a;
[注意】指针变量只能存放地址,不能把整数赋值给指针变量。
int *p;
p=100;//不合法
3、以下系统中,int类型占几个字节,指针占几个字节,操作系统可以使用的最大内存空间是多大:( )
A.32位下:4,4,2^32 64位下:8,8,2^64
B.32位下:4,4,不限制 64位下:4,8,不限制
C.32位下:4,4,2^32 64位下:4,8,2^64
D.32位下:4,4,2^32 64位下:4,4,2^64
【C】在32位系统下,int类型占4个字节,指针占4个字节,最大内存空间2^32
在64位系统下,int类型占4个字节,指针占8个字节,最大内存空间2^64
4、若有定义语句:double *p,a;则能正确赋值并通过scanf语句给输入项读入数据的程序段是()。
A.*p=&a;scanf("%lf",p);
B.*p=&a;scanf("%f",p);
C.p=&a;scanf("%lf:,*p);
D.p=&a;scanf("%lf",p);
【D】 double类型是双精度,所以用%lf。根据前面说的赋值,就是先定义后赋值的类型,就是p=&a。scanf("%1f",p)表示用键盘输入的数赋给指针变量p所指向的地址单元中。
总结
以上就是今天要讲的内容,本文仅仅简单介绍了指针的概念性的东西。