首页 > 其他分享 >【C语言】指针(一)

【C语言】指针(一)

时间:2023-08-12 15:00:47浏览次数:29  
标签:变量 int C语言 地址 printf main 指针

学指针不讲内存就是耍流氓!!!

1.内存和地址

1.1内存

  1. 在计算机中为了方便管理内存,内存会被划分为字节为单位的内存空间,也就是说一个内存单元的大小是一个字节。
  2. 为了方便找到这个内存单元,我们会给每个内存单元一个编号,就像生活中每个房间都有门牌号。
  3. 有了内存单元的编号,就可以快速找到内存单元。
  4. 编号 == 地址 == 地址在C语言中也被称为指针
int main()
{
	int a = 10;
  int*p = &a;//p指向的对象是int类型的;*是说明p是指针变量
  return 0;
}
  • 指针变量就是用来存放地址的
  • 存放在指针变量中的值,都会被当作地址使用

1.2究竟该如何理解编址

  • CPU访问内存中的某个字节空间,必须知道这个字节空间在内存的什么位置,⽽因为内存中字节很多,所以需要给内存进⾏编址(就如同宿舍很多,需要给宿舍编号⼀样)。
  • 计算机中的编址,并不是把每个字节的地址记录下来,⽽是通过硬件设计完成的。
  • 钢琴、吉他上⾯没有写上“都瑞咪发嗦啦”这样的信息,但演奏者照样能够准确找到每⼀个琴弦的每⼀个位置,这是为何?因为制造商已经在乐器硬件层⾯上设计好了,并且所有的演奏者都知道。本质是⼀种约定出来的共识

【C语言】指针(一)_指针

  • ⾸先,必须理解,计算机内是有很多的硬件单元,⽽硬件单元是要互相协同⼯作的。所谓的协同,⾄少相互之间要能够进⾏数据传递。
  • 但是硬件与硬件之间是互相独⽴的,那么如何通信呢?答案很简单,⽤"线"连起来。⽽CPU和内存之间也是有⼤量的数据交互的,所以,两者必须也⽤线连起来。
  • 不过,我们今天关⼼⼀组线,叫做地址总线。
  1. 我们可以简单理解,32位机器有32根地址总线,每根线只有两态,表⽰0,1【电脉冲有⽆】,那么⼀根线,就能表⽰2种含义,2根线就能表⽰4种含义,依次类推。32根地址线,就能表⽰2^32种含义,每⼀种含义都代表⼀个地址
  2. 地址信息被下达给内存,在内存上就可以找到该地址对应的数据,将数据在通过数据总线传⼊CPU内寄存器。

2.指针变量和地址

2.1取地址操作符(&)

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

【C语言】指针(一)_指针变量_02

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

0x006FFD70
0x006FFD71
0x006FFD72
0x006FFD73

那我们如何能得到a的地址呢?  这⾥就得学习⼀个操作符(&)-取地址操作符

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

按照我画图的例⼦,会打印处理:006FFD70, &a取出的是a所占4个字节中地址较⼩的字节的地址。

【C语言】指针(一)_操作符_03

虽然整型变量占⽤4个字节,我们只要知道了第⼀个字节地址,顺藤摸⽠访问到4个字节的数据也是可⾏的。

2.2指针变量和解引用操作符(*)

2.2.1指针变量

  • 那我们通过取地址操作符(&)拿到的地址是⼀个数值,⽐如:0x006FFD70,这个数值有时候也是需要存储起来,⽅便后期再使⽤的,那我们把这样的地址值存放在哪⾥呢?答案是:指针变量中。 ⽐如:
#include <stdio.h>

int main()
{
 int a = 10;
 int* pa = &a;//取出a的地址并存储到指针变量pa中 

 return 0;
8 }
  • 指针变量也是一种变量,这种变量就是用来存放地址的,存放在指针变量中的值都会理解为地址

2.2.2如何拆解指针类型

  • 我们看到pa的类型是 int* ,我们该如何理解指针的类型呢?
int a = 10;
int * pa = &a;
  • 这⾥pa左边写的是 int* , * 是在说明pa是指针变量,⽽前⾯的 int 是在说明pa指向的是整型(int)类型的对象。

【C语言】指针(一)_#include_04

  • 同上,当有一个char类型的变量ch,ch的地址就应该存放在char类型指针变量中......

2.2.3解引用操作符

  • 我们将地址保存起来,未来是要使⽤的,那怎么使⽤呢?
  • 在现实⽣活中,我们使⽤地址要找到⼀个房间,在房间⾥可以拿去或者存放物品。
  • C语⾔中其实也是⼀样的,我们只要拿到了地址(指针),就可以通过地址(指针)找到地址(指针)指向的对象,这⾥必须学习⼀个操作符叫解引⽤操作符(*)。
#include <stdio.h>

int main()
{
 int a = 100;
 int* pa = &a;
 *pa = 0;
 return 0;
}
  • 上⾯代码中第7⾏就使⽤了解引⽤操作符, *pa 的意思就是通过pa中存放的地址,找到指向的空间,*pa其实就是a变量了;所以*pa= 0,这个操作符是把a改成了0.
  • 有同学肯定在想,这⾥如果⽬的就是把a改成0的话,写成 a = 0; 不就完了,为啥⾮要使⽤指针呢?
  • 其实这⾥是把a的修改交给了pa来操作,这样对a的修改,就多了⼀种的途径,写代码就会更加灵活,后期慢慢就能理解了。

2.3指针变量的大小

  • 前⾯的内容我们了解到,32位机器假设有32根地址总线,每根地址线出来的电信号转换成数字信号后是1或者0,那我们把32根地址线产⽣的2进制序列当做⼀个地址,那么⼀个地址就是32个bit位,需要4个字节才能存储。
  • 如果指针变量是⽤来存放地址的,那么指针变的⼤⼩就得是4个字节的空间才可以。
  • 同理64位机器,假设有64根地址线,⼀个地址就是64个⼆进制位组成的⼆进制序列,存储起来就需要8个字节的空间,指针变的⼤⼩就是8个字节。
#include <stdio.h>

int main()
{
	int num = 10;
	int* p = #

	char ch = 'w';
	char* pc = &ch;

	printf("%zd\n", sizeof(p));//
	printf("%zd\n", sizeof(pc));//

	printf("%zd\n", sizeof(char*));
	printf("%zd\n", sizeof(short*));
	printf("%zd\n", sizeof(int*));
	printf("%zd\n", sizeof(long*));
	printf("%zd\n", sizeof(float*));
	printf("%zd\n", sizeof(double*));

	return 0;
}

【C语言】指针(一)_操作符_05【C语言】指针(一)_C语言_06

结论:

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

3.指针变量类型的意义

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

    标签:变量,int,C语言,地址,printf,main,指针
    From: https://blog.51cto.com/u_16189938/7059231

相关文章

  • 指针
    >指针就是地址,地址就是指针inta=1;int*p;p=&a;//等价于int*p=&a//p、&a是int*,*p、a是int指针变量也有地址,只是每次运行随机分配不固定!!!!指针变量++,类似于inta,a++。不会改变指针变量本身的地址,只会改变指针变量这块地址上存放的地址指针加减根据char*int*......
  • 随笔-C-指针数组使用简记
    typedefstructmem_list*cns_detail_encode_result[encode_type_max];(gdb)p&((structmem_list**)0x7fffb4557950)[0]#&取对应点的位置$29=(structmem_list**)0x7fffb4557950(gdb)p((structmem_list**)0x7fffb4557950)+0$30=(structmem_list**)......
  • Linux下C语言调用libcurl库下载文件到本地
    一、项目介绍当前文章介绍如何使用C语言调用libcurl库在Linux(Ubuntu)操作系统下实现网络文件下载功能。libcurl是一个开源的跨平台网络传输库,用于在C和C++等编程语言中实现各种网络通信协议的客户端功能。它支持多种协议,包括HTTP、HTTPS、FTP、SMTP、POP3等,可以方便地进行数据的上传......
  • C语言小白,下面是一些笔记,大神勿入!
    ~ --按位取反,在二进制中,原来的1变为0,0变为1,得到补码原码:直接按照正负写出的二进制序列反码:原码的符号位不变,其他位按位取反得到补码:反码加一得到inta=0;intb=~a;//b是有符号的整形,其二进位最左边一个数为0为正数,为1是负数printf("%d\n",b);//打印的是这个数的原码inta=10;int......
  • 关于C语言输入输出的逗号问题(小细节)
    C语言的输入输出必须要遵循scanf和printf的格式,就是你是什么格式你就要输入什么。一、输入问题#include<stdio.h>intmain(){ inta,b;scanf("%d,%d",&a,&b); printf("a+b=%d",a+b);return0;}编辑 这个程序我们可以看到它运行的结果是错误的!为什么呢,因为我们在s......
  • 有关成员函数const修饰,对传入的成员属性影响以及返回指针引用的bug问题
    boolcontains(_T&data,bn_ptrt)const 此时传入的成员参数是带有const属性的,但是data是不带const的,通过影响成员参数访问权限,而达到不能修改的目的;BinarySearchTree<_T>&BinarySearchTree<_T>::operator=(constbst_refbst){ if(this!=&bst) { makeEmpty(); ......
  • C语言里.和->的区别
    ->使用一个指向结构体或对象的指针访问其内成员.是直接通过结构体或对象来访问他们的内部成员变量 早期的C语言不支持将结构体作为参数在函数之间传递,只能用指向结构的指针在函数间进行传递  a->b的含义是(*a).b,所以他们是不同的,不过的确->可以用*和.实......
  • 学习《C和指针》的总结(1)
    一、GDB,我使用的是notepad++,因为它轻量化,再用MinGW作为编译器,配置宏:Compile、Run和GDB。GDB指令:1、b13 :在第十三行打断点2、r:运行代码到第十三行3、n:运行下一行代码4、s:如果下一行是调用函数,使用此指令进入调用函数5、pa:打印变量a的值,执行一次就打一次6......
  • C++11实用特性3 --智能指针
    1智能指针在C++中没有垃圾回收机制,必须自己释放分配的内存,否则就会造成内存泄露。解决这个问题最有效的方法是使用智能指针(smartpointer)。智能指针是存储指向动态分配(堆)对象指针的类,用于生存期的控制,能够确保在离开指针所在作用域时,自动地销毁动态分配的对象,防止内存泄露。智能......
  • 【C语言基础语法】2. 变量和数据类型
    目录一、变量和常量 1.1关键字 1.2数据类型 1.3变量名命名二、进制三、整型 3.1整型的输出 3.2整型的输入 3.3整型的分类四、字符 4.1字符的输出 4.2字符的输入 4.3ascill码表 4.4转义字符五、浮点型六、类型限定符七、格式化 7.1格式化输出 7.......