江牧律师
首页
往期整理
  •   历史归档
  •   文章分类
  •   文章标签
关于我
江牧
文章
10
分类
2
标签
6
首页
往期整理
历史归档
文章分类
文章标签
关于我
技术学习
快速理解C语言指针和数组的关系
发布于: 2024-8-27
最后更新: 2024-10-9
次查看
C语言
知识点
type
status
date
slug
summary
tags
category
icon
password
😀
指针,C语言的核心
 

📝 主旨内容

指针变量声明的一般形式:type *var_name;

1.定义

int* p = &a
*是解引用操作符,意思是通过p中存放的地址,找到p所指向的对象,*p或者说a就是p指向的对象。
*说明p是指针变量,int说明p指向的对象a是int类型。指针就是内存单元的地址,也就是内存单元的编号。
var 变量的地址: 0x7ffeeef168d8 ip 变量中存储的地址: 0x7ffeeef168d8 *ip 变量的值: 20
 

2.指针使用示例

先看下面这样一个错误范例
x和y有自己单独的地址
x和y有自己单独的地址
本质上只交换了x和y的值,对于a和b的值没有影响
本质上只交换了x和y的值,对于a和b的值没有影响
我们发现,问题在于:实参a和b传给形参x和y后,形参是实参的一份临时拷贝,形参也有自己的独立空间,因此对形参的修改不会影响实参。
正确做法:
对指针交换变量内容的解释
对指针交换变量内容的解释
对“为什么不能直接交换px和py”的解释
对“为什么不能直接交换px和py”的解释
 

3.一些关于指针的结论:

3.1指针结论的推导

公理:
1.指针也就是内存地址,指针变量是用来存放内存地址的变量。
2.取地址里面的值的第一种方式:地址[i]
3.取地址里面的值的第二种方式:*地址
 
在绝大多数关于数组的表达式中,数组名代表指针常量,这个指针指向数组首个元素。 从数值上讲,数组名表示的值就是首个元素的地址。 因此:
  • arr=&arr[0]
另外我们还知道:
  • arr+i 指针+1 并不是指针代表的地址值+1。 指针变量加1,即向后移动1 个位置,表示指针变量指向下一个数据元素的首地址。而不是在原地址基础上加1。至于真实的地址加了多少,要看原来指针指向的数据类型是什么。 例如:char型,右移1个字节;int型,右移4个字节。 这些操作是由编译器来完成的。所以,指针必须指向某个类型,这样编译器才能知道指针每次加1时真正内存的步长是多少。
    那么我们可以很轻易地推导出:
    • arr[i]=*(arr+i) 这也吻合了为什么数组下标从0开始:为了保证指针运算与数组下标统一。
    更进一步,我们可以得出类似下面这样形式的结论:
    • (arr+1)[2] = arr[3] = *(arr+3)
    另外,由于arr+i表示元素位置的偏移,arr+i得到的也是一个指针(地址)。那么我们也可以易知,指针是可以相减的,指针-指针得到的是指针和指针之间相差的个数(不是所有的指针都能相减,指向同一块空间的2个指针才能相减)。即:
    • &arr[m]-&arr[n] = m-n
      • 此外,我们还要区分arr+1和&arr+1
        • &arr+1
          arr+1=&arr[0]+1
          &arr是指向整个数组的指针,取出的是整个数组的地址。因此,如果我们将&arr移动1个位置,它将移动一整个数组的地址,指向下一个包含5个元素的块。
          arr是指向数组第一个元素的指针。因此,如果我们将arr移动1个位置,它将指向第二个元素。
          如果数组基地址为00D5F940,则&arr+1将为00D5F940+(5*4),即00D5F954
          如果数组基地址是00D5F940 ,则arr+1将是00D5F940+4,即00D5F944
      notion image
      notion image
      • 区分*p++和(*p)++ p++的意思是对p解引用后,再P+=1 (*p)++的意思是对p解引用后的值+1

      3.2练习

      不用strlen()函数,计算字符串长度
       

      4.指针变量的大小

      • 不管是什么类型的指针,都是在创建指针变量。 指针变量是用来存放地址的。 指针变量的大小取决于一个地址存放的时候需要多大空间。 对于32位的机器,假设有32根地址线,那么假设每根地址线在寻址的时候产生高电平(高电压)和低电平(低电压)就是(1或者0); 那么32根地址线产生的地址就会是:2^32 每个地址标识一个字节,那我们就可以给(2^32Byte==2^32/1024KB== 2^32/1024/1024MB=2^32/1024/1024/1024GB==4GB)4G的空闲进行编址。
        • 这里我们就明白:
        • 在32位的机器上,地址是32个0或者1组成二进制序列,那地址就得用4个字节(4byte=32bit)的空间来存储,所以一个指针变量的大小就应该是4个字节。
        • 那如果在64位机器上,如果有64个地址线,那一个指针变量的大小是8个字节,才能存放一个地址。即: 32位机器上的地址:32bit位 - 4byte,所以指针变量的大小是4个字节 64位机器上的地址:64bit位 - 8byte,所以指针变量的大小是8个字节
       
       
       
       
       
      • 作者:江牧
      • 链接:https://lawyerjiang.top/article/key/c/2
      • 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
      相关文章
      document.write()、textContent、innerText 与innerHTML的区别
      计算输入的数字在二进制下包含1的个数
      解引用“指向空间已被释放的指针”,会得到怎样的值?
      序列中删除指定数字
      C语言中将数字0~9与对应字符相互转换
      C/C++不能在子函数中求主函数中的数组长度
      C/C++不能在子函数中求主函数中的数组长度C语言中随机数的实现
      Loading...
      目录
      0%
      📝 主旨内容1.定义2.指针使用示例3.一些关于指针的结论:3.1指针结论的推导3.2练习4.指针变量的大小
      江牧
      江牧
      无限进步!
      文章
      10
      分类
      2
      标签
      6
      最新发布
      记一次个人服务器的搭建过程
      记一次个人服务器的搭建过程
      2025-4-28
      document.write()、textContent、innerText 与innerHTML的区别
      document.write()、textContent、innerText 与innerHTML的区别
      2024-10-9
      起点
      起点
      2024-10-9
      解引用“指向空间已被释放的指针”,会得到怎样的值?
      解引用“指向空间已被释放的指针”,会得到怎样的值?
      2024-10-9
      C语言中将数字0~9与对应字符相互转换
      C语言中将数字0~9与对应字符相互转换
      2024-10-9
      C/C++不能在子函数中求主函数中的数组长度
      C/C++不能在子函数中求主函数中的数组长度
      2024-10-9
      公告
      -- 本网站正处于大规模装修建设中 --
      目录
      0%
      📝 主旨内容1.定义2.指针使用示例3.一些关于指针的结论:3.1指针结论的推导3.2练习4.指针变量的大小
      2022-2025 江牧.

      江牧律师 | 无限进步!

      Powered by NotionNext 4.7.4.