指针在C语言中有着不可取代的地位,今天我们就来了解下指针到底是什么,有什么作用。
目录
基础知识
进入正题之前有几知识点需要先说明
注意:本文采用32位计算机
计算机中的单位
单位名称 | 换算 |
bit(计算机中最小单位) | |
byte | 8bit |
kb | 1024byte |
mb | 1024kb |
gb | 1024mb |
tb | 1024gb |
进制
计算机中有三种进制
1,二进制:0,1
2,八进制: 0,1,2,3,4,5,6,7
3,十进制:0,1,2,3,4,5,6,7,8,9
4,十六进制:0,1,2,3,4,5,6,7,8,9,a(10),b(11),c(12),d(13),e(14),f(15)
进位原理:十进制封是进一,二进制封二进一,其他以此类推
数据类型的所需字节
int main()
{
printf("char=%d\n", sizeof(char));
printf("short=%d\n", sizeof(short));
printf("int=%d\n", sizeof(int));
printf("long=%d\n", sizeof(long));
printf("long long=%d\n", sizeof(long long));
printf("float=%d\n", sizeof(float));
printf("double=%d\n", sizeof(double));
system("pause");
return 0;
}
内存
内存是计算机中特别重要的存储器,可以说内存是程序的运行空间
显示中它长这样
抽象化后,它长这样
0000 | 0001 | 0002 | 0003 | 0004 | 0005 | 0006 | 0007 | 0008 | 0009 |
为了方便是使用,内存中被划分了许多细小的单元(具体多少之后再谈),又为了便于使用,每一个单元都被编上了号,上表中0000到0009就是内存的编号。
当然实际计算机是以二进制编号
实际二进制表示0000 0000 0000 0000 0000 0000 0000 0000
在编译器中是以十六进制编号
十六进制表示0x00 00 00 00
内存的大小
内存单元被划分为byte,每个单元的空间是1byte
内存的大小有4g,8g,16g等等,本文采用4g
4g内存的空间:4gb*1024*1024*1024=4,294,967,296byte
所以4g内存中,有4,294,967,296个空间
而他的编码则是0到4,294,967,295(注意这里,编码是从0开始,计算是从1开始,所以有1位数的差异)
将0和4,294,967,295换算
十进制 | 二进制 | 十六进制 |
0 | 0000 0000 0000 0000 0000 0000 0000 0000 | 0x00000000 |
4,294,967,295 | 1111 1111 1111 1111 1111 1111 1111 1111 | 0xFFFFFFFF |
注意:变量都是存储在内存中,所以变量是有地址的,它的地址就是内存的地址
注意:变量都是存储在内存中,所以变量是有地址的,它的地址就是内存的地址
注意:变量都是存储在内存中,所以变量是有地址的,它的地址就是内存的地址
指针
指针是为了有效使用内存的一种变量,它能够存储变量的地址,简单地说,指针就是地址。
上图中,可以看出指针p是用来保存变量a的地址的
指针保存地址的规律
前面的知识点已经提过,每种变量占据的空间不同,比如int就是4个字节,但是指针中只能保存一个地址,那么指针是怎么保存地址的呢
上图中0X003BF8D0就是变量a的指针,实际所占用的内存空间是0a以及后面的3个空间,分别是0X003BF8D0,0X003BF8D1,0X003BF8D2,0X003BF8D3。
这里可以看到指针p所保存的内容是0X003BF8D0,所以指针保存的是变量的第一个地址。
指针保存地址的方法
C语言操作符中有两个特殊的操作符
&:取地址操作符,表示获取对方的地址
*:解引用操作符,表示通过地址访问对方
int main()
{
int a = 10;
int *p = &a;
printf("%d", *p);
system("pause");
return 0;
}
上面的代码中,int *p=&a就是将a的地址,存入p的空间,而printf("%d", *p);则是通过*p访问到a,并通过printf函数打印*p所访问的数值,结果是10,从这里可以看出*p某种程度上就是a的别名
指针的类型
上面的代码中,指针p必须和变量a是一样的类型,那么如果保存其他类型的变量,指针是否也是一样使用int类型呢,答案是否定的,指针的类型必须与变量的类型相同。
float类型的指针保存int类型变量,虽然不会报错,但是通过*p访问时,里面的值已经不是10了
所以一定要注意,指针的类型一定要与变量的类型相同
指针的大小
既然指针有各种不同的类型,那么指针的大小是否一样呢
int main()
{
printf("char* p=%d\n", sizeof(char*));
printf("short* p=%d\n", sizeof(short*));
printf("int* p=%d\n", sizeof(int*));
printf("long* p=%d\n", sizeof(long*));
printf("long long* p=%d\n", sizeof(long long*));
printf("float* p=%d\n", sizeof(float*));
printf("double* p=%d\n", sizeof(double*));
system("pause");
return 0;
}
上面代码的运行结果都是4,这就表示无论什么类型的指针都只有4个字节的大小。
还记得前面讲过的内存地址那里么,内存地址的大小就是4个字节,所以指针的大小只与内存地址的大小有关,32位计算机中是4个字节,64为计算机中是8个字节
指针的声明与赋值
指针的声明与变量类似
int *p;
请注意,这里的*并不是解引用操作符,而是为了说明p是个指针的符号
p=&a
给指针赋值必须使用&操作符,指针默认收到的数据都是地址,如果不加&符号,会导致指针指向别的地方,如果在该程序内,会造成程序崩溃,如果指向了系统内存,emmm........所以这里无法演示,感兴趣的可以自己试试。
多个指针指向一个变量
C语言中,并没有规定一个变量只能被一个指针指向,所以么........
int main()
{
int a = 10;
int *p = &a;
int *q = p;
printf("*p=%d\n", *p);
printf("*q=%d\n", *q);
*q = 10086;
printf("*p=%d\n", *p);
printf("*q=%d\n", *q);
system("pause");
return 0;
}
指针与const
之前我们说过const可以锁定变量的值,使变量不能被修改,指针也是变量,自然可以被锁定,只不过锁定的方式有些不同
上面的代码,*p已经被锁定,无法通过解引用操作修改a的值。
上面的代码中,指针p被锁定,所以在此给指针赋值时还报错。