个人理解,欢迎指正

指针就是记录数据的内存地址的变量。指针可以指向单个变量,也可以指向数组。

数组是一个概念,是若干个类型相同的元素的有序集合。在Fortran语言中,数组中存放的元素,可以是整数,实数,复数,甚至结构体(或称自定义数据类型)。但是,在Fortran中,数组中存放的元素不能是指针。不存在这样一个数组,该数组的每一个元素都是一个指针,分别指向不同的数组。

那么怎样才能实现,有一个数组,而数组中每一个元素都能指向其它数组呢?

因为数组中存放的元素可以是结构体,那么可以通过定义一个结构体,在结构体中定义一个指针变量来解决。

  1. type container
  2. class(object), pointer :: obj
  3. end type container
  4.  
  5. type(container), allocatable, dimension(:) :: objects
  6. allocate (objects(:num_objects))
  7. objects()%obj => s1

其中,objects(0:num_objects)就是定义的结构体数组,数组中的第0个元素的obj分量(objects(0)%obj)指向一个变量s1,s1是类型为object的变量。

上式objects数组中的每一个元素都是指向单个变量的,那么如果需要结构体数组中的每一个元素都指向一个数组,则定义结构体中的指针变量需要定义为是指向数组的(下面第10行):

  1. program ex1
  2. implicit none
  3. integer :: i,j
  4.  
  5. !//声明目标数组work
  6. real(RK),allocatable,target :: work(:,:)
  7.  
  8. !//定义结构体类型qcontainer,该类型中的分量obj可以指向一个一维的数组
  9. type qcontainer
  10. real(RK),pointer :: obj(:)
  11. end type qcontainer
  12.  
  13. !//声明一个一维的的数组qtwork
  14. type(qcontainer),allocatable :: qtwork(:)
  15.  
  16. !//定义数组work并赋初值
  17. allocate(work(,))
  18. do i=,
  19. do j=,
  20. work(i,j)=i*j***
  21. end do
  22. end do
  23.  
  24. !//定义数组qtwork
  25. allocate(qtwork())
  26.  
  27. !//qtwork中第j个元素的object分量指向数组work的第j列
  28. qtwork(j)%obj => work(:,j)
  29.  
  30. end program ex1

关于彭书中的“”指针数组“

彭国伦《Fortran95程序设计》书中275页上说,“指针也可以声明成数组”,并给了以下示例代码

  1. program ex1004
  2. implicit none
  3. integer, pointer :: a(:)
  4. integer, target :: b()=(/ ,,,, /)
  5. ! 把指针数组a指向数组b
  6. a=>b
  7. ! a(~)=>b(~)
  8. write(*,*) a
  9. a=>b(:)
  10. ! a()=>b(), a()=>b(), a()=>b()
  11. write(*,*) a
  12. a=>b(::)
  13. ! a()=>b(), a()=>b(), a()=>b()
  14. write(*,*) a
  15. a=>b(::-)
  16. ! a()=>b(), a()=>b(), a()=>b(), a()=>b(), a()=>b()
  17. write(*,*) a
  18. stop
  19. end

这里用指针a表示了数组b。这告诉我们,指针不仅可以指向单个变量的内存地址,还可以指向数组。

但是需要注意的是,指针a(:)中的每一个变量a(i)都确定的表示了某一个单独的变量,而不是表示变量的集合的数组即指针a(:)只能表示一个数组,不能同时表示多个数组的集合。

另外,需要注意,声明指针a的时候,可以说明a的形状,但不能指定a的数组大小。换句话说,声明指针a的时候,可以告诉编译器,a所指向的变量是几维的数组,但是不能告诉编译器,a所指向的数组是大小是100×100的。

第3行换成以下语句是非法的

  1. !//非法的代码
  2. integer, pointer :: a()

编译器错误提示是“ ALLOCATABLE or POINTER attribute dictates a deferred-shape-array.” 即声明变量时,allocatable或pointer的属性表明数组为假定形状数组。如果此时声明上述语句(即给了数组的大小),那显然矛盾。

总结

  • 在Fortran中,指针可以指向一个数组或者一个数组中的一部分,但指针不能同时表示多个数组。
  • 数组是若干相同类型元素的集合,但数组的元素不能是指针。
  • 如果想实现一个数组,且数组的元素具有指针的功能,可以定义一个结构体类型的数组。

附录代码:

  1. program test
  2. implicit none
  3. integer i,j,k
  4. real,allocatable,target :: work(:,:)
  5.  
  6. type qcontainer
  7. real,pointer :: obj(:)
  8. end type qcontainer
  9.  
  10. type(qcontainer),allocatable :: qtwork(:) ,qtemp
  11.  
  12. allocate(work(,))
  13. allocate(qtwork())
  14.  
  15. !//初始化
  16. do j=,
  17. do i=,
  18. work(i,j)=i*j***
  19. end do
  20. end do
  21.  
  22. !//指针变量赋值
  23. do j=,
  24. qtwork(j)%obj => work(:,j)
  25. end do
  26.  
  27. !//打印输入数组
  28. print*,"input array: "
  29. do j=,
  30. print*,work(:,j)
  31. end do
  32.  
  33. !//打印指向的数组
  34. print*,"point array: "
  35. do j=,
  36. print*,qtwork(j)%obj
  37. end do
  38.  
  39. !//置换
  40. print*,"swap"
  41. qtemp = qtwork()
  42. do j=,
  43. qtwork(j) = qtwork(j+)
  44. end do
  45. qtwork()=qtemp
  46.  
  47. !//输出置换结果
  48. do j=,
  49. print*,qtwork(j)%obj
  50. end do
  51.  
  52. deallocate(work)
  53.  
  54. end program

输出结果:

  1. input array:
  2. 7.000000 14.00000
  3. 28.00000 56.00000
  4. 63.00000 126.0000
  5. point array:
  6. 7.000000 14.00000
  7. 28.00000 56.00000
  8. 63.00000 126.0000
  9. swap
  10. 28.00000 56.00000
  11. 63.00000 126.0000
  12. 7.000000 14.00000
  13. Press any key to continue . . .

Fortran的数组与指针的更多相关文章

  1. 把《c++ primer》读薄(4-2 c和c++的数组 和 指针初探)

    督促读书,总结精华,提炼笔记,抛砖引玉,有不合适的地方,欢迎留言指正. 问题1.我们知道,将一个数组赋给另一个数组,就是将一个数组的元素逐个赋值给另一数组的对应元素,相应的,将一个vector 赋给另 ...

  2. C语言核心之数组和指针详解

    指针 相信大家对下面的代码不陌生: int i=2; int *p; p=&i;这是最简单的指针应用,也是最基本的用法.再来熟悉一下什么是指针:首先指针是一个变量,它保存的并不是平常的数据,而 ...

  3. 《征服 C 指针》摘录3:数组 与 指针

    一.数组 和 指针 的微妙关系 数组 是指将固定个数.相同类型的变量排列起来的对象. 正如之前说明的那样,给指针加 N,指针前进“当前指针指向的变量类型的长度 X N”. 因此,给指向数组的某个元素的 ...

  4. C指针-数组和指针的归一

    int bArr[] = {1,2,3}; int *iarr = bArr; *iarr = 6; printf("%d\n",*iarr); printf("%d\n ...

  5. 《C专家编程》第四章——令人震惊的事实:数组和指针并不相同

    数组和指针是C语言里相当重要的两部分内容,也是新手程序员最容易搞混的两个地方,本章我们锁定指针与数组,探讨它们的异同点. 首先来看指针与数组在声明上的区别: int a[10]; int *p; 很明 ...

  6. (C语言)数组与指针的区别

    以前常常听过这种说法,说数组和指针这两者比较像,但是不能混淆,可是一直没能理解.刚刚在李云的<专业嵌入式软件开发>中,看了讲述数组与指针区别的一章,似乎有所领悟.本着知乎上看到的这张图,我 ...

  7. C语言教学--二维数组和指针的理解

    对于初学者对二维数组和指针的理解很模糊, 或者感觉很难理解, 其实我们和生活联系起来, 这一切都会变得清晰透彻. 我们用理解一维数组的思想来理解二维数组, 对于一维数组,每个箱子里存放的是具体的苹果, ...

  8. 【C语言学习】《C Primer Plus》第10章 数组和指针

    学习总结 1.数组初始化方式: int a[]={1,2,3} int a[SIZE]={1,2,3} //SIZE是宏定义,数组初始化个数不能大于SIZE,否则报错:当个数小 //SIZE,自动补0 ...

  9. C语言学习004:数组与指针

    在C语言中,字符串实际上就是字符数组,在内存中字符串"Shatner"存储的形式是这样的

随机推荐

  1. java 和 javascript CryptoJS 进行HmacSHA1加密

    import java.io.IOException; import java.io.UnsupportedEncodingException; import java.security.Invali ...

  2. int to string & string to int

    #include "stdafx.h" #include <string> #include <sstream> using namespace std; ...

  3. CSS 构造表格

    表格边框 CSS 中设置表格边框,请使用 border 属性: <style type="text/css"> table{ border:1px solid red; ...

  4. RLE Iterator LT900

    Write an iterator that iterates through a run-length encoded sequence. The iterator is initialized b ...

  5. Python - 格式化字符串的用法

    0. 摘要 Python支持多种格式化字符串的方法,包括%-fromatting.str.format().f-strings三种,f-strings是Python3.6以后出现的一种新方法,相比其他 ...

  6. TensorFlow函数(八)tf.control_dependencies()

    tf.control_dependencies(control_inputs) 此函数指定某些操作执行的依赖关系 返回一个控制依赖的上下文管理器,使用 with 关键字可以让在这个上下文环境中的操作都 ...

  7. memcached迁移方案——记一次memcached session服务的迁移

    背景: (1)由于机房调整,需要迁移memcached: (2)需要在短期内迁移完成(一周以内): (3)该memcached 保存了用户的登录数据,非常重要,一旦出问题将导致大量的用户被踢出: (4 ...

  8. 多启动引导工具——AIO Boot

    该软件功能十分强大 官网介绍的也十分详尽 这里仅仅简单标记一下用来以后查找 https://www.aioboot.com/en/ 效果图: 支持多语言: 简单运用:

  9. regex_iterator

    绝对不能在循环中通过regex_search获取模式在源字符串所有的实例:应该改为regex_iterator或则regex_token_iterator,一般情况下需要位一个特定的容器来指定一个尾迭 ...

  10. 集合之List总结

    前面LZ已经充分介绍了有关于List接口的大部分知识,如ArrayList.LinkedList.Vector.Stack,通过这几个知识点可以对List接口有了比较深的了解了.只有通过归纳总结的知识 ...