C语言入门11 指针基础

文章详细介绍了32位系统中指针的概念,包括地址的分配方式、指针变量的定义和使用、指针与变量的关系、指针的自增行为以及指针与数组元素之间的联系。通过示例代码阐述了不同类型的指针在自增时的行为差异,并强调了数组名作为首地址的特性。
摘要由CSDN通过智能技术生成

一、前言

在32位系统下,系统给虚拟内存的每个存储单元分配了一个编号,从0x00 00 00 00 开始到 0xff ff ff ff 结束(4个字节),这个编号成为地址(虚拟地址)。而指针就是地址一个存储单元可以存储一个字节

指针变量:是一个变量,即用这个变量来存放一个地址编号。因为是在32位平台,地址总线是32位的,所以指针变量占4个字节。

注意:

  • 无论什么类型的地址,都是存储单元的编号,也就是虚拟内存,在32位平台下都是4字节
  • 对应类型的指针变量,只能存放对应类型的变量的地址。例如整型的指针变量只能存放整型变量的地址。

如下图,字符ch = 'b’占一个字节,他有一个地址编号,这个地址编号就是ch的地址。整型变量a = 0x12 34 56 78,a占4个字节,就有4个地址编号,默认最小那个为变量的地址,也就是0x00002000。(低位-》高位)
地址图片

二、指针的定义

关于指针的定义,首先要了解两个符号:

  1. & :取地址。
  2. * :定义时表修饰,其他时候表取值。
#include<stdio.h>
int main() {
	int *p;//在定义指针变量时*修饰p是一个指针变量
	int a = 0x1234abcd;x
	p = &a;//用&取地址,把a的地址赋值给p
	printf("%x\n",*p);//用*取值,即a,这里输出0x1234abcd
	return 0;
}

上面那段代码,p保存了a的地址,也可以说p指向a。

三、指针和变量的关系

通过*p取值,那么有的值是一个字节(char),有的是四个字节(int),而p只存了首地址,那么怎么知道取多少个字节呢,这就取决于指针的类型,如果指针是char类型,那么只会取一个字节,如果指针是int型,那么会再往后取三个字节一共四个字节。

#include<stdio.h>
int main() {
	int a = 0x12345678;
	char* p1;
	p1 = (char*)&a;
	printf("%d", *p1);//这里输出是120,也就是英文x
	return 0;
}

如上所示,当p1 = (char*)&a;时(强转了类型),p1保存的是a的首地址,也就是0x78。后面又进行*p1的取值操作,此时由于p1是char类型,所以只会取一个字节,就导致了最终结果就是0x78,也就是120。

四、指针的自增

首先来看一个例子(注释即使输出结果):

#include<stdio.h>
int main() {
	int a = 0x12345678, b = 0xabcdef66;
	char* p1;
	int* p2;
	p1 = (char*)&a;
	p2 = &b;
	printf("%x\n", p1);//8ff790
	printf("%x\n", ++p1);//8ff791
	printf("%x\n", p2);//8ff784
	printf("%x\n", ++p2);//8ff788
	return 0;
}

由此可见,指针的自增不是单纯的指向下一个存储单元这么简单而是跟指针类型有关,当指针类型为char,每次自增都会+1;而当指针类型为int时,每次自增都会+4。最后总结,指针的自增会直接跳过当前指针所指向变量的所有存储单元,去到下一个存储单元的位置。

五、指针和数组元素的关系

  • 直接上图:
    指针和数组
    指针存放的是数组第一个元素(下标为0)的第一个存储单元的地址。因为数组在虚拟内存的存储中是连续的,因此可以通过指针自增来直接访问到下一个元素。

  • 再看一段代码:

#include<stdio.h>
int main() {
	int a[] = { 1,2,3,4,5 };
	int* p1, * p2;
	p1 = a;
	p2 = &a[0];
	printf("%x\n", p1);//cffeb8
	printf("%x\n", p2);//cffeb8
	return 0;
}

可以看到数组名就是数组的首地址,因为这是C语言规定的,数组名是一个常量,不能被赋值。

  • 对数组元素的引用方法:
#include<stdio.h>
int main() {
	int a[] = { 1,2,3,4,5 };
	int* p;
	p = a;
	printf("%d\n", p[2]);//3
	printf("%d\n", *(p+2));//3
	printf("%d\n", a[2]);//3
	printf("%d\n", *(a+2));//3
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值