指针从入门到精通(一)-1

简介: 指针从入门到精通(一)

一、内存、地址、指针变量

在计算机中我们把内存单元的编号也称为地址

C语⾔中给地址起了新的名字叫:指针。

 所以我们可以理解为: 内存单元的编号 == 地址 == 指针


1.1  取地址操作符(&)

理解了内存和地址的关系,我们再回到C语⾔,在C语⾔中创建变量其实就是向内存申请空间,⽐如:

#include <stdio.h>
int main()
{
int a = 10;
return 0;
}


上述的代码就是创建了整型变量a,内存中申请4个字节,⽤于存放整数10,其中每个字节都 有地址,上图中4个字节的地址分别是什么呢?

别急,下面我们就学习如何得到a的地址呢?

这⾥就得学习⼀个操作符&-取地址操作符

#include <stdio.h>
int main()
{
  int a = 10;
  &a;//取出a的地址
  printf("%p\n", &a);
  return 0;
}


我们从存放a的内存中发现:程序打印出的003EFCEC就是a所占 4个字节中地址较⼩的字节的地址。


1.2  指针变量

那我们通过取地址操作符(&)拿到的地址是⼀个数值,⽐如:003EFCEC ,这个数值有时候也是需要 存储起来,⽅便后期再使⽤的,那我们把这样的地址值存放在哪⾥呢?

答案是: 指针变量中 。


⽐如:

#include <stdio.h>
int main()
{
int a = 10;
int* pa = &a;//取出a的地址并存储到指针变量pa中
return 0;
}


指针变量也是⼀种变量,这种变量就是⽤来存放地址的,存放在指针变量中的值都会理解为地址。


image.png

正如上面所说,*代表后面的东西时指针变量,int代表指针变量指向对象的类型

那聪明的你,能否猜到:


char ch = 'w';

ch的地址应该存储哪个类型的指针变量呢?

没错!char * p=&ch;


1.3 解引用操作符(*)

上面我们学习到将地址存储到指针变量中,那么通过地址或者指针,我们能否找到地址或者指针指向的对象?答案时可以!

这⾥必须学习⼀个操作符叫解引⽤操作符(*)。


*就是解引⽤操作符, *pa 的意思就是通过pa中存放的地址,找到地址或指针指向的空间,*pa其实就是a变量了;所以*pa = 0,这个操作符是把a改成了0.

1.4 指针变量的大小

在了解指针变量大小之前,我们先了解一下计算机是如何编址的。

⾸先,必须理解,计算机内是有很多的硬件单 元,⽽硬件单元是要互相协同⼯作的。所谓的协

同,⾄少相互之间要能够进⾏数据传递。 但是硬件与硬件之间是互相独⽴的,那么如何通信呢?答案很简单,⽤"线"连起来。

⽽CPU和内存之间也是有⼤量的数据交互的,所以,两者必须也⽤线连起来。

不过,我们今天关心⼀组线,叫做地址总线。

我们可以简单理解,32位机器有32根地址总线, 每根线只有两态,表示0,1【电脉冲有无】,那么

⼀根线,就能表⽰2种含义,2根线就能表⽰4种含义,依次类推。32根地址线,就能表⽰2^32种含

义,每⼀种含义都代表⼀个地址。地址信息被下达给内存,在内存上,就可以找到

该地址对应的数据,将数据在通过数据总线传入CPU内寄存器。

ebcf4805ffdc1b1fcb7261e3740985ed_0b969f2b3b66402988347abf6d3147b0.png

32位机器假设有32根地址总线,每根地址线出来的电信号转换成数字信号后是1或者0,那我们把32根地址线产⽣的2进制序列当做⼀个地址,那么⼀个地址就是32个bit位,要4 个字节才能存储。


如果指针变量是⽤来存放地址的,那么指针变的⼤⼩就得是4个字节的空间才可以。

同理64位机器,假设有64根地址线,⼀个地址就是64个⼆进制位组成的⼆进制序列,存储起来就需要 8个字节的空间,指针变量的大小就是8个字节。


下面我们就来验证一下:

#include <stdio.h>
//指针变量的⼤⼩取决于地址的⼤⼩
//32位平台下地址是32个bit位(即4个字节)
//64位平台下地址是64个bit位(即8个字节)
int main()
{
  printf("%zd\n", sizeof(char*));
  printf("%zd\n", sizeof(short*));
  printf("%zd\n", sizeof(int*));
  printf("%zd\n", sizeof(double*));
  return 0;
}


X86环境输出结果:

X64环境输出结果:


结论:

(1)32位平台下地址是32个bit位,指针变量大小是4个字节。

(2) 64位平台下地址是64个bit位,指针变量大小是8个字节。

(3)注意指针变量的大小和类型是无关关的,只要指针类型的变量,在相同的平台下,大小都是相同的。


1.5 指针变量类型的意义

指针变量的大小和类型无关,只要是指针变量,在同⼀个平台下,大小都是⼀样的,为什么还要有各 种各样的指针类型呢?

其实指针类型是有重要意义!

我们不妨调试一下,下面的代码:

//代码1
#include <stdio.h>
int main()
{
  int n = 0x11223344;
  int* pi = &n;
  *pi = 0;
  return 0;
}
//代码2
#include <stdio.h>
int main()
{
    int n = 0x11223344;
    char* pc = (char*)&n;
    *pc = 0;
    return 0;
}

代码1调试结果:

代码2调试结果:


调试我们可以看到,代码1会将n的4个字节全部改为0,但是代码2只是将n的第⼀个字节改为0。

结论1:指针的类型决定了,对指针解引⽤的时候有多大的权限(⼀次能操作几个字节)。

比如: char* 的指针解引用就只能访问⼀个字节,而int* 的指针的解引⽤就能访问四个字节。

除此之外,指针变量类型还有其他意义吗?

答案是肯定的,我们不妨分析一下,下面这串代码:

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

代码运行结果如下:

我们可以看出, char* 类型的指针变量+1跳过1个字节, int* 类型的指针变量+1跳过了4个字节。

这就是指针变量的类型差异带来的变化。

结论2:指针的类型决定了指针向前或者向后⾛⼀步有多大(距离)。

相关文章
|
20天前
|
存储 安全 编译器
【C++专栏】C++入门 | auto关键字、范围for、指针空值nullptr
【C++专栏】C++入门 | auto关键字、范围for、指针空值nullptr
34 0
|
20天前
|
存储 C语言 C++
c语言从入门到实战——数组指针与函数指针
数组指针和函数指针都是指针类型,但是它们指向不同的数据类型。 数组指针:数组指针指向的是数组类型。 函数指针:函数指针指向的是函数类型。 数组指针和函数指针是C语言中的两种重要指针类型。数组指针指向一个数组,可以用来访问和修改数组中的元素;而函数指针则指向一个函数,可以用来调用该函数。两者在语法和用法上有所不同,需要仔细区分。正确理解和使用它们可以提高程序的效率和可维护性。
34 0
|
20天前
|
存储 安全 编译器
c语言从入门到实战——初识指针
C语言指针是一种变量,它存储了另一个变量的内存地址。通过指针,我们可以直接访问内存中的数据,从而实现灵活的数据操作。 指针是编程中的一个概念,它存储的是内存地址,指向某个变量。通过指针,可以直接访问和操作内存中的数据,提高程序效率。但使用指针时需小心,避免空指针和野指针等问题,确保程序安全稳定。
60 0
|
8天前
入门后指针进阶习题深度分析
入门后指针进阶习题深度分析
18 1
|
20天前
|
算法 测试技术 容器
【刷题】双指针入门
经过这四道题目的洗礼,我大概对双指针有了初步印象,接下来我会继续努力!!!
51 13
【刷题】双指针入门
|
20天前
|
算法 C++
【C++入门到精通】智能指针 shared_ptr循环引用 | weak_ptr 简介及C++模拟实现 [ C++入门 ]
【C++入门到精通】智能指针 shared_ptr循环引用 | weak_ptr 简介及C++模拟实现 [ C++入门 ]
19 0
|
20天前
|
安全 算法 数据安全/隐私保护
【C++入门到精通】智能指针 shared_ptr 简介及C++模拟实现 [ C++入门 ]
【C++入门到精通】智能指针 shared_ptr 简介及C++模拟实现 [ C++入门 ]
20 0
|
20天前
|
存储 算法 安全
【C++入门到精通】智能指针 auto_ptr、unique_ptr简介及C++模拟实现 [ C++入门 ]
【C++入门到精通】智能指针 auto_ptr、unique_ptr简介及C++模拟实现 [ C++入门 ]
14 0
|
20天前
|
安全 算法 IDE
【C++入门到精通】智能指针 [ C++入门 ]
【C++入门到精通】智能指针 [ C++入门 ]
13 0
|
20天前
|
存储 编译器 C++
【C++成长记】C++入门 | 类和对象(上) |类的作用域、类的实例化、类的对象大小的计算、类成员函数的this指针
【C++成长记】C++入门 | 类和对象(上) |类的作用域、类的实例化、类的对象大小的计算、类成员函数的this指针