C 认识指针

目录

一、取地址操作符(&)

二、解引用操作符(*)

三、指针变量

[1、 指针变量的大小](#1、 指针变量的大小)

[2、 指针变量类型的意义](#2、 指针变量类型的意义)

[2.1 指针的解引用](#2.1 指针的解引用)

[2.2 指针 +- 整数](#2.2 指针 +- 整数)

[2.3 调试解决疑惑](#2.3 调试解决疑惑)


认识指针,指针比较害羞内敛,我们需要通过他的好朋友们认识他

一、取地址操作符(&)

cpp 复制代码
//VS2022 x86
#include <stdio.h>
int main()
{
	int i = 1314;
	int* p = &i; //  &  取地址操作符;将 i 里的地址取出来放到 p 里
                 //int* 表示p是整型指针变量,指针是用来存放地址的
    printf("%p\n", p);    
	printf("%p\n", &i);
	return 0;
}

把平台换成 x86 好观察(x64也可以,只是长一些,为了这篇文章后面统一都是x86平台)

运行后可以看到之这一长串数字加字母,不用管他,知道这是地址就行,可以看出:

指针p 里存放的地址和从 变量i 中取出来的地址是一样的;每次编译地址都会变,但 p == &i 。


二、解引用操作符(*)

cpp 复制代码
#include <stdio.h>
int main()
{
	int i = 1314;
	int* p = &i;
	printf("%d\n", i);
	*p = 20;    // * 解引用操作符
	printf("%d\n", i);
	return 0;
}

可以看到 变量i 的值被改变了,这是因为 *p 的意思是将 p 里存放的地址通过解引用从而找到 变量i,然后赋值20;

可以这么理解,i 是一个宝藏,p 就是这个宝藏所在坐标,然后你通过正确的解读宝藏在地图上的位置(*)最终找到了宝藏,随后把它挖走并往里面放了个石头埋起来戏耍后面的人,i 就变成了石头。


三、指针变量

前面通过对他朋友的认识,顺便知道了指针变量是用来存放地址的,那这里我们需要了解他的特点

1、 指针变量的大小

cpp 复制代码
#include <stdio.h>
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环境下(32位平台) x64环境下(64位平台)

结论:

  • 32位平台下地址是32个bit位,指针变量大小是4个字节;
  • 64位平台下地址是64个bit位,指针变量大小是8个字节;
  • 注意指针变量的大小和类型是无关的,只要指针类型的变量,在相同的平台下,大小都是相同的。

不管给他任何修饰词(int*、char*),在我们面前(32位平台)就是腼腆得很,在朋友面前(64位平台)就是开放得很,所以和他交上朋友才能更了解他嘿嘿。

那就疑惑了,变量规定类型是因为有字节大小区分,指针变量大小在不同类型下字节大小都一样,那为什么要规定指针变量的类型呢?

2、 指针变量类型的意义

2.1 指针的解引用

通过代码就能很清楚的看出来啦,好好看好好学

cpp 复制代码
#include <stdio.h>
int main()
{
	int n = 0x11223344;	//十六进制,两个数字代表一个字节
	char* p = (char*) &n;    //不强转会报警告
	*p = 0;
	printf("%x", n);    //%x 打印十六进制整数
	return 0;
}
cpp 复制代码
#include <stdio.h>
int main()
{
	int n = 0x11223344;	//十六进制,一个数字代表一个字节
	int* p = &n;
	*p = 0;
	printf("%x", n);
	return 0;
}

char* p int* p

可以看到,int* p 会将n的4个字节全部改为0,但是 char* p 只是将n的第⼀个字节改为0。

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

2.2 指针 +- 整数
cpp 复制代码
#include <stdio.h>
int main()
{
	int n = 10;
	printf("%p\n", &n);
	printf("=================\n");

	char* pc = (char*)&n;
	printf("%p\n", pc);
	printf("%p\n", pc + 1);
	printf("=================\n");

	int* pi = &n;
	printf("%p\n", pi);
	printf("%p\n", pi + 1);
	return 0;
}

我们可以看出, char* 类型的指针变量 +1 跳过 1个字节, int* 类型的指针变量 +1 跳过了 4个字节。 这就是指针变量的类型差异带来的变化。指针 +1 ,其实跳过1个指针指向的元素。指针可以+1,那也可以-1。

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

2.3 调试解决疑惑

诶不对哇,3.2中 cha* p 怎么改第一个字节把0x11223344的44改了,不应该是改11吗,来,跟我调试起来

(1)

(2)Ctrl+Fn+F10(或者Ctrl+F10)进入调试

(3)

(4)

(5)注意左边的箭头,Fn+F10 箭头会指向下一条语句,下到图片位置

看到了吧,内存中的0x11223344是倒着存进内存里的,所以第一个字节是44,继续按Fn+F10就可以看到 44 变为 00。


相关推荐
呜喵王阿尔萨斯10 分钟前
编程中的英语
c语言·c++
糖葫芦君31 分钟前
Policy Gradient【强化学习的数学原理】
算法
only-lucky1 小时前
C语言socket编程-补充
服务器·c语言·php
向阳@向远方2 小时前
第二章 简单程序设计
开发语言·c++·算法
JeffersonZU2 小时前
Linux/Unix进程概念及基本操作(PID、内存布局、虚拟内存、环境变量、fork、exit、wait、exec、system)
linux·c语言·unix·gnu
github_czy3 小时前
RRF (Reciprocal Rank Fusion) 排序算法详解
算法·排序算法
许愿与你永世安宁4 小时前
力扣343 整数拆分
数据结构·算法·leetcode
爱coding的橙子4 小时前
每日算法刷题Day42 7.5:leetcode前缀和3道题,用时2h
算法·leetcode·职场和发展
ruanjiananquan994 小时前
c,c++语言的栈内存、堆内存及任意读写内存
java·c语言·c++
满分观察网友z4 小时前
从一次手滑,我洞悉了用户输入的所有可能性(3330. 找到初始输入字符串 I)
算法