1 / 81

第十章 指 针

第十章 指 针. 指针的基本概念 指向变量的指针变量 指向数组元素的指针变量 指向字符串的指针变量 指针变量做函数参数 指针数组和指向指针变量的指针. 10.1 地址和指针的概念. 地址和指针的概念. 首先回忆一下:内存单元的组织形式?. “ 位”和“字节”;“内存单元的内容”和“内存单元的地址”. “ 位”是最小的电子线路单元,每一个“位”可以保存一个二进制数,即 0 或 1 。 “字节”是由若干个“位”组成的,是基本的数据存储单元,即编译系统是以“字节”为基本单元为数据分配存储空间的。.

jerry-mays
Download Presentation

第十章 指 针

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第十章 指 针 • 指针的基本概念 • 指向变量的指针变量 • 指向数组元素的指针变量 • 指向字符串的指针变量 • 指针变量做函数参数 • 指针数组和指向指针变量的指针

  2. 10.1 地址和指针的概念

  3. 地址和指针的概念 首先回忆一下:内存单元的组织形式? “位”和“字节”;“内存单元的内容”和“内存单元的地址” • “位”是最小的电子线路单元,每一个“位”可以保存一个二进制数,即0或1。 • “字节”是由若干个“位”组成的,是基本的数据存储单元,即编译系统是以“字节”为基本单元为数据分配存储空间的。 • 内存中每一个字节都有一个唯一的“编号”,这就是内存单元的地址。 • 字节单元中保存的数据,即是内存单元的内容。

  4. 地址和指针的概念 同时,编译系统把每个变量所占字节单元的地址信息和变量名对应起来 程序定义变量int a; 编译系统为每一个定义的变量分配相应数目的字节单元 编译系统首先根据变量名与地址的对应关系,找到变量a的地址 程序中访问该变量a=234; 然后,把常量234放到由该地址所指向的内存单元去 再回忆一下:数据在内存中是如何存储和如何读取的? 1. 定义变量,系统分配内存单元: 2. 访问变量:首先确定变量的地址

  5. 地址和指针的概念 把变量a 的地址保存到指针变量中 p = &a; 程序定义普通变量 int a ; 程序定义指针变量 int *p ; 然后把常量234放到该值(地址)所指向的内存单元去 首先取出变量 p的值(实际上就是a 的地址) *p=234 ; 这种利用变量名及其对应的地址信息(该信息由系统自动维护,无法操纵)存取变量值的方式称之为“直接访问”方式。 我们也可以采取另一种称之为“间接访问”的方式,即把某个变量的地址保存在另一个变量里。 “直接访问”方式: a = 234; “间接访问”方式: *p = 234;

  6. 地址和指针的概念 指针就是内存单元的地址。 专门用于保存地址的变量叫做 指针变量。 指针变量的值就是地址。指针 变量指向该地址所指向的单元。

  7. 常量 10 0 23 int b int c int* p int** x int* q int** y 指针的指针变量 变量 int a 地址常量 &a &b &c 10 p放的是a单元的地址,所以*p==10 指针变量 指针变量的地址&p &q &a p的内容是&a: a的地址/a的指针, 所以p指向a a单元的内容 a a单元的地址(&a)所指单元(a)的内容 *(&a) &p **x 即*(*x) 即*p 即10

  8. 10.2 变量的指针和指向变量的指针变量

  9. 变量的指针和指向变量的指针变量 • 变量的指针就是变量的地址(编译系统分配给该变量的内存单元的地址) • 用于保存变量的指针的变量就是指向变量的指针变量。 • 定义指针变量 定义的一般形式: 类型说明符 *指针变量名; 如: int *pa, *pb; float *pf1, *pf2; char *ch1, *ch2; 说明: ① “类型说明符”表示该指针变量可以指向的变量的类型,即该指针变量可以而且只能保存这种类型的变量的地址; ② 一个“*”号表示定义的变量是一个能够保存普通变量地址的指针变量,而不是一个保存具体数据的普通变量。

  10. 指针变量的赋值 指针变量只能保存地址。可以用下面的三种方式给它赋值: 1. 使用取地址运算符 & ,把地址值赋给指针变量 比如: int *pa, *pb, a, b; pa = &a; pb = &b; 2. 把另一个指针变量的值赋给指针变量 比如: int *pa, *pb, a, b; pa = &a; pb = pa; 3. 给指针变量赋NULL值(NULL是在 stdio.h 头文件中定义的符号常量,该常量代表整数0),表示该指针变量本身的值为0,它不指向任何内存单元。 比如: int *pa, *pb, *pc; pa = NULL;pb = 0; pc = ‘\0’;

  11. 使一个指针变量指向同类型的变量 pb b pa a &b &a ? 定义指针变量后,怎样使它指向一个同类型的普通变量呢 方法:只需把某个同类型变量的地址(指针)赋值给该指针 变量即可。然后,我们就可以说,该指针变量指向了某个普 通变量。 比如: int *pa, *pb, a, b; pa = &a; pb = &b;

  12. 使一个指针变量指向同类型的变量 注意:某个类型的指针变量只能保存同类型的变量的指针 (即一个指针变量只能指向同类型的变量) 比如: int *pa, *pb, a, b; float *p1, *p2, f1, f2; pa = &a; pb = &b; /* 正确的赋值 */ p1 = &a; p2 = &b; /* 错误的赋值 */ p1 = a; p2 = 1234; /* 错误的赋值 */ Error: Cannot convert 'int *' to 'float *' Error: Cannot convert 'int' to 'float *'

  13. 两个有关指针的运算符 &a pa a *pa ① 取地址运算符:& ( 只能取变量或数组名,数组元素的地址) ② 指针运算符(间接访问运算符):* (单目) 优先级:与取地址运算符&同级 结合性:右结合性 用法: *指针变量名 (访问地址所指单元(的内容)) 比如:int a, *pa; pa = &a; 则: &a 为变量a的地址;等价于 pa *pa 代表指针变量pa所指向的存储单元,等价于 a

  14. 通过指针变量访问变量:例10-1 #include “stdio.h” void main( ) { int a, b; int *pa, *pb; a = 100; b = 200; pa = &a; pb = &b; printf(“a=%d, b=%d\n”, a, b); printf(“a=%d, b=%d\n”, *pa, *pb); } 运行结果: a=100, b=200 a=100, b=200 让pa和pb 分别指向变量a和b 使用变量名访问变量:输出变量a和b的值 使用变量的地址访问变量:输出pa和pb指向的内存单元的值。实际上就是变量a和b的值

  15. 有关指针变量的说明 ① 一个指针变量可以指向任何一个同类型的普通变量;但是, 在某一个时刻,它只能指向某一个同类型的变量 int *pa, *pb, a, b; pa = &a; pb = &b; pa = &b; pb = &a; ② 让指针变量指向某个同类型普通变量的方法是:把该普通 变量的地址保存到指针变量中。 ③ 必须对指针变量进行了正确合法的初始化后,才能使用该指针 变量访问它所指向的内存单元。未指向内存单元的指针变量,不能用。 int *pa, *pb, a, b; pa=0x1000;*pa = 100; *pb=200; 或 printf(“*pa=%d\n”, *pa);

  16. 有关指针变量的说明 ④ 即使对指针变量进行了正确合法的初始化后,也只能用该 指针变量访问合法的允许访问的内存单元。不能使用该指针 变量去随意访问其它不确定的内存单元,否则,结果是不可 预料的。 int *pa, *pb, a, b; pa = &a; *pa = 100; pb = &b; *pb = 200; printf(“value after a = %d\n”, *(pa + 1)); printf(“value after b = %d\n”, *(pb + 1)); *(pa + 1) = 1000; *(pb + 1) = 2000; 正确安全使用指针变量 错误使用指针变量 错误使用指针变量而且可能很危险

  17. 有关运算符*和&的说明 pa 100 200 • ① 假设有 int a, *pa; pa = &a; 则: • &*pa 相当于 &a,因为 *pa 就相当于 a • *&a 相当于 a ,因为 &a 就相当于 pa,*pa 相当于 a • (*pa) ++ 相当于 (a ++) ② 注意 (*pa) ++ 和 *pa ++ 的区别 由于 ++ 和 * 为同一运算级别,则根据结合性, *pa ++ 相当于*(pa ++) ,与(*pa) ++是完全不同的。 *(pa ++):先得到pa当前指向的单元的值(未用),再使pa自增 (*pa) ++:是pa所指向的单元的值自增 *(pa ++) :得到100(未用),pa自增 (*pa) ++ :pa所指向单元的值100加1, 得到101,而pa不变,

  18. 指向变量的指针变量做函数参数 ? 为什么要引入指针变量?指针变量的用途到底是什么? 指针变量的用途存储地址值,可以表示动态分配的构造型数据,处理字符串,等等,其中一个用途是做函数的参数。 回忆一下: 以前的函数,都是用普通变量做形参和实参。由于函数调用时参数的传递过程是由“实参→形参”的“单向值传递”,函数接收到的只是实参的值(准确的说,是实参的拷贝),所以在函数中我们无法改变实参的值。 但是: 如果我们能把要修改的变量的地址传给函数,而函数又能接收到这个地址,那么在函数中,我们就可以改变这个地址所指向的单元,而这个单元实际上就是要修改的变量的单元,那么就达到了修改该变量的目的。

  19. 指针变量做函数参数:例10-2 #include “stdio.h” void Swap(int *p1, int *p2) { int temp; temp = *p1; *p1 = *p2; *p2 = temp; } void main( ) { int a, b; int *pa, *pb; a = 100; b = 200; pa = &a; pb = &b; printf(“a=%d, b=%d\n”, *pa, *pb); Swap(pa, pb); printf(“a=%d, b=%d\n”, a, b); } 用指针变量作形参 交换两个形参指针变量所指向的内存单元的值 也可以直接用变量的地址作实参,即: Swap(&a, &b); 用指针变量作实参

  20. 指针变量做函数参数的执行过程 pa a pb b &a 100 &b 200 p1 p2 &a &b pa a pb b &a 200 &b 100 • 调用函数之前: 100 200 • 调用函数开始: • pa和pb分别单向值传递给p1和p2 然后交换p1和p2所指向的内存单元(实际上就是a和b)的值 • 调用函数返回: • p1和p2释放单元,但a和b的值已经交换

  21. 错误的Swap函数 考虑一下:如果不用指针变量做参数,仍然用普通变量做参数实现Swap函数,能否达到交换两个变量值的目的? #include “stdio.h” void Swap(int, int); void main( ) { int a =100, b = 200 printf(“a=%d, b=%d\n”, a, b); Swap(a, b); printf(“a=%d, b=%d\n”, a, b); } void Swap(int p1, int p2) { int temp; temp = p1; p1 = p2; p2 = temp; } 用普通变量作实参 用普通变量作形参 交换两个形参变量的值

  22. 错误的Swap函数的执行过程 a b 100 200 p1 p2 100 200 a b 100 200 • 调用函数之前: • 调用函数开始: • a和b分别单向值传递给p1和p2 200 100 然后交换两个形参变量p1和p2的值 • 调用函数返回: • p1和p2释放单元,但a和b的值却没有变化,因为形参不会把值传回给实参。

  23. 课堂练习 ◆ 1. 下若有语句 char *p1, *p2, *p3, *p4, ch;则不能正确赋值的语句是( ) 。 (A) p1 = &ch; scanf(“%c”, p1); (B) *p2 = getchar( ); (C) p3 = &ch; *p3 = getchar( ); (D) scanf(“%c”, p4); 答案: (B) (D) ◆ 2. 对于两个同类型的指针变量,它们之间不能进行的运算是( ) 。 (A) + (B) - (C) = (D) == 答案: (A)

  24. 课堂练习 ◆ 3. 下面的Swap函数,能否达到交换两个变量值的目的? #include “stdio.h” void Swap(int*, int*); void main( ) { int a =100, b = 200, *pa, *pb; pa = &a; pb = &b; printf(“a=%d, b=%d\n”, a, b); Swap(pa, pb); printf(“a=%d, b=%d\n”, *pa, *pb); } void Swap(int *p1, int *p2) { int *temp; temp = p1; p1 = p2; p2 = temp; } 答案:不能。 因为该函数交 换的是两个形 参指针变量本 身的值,而并 没有交换它们 所指向的变量 的值。 变量的值,通过指针变量形参函数调用,有可能改变 指针变量的值,通过指针变量形参函数调用,不可能改变

  25. 10.3 数组和指向数组元素的指针变量

  26. 数组和指向数组元素的指针变量 ◆ 数组的每一个元素都相当于一个同类型的变量,也都在内存中占 据存储单元,也都有相应的地址。 ◆ 既然可以定义指向变量的指针变量,当然也可以定义指向数组元 素的指针变量,用它保存的是数组中某一个元素的地址。 ◆ 数组的名字就是数组的首地址(即数组第一个元素的地址) ◆ 用于保存数组名字的变量就是指向数组元素的指针变量。 指向数组元素的指针变量和指向变量的指针变量是同一种类型的 指针变量,指向数组元素的指针变量加,减数在一定范围内是安全的 ◆ 引用数组元素既可以用数组名加下标法,也可以用指针法。 其本质都是使用指向数组元素的指针。

  27. 指向数组元素的指针变量的定义 • 指向数组元素的指针变量的定义 • 定义方法: 类型说明符 *指针变量名; int *pa, *pb, a[10], b[10]; float *pf1, *pf2; char *str1, *str2; 可见,定义指向变量的指针变量和定义指向数组元素的指针 变量的方法是一样的。

  28. 使一个指针变量指向同类型的数组元素 ? 定义指针变量后,怎样使它指向一个同类型的数组元素呢 方法:只需把某个同类型的数组的首地址(指针)赋值给该 指针变量即可。然后,我们就可以说,这个指针变量指向了 该数组元素。注意:有的地方把它称为指向数组的指针变量 其实,是数组元素的指针变量 比如: int *pa, *pb, a[10], b[10]; pa = &a[0]; pb = &b[0]; /*数组首地址就是数组第一个元素的地址*/ 或者: int *pa, *pb, a[10], b[10]; pa = a; pb = b; /*数组名代表首地址*/ pa=&a

  29. 通过指针变量引用数组元素 • 能够通过指针变量引用数组元素的前提:已经定义了一个指针变量,并且已经给它赋值使它指向某个同类型的数组元素。在有效的范围内对它加,减整数, 运算后它指向仍然是数组元素 • 访问方法: 指针法或下标法 如果指针变量p的初值为&a[0],则: ① p+i 或 a+i就是a[i]的地址,即它们指向a数组中下标为 i 的元素 p + i ==&a[i] &a[i] == a + i ② *(p+i) 或 *(a+i)就是它们所指向的数组元素,即 a[i] *(p + i) ==a[i] *(a + i) == a[i] ③ 指针变量也可以使用下标法,如 p[i] 和 *(p + i) 等价

  30. 通过指针变量引用数组元素 ← &a[0] =a+0 =p+0 *(a+0)= *(p+0)= a[0] ← &a[1] =a+1 =p+1 *(a+1)= *(p+1)= a[1] ← &a[2] =a+2 =p+2 *(a+2)= *(p+2)= a[2] … ← &a[9] =a+9 =p+9 *(a+9)= *(p+9)= a[9] 如有: int a[10], *p; p = a; 或 p = &a[0]; • 注意: 在对指向连续存储单元的指针变量进行加减运算时,数字1并不代表加减一个字节,而是代表该指针变量所属数据类型的数据所占的字节单元的长度。如int型指针变量加减1时,指针实际移动4个字节;float 形指针变量加减1时,指针实际移动8个字节;依次类推。

  31. 通过指针变量引用数组元素:例10-4-1 ◆ 编程从键盘接收数组中的全部元素并输出。 /* 方法1:用数组名和下标 */ #include “stdio.h” void main( ) { int a[10], n; for(n = 0; n < 10; n ++) scanf(“%d”, &a[n]); printf(“\n”); for(n = 0; n < 10; n ++) printf(“%d ”, a[n]); } 特点: 直观易懂。 系统内部计算元素地址。每访问一个新的元素就重新计算一次地址。

  32. 通过指针变量引用数组元素:例10-4-2 ◆ 编程从键盘接收数组中的全部元素并输出。 /* 方法2:用数组名+偏移量得到元素地址*/ #include “stdio.h” void main( ) { int a[10], n; for(n = 0; n < 10; n ++) scanf(“%d”, a + n); printf(“\n”); for(n = 0; n < 10; n ++) printf(“%d ”, *(a + n)); } 特点: 利用数组名这个指针常量加上一个变化的地址偏移量来得到元素地址。 每访问一个新的元素就重新计算一次地址。

  33. 通过指针变量引用数组元素:例10-4-3 ◆ 编程从键盘接收数组中的全部元素并输出。 /* 方法3:用指针变量得到元素地址*/ #include “stdio.h” void main( ) { int a[10], n; int *pa = a; for(n = 0; n < 10; n ++) scanf(“%d”, pa + n); printf(“\n”); for(n = 0; n < 10; n ++) printf(“%d ”, *(pa + n)); } 特点: 利用一个指向数组的指针变量加上一个变化的地址偏移量来得到元素地址。 指针变量本身的值没有变化。

  34. 通过指针变量引用数组元素:例10-4-4 ◆ 编程从键盘接收数组中的全部元素并输出。 /* 方法4:用指针变量得到元素地址*/ #include “stdio.h” void main( ) { int a[10], n; int *pa = a; for(n = 0; n < 10; n ++) scanf(“%d”, pa ++); printf(“\n”); pa = a; for(n = 0; n < 10; n ++) printf(“%d ”, *(pa ++)); } 特点: 利用一个指向数组的指针变量来得到元素地址。 指针变量本身的值在变化。 使用普通变量作循环控制变量。 要时刻注意指针变量的当前值。存在安全隐患

  35. 通过指针变量引用数组元素:例10-4-5 ◆ 编程从键盘接收数组中的全部元素并输出。 /* 方法5:用指针变量得到元素地址*/ #include “stdio.h” void main( ) { int a[10], n; int *pa = a; for(n = 0; n < 10; n ++) scanf(“%d”, pa ++); printf(“\n”); for(pa = a; pa < a+10; ) printf(“%d ”, *(pa ++)); } 特点: 指针变量本身的值在变化。 使用指针变量作循环控制变量。 要时刻注意指针变量的当前值。 要正确确定循环控制变量初值和终值。

  36. 通过指针变量访问数组元素时的注意事项 注意:在利用指针变量本身的值的改变来访问数组元素时, 要时刻注意指针变量的当前值。 #include “stdio.h” void main( ) { int a[10], n; int *pa = a; for(n = 0; n < 10; n ++) scanf(“%d”, pa ++); printf(“\n”); pa = a; for(n = 0; n < 10; n ++) printf(“%d ”, *(pa ++)); } 这一句不能少,否则后面输出的结果就不对了。因为此时指针已经指向数组的有效范围之外去了。

  37. 指向数组元素的指针变量的有关运算 如有: int a[10], *pa; pa = a; 或 pa = &a[0]; ① pa ++ 或 pa += 1,使 pa 指向下一个元素(即得到 下个元素的地址) pa -- 或 pa -= 1,使 pa 指向上一个元素(即得到上 个元素的地址) ② * pa ++ 等价于 * (pa ++) ,即先得到 pa 当前指 向的元素的值,然后再使 pa 自增,从而指向下一个元素 ③ * ++ pa 等价于 * (++ pa) ,即先使 pa 自增,然 后得到 pa 当前指向的元素的值 ④ (* pa) ++ ,则是表示 pa 当前指向的元素的值加1

  38. 指向数组元素的指针变量做函数参数 同指向变量的指针变量一样,指向数组元素的指针变量除了用于访问数组元素之外,主要的用途仍然是用作函数的参数 这时:主调函数向被调函数传递的值是指针(即地址), 因此可以在被调函数内访问(输出或改变)这些地址所指向 的单元的内容。 所谓用指针变量做函数参数,是指用可以保存和接收地址 信息的数据来做函数参数,比如指针变量或数组的名字。因 此有以下几种组合: 1. 实参和形参都是数组名 2. 实参和形参都是指针变量 3. 实参是数组名,形参是指针变量 4. 实参是指针变量,形参是数组名

  39. 指向数组元素的指针变量做函数参数:例 ◆编程从键盘接收数组中的全部元素并输出。 现在用函数实现: 把数组元素的输入和输出分别用两个函数来完成。这时就需 要在主函数和用户自定义函数之间传递数组的首地址信息。 而转递地址信息必须使用指针变量或数组名。

  40. 指向数组元素的指针变量做函数参数:例 #include “stdio.h” void InputArray(int arr[ ], int n) { for(int i = 0; i < n; i ++) scanf(“%d”, &arr[i]); } void OutputArray(int arr[ ], int n) { for(int i = 0; i < n; i ++) printf(“%d ”, arr[i]); } void main( ) { int a[10], n = 10; int *pa = a; InputArray(a, n); OutputArray(a, n); } 数组名作形参 数组名作实参

  41. 指向数组元素的指针变量做函数参数:例 数组名作形参 #include “stdio.h” void InputArray(int arr[ ], int n) { for(int i = 0; i < n; i ++) scanf(“%d”, &arr[i]); } void OutputArray(int arr[ ], int n) { for(int i = 0; i < n; i ++) printf(“%d ”, arr[i]); } void main( ) { int a[10], n = 10; int *pa = a; InputArray(pa, n); OutputArray(pa, n); } 指针变量作实参

  42. 指向数组元素的指针变量做函数参数:例 #include “stdio.h” void InputArray(int *arr, int n) { for(int i = 0; i < n; i ++) scanf(“%d”, arr + i); } void OutputArray(int *arr, int n) { for(int i = 0; i < n; i ++) printf(“%d ”, *(arr + i)); } void main( ) { int a[10], n = 10; int *pa = a; InputArray(a, n); OutputArray(a, n); } 指针变量作形参 数组名作实参

  43. 指向数组元素的指针变量做函数参数:例 指针变量作形参 #include “stdio.h” void InputArray(int *arr, int n) { for(int i = 0; i < n; i ++) scanf(“%d”, arr + i); } void OutputArray(int *arr, int n) { for(int i = 0; i < n; i ++) printf(“%d ”, *(arr + i)); } void main( ) { int a[10], n = 10; int *pa = a; InputArray(pa, n); OutputArray(pa, n); } 指针变量作实参

  44. 课堂练习 ◆ 1. 若有语句 int a[ ]={1, 2, 3, 4, 5}, *pa, n; pa = a; 0≤n≤4,则( )是对a数组元素地址的正确 引用。 (A) a + n (B) a ++ (C) & pa (D) &*pa 答案: (A) (D) ◆ 2. 若有语句 int a[ ]={1, 2, 3, 4, 5}, *pa, n; pa = a; 0≤n≤4,则( )是对a数组元素的错误引用。 (A) *(a + n) (B) *(&a[n]) (C) pa + n (D) pa[n] 答案: (C)

  45. 课堂练习◆3. 写出下面程序执行的结果。 #include “stdio.h” void main( ) { int a[5] ={1, 2, 3, 4, 5}, n, *pa; for(pa = a; pa < a + 5; pa ++) printf(“%d ”, *pa); *pa = a[0]; printf(“\n”); for(n = 0; n < 5; n ++) *(a + n) = *(a + n + 1); for(n = 0; n < 5; n ++) printf(“%d ”, a[n]); } • 运行结果: • 1 2 3 4 5 • 3 4 5 1 • 报应用程序出错 第一个打印循环结束时pa指向a+5,系统并没有分配该地址给a数组 将a[0] 赋给该地址上的单元,冲掉了其他内存程序内容。这种破坏 的影响,有后发性,要到运行那个程序时才看得出来

  46. 10.4 字符串的指针和指向字符串的指针变量

  47. 字符串的指针和指向字符串的指针变量 ◆ C语言是用连续的字节单元来保存字符串的,字符串以指针表示。 如果字符数组的初始化值是字符串,字符串就保存在字符数组中 字符串指针和字符数组名是同一个东西。 ◆ 字符串的指针就是字符串中第一个字符所在内存单元的地址 ◆ 可以定义指向字符串的指针变量,如果给它赋值字符串,它保存 的是字符串中第一个字符所在内存单元的地址。与字符数组名 类似,也是指向连续的字节单元的首地址 ◆ 指向字符串的指针变量实际就是一个指向字符型变量的字符指针 变量,它用来存放字符串的指针常量

  48. 指向字符串的字符指针变量的定义 • 指向字符串的指针变量的定义 char *指针变量名; char string1[80], string2[80]; char *str1, *str2; 其中,string1和string2、str1和str2都是字符指针类型的数据,都可以保存字符的地址信息,所不同的是: string1和string2是字符指针常量,它们表示的值无法改变,指向固定的内存单元,可以通过改变数组元素值,在不同时间放不同的字符串到这个固定的内存单元,这些不同的字符串有相同的地址指针常量值 而str1和str2是字符指针变量,它们存储的值可以改变,可以指向任何字符数组指针常量,字符串指针常量,任何字符变量的地址.如果不给它赋值,它不指向任何地址,不指向任何内存单元。

  49. 使一个字符指针变量指向字符串 ? 定义字符指针变量后,怎样使它指向一个字符串呢 方法:只需把某个字符串的指针赋值给该字符指针变量即可。 然后,我们就可以说,这个字符指针变量指向了该字符串。 上述操作有两种情况: 1.先定义字符数组保存字符串,然后再定义字符型指针变 量指向该数组首元素;这时指针变量指向的内容可以改变 2.不定义字符数组,直接定义字符型指针变量,然后把字 符串赋值给该指针变量。这时指针变量指向的内容不能改变 注意区分 :指针变量的内容,指针变量指向的内容

  50. 使一个指针变量指向字符串:第一种情况 1.先定义字符数组保存字符串,然后再定义字符型指针变量指向该数组首元素,也就是指向该字符串; #include “stdio.h” void main( ) { char str[80] = “Hello, World”; char *pstr = str; /* 定义字符型指针变量 */ printf(“%s\n”, str); /* 用数组名访问*/ printf(“%s\n”, pstr); /* 用指针变量访问*/ str[0]=‘A’; *pstr=‘a’;} str是字符数组名,包含了字符数组的首元素地址信息,相当于一个字符型数据的指针,所以可以把它赋值给一个字符型的指针变量。然后就可以用该指针变量来访问字符串。

More Related