指针(一)
好久不见大家好,长时间没有更新了
今天我们说指针(○゜^○)
想必大家对指针有一个恐惧感,在学习C语言的过程中我们,一定听说过指针的难度,今天我们对于新生会说,入门级的指针知识
1,内存和地址
在了解指针的前,我们先了解内存和地址的概念
首先地址;
(1)为了有效的使用内存,把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节。
如图
(2)为了能够有效的访问即快速找到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地址。
如图
内存;
CPU(中央处理器)在处理数据的时候,需要的数据是在内存中读取的,处理后的数
据也会放回内存中,内存就是用来储存数据的地方
我们能够从下面的图片中看到内存中一个一个的空间有不同的编号 这些编号有什么含义呢?ᴥ
在计算机中我们把内存单元的编号也称为地址。C语⾔中给地址起了新的名字叫:指针。
(ノ^o^)ノ
简单的了解指针后,我们可以去了解地址总线
1.1地址总线
32位机器有32根地址总线,
每根线只有两态,表⽰0,1【电脉冲有⽆】,那么
⼀根线,就能表⽰2种含义,2根线就能表⽰4种含
义,依次类推。32根地址线,就能表⽰2^32种含
义,每⼀种含义都代表⼀个地址。
地址信息被下达给内存,在内存上,就可以找到该地址对应的数据,将数据在通过数据总线传⼊CPU内寄存器。
同理
64位机器有64根地址总线,
每根线只有两态,表⽰0,1【电脉冲有⽆】,那么
⼀根线,就能表⽰2种含义,2根线就能表⽰4种含
义依次类推。64根地址线,就能表⽰2^64种含义,每⼀种含义都代表⼀个地址。
地址信息被下达给内存,在内存上,就可以找到该地址对应的数据,将数据在通过数据总线传⼊CPU内寄存器。
2,指针变量和取地址符&
指针提供一种以符号形式使用地址的方法。因为计算机的硬件指令非常依赖地址指针在某种程度上把程序员想要传达的指令以更接近机器的方式表达。因此,使用指针的程序更有效率,尤其是,指针能有效地处理数组
当我们使用一组数据比如
int main()
{
int a = 10;
printf("%d", a);
return 0;
}
那他的地址是什么呢?我们使用%P去打印一个数据的地址 ,当我们要使用地址,要有一个介质,于是就有了&取地址符
#include
int main()
{
int a = 10;
printf("a=%dn", a);
printf("a=%p", &a);
return 0;
}
在上面,我们使用取地址符看到了a的地址,是 16进制的样子,是我们知道地址又有什么用呢?我们又该如何去使用我们的地址?(‾.‾“)┐
3,指针变量和解引⽤操作符(*)
指针变量
那我们通过取地址操作符(&)拿到的地址是⼀个数值,⽐如:0x006FFD70,这个数值有时候也是需要存储起来,⽅便后期再使⽤的,那我们把这样的地址值存放在哪⾥呢?答案是:指针变量中。
例如
int main()
{
int a = 10;
return 0;
}
int main()
{
int a = 10;
int* pa = &a; //将a的地址放到了int *类型的指针变量pa中
printf("%pn", pa);
printf("%pn", &a);
return 0;
}
指针变量是什么?指针变量也是⼀种变量,这种变量就是⽤来存放地址的,存放在指针变量中的值都会理解为地址。
如何拆解指针类型
当我们使用指针变量时,我们使用什么样子的指针变量?指针变量的类型是什么?
像下面的的代码
int main()
{
int a = 10;
int* pa = &a; //将a的地址放到了int *类型的指针变量pa中
printf("%pn", pa);
printf("%pn", &a);
return 0;
}
这⾥pa左边写的是 int* , * 是在说明pa是指针变量,⽽前⾯的 int 是在说明pa指向的是整型(int)
类型的对象。
如果有⼀个char类型的变量a,a的地址,要放在什么类型的指针变量中呢?
例如char a='f'
pa=&a
当我们了解指针变量的时候,我们还要去指导指针变量到底多大呢?其实指针变量在固定的位数下,指针变量的大小是相同的。比如说接下来是32位的。我们可以通过代码去看到他们所占的字节。
int main()
{
printf("%dn", sizeof(int*));
printf("%dn", sizeof(char*));
printf("%dn", sizeof(short*));
printf("%dn", sizeof(long*));
printf("%dn", sizeof(long long*));
printf("%dn", sizeof(float*));
printf("%dn", sizeof(double*));
return 0;
}
下面的是64位的
int main()
{
printf("%dn", sizeof(int*));
printf("%dn", sizeof(char*));
printf("%dn", sizeof(short*));
printf("%dn", sizeof(long*));
printf("%dn", 服务器托管网sizeof(long long*));
printf("%dn", sizeof(float*));
printf("%dn", sizeof(double*));
return 0;
}
于是我们就可以得到这样一个结论,在同样的操作位数下。指针变量的大小是不变的。
32位平台下地址是32个bit位,指针变量⼤⼩是4个字节
• 64位平台下地址是64个bit位,指针变量⼤⼩是8个字节
• 注意指针变量的⼤⼩和类型是⽆关的,只要指针类型的变量,在相同的平台下,⼤⼩都是相同的。
4,解引⽤操作符
解引用操作符是c语言常用的操作符,它是我们要使用地址的时候才要去使用。比如下面这样的代码。
int main()
{
int a = 10;
int* pa = &a;
return 0;
}
我们可以通过接引用操作符去修改a的值,这里其实。我们没有直接的去改变a的值,我们是通过a的地址找到了a所占的空间,然后去改变a的值。通俗来说就是我们通过了其他方式去改变了a,而不是直接改变了a。
为啥⾮要使⽤指针呢?
其实这⾥是把a的修改交给了pa来操作,这样对a的修改,就多了⼀种的途径,写代码就会更加灵活,
#include
int main()
{
int a = 10;
int* pa = &a;
printf("%dn", a);
*pa = 20;
printf("%dn", a);
return 0;
}
大家可能看到我在上面写代码的指针变量的*和前面的*的位置都不同。这里主要是为了告诉大家,这几种写法都是对的。
( )❤
int main()
{
int a = 10;
int* pa = &a;
printf("%d", a);
return 0;
}
int main()
{
int a = 10;
int *pa = &a;
printf("%d", a);
return 0;
}
int main()
{
int a = 10;
int * pa = &a;
printf("%d", a);
return 0;
}
上面都一样在VS2022都是对的
5,指针变量和数组
通过以往的学习,我们了解过数组,再通过上面的学习,我们了解了指针变量,那么指针变量和数组之间又有什么关系,又有什么有趣的现象呢?让我们去探究一下。
我们先看这样一串代码。
#include
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10};
int* pa = &arr;
int i = 0;
for (i = 0; i
为什么打印的不是arr数组的所有数呢?打印的却都是1,我们刚刚得知int *pa是我们用来存放数组地址的指针变量。我们打印我们的指针变量.打印的全都是1,那么会不会是因为我们放到指针变量的地址是数组首元素的地址呢~(^◇^)/
我们验证一下
#include
int main()
{
int arr[服务器托管网10] = { 1,2,3,4,5,6,7,8,9,10};
int* pa = &arr;
int i = 0;
for (i = 0; i
我们惊喜的发现PA所存放的地址就是数组首元素的地址,以前我们学会用循环去打印一个数组内所有的元素。现在我们如何使用指针变量去打印呢。我们先写出下面这样的代码。
#define _CRT_SECURE_NO_WARNINGS 1
#include
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10};
int* pa = &arr;
int i = 0;
for (i = 0; i
5.1指针的变化
我们发现这样的代码很容易的,就将我们数组内所有的元素打印出来了,那他是怎么做到的呢?❃ႣᄎႣ❃
我们通过其他的代码去观察他是怎么实现的。例如下面这样的代码。
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10};
int* pa = &arr;
int i = 0;
for (i = 0; i
第一次循环
第二次循环
第三次循环
我们惊奇的发现,他每次好像跳过了4个字节。而不是一个字节一个字节的修改。每一次pa+1的时候,他都会跳过4个
难道所有的指针变量都会跳过4个字节吗?我们接下来再看看char的ᴥ
#include
int main()
{
char arr[10] = { 1,2,3,4,5,6,7,8,9,10};
char* pa = &arr;
char i = 0;
for (i = 0; i
第一次循环
第二次循环
我们又发现(〜^∇^)〜char并没有像int每一次修改都跳4个。还是一个一个的修改。我自己画的图不要介意,谢谢。
6,void* 指针
在指针类型中有⼀种特殊的类型是 void* 类型的,可以理解为⽆具体类型的指针(或者叫泛型指
针),这种类型的指针可以⽤来接受任意类型地址。但是也有局限性, void* 类型的指针不能直接进指针的+-整数和解引⽤的运算。
int main()
{
int a = 10;
char ch = 'a';
char* pa=&a;
}
我们可以看到,虽然运行正确,但是系统给出了类型不兼容的提示。但如果我们将它换成void类型的指针。
就像下面这样一段代码。我们的系统并没有给出错误提示。
#include
int main()
{
int a = 10;
char ch = 'a';
void* pa=&a;
}
但是void* 类型的指针不能直接进指针的+-整数和解引⽤的运算。
就向下面的代码一样
int main()
{
int a = 10;
void* pa=&a;
*pa = 20;
}
系统错误了
于是我们在这里简单的介绍了一下,这个指针后面呢,我们会写关于指针的其他知识,毕竟这才是指针1为什么不往后写?主要是本人也有点小累了。最后完结,撒花。
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net
相关推荐: Node.js 从前端到全栈的艰难历程Users
Node.js 从前端到全栈的艰难历程 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,它可以在服务器端运行 JavaScript 代码,使得 JavaScript 不再仅限于浏览器中的客户端脚本语言,而可以成为一种全栈…