【高级语言程序设计(一)】第 7 章:指针

这篇具有很好参考价值的文章主要介绍了【高级语言程序设计(一)】第 7 章:指针。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、指针和指针变量

(1)指针 

(2)指针变量

(3)指针变量的定义

(4)指针变量的初始化

(5)指针变量的一般使用

① 给指针变量赋值

② 直接使用指针变量

③ 通过指针变量引用所指向的变量

(6)指针的基本运算 

① 取地址运算符 &

② 指针运算符 *

③ 取地址运算符和指针运算符的说明

④ 取地址运算符和指针运算符的优先级和结合性

(7)指针变量的引用

(8)指针变量作为函数参数

① 值传递 

② 地址传递 

二、指针和数组 

(1)指针和一维数组

(2)指针变量指向方法

① 指针变量指向一维数组

② 指针变量指向一维数组元素

③ 指针变量指向一维数组(利用指针变量引用一维数组元素)

④ 指针变量指向下标为 i 的一维数组元素(利用指针变量引用数组元素)

⑤ 指针变量指向一维数组(引用下标为 i 的一维数组元素)

⑥ 「示例」指向数组元素的指针

⑦ 「示例」通过指针引用数组元素

(3)一级指针变量与一维数组的关系

(4)表示数组元素的两种方法

① 下标法

② 指针法

(5)用三种方法输出数组中全部元素的值

① 下标法

② 指针法

③ 指针法和指针下标

(6)算术运算 

(7)关系运算

三、指针和字符串

(1)字符串的表示形式

① 用字符数组实现

② 用字符指针实现

③  用下标法存取字符串中的字符实现

(2)指向字符串的指针变量

① 将指针变量指向字符串的方法

②  利用指针变量处理字符串的处理方式

(3)指向字符数组的指针变量

① 字符指针和字符数组的区别

② 对使用字符指针变量和字符数组的讨论

四、指针和函数

(1)指针变量作为函数参数

(2)数组名作为函数参数 

① 实参与形参均用数组名 

② 实参用数组名,形参用指针变量

③ 实参与形参均用指针变量

④ 实参用指针变量,形参用数组名

(3)指针型函数的定义

(4)指针型函数的调用

五、指针数组

(1)指针数组的定义 

(2)指针数组的初始化 

(3)指针数组元素的赋值 

① 将数组名赋予指针数组各元素 

② 将字符串直接赋予指针数组元素 

(4)指针元素的使用

六、指针的程序设计举例

(1)示例一

(2)示例二



一、指针和指针变量

(1)指针 

  • C 语言中指针是一种数据类型。
  • 指针是存放数据的内存单元地址。
  • 计算机系统的内存拥有大量的存储单元(每个存储单元的大小为1字节),为了便于管理,必须为每个存储单元编号,该编号就是存储单元的 “地址” 。
  • 每个存储单元拥有一个唯一的地址。

(2)指针变量

  • 指针变量除了可以存放变量的地址外,还可以存放其他数据的地址。
  • 例如可以存放数组和函数的地址。

(3)指针变量的定义

指针变量定义的一般形式:
【格式】 数据类型符 * 指针变量名 [=初始地址值] , … ;
【功能】定义指向 “数据类型符” 的变量或数组的指针变量,同时为其赋初值。
【说明】
  1. “*” 表示定义的是一个指针变量。指针变量的前面必须有 “*” 号。
  2. 在定义指针变量的同时也可以定义普通变量或数组等。
  3. “数据类型符” 是指针变量所指向变量的数据类型,可以是任何基本数据类型,也可以是其他数据类型。
  4. “初始地址值” 通常是 “&变量名” “&数组元素” 或 “一维数组名” ,这里的变量或数组必须是已定义的。
  5. 在定义指针变量时,可以只给部分指针变量赋初值。
  6. 指针变量的初始化,除了可以是已定义变量的地址,也可以是已初始化的同类型的指针变量,也可以是 NULL(空指针)。
  7. 指针变量初始化时,指针变量的 “数据类型符” 必须与其 “初始地址值” 中保存的数据的类型相同。

(4)指针变量的初始化

【格式】[存储类型] 数据类型 * 指针名 = 初始地址值 ;

【高级语言程序设计(一)】第 7 章:指针

/* 错误代码示例:变量必须已说明过类型应一致 */
int *p=&i;
int i;
/* 错误示例:不能用auto变量的地址,去初始化static型指针 */
main( )
{ int i;
static int *p=&i;
.............. }
/* 正确示例:赋给指针变量,不是赋给目标变量 */
int i;
int *p=&i;
/* 正确示例:用已初始化指针变量作初值 */
int i;
int *p=&i;
int *q=p;
/* 指针变量赋值 */
int i, j;
int *p1,
*p2;
p1=&i; p2=&j ;
i=3; *p1=5;
j=6; *p2=8;

【高级语言程序设计(一)】第 7 章:指针


(5)指针变量的一般使用

① 给指针变量赋值

【格式】 指针变量 = 地址型表达式
  • 其中, “地址型表达式” 即运算结果是地址型的表达式。
  • C 语言规定,变量地址只能通过取地址运算符获得,即 “&” ,其运算对象是变量或数组元素名,运算结果是对应变量或数组元素的地址。
  • 需要注意的是,虽然地址是一个整数,但是 C 语言中不允许把整数看成 “地址常量” ,所以此处的 “地址型表达式” 不能是整数。

② 直接使用指针变量

【格式】 指针变量名
  • 需要使用地址时,可以直接引用指针变量名。

③ 通过指针变量引用所指向的变量

【格式】* 指针变量名

  • C 程序中, “* 指针变量名” 代表其指向的变量或数组元素,其中的 “*” 称为指针运算符。
  • 需要注意的是,这种引用方式要求指针变量必须已经定义且有值。

(6)指针的基本运算 

① 取地址运算符 &

  • 取地址运算符 “&” 的功能是取变量的地址,它是单目运算符。
  • 取地址运算符的运算对象必须是已经定义的变量或数组元素,但不能是数组名。
  • 运算结果是运算对象的地址。

② 指针运算符 *

  • 指针运算符 “*” 的功能是取指针变量所指向地址中的内容,与取地址运算符 “&” 的运算是互逆的,它是单目运算符。
  • 指针运算符的运算对象必须是地址,可以是已赋值的指针变量,也可以是变量或数组元素的地址,但不能是整数,也不能是非地址型的变量。
  • 运算结果就是地址对应的变量。

③ 取地址运算符和指针运算符的说明

【高级语言程序设计(一)】第 7 章:指针

④ 取地址运算符和指针运算符的优先级和结合性

  1. 取地址运算符、指针运算符和自增、自减等单目运算符的优先级相同。
  2. 所有单目运算符的结合性为从右至左。

(7)指针变量的引用

/* 示例:通过指针变量访问整型变量 */
#include <stdio.h>
void main( )
{
int a, b, *p1, *p2 ;
a=100; b=10;
p1=&a; p2=&b;
printf(“a=%d, b=%d\n”, a, b);
printf(“*p1=%d, *p2=%d\n”, *p1, *p2);
printf(“&a=%x,& b=%x\n”, &a, &b);
printf(“p1=%x, p2=%x\n”, p1, p2);
printf(“&p1=%x, &p2=%x\n”, &p1, &p2);
}

 【高级语言程序设计(一)】第 7 章:指针【高级语言程序设计(一)】第 7 章:指针


(8)指针变量作为函数参数

特点:共享内存, 双向” 传递 

① 值传递 

【高级语言程序设计(一)】第 7 章:指针

/* 「值传递」示例:将数从大到小输出 
    函数调用结束后,分配给 x,y,temp 单元释放 */

#include <stdio.h>
void swap(int x,int y)
{
  int temp;
  temp=x;
  x=y;
  y=temp;
}

void main()
{ 
  int a,b;
  scanf("%d,%d", &a, &b);
  if(a<b) swap(a,b);
  printf("\n%d,%d\n", a, b);
}

 【高级语言程序设计(一)】第 7 章:指针

② 地址传递 

【高级语言程序设计(一)】第 7 章:指针

/* 示例:将数从大到小输出(使用指针变量作函数参数) */
#include <stdio.h>
void main()
{
  void swap(int *p1, int *p2);
  int a,b;
  int *pointer_1,
  *pointer_2;
  scanf("%d,%d", &a, &b);
  pointer_1=&a; pointer_2=&b;
  if(a<b) swap(pointer_1,pointer_2);
  printf("\n%d,%d\n", a, b);
}

void swap(int *p1, int *p2)
{ 
  int temp;
  temp=*p1;
  *p1=*p2;
  *p2=temp;
}

 【高级语言程序设计(一)】第 7 章:指针



二、指针和数组 

(1)指针和一维数组

数组的指针是指向数组在内存的起始地址,数组元素的指针是指向数组元素在内存的起始地址。

(2)指针变量指向方法

指针变量指向一维数组

若将指针变量指向一维数组,可以采用以下 2 种方法:
  1. 在数据定义语句中用赋初值的方式,即:*指针变量=数组名
  2. 在程序中用赋值的方式,即:指针变量=数组名;

② 指针变量指向一维数组元素

若将指针变量指向一维数组元素,可以采用以下 2 种方法:
  1. 在数据定义语句中用赋初值的方式,即:*指针变量=&数组名[下标]
  2. 在程序中用赋值的方式,即:指针变量=&数组名[下标];

③ 指针变量指向一维数组(利用指针变量引用一维数组元素)

当指针变量指向一维数组,利用指针变量引用一维数组元素的方法如下:
  1. 引用下标为 0 的数组元素 *(指针变量+0)*指针变量指针变量[0]
  2. 引用下标为 i 的数组元素 *(指针变量+i)  或 指针变量[i]

④ 指针变量指向下标为 i 的一维数组元素(利用指针变量引用数组元素)

当指针变量指向下标为 i 的一维数组元素时,利用指针变量引用数组元素的方法如下:
  1. 引用下标为 i 的数组元素 *(指针变量+0) *指针变量
  2. 引用下标为 i-k 的数组元素 *(指针变量-k)
  3. 引用下标为 i+k 的数组元素 *(指针变量+k)

⑤ 指针变量指向一维数组(引用下标为 i 的一维数组元素)

当指针变量指向一维数组时,引用下标为 i 的一维数组元素可以采用 4 种方法:

  1. *(指针变量+i)
  2. *(数组名+i)
  3. 指针变量[i]
  4. 数组名[i]

⑥ 「示例」指向数组元素的指针

 【高级语言程序设计(一)】第 7 章:指针

/* 示例:指向数组元素的指针 */
int a[10];
int *p;
p=&a[0];    /* 或 p=a;  定义后赋值,两者等价 */

【高级语言程序设计(一)】第 7 章:指针

/* 示例:定义指针变量时赋初值 */
int *p=&a[0];
int *p=a;

⑦ 「示例」通过指针引用数组元素

如果:
int a[10];
int *p;
p=&a[1];     /* p指向数组元素a[1] */
则:
*p=1 /* 表示对 p 当前指向的数组元素 a[1] 赋予值 1 */

而:

  • p+1 指向同一数组的下一个元素 a[2]
  • 的值(地址)加了 个字节,p+1=p+1×d(整型,d=2实型,d=4;字符型d=1)指针变量所指数组元素的地址的计算,与数组数据类型有关。
设:
​​​​​​​p=&a[0]
则:
  • p+i 和 a+i 就是 a[i] 的地址 a+i×d
  • *(p+i) 或 *(a+i) 是 p+i 或 a+i 指向的数组元素 a[i]
  • 指向数组的指针变量可带下标,p[i] 与 *(p+i) 等价

(3)一级指针变量与一维数组的关系

int *p int q[10]
  • 数组名是指针(地址)常量
  • p=q; p+i 是 q[i] 的地址
  • 数组元素的表示方法下标法指针法

【高级语言程序设计(一)】第 7 章:指针

  • 形参数组实质上是指针变量

【高级语言程序设计(一)】第 7 章:指针

  • 在定义指针变量(不是形参)时,不能把 int *p 写成 int p[];
  • 系统只给 分配能保存一个指针值的内存区(一般 字节);而给 q 分配 2*10 字节的内存区

(4)表示数组元素的两种方法

① 下标法

【高级语言程序设计(一)】第 7 章:指针

② 指针法

【高级语言程序设计(一)】第 7 章:指针

【高级语言程序设计(一)】第 7 章:指针


(5)用三种方法输出数组中全部元素的值

下面 3 种示例代码中,使用指针变量时要注意的问题:

  1. p++:合法,因为 p 是指针变量,++ 只能用于变量。
  2. a++:不合法,因为 a 是数组名,其值是数组元素的首地址,是常量,程序运行期间值固定不变。
  3. 指针变量使用时要注意当前值。

① 下标法

#include <stdio.h>
void main()
{
  int a[10];
  int i;
  for(i=0; i<10; i++)
  scanf("%d", &a[i]);
  printf("\n");
  for(i=0; i<10; i++)
  printf("%d", a[i]);
}

【高级语言程序设计(一)】第 7 章:指针

② 指针法

#include <stdio.h>
void main()
{
  int a[10];
  int *p,i;
  for(i=0; i<10; i++)
  scanf("%d", &a[i]);
  printf("\n");
  for(p=a,i=0; i<10; i++)
  printf("%d", *(p+i));
}

【高级语言程序设计(一)】第 7 章:指针

③ 针法和指针下标

#include <stdio.h>
void main()
{
  int a[10];
  int *p,i;
  for(i=0; i<10; i++)
  scanf("%d", &a[i]);
  printf("\n");
  for(p=a; p<(a+10); p++)
  printf("%d", *p);
}

 【高级语言程序设计(一)】第 7 章:指针


(6)算术运算 

指针变量可以进行的算术运算包括:

  • 指针变量 ± 整数
  • 指针变量 ++/++ 指针变量
  • 指针变量 --/-- 指针变量
  • 指针变量1 - 指针变量2
由于指针运算符 * 与自增运算符 ++、自减运算符 -- 的优先级相同,结合方向都是 从右至左 ,因此需要注意以下各种形式的含义不同。

*++px;      /* 先使指针变量 px 加 1,再取新的指针变量 px 所指向地址的内容 */

*(++px);    /* 等价于 *++px; */


*px++;      /* 先取指针变量 px 所指向地址的内容,再使指针变量 px 加 1 */

*(px++);    /* 等价于 *px++; */


++(*px);    /* 将指针变量 px 所指向地址的内容加 1 */

++*px;      /* 等价于 ++(*px); */


*(--px);      /* 先使指针变量 px 减 1,再取新的 px 所指向地址的内容 */

*--px;        /* 等价于 *(--px); */


*(px--);      /* 先取指针变量 px 所指向地址的内容,再使指针变量 px 减 1 */

*px--;        /* 等价于 *(px--); */


--(px);       /* 将指针变量 px 所指向地址的内容减 1 */

--*px;        /* 等价于 --(px); */


px-py;      /* 是指两个相同类型的指针可以进行减法运算,运算结果是两个指针之间的数据个数,而不是两个指针的地址之差 */


(7)关系运算

  • 两个类型相同的指针变量可以运用关系运算符比较大小,表示两个指针变量所指向地址位置的前后关系,即前者为小,后者为大。
  • 需要注意的是,如果两个指针变量不是指向同一个数组,则比较大小没有实际意义。


三、指针和字符串

(1)字符串的表示形式

① 用字符数组实现

字符串 : 用双引号括起的一串字符。
  • 可赋给字符型的数组或指针变量
  • 可通过字符型数组名或字符型指针变量输出

【高级语言程序设计(一)】第 7 章:指针

​​/* 示例:定义字符数组 */
#include <stdio.h>
void main()
{ 
  char string[]="I love China!";
  printf("%s\n", string);
  printf("%s\n", string+7);
}

​​/* 运行结果 */
I love Chine!
Chine!

② 用字符指针实现

  • 字符串的指针就是字符串的首地址,即第一个字符的地址,可以使用字符指针变量来保存这个地址
  • 使用字符指针可以处理字符串
  • 字符指针的定义及使用
定义和初始化:
/* 示例:定义和初始化 */
char *string="I love China!";
在程序中可以直接把字符串常量赋给 一个指针变量:
/* 示例:在程序中可以直接把字符串常量赋给一个指针变量 */
char *string;
string="I love China!";

定义字符指针:

/* 示例:定义字符指针 */
#include <stdio.h>
void main( )
{ 
  char *string="I love China!";
  printf("%s\n", string);
}

/* 运行结果 */
I love Chine!

【高级语言程序设计(一)】第 7 章:指针

/* 示例:定义字符指针(改动后的) */
#include <stdio.h>
void main( )
{ 
  char *string="I love China!";
  printf("%s\n", string);
  string+=7;
      while(*string)  /* *string!='\0' */
      { 
         putchar(string[0]);
         string++;
       }
}

/* 运行结果 */
I love Chine!
Chine!

【高级语言程序设计(一)】第 7 章:指针

③  用下标法存取字符串中的字符实现

【高级语言程序设计(一)】第 7 章:指针

/* 示例:将字符串a复制为字符串b */
#include <stdio.h>
void main()
{ 
  char a[]="I am boy.", b[20];
  int i;
  for(i=0; *(a+i)!='\0'; i++)
     *(b+i)=*(a+i);
     *(b+i)='\0';
  printf("string a is: %s\n", a);
  printf("string b is: ");
  for(i=0; b[i]!='\0'; i++)
     printf("%c", b[i]);
  printf("\n");
}

/* 运行结果 */
string a is: I am boy. 
string b is: I am boy.

(2)指向字符串的指针变量

① 将指针变量指向字符串的方法

  1. 在数据定义语句中用赋初值的方式:*指针变量=字符串;
  2. 在程序中用赋值的方式:指针变量=字符串;
需要注意的是,这两种方法并不是将字符串赋予指针变量,而是将存放字符串的连续内存单元的首地址赋予指针变量。

②  利用指针变量处理字符串的处理方式

当指针变量指向字符串时,则可以利用指针变量处理字符串,处理方式主要有:
1. 处理整个字符串
  • 输出整个字符串:printf("%s" ,指针变量);
  • 输入整个字符串:scanf("%s" ,指针变量);
/* 示例:处理整个字符串 */
#include <stdio.h>
int main(void)
{
  char*string="I love China.";
  printf("%s\n",string);
  return 0;
}

/* 运行结果 */
I love China.

2. 处理字符串中的单个字符

/* 示例:使用指向字符串的指针变量处理字符串中单个字符 */
#include <stdio.h>
int main(void)
{
  char *string="I love China.";
  for(;*string!='\0'; string++) printt("%c", *string); /* 利用for循环和指向字符串的指针变量string 逐一输出字符串各字符 */
  printf("\n");
  return 0;
}

/* 运行结果 */
l love China.

(3)指向字符数组的指针变量

  • C 语言中,字符串是按字符数组进行处理的,系统存储一个字符串时先分配一个起始地址,从该地址开始连续存放字符串中的字符。
  • 这一起始地址即字符串首字符的地址。
  • 所以,可以将一个字符串赋值给一个字符数组,也可以赋值给一个字符指针变量。

① 字符指针和字符数组的区别

字符指针和字符数组的区别主要体现在:
  1. 存储内容不同
  2. 赋值方式不同
  3. 字符指针变量在定义后应先赋值才能引用
  4. 指针变量的值是可以改变的,字符指针变量也不例外;而数组名代表数组的首地址,是一个常量,而常量是不能改变的。

② 对使用字符指针变量字符数组的讨论

char *cp; char str[20]; 的区别:
1、str  由若干元素组成,每个元素放一个字符;而  cp  中存放字符串首地址
2、赋值方式:
  • 字符数组只能对元素赋值
/* 示例:错误代码 */
char str[20];
str="I love China!";
  • 字符指针变量可以用
/* 示例:正确代码 */
char *cp;
cp="I love China!"; 
  • 赋初值
/* 示例:正确代码,等价 char *cp; cp=“China!”; */
char *cp="China!"; 

/* 示例:错误代码,不等价 char str[14]; str[]="China" */
char str[14]={"China"};


四、指针和函数

(1)指针变量作为函数参数

  1. 指针变量既可以作为函数的形参,也可以作为函数的实参。
  2. 指针变量作为函数参数,形参和实参之间的数据传递方式本质上是值传递,只是在调用函数时传递的内容是地址,这样使得形参变量和实参变量指向同一个变量。
  3. 若被调函数中有对形参所指变量内存的改变,实际上是改变了实参所指变量的内容。

(2)数组名作为函数参数 

1. 数组名作为函数形参时,接收实参数组的首地址;
2. 数组名作为函数实参时,将数组的首地址传递给形参数组。
3. 引入指向数组的指针变量后,数组及指向数组的指针变量作为函数参数时,可有四种等价形式:
  • 形参、实参均为数组名
  • 形参、实参均为指针变量
  • 形参为指针变量、实参为数组名
  • 形参为数组名、实参为指针变量
数组名作函数参数, 地址传递 当用数组名做函数 实参时相当于将数组的 首地址传给被调函数的 形参,此时,形参数组 和实参数组占用的是同 一段内存, 所以当在被 调函数中对形参数组元 素进行修改时,实参数 组中的数据也将被修改, 因为它们是同一个地址。
【高级语言程序设计(一)】第 7 章:指针
/* 示例:数组名作函数参数 */
void main( )
{
  f(int arr[], int n);
  int array[10];
       ┆
  f(array, 10);
       ┆
}

void f(int arr[], int n)
{
  ┆
}
用数组做函数参数有如下 4 种情况:
【示例】将数组 a  中  个整数按相反顺序存放。
【思路】数组元素头尾对调。
【调用方式】
  • 实参与形参均用数组名
/* 实参形参都用数组名 */
int a[10];                  inv(int x[], int n)
inv(a, 10)                  { …… }
  • 实参用数组名,形参用指针变量
/* 实参用数组名,形参用指针变量 */
int a[10];                   inv(int *x, int n)
inv(a, 10)                   { …… }
  • 实参与形参均用指针变量
/* 实参形参都用指针变量 */
int a[10];                   inv(int *x, int n)
int *p=a;                    { …… }
inv(p, 10)
  • 实参用指针变量,形参用数组名
/* 实参用指针变量,形参用数组名 */
int a[10];                   inv(int x[ ],int n)
int *p=a;                    { …… }
inv(p,10)

① 实参与形参均用数组名 

【高级语言程序设计(一)】第 7 章:指针

/* 示例:将数组 a 中 n 个整数按相反顺序存放 */
/* [调用方式] 实参与形参均用数组名 */
#include <stdio.h>
void main()
{
  void inv(int x[], int n);
  int i, a[10]={3,7,9,11,0,6,7,5,4,2};
  printf("The original array:\n");
  for(i=0; i<10; i++) printf("%d,", a[i]);
      printf("\n");
  inv(a,10);
  printf("The array has been inverted:\n");
  for(i=0; i<10; i++) printf("%d,", a[i]);
     printf("\n");
}

void inv(int x[], int n)
{ 
  int temp, i, j, m=(n-1)/2;
  for(i=0; i<=m; i++)
     { 
        j=n-1-i;
        temp=x[i]; x[i]=x[j]; x[j]=temp; 
     }
  return;
}

② 实参用数组名,形参用指针变量

【高级语言程序设计(一)】第 7 章:指针

/* 示例:将数组 a 中 n 个整数按相反顺序存放 */
/* [调用方式] 实参用数组名,形参用指针变量 */
#include <stdio.h>
void main()
{
  void inv(int *x, int n);
  int i, a[10]={3,7,9,11,0,6,7,5,4,2};
  printf("The original array:\n");
  for(i=0; i<10; i++) printf("%d,", a[i]);
      printf("\n"); inv(a,10);
  printf("The array has been inverted:\n");
  for(i=0; i<10; i++) printf("%d,", a[i]);
      printf("\n");
}

void inv(int *x, int n)
{ 
  int temp, *p, *i, *j, m=(n-1)/2;
  i=x; j=x+n-1; p=x+m;
  for(; i<=p; i++, j--)
     { 
        temp=*i; *i=*j; *j=temp; 
     }
  return;
}

③ 实参与形参均用指针变量

/* 示例:将数组 a 中 n 个整数按相反顺序存放 */
/* [调用方式] 实参与形参均用指针变量 */
#include <stdio.h>
void main()
{
  void inv(int *x, int n);
  int i, arr[10], *p=arr;
  printf("The original array:\n");
  for(i=0; i<10; i++, p++)
      scanf("%d", p);
  p=arr; inv(p, 10);
  printf("The array has been inverted:\n");
  for(p=arr; p<arr+10; p++)
      printf("%d", *p);
  printf("\n");
}

void inv(int *x, int n)
{ 
  int *p, m, temp, *i, *j;
  m=(n-1)/2;
  i=x; j=x+n-1; p=x+m;
  for(; i<=p; i++, j--)
     { 
        temp=*i; *i=*j; *j=temp; 
     }
  return;
}

④ 实参用指针变量,形参用数组名

/* 示例:将数组 a 中 n 个整数按相反顺序存放 */
/* [调用方式] 实参用指针变量,形参用数组名 */
#include <stdio.h>
void main()
{
  void inv(int x[], int n);
  int i, a[10], *p=a;
  for(i=0; i<10; i++, p++)
      scanf("%d", p);
  p=a;
  inv(p,10);
  printf("The array has been inverted:\n");
  for(p=arr; p<arr+10; p++)
      printf("%d", *p);
  printf("\n");
}

void inv(int x[ ], int n)
{ 
  int t, i, j, m=(n-1)/2;
  for(i=0; i<=m; i++)
     { 
        j=n-1-i; 
        t=x[i]; x[i]=x[j]; x[j]=t; 
     }
  return;
}

(3)指针型函数的定义

  • C 语言中,函数可以返回整型、实型、字符型数据,也可以返回指针类型数据,即返回一个地址。
  • 指针型函数是指函数的返回值是指针型,即这类函数的返回值必须是地址值,调用该类函数时,接收返回值的必须是指针变量、指针数组元素等能够存放地址值的对象。
  • 定义指针型函数的格式和有返回值的函数的定义格式基本相同,唯一的区别是在函数名前面加一个 “*” ,表示函数的返回值是指针型数据。

(4)指针型函数的调用

指针型函数的调用和一般函数的调用方法完全相同,但需要注意的是:
  • 只能使用指针变量或指针数组元素接收指针型函数的返回值
  • 不能使用数组名接收指针型函数的返回值
  • 因为函数名是地址常量,不是地址型变量,不能接收地址型变量数据


五、指针数组

(1)指针数组的定义 

【定义】指针数组是数组中的元素均为指针变量。
【格式】 数据类型符 *指针数组名[数组长度];
【功能】定义指针数组,有 “长度” 个数组元素。
【说明】
  1. 指针数组名是标识符,前面必须加 “*” 号。
  2. 定义指针数组的同时可以定义普通变量、数组和指针变量等。
  3. “数据类型符” 可以是任何基本数据类型。
  4. “数据类型符” 不是指针数组元素中存放的数据类型,而是其所指向数据的数据类型。

(2)指针数组的初始化 

/* 示例 */
char *ps[]={"China", "America", "Russia", NULL};
定义了一个用于指向字符型数据的指针数组 ps,其长度为 4 ,同时对指针数组元素赋初值,前面三个是字符型指针,最后一个是空指针。
/* 示例 */
int a[3][3]={1,2,3,4,5,6,7,8,9};
int *p[3]={a[0],a[1],a[2]};      /* 利用二维数组元素初始化指针数组p */

(3)指针数组元素的赋值 

① 将数组名赋予指针数组各元素 

/* 示例 */
char s[4][20]={"China", "America", "Russia", NULL};
char *p[4];
p[0]=s[0];    /* 给指针数组元素 p[0] 赋值 s[0] ,s[0] 是字符串 "China" 的首地址 */

② 将字符串直接赋予指针数组元素 

/* 示例 */
char *p[4];
p[0]="China";  /* 直接给指针数组元素 p[0] 赋值为字符串 "China" 的首地址 */

(4)指针元素的使用

  • 指针数组元素的表示方法和普通数组元素的表示方法完全相同。
  • 指针数元素的使用和指针变量的使用完全相同,可以对其赋予地址值,可以利用其引用所指向的变量或数组元素,也可以参与运算。

【高级语言程序设计(一)】第 7 章:指针

其中算术运算和关系运算一般只用于指针数组元素指向同一个指针数组。 


六、指针的程序设计举例

(1)示例一

/* 
  pointer[i]+j、array[i]+j、 &array[i][j] 等价,均指向 array[i][j]
  *(pointer[i]+j)、 *(*(pointer+i)+j)、 pointer[i][j] 与 array[i][j] 等价
*/

#include <stdio.h>
#include <string.h>
int main(void)
{
  int array[3][3]={1,2,3,4,5,6,7,8,9), i, j;       /* 定义一个整形二维数组 array */
  int *pointer[3]={array[0], array[1], array[2]};  /* 定义一个指向整形数据的指针数组 pointer 并初始化,即将二维数组 array 的每行元素的首地址赋予指针数组的各元素 */
  for(i=0; i<3; i++)
      for(j=0; j<3; j++)
          printf("%4d", pointer[i][j]);            /* 利用指向二维数组元素的指针数组输出二维数组各元素的值 */
  return 0;
}

【代码详解】

1. 在 main 函数中,定义一个 3 行 3 列、类型为整形的二维数组 array ,并且初始化它的每一个元素,代码如下:

int array[3][3]={1,2,3,4,5,6,7,8,9};

2. 定义一个指向 int 类型的指针数组 pointer ,它有 3 个元素,即数组的行数。将二维数组每一行的首元素的地址分别赋给 pointer 数组中的相应元素,代码如下:

int *pointer[3]={array[0], array[1], array[2]};

3. 使用嵌套的 for 循环遍历二维数组 array 的每个元素,并使用指向二维数组元素的指针数组 pointer 输出相应元素的值,代码如下:

for(i=0; i<3; i++)
  for(j=0; j<3; j++)
      printf("%4d", pointer[i][j]);

4. 在输出时,利用了 pointer[i][j] 等价于 *(pointer[i]+j),即先取得 pointer[i] 指针指向的地址,再加上 j 偏移量,最后用 * 取指针指向的值,这样就不必再写二重循环取数组元素。因此,*(pointer[i]+j)、*(*(pointer+i)+j)、pointer[i][j] 与 array[i][j]等价。


(2)示例二

/* 输入三个国家的名称,按字母顺序排序后输出 */
#include <stdio.h>
#include <string.h>
int main(void)
{
  char *s[]={"China", "America", "Russia"}, *p;   /* 定义指针数组s和指针变量p */
  int i, j, k=3;
  for(i=0; i<k-1; i++)
      for(j=0; j<k-1; j++)
          if(strcmp(s[j],s[j+1]>0)
            { 
               p=s[j]; s[j]=s[j+1]; s[j+1]=p; 
            }
  for(i=0; i<k; i++)
      printf("%s\n", s[i]);
  return 0;
}

【代码详解】

这是一个 C++ 代码,它实现了输入三个国家的名称,按字母顺序排序后输出的功能。下面是代码的详细解释:

  1. #include 是 C++ 中的预处理指令,它会在编译之前将 stdio.h 和 string.h 头文件插入到代码中,以便在程序中使用这些库函数。

  2. char *s[]={"China", "America", "Russia"}, *p; 是定义了一个指针数组 s 和一个指针变量 p, *s[] 是一个指向字符类型的指针数组,数组中存放的是 char 类型的指针变量,每个指针变量指向一个字符串。在本例中,数组中存放了三个国家的名称。

  3. int i, j, k=3; 是定义了三个整型变量 ij 和 k,并将 k 初始化为 3。其中,i 和 j 是循环变量,用于控制循环次数,k 存储指针数组s的元素数量,也即需要排序的国家名称数量。

  4. for(i=0; i<k-1; i++) for(j=0; j<k-1; j++) if(strcmp(s[j],s[j+1])>0) { p=s[j]; s[j]=s[j+1]; s[j+1]=p; } 是一个双重循环,用于字符串的排序。外层循环变量 i 用于控制循环次数,因为只有 k-1 次循环后才可以完成排序,内层循环变量 j 也用于控制循环次数,每次循环会比较相邻的两个字符串,如果前一个字符串比后一个字符串的字典序大,则通过指针交换的方法进行排序,最后完成整个数组的排序。

    1. strcmp(s[j],s[j+1])>0 表示字符串 s[j] 是否比字符串 s[j+1] 大,如果是,说明 s[j] 排在 s[j+1] 的后面,需要进行交换。
    2. p=s[j]; s[j]=s[j+1]; s[j+1]=p; 是通过指针变量 p 进行指针交换,将 s[j] 和 s[j+1] 的值进行交换。
  5. for(i=0; i<k; i++) printf("%s\n", s[i]); 是一个循环语句,用于输出排序后的字符串,%s 是 C++ 语言中的格式控制字符串,用于输出字符串,%s\n 表示输出字符串并换行。

  6. return 0; 表示程序执行完毕,程序结束,并将执行结果返回给操作系统。文章来源地址https://www.toymoban.com/news/detail-464717.html

到了这里,关于【高级语言程序设计(一)】第 7 章:指针的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【高级语言程序设计(一)】第 10 章:文件

    目录 一、文件概述 (1)文件定义 (2)文件命名 (3)文件分类 ① 按照文件的内容划分 ② 按照文件的组织形式划分 ③ 按照文件的存储形式划分 ④ 按照文件的存储介质划分 (4)文件存取方式 (5)文件系统  二、文件的打开和关闭函数 (1)文件打开函数 ①  库函数

    2024年02月08日
    浏览(45)
  • Go语言程序设计-第9章--使用共享变量实现并发

    一个能在串行程序中正确工作的函数。如果这个函数在并发调用时仍然能正确工作,那么这个函数是并发安全的。在这里并发调用是指,在没有额外同步机制的情况下,从两个或者多个 goroutine 同时调用这个函数。如果一个类型的所有可访问方法和操作都是并发安全时,则它

    2024年02月02日
    浏览(71)
  • 【2022级研究生人工智能高级语言程序设计考试说明】

    考试题共包括4道大题: 第一大题:分类和回归----(7选1) 第二大题:降维和聚类----(6选1) 第三大题:API调用(课程中学习过的所有云平台)----(11选1) 第四大题:深度学习项目----(10选1) 题目采取随机分配方式,请查阅 人工智能高级语言程序设计考试-题目分配表 ,

    2024年02月11日
    浏览(60)
  • 南京邮电大学通达学院 高级语言程序设计(C语言) 题库选择、填空、读程序题答案及解析、程序填空答案、编程题答案及代码作用的概括性说明

    关于概念的问题不做解析,都是死东西,也解析不了                                                                                                                                                  

    2024年02月04日
    浏览(89)
  • C++程序设计基础【五】(引用和指针)

    引用是对象的替代名称,以简化实体之间的通信。当声明一个引用变量时,不会在内存中创建一个新的对象,而只是声明一个现有变量的替代名称 引用变量在原始变量前加上r并将首字母大写,形成约定,方便查看绑定的对象 1.复合类型 引用类型是复合类型,但不能用double的

    2024年02月07日
    浏览(39)
  • 【Java高级程序设计】注解实验

    @Label注解: person类:  PersonAction接口: PersonInput类,负责提示录入人员的相关属性,提示必须是注解@Label所标注的中文名称。 PersonDisplay,负责显示人员信息,显示时的属性名称必须为注解@Label所标注的中文名称 测试类: 运行结果: @Column注解 Person类: MySqlDAO类: CreateSQL类

    2024年02月07日
    浏览(59)
  • 数字集成电路设计(六、Verilog HDL高级程序设计举例)

    在我们的数电,集成电路设计里面,一定是层次化设计的 在一个手机芯片的一个部分,写的硬件描述语言的层次都能达到20几层,对于这样的设计,我i们就能想到采用底层的设计,中间层的设计和顶层的设计。对于小规模电路,极小规模电路,通常想的是先有模块然后去搭一

    2024年04月16日
    浏览(62)
  • Verilog学习笔记(5):Verilog高级程序设计

    串行加法器: 一个四位串行加法器由4个全加器构成。全加器是串行加法器的子模块,而全加器是由基本的逻辑门构成,这些基本的逻辑门就是所说的叶子模块。这个设计中运用叶子模块(基本逻辑门)搭建成子模块(全加器),再用子模块搭建成所需要的电路(串行加法器

    2024年02月11日
    浏览(44)
  • Python 程序设计入门(025)—— 使用 os 模块操作文件与目录

    Python 内置了 os 模块及其子模块 os.path,用于对目录或文件进行操作。在使用 os 模块及其子模块 os.path 模块时,需要使用 import 导入该模块,才能使用它们提供的函数或方法。 1、os 模块提供的操作目录的函数 os 模块提供的操作目录的函数如下表所示: 函数 说明 getcwd() 返回当

    2024年02月11日
    浏览(57)
  • 《抽象代数极简教程》全书目录 / By 禅与计算机程序设计艺术&ChatGPT

    —— By 禅与计算机程序设计艺术ChatGPT 1.1 集合的基本概念 1.2 二元运算 1.3 代数系统的定义 1.4 例子:整数集合的代数系统 2.1 群的定义 2.2 群的基本性质 2.3 群的例子 2.4 子群 2.5 商群 2.6 同态与同构 3.1 环的定义 3.2 环的基本性质 3.3 环的例子 3.4 理想 3.5 商环 3.6 同态与同构 4

    2024年02月03日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包