一个变量有地址,一个数组包含若干元素,每个数组元素都在内存中占用存储单元,它们都有相应的地址。指针变量既然可以指向变量,当然也可以指向数组和数组元素(把数据起始地址或某一元素的地址放到一个指针变量中)。所谓数组的指针是指数组的起始地址,数组元素的指针数组元素的地址。

这种指针变量的定义与以前介绍的指向变量的指针变量相同。应当注意,如果数组为int型,则指针变量亦应指向int型。

C语言规定数组名代表数组的首地址,也就是第一个元素的地址。因此,下面两个语句等价:

p=&a[0];

p=a;

注意数组a不代表整个数组,上述"p=a;"的作用是"把a数组的首地址赋给指针变量p",而不是"把数组a各元素的值赋给p"。

在定义指针变量时可以赋给初值:

int*p=&a[0];

它等效于:

int*p;

p=&a[0];

当然定义时也可以写成

int*p=a;

它的作用是将a的首地址(即a[0]的地址)赋给指针变量p(而不是*p)。

假设p已定义为指针变量,并已给它赋了一个地址,使它指向某一个数组元素。

如果有以下赋值语句: *p=1; 表示对P当前所指向的数组元素赋以一个值(值为1)。

C规定对p+1指向数组的下一个元素(而不是将p值简单地加1)。

如果p的这初值为&a[0],则: (1)p+i和a+i就是a[i]的地址,或者说,它们指向a数组的第i个元素。 (2)*(p+i)或*(a+i)是p+i或a+i所指向的数组元素,即a[i]。 (3)指向数组的指针变量也可以带下标,如p[i]与*(p+i)等价。

根据以上叙述,引用一个数组元素,可以用: (1)下标法,如a[i]形式; (2)指针法,如*(a+i)或*(p+i)。

要输出各元素的值有三种方法: ○1下标法 ○2通过数组名计算数组元素地址,找出元素的值。 ○3用指针变量指向数组元素。

对三种方法的比较: (1)第1、2种方法执行效率是相同的。 (2)第3种方法比1、2法快,用指针变量直接指向元素,不必每次都重新计算地址,像 p++这样的自加操作是比较快的。 (3)用下标法比较直观,能直接知道是第几个元素。用地址法或指针变量的方法不直观,难以很快地判断出当前处理的是哪一个元素。

在使用指针变量时,有几个问题要注意: 1、指针变量可以实现使本身的值改变。 2、要注意指针变量的当前值。 3、虽然定义数组包含10个元素,用p指向数组元素,但批针变量可以指到数组以后的内存单元。 4、注意指针变量的运算。

因此,用数组名作实参,在调用函数时实际上是把数据的首地址传给形参(注意,不是把数组的值传给形参)。

请注意,在调用函数后,实参数组的元素值可能会发生改变,这种值的变化实际上并不是从形参传回实参的,而是由于形参与实参数组共享同一段内存而造成的。

如果有一个实参数组,想在函数中改变此数组的元素的值,实参与形参的对应关系有以下4种情况: 1、形参和实参都用数组名。 2、实参用数组名,形参用指针变量。 3、实参形参都有指针变量。 4、实参为指针变量,形参为数组名。

 
 

C语言学习笔记 (004) - 数组名和数组首地址(转)的更多相关文章

  1. C语言 数组名不是首地址指针

    今天上计算机系统课的时候老师讲到了C中的聚合类型的数据结构.在解释数组名的时候说"数组名是一个指针,指向该数组的第一个元素",附上ppt(第二行): 我觉得这是不正确的,是一个常见 ...

  2. C语言学习笔记(一):数组传递时退化为指针

    这几天闲来无事,写了一个数组元素排序函数如下: #include <stdio.h> #include <stdlib.h> void ArraySort(int array[ ...

  3. Go语言学习笔记八: 数组

    Go语言学习笔记八: 数组 数组地球人都知道.所以只说说Go语言的特殊(奇葩)写法. 我一直在想一个人参与了两种语言的设计,但是最后两种语言的语法差异这么大.这是自己否定自己么,为什么不与之前统一一下 ...

  4. C语言学习笔记--数组指针和指针数组

    C 语言中的数组有自己特定的类型,数组的类型由元素类型和数组大小共同决定.(如 int array[5]类型为 int[5]) 1.定义数组类型 C 语言中通过 typedef 为数组类型重命名:ty ...

  5. C语言学习笔记--多维数组和多维指针

    1. 指向指针的指针 (1)指针的本质是变量,会占用一定的内存空间 (2)可以定义指针的指针来保存指针变量的地址值 (3)指针是个变量,同样也存在传值调用与传址调用 重置动态空间的大小 #includ ...

  6. C语言学习笔记--指针和数组的关系

    1.数组的本质 (1)数组是一段连续的内存空间 (2)数组的空间大小:sizeof(array_type)*array_size; (3)数组名可看做指向数组第一个元素的常量指针 (4)数组声明时编译 ...

  7. Go语言学习笔记(1)——顺序编程

    Go语言学习笔记这一堆主要是<Go语言编程>(人民邮电出版社)的读书笔记.中间会穿插一些零碎的点,比如源码学习之类的.大概就是这样吧. 1. 顺序编程 1.1 变量 变量的声明: var ...

  8. C语言学习笔记---谭浩强

    前段时间有机会去面试了一次,真是备受“打击”(其实是启发),总的来说就是让我意识到了学习工具和学习技术的区别.所以最近在看一些数据结构和算法,操作系统,python中的并行编程与异步编程等东西.然而数 ...

  9. 2017-05-4-C语言学习笔记

    C语言学习笔记... ------------------------------------ Hello C语言:什么是程序:程序是指:完成某件事的既定方式和过程.计算机中的程序是指:为了让计算机执 ...

随机推荐

  1. 【Spark】SparkStreaming-CPU资源设置的蹊跷

    SparkStreaming-CPU资源设置的蹊跷. Spark streaming network_wordcount.py does not print result - Stack Overfl ...

  2. 【API规范】OpenAPI规范

    OpenAPI规范 openAPI 3.0_百度搜索 OpenAPI Specification 2.0 - CSDN博客 APP相关_API 列表_OpenAPI 2.0_开发指南_移动推送-阿里云 ...

  3. List 多次排序

    List<Patientmain> list = patientmains.OrderBy(p => p.Firstname).ThenBy(p => p.Middlename ...

  4. Linux系统下对NFS服务安全加固的方法

    NFS(Network File System)是 FreeBSD 支持的一种文件系统,它允许网络中的计算机之间通过 TCP/IP 网络共享资源.不正确的配置和使用 NFS,会带来安全问题. 概述 N ...

  5. Eclipse Maven项目报错3之找不到配置文件spring-servlet-context.xml

    一.具体错误如下图所示 根据文字提示可以看出是这个文件找不到,但是我去项目的这个目录找了,这个文件确实存在,那么是什么问题呢 二.解决问题 原因分析(来自网上) 代码编译的过程,是一个自动生成相应编译 ...

  6. mybatis 是如何与数据表对应上的 ?

    MyBatis也需要进行表和实体 的关联.我们查询的是表,返回的结果是实体类.这之间有一个对应关系. 如果说实体类的属性和表的列名一一对应,名字一样,那就自动解决了这个问题.但是如果实体类的属性和表的 ...

  7. iOS开发技巧 - 使用UIDatePicker来选择日期和时间

    (Swift) import UIKit class ViewController: UIViewController { var datePicker: UIDatePicker! func dat ...

  8. SqlServer插入1000条记录

    1.想在SqlServer中插入指定数量的测试记录怎么办? 2.解决: DECLARE @var INT ) BEGIN INSERT INTO test (Name) VALUES (convert ...

  9. Redis3.2.5 集群搭建以及Spring-boot测试

    1:集群中的机器信息 IP PORT 192.168.3.10 7000,7001,7002 192.168.3.11 7004,7005,7006 2:安装Redis 分别在10与11机器上面安装R ...

  10. IDEA中Gradle插件的使用

    Idea本身已经集成了Gradle插件,你可以在File | Settings | Build, Execution, Deployment | Build Tools | Gradle 下找到 相关 ...