第五章 指针(一)

  C语言的强大和良好的自由性绝大部分体现在指针的灵活运用上,指针可以说是C语言的灵魂。

一、不同类型指针之间的区别和联系

  1.不同类型的指针

  指针变量占用内存的大小与 它本身的类型无关,而是由使用的计算机决定的。但是不同类型的指针之间也是有区别的,因为不同类型的指针变量所指向内存区域的大小并不相同。“指针就是地址,地址就是指针”这种说法并不准确,忽略了类型的作用,指针应该是:地址+类型。

  2.普通指针和数组指针

 1 int index;
 2     char a[4] = {‘a‘,‘b‘,‘c‘,‘d‘};
 3     char (*pa)[4];
 4     char *pb;
 5     char *pc;
 6
 7     pa = &a;
 8     pb = a;
 9     pc = &a[0];
10
11     printf("pa所指的地址:%d\n",pa);
12     printf("pb所指的地址:%d\n",pb);
13     printf("pc所指的地址:%d\n",pc);
14
15     printf("pa+1所指的地址:%d\n",pa+1);
16     printf("pb+1所指的地址:%d\n",pb+1);
17     printf("pc+1所指的地址:%d\n",pc+1);
18
19     for(index = 0; index < 4; index++)
20     {
21         printf("pa[%d]=%c\n", index, pa[0][index]);
22         printf("pb[%d]=%c\n", index, pb[index]);
23         printf("pc[%d]=%c\n", index, pc[index]);
24     }

上面的代码可以很好的诠释指针与数组的关系。运行结果如下:

  

  其中有几个有意思的点:1)pa为什么定义成这样? 2)为什么pa、pb、pc分别+1的值不同? 3)怎么通过pa输出字符串?

二、指针与数组之间的关系

  1.指针对于数组的引用

 1     int a[3][3];
 2     int i,j;
 3     int *p;
 4     int (*pa)[3];
 5
 6     for(i = 0; i < 3; i++)
 7     {
 8         for(j = 0; j < 3; j++)
 9         {
10             a[i][j] = i*3+j;
11         }
12     }
13
14     p = a[0];
15     for(i = 0; i < 9; i++)
16     {
17         printf("a[%d][%d] = %d  ", i/3, i%3, p[i]);
18         if(i%3 == 2)
19         {
20             printf("\n");
21         }
22     }
23
24     pa = a;
25     for(i = 0; i < 9; i++)
26     {
27         printf("a[%d][%d] = %d  ", i/3, i%3, *(*pa+i));
28         if(i%3 == 2)
29         {
30             printf("\n");
31         }
32     }

2.通过指针数组创建动态数组

 1 #define N 4
 2 #define M 3
 3
 4     int i;
 5     int j;
 6     int index;
 7     int *a[N];
 8
 9     for(index = 0; index < N; index++)
10     {
11         //简单例子不做错误处理
12         a[index] = (int *)malloc(sizeof(int)*M);
13     }
14
15     for(i = 0; i < N; i++)
16     {
17         for(j = 0; j < M; j++)
18         {
19             a[i][j] = i*M + j;
20             printf("a[%d][%d] = %d  ", i, j ,a[i][j]);
21         }
22         printf("\n");
23     }
24
25     for(index = 0; index < N; index++)
26     {
27         free(a[index]);
28     }
29
30 #undef N
31 #undef M

3.通过数组指针创建动态数组

 1 #define N 4
 2 #define M 3
 3
 4     int i;
 5     int j;
 6     int (*a)[N];
 7
 8     a = (int (*)[N]) malloc (sizeof(int)*M*N);
 9
10     for(i = 0; i < M; i++)
11     {
12         for(j = 0; j < N; j++)
13         {
14             a[i][j] = i*N + j;
15             printf("a[%d][%d] = 0x%d  ", i, j, a[i][j]);
16         }
17         printf("\n");
18     }
19
20     for(i = 0; i < N; i++)
21     {
22         for(j = 0; j < M; j++)
23         {
24             a[i][j] = i*M + j;
25             printf("a[%d][%d] = 0x%d  ", i, j, a[i][j]);
26         }
27         printf("\n");
28     }
29
30     free(a);
31
32
33 #undef N
34 #undef M

  上例书中的代码是有问题的,你能看出问题在那里吗?

4.指针数组对数组的引用

 1 #define N 4
 2 #define M 3
 3
 4     int i,j;
 5     int *a[N];
 6     int b[N][M];
 7
 8     for(i = 0; i < N; i++)
 9     {
10         a[i] = b[i];
11         for(j = 0; j < M; j++)
12         {
13             b[i][j] = i*M+j;
14             printf("a[%d][%d] = %d  ", i, j, a[i][j]);
15         }
16         printf("\n");
17     }
18 #undef N
19 #undef M

5.数组指针对数组的引用

 1 #define N 4
 2 #define M 3
 3
 4     int i,j;
 5     int (*a)[M];
 6     int b[N][M];
 7
 8     for(i = 0; i < N; i++)
 9     {
10         a = b;
11         for(j = 0; j < M; j++)
12         {
13             b[i][j] = i*M+j;
14             printf("a[%d][%d] = %d  ", i, j, a[i][j]);
15         }
16         printf("\n");
17     }
18 #undef N
19 #undef M

  注意和4中实例代码的区别

时间: 2024-08-25 12:45:53

第五章 指针(一)的相关文章

第五章 指针与数组

5.2 指针与函数参数 #include <stdio.h> #include <stdlib.h> #include <ctype.h> int getch(void); void ungetch(int); /*getint 函数:将输入中的下一个整型数赋值给*pn */ int getint(int* pn) { int c, sign; while (isspace(c = getch())) /*跳过空白符*/ ; if (!isdigit(c) &&

K&amp;R——第五章 指针与数组

#include <stdio.h> #define maxsize 5000 char buf[maxsize]; char *head = buf; char *new(int size) { //分配元素字长 //可用内存分配完毕 if (maxsize - (buf - head) < size) return 0; head += size; return head - size; } int *arr; int *arr2; char *str; int main() { a

C和指针 (pointers on C)——第十五章:输入输出函数

第十五章 输入输出函数 这一章读完的第一感觉就是"呵呵". 如果说上过C语言课,基本上scanf()/printf()算是用的比较熟练了.尤其是那些抽象的格式说明.还有scanf()为什么要加括号. 读过本书前面的内容的话,getchar(),putchar(),gets(),puts()这些应该也问题不大. 再如果的话,你学过计算机图形学,你玩过OpenGL,听说过双缓存机制,那么fflush()也肯定弄明白了. 再加上FILE的操作,输入输出定位刷新删除改名,流的概念. 这一章就会

C和指针 (pointers on C)——第五章:操作符和表达式

第五章 操作符和表达式 这一章如果没做过玩过单片机.汇编的话,读起来可能比较吃力,尤其是在移位运算符.位运算符应用上.另外多注意一下左值和右值的理解. 总结: 算术操作符.赋值操作符.关系操作符.条件操作符. 短路求值(short-circuited evalution):如||这样的二目操作符,如果它的左操作数是真,右操作数便不再求值.带来的后果是如果右操作数的数组下标不合法,那么也不会报错. C并不具备显式得布尔类型,布尔值是用整型表达式来表示的.在表达式中混用布尔值和任意的整型值可能会产生

JS复习第五章

第五章 引用类型 一.Object类型 创建object实例的方式有两种. 第一种是使用new操作符后跟object构造函数,如下所示: ver person = new Object( ) ; person.name = “Nicholas” ; person.age = 29 ; 另一种方式是使用对象字面量表示法: var person = { name : “Nicholas”, age : 29 } ; 对象字面量是向函数传递大量可选参数的首选形式. function displayIn

JavaScript高级程序设计(第3版)第五章读书笔记

第五章 引用类型 创建Object实例的方式有两种,第一种是使用new操作符后跟Object构造函数,例如: var person = new Object( ); person.name = “Nicholas”; person.age=29; 第二种是使用对象字面量表示法.如: var person = { name : “Nicholas”, age : 29 }; 在最后一个属性后面添加逗号,会在IE7及更早版本和Opera中导致错误. 两种访问对象属性的方法,一是方括号语法,例如per

现代编译原理--第五章(活动记录)

(转载请表明出处  http://www.cnblogs.com/BlackWalnut/p/4559245.html ) 第五章是到目前位置最让我头疼的一章,不是因为难,是因为对最终的目的不太明确.整章前半部分用十分精简的语言介绍了一个新的概念,活动记录,也就是在函数调用时,一个调用栈究竟发生了什么事.但是,在最终编码实现过程中,总不能理解作者为什么给了这些变量?或者说,完全不知道作者究竟想让我完成一个怎样的功能.纠结了好几天,后来索性往后继续看,看看能不能找到其他的线索.直到看完后一章,硬着

第十五章 文件属性类的实现

                  第十五章    文件属性类的实现        根用户的权限也不能是无限大.必须考虑到保护用户的隐私!用户的文件内容.程序代码可设置为根用户也不能观看,只能是文件拥有者可以查看.修改.但根用户可以删除一切非根用户的文件.也可以查看用户的目录.所以,i_mode字符更改如下:      BU16 i_mode; // 描述文件的访问权限:文件的读.写.执行权限  // i_mode.15-13  ftype; 文件类型: 0-符号软连接文件, // 1-硬连接文

第十五章 链表

/** 数组与链表的区别:数组易随机访问,链表易插入和删除 链表组成:储存数据元素的数据域,储存下一结点地址的指针域 链表易于插入与删除 lists 的用法????????????????????? *///建立一个图书链表 #include<iostream> #include <string> using namespace std; struct book //第一步: 用于建立节点. class 默认为私有 struct 默认为公有 //节点组成:①数据域 ②指针域(*ne