再议C语言第二节(数组与指针)讲座整理

2024-05-25 15:18

本文主要是介绍再议C语言第二节(数组与指针)讲座整理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

首先先区分一下两个容易混淆的定义:
数组指针是指向数组首元素的地址的指针,其本质为指针(这个指针存放的是数组首地址的地址,相当于2级指针,这个指针不可移动); 指针数组是数组元素为指针的数组,其本质为数组。例如:*p[2]是指针数组,实质是一个数组,里面的两个元素都是指针 []的优先级比*的优先级高,p先与[]结合,形成数组p[2],有两个元素的数组,再与*结合,表示此数组是指针类型的,每个数组元素相当于一个指针变量。
指针数组中的每一个元素均为指针,即有诸形如“*ptr_array[i]”的指针。指针数组中的元素亦可以表示为“*(*(ptr_array+i))”。又因为“()”的优先级较“*”高,且“*”是右结合的,因此可以写作**(ptr_array+i)。由于数组元素均为指针,因此ptr_array[i]是指第i+1个元素的指针。
                                              ————以上摘自百度百科
数组和指针的区别
首先对于编译器而言, 一个数组是一个地址,一个指针是一个地址的地址。 
数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。数组名对应着(而 不是指向)一块内存,其地址与容量在生命期内保持不变,只有数组的内容可以改变。一般变量在内存单元中存放的是数据,指针变量在内存单元中存放的是地址。无论何种类型的指针都占4个字节的内存空间。 其中void和带有const的指针变量容易出错,void修饰指针代表的是一种不确定类型的指针,任何类型的指针都可以直接赋给它,无需类型转换,但是不能对void指针进行算术操作。当使用带有const的指针时其实有两种意思。一种指的是不能修改指针本身的内容,另一种指的是你不能修改指针指向的内容。先说指向const的指针,它的意思是指针指向的内容是不能被修改的。它有两种写法。
      const int* p; (推荐)
      int const* p;
      第一种可以理解为,p是一个指针,它指向的内容是const int 类型。p本身不用初始化它可以指向任何标示符,但它指向的内容是不能被改变的。
      第二种很容易被理解成是p是一个指向int的const指针(指针本身不能被修改),但这样理解是错误的,它也是表示的是指向const的指针(指针指向的内容是不能被修改的),它跟第一种表达的是一个意思。为了避免混淆推荐大家用第一种。
     再说const指针,它的意思是指针本身的值是不能被修改的。它只有一种写法
      int* const p=一个地址; (因为指针本身的值是不能被修改的所以它必须被初始化)
     这种形式可以被理解为,p是一个指针,这个指针是指向int 的const指针。它指向的值是可以被改变的如*p=3;
     还有一种情况是这个指针本身和它指向的内容都是不能被改变的,请往下看。
      const int* const p=一个地址;
      int const* const p=一个地址;
指向const的指针(指针指向的内容不能被修改)const关健字总是出现在*的左边而const指针(指针本身不能被修改)const关健字总是出现在*的右边,那不用说两个const中间加个*肯定是指针本身和它指向的内容都是不能被改变的。
  这次讲座欢神学长还讲了 左值与右值的概念:
在常见的C风格的语言中,有一些细微的地方是容易被忽视的,如表达式:a=b 这样的表达式在大多数编程语言中都是合法的,它是一个简单的赋值表达式,站在编译器的角度它又是怎么样对待与处理的呢?
      我们先温习一下,“地址”和“地址的内容”两个概念。在编译器看来,赋值运算符两边的a和b并不是两个地位平等的代号。这里的等号“=”并不代表a和b的地位平等,这里符号a的含义是a所代表的地址,习惯上我们称之为左值。而符号b的含义是b所代表的地址的内容,习惯上我们称之为右值,确切的说右值就是除了左值以外的值,他们可能是立即数和变量的某些组合。左值在编译时可知,表示存储结果的地方。通常只有允许修改的左值可以合法用作赋值运算符左边的操作数。所以尽管数组的名字表示“地址”,它是“左值”,但是它不是一个可以修改的左值,所以它也就不能用作赋值运算符的左操作数了,同理,用关键字const修饰的变量也是如此。编译器为每个变量分配一个地址(左值),虽然具体什么时候分配这个地址各个语言的编译器可能有所不同,但是变量在运行时会一直保存于这个地址。
      相对应的,存储于变量中的值(它的右值)只有在运行时才可知。如果需要用到变量中存储的值,编译器就发出指令从指定的地址读入变量值并将它存于寄存器中。也就是说,右值是运行时才会需要去用的实际值。于是"a=b;"的背后发生的事情大致就是,编译器会先检查操作数的合法性,如果操作数合法,就生成如下的指令:取b的右值(可能是一个立即数),将其保存至a的左值(一个地址)。在这里,a作为左值出现,但是实际其作用的是存储a的地址,这条语句的作用就是将这个地址存储的值赋值为b所代表的常量。b作为右值出现的时候就代表的是存储b的地址所存储的值,用语句表达就是*(&b)。先取到地址,再对该地址反引用取得这个地址存储的值。

这篇关于再议C语言第二节(数组与指针)讲座整理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1001870

相关文章

C语言中位操作的实际应用举例

《C语言中位操作的实际应用举例》:本文主要介绍C语言中位操作的实际应用,总结了位操作的使用场景,并指出了需要注意的问题,如可读性、平台依赖性和溢出风险,文中通过代码介绍的非常详细,需要的朋友可以参... 目录1. 嵌入式系统与硬件寄存器操作2. 网络协议解析3. 图像处理与颜色编码4. 高效处理布尔标志集合

Go语言开发实现查询IP信息的MCP服务器

《Go语言开发实现查询IP信息的MCP服务器》随着MCP的快速普及和广泛应用,MCP服务器也层出不穷,本文将详细介绍如何在Go语言中使用go-mcp库来开发一个查询IP信息的MCP... 目录前言mcp-ip-geo 服务器目录结构说明查询 IP 信息功能实现工具实现工具管理查询单个 IP 信息工具的实现服

C 语言中enum枚举的定义和使用小结

《C语言中enum枚举的定义和使用小结》在C语言里,enum(枚举)是一种用户自定义的数据类型,它能够让你创建一组具名的整数常量,下面我会从定义、使用、特性等方面详细介绍enum,感兴趣的朋友一起看... 目录1、引言2、基本定义3、定义枚举变量4、自定义枚举常量的值5、枚举与switch语句结合使用6、枚

Java数组初始化的五种方式

《Java数组初始化的五种方式》数组是Java中最基础且常用的数据结构之一,其初始化方式多样且各具特点,本文详细讲解Java数组初始化的五种方式,分析其适用场景、优劣势对比及注意事项,帮助避免常见陷阱... 目录1. 静态初始化:简洁但固定代码示例核心特点适用场景注意事项2. 动态初始化:灵活但需手动管理代

go 指针接收者和值接收者的区别小结

《go指针接收者和值接收者的区别小结》在Go语言中,值接收者和指针接收者是方法定义中的两种接收者类型,本文主要介绍了go指针接收者和值接收者的区别小结,文中通过示例代码介绍的非常详细,需要的朋友们下... 目录go 指针接收者和值接收者的区别易错点辨析go 指针接收者和值接收者的区别指针接收者和值接收者的

C++中初始化二维数组的几种常见方法

《C++中初始化二维数组的几种常见方法》本文详细介绍了在C++中初始化二维数组的不同方式,包括静态初始化、循环、全部为零、部分初始化、std::array和std::vector,以及std::vec... 目录1. 静态初始化2. 使用循环初始化3. 全部初始化为零4. 部分初始化5. 使用 std::a

shell编程之函数与数组的使用详解

《shell编程之函数与数组的使用详解》:本文主要介绍shell编程之函数与数组的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录shell函数函数的用法俩个数求和系统资源监控并报警函数函数变量的作用范围函数的参数递归函数shell数组获取数组的长度读取某下的

Go 语言中的select语句详解及工作原理

《Go语言中的select语句详解及工作原理》在Go语言中,select语句是用于处理多个通道(channel)操作的一种控制结构,它类似于switch语句,本文给大家介绍Go语言中的select语... 目录Go 语言中的 select 是做什么的基本功能语法工作原理示例示例 1:监听多个通道示例 2:带

Java Optional避免空指针异常的实现

《JavaOptional避免空指针异常的实现》空指针异常一直是困扰开发者的常见问题之一,本文主要介绍了JavaOptional避免空指针异常的实现,帮助开发者编写更健壮、可读性更高的代码,减少因... 目录一、Optional 概述二、Optional 的创建三、Optional 的常用方法四、Optio

C语言函数递归实际应用举例详解

《C语言函数递归实际应用举例详解》程序调用自身的编程技巧称为递归,递归做为一种算法在程序设计语言中广泛应用,:本文主要介绍C语言函数递归实际应用举例的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录前言一、递归的概念与思想二、递归的限制条件 三、递归的实际应用举例(一)求 n 的阶乘(二)顺序打印