清华_软件学院_C语言_第06章_指针_64904778
清华大学C语言教学课件(共16个PPT)第1个共26页文档
53、 伟 大 的 事 业,需 要决心 ,能力 ,组织 和责任 感。 ——易 卜 生 54、 唯 书 籍 不 朽。——乔 特
55、 为 中 华 之 崛起而 读书。 ——周 恩来
清华大学C语言教学课件(共16个PPT)
第1个
21、没有人陪你走一辈子,所以你要 适应孤 独,没 有人会 帮你一 辈子, 所以你 要奋斗 一生。 22、当眼泪流尽的时候,留下的应该 是坚强 。 23、要改变命运,首先改变自己。
24、勇气很有理由被当作人类德性之 首,因 为这种 德性保 证了所 有其余 的德性 。--温 斯顿. 丘吉尔 。 25、梯子的梯阶从来不是用来搁脚的 ,它只 是让人 们的脚 放上一 段时间 ,以便 让别一 只脚能 够再往 上登。
清华大学谭浩强教授的C++教程第6章
行开头的int是指 第2行开头的 是指: 所定义的指针变量是指向整 行开头的 是指: 型数据的指针变量.也就是说,指针变量pointer_1 型数据的指针变量.也就是说,指针变量 只能用来指向整型数据(例如 和pointer_2只能用来指向整型数据 例如 和j),而 只能用来指向整型数据 例如i和 , 不能指向浮点型变量a和 .这个int就是指针变量 不能指向浮点型变量 和b.这个 就是指针变量 的基类型. 的基类型.指针变量的基类型用来指定该指针变量 可以指向的变量的类型. 可以指向的变量的类型. 定义指针变量的一般形式为
图6.6 (2) *&a的含义是什么?先进行 的运算,得a的 的含义是什么? 的运算, 的含义是什么 先进行&a的运算 的 地址,再进行*运算 运算, 所指向的变量, 地址,再进行 运算,即&a所指向的变量,*&a和 所指向的变量 和 *pointer_1的作用是一样的(假设已执行了 的作用是一样的( 的作用是一样的 ),它们等价于变量 "pointer_1=&a;"),它们等价于变量 .即*&a ),它们等价于变量a. 等价, 与a等价,见图 . 等价 见图6.7.
图6.7 输入a和 两个整数 按先大后小的顺序输出a 两个整数, 例6.2 输入 和b两个整数,按先大后小的顺序输出 和b(用指针变量处理 . 用指针变量处理). 用指针变量处理 解此题的思路是: 设两个指针变量p1和 , 解此题的思路是: 设两个指针变量 和p2,使它 们分别指向a和 . 指向a和 中的大者 中的大者, 指 们分别指向 和b.使p1指向 和b中的大者,p2指 指向 向小者,顺序输出*p1,*p2就实现了按先大后小的 向小者,顺序输出 就实现了按先大后小的 顺序输出a和 .按此思路编写程序如下: 顺序输出 和b.按此思路编写程序如下:
C语言课件(清华大学出版社)
C程序设计(第三版)
第二章
C程序设计(第三版)
本章要点
算法的概念 算法的表示 结构化程序设计方法
C程序设计(第三版)
主要内容
2.1 算法的概念 2.2 简单算法举例 2.3 算法的特性 2.4 怎样表示一个算法 2.5 化程序设计方法
(8)程序可移植性好(与汇编语言比)。 基本上不做修改就能用于各种型号的计 算机和各种操作系统。
C程序设计(第三版)
1.2 C语言的特点
问题:既然有了面向对象的C++语言,为 什么还要学习C语言?
解释1:C++是由于开发大型应用软件的需 要而产生的,并不是所有的人都要去编 写大型软件。
解释2:面向对象的基础是面向过程。C++ 是面向对象的语言,C是面向过程的,学 起来比C语言困难得多,所以不太适合程 序设计的初学者。
C程序设计(第三版)
设y为被检测的年份,算法可表示如下 :
S1:2000 → y
S2:若y不能被4整除,则输出y “不是闰年”。然后转 到S6
S3:若y能被4整除,不能被100整除,则输出y “是闰 年”。然后转到S6
S4:若y能被100整除,又能被400整除,输出y“是闰年 ”,否则输出“不是闰年”。 然后转到S6。
C程序设计(第三版)
用这种方法表示的算法具有通用性、 灵活性。S3到S5组成一个循环,在实现 算法时 要反复多次执行S3,S4,S5等步 骤,直到某一时刻,执行S5步骤时经过 判断,乘数i已超过规定的数值而不返回 S3步骤为止。此时算法结束,变量p的值 就是所求结果。
c++6_自定义类型的运算
12
C++语言程序设计
清华大学 郑莉
例6-3:用“+”运算符实现复数的加法
运 算 符 重 载 函 数
—重载“+”为成员函数
#include<iostream> using namespace std; class Complex { protected: double real; //复数的实部 double image; //复数的虚部 public: Complex(double r = 0.0, double i = 0.0){real = r; image = i;} void output(); //用于输出复数的函数 Complex operator +(Complex c); //实现复数与复数相加的函数 Complex operator +(double r); //实现复数与实数相加的函数 };
7
C++语言程序设计
清华大学 郑莉
用 函 数 实 现 对 象 的 运 算
例6-2:实现复数的加法运算—用非成员函数
void Complex::output() { if (image < 0.0) cout<<"("<<real<<image<<"i)"<<endl; else cout<<"("<<real<<"+"<<image<<"i)"<<endl; }
. 成员访问运算符
.* 成员指针运算符 :: 作用域区分运算符 ?: 条件运算符 sizeof 测数据空间大小运算符 除此之外,C++的其他运算符都可以重载。
清华大学 Visual C# 2000 程序设计 第六章
6.2 属性
6.2.1 属性的声明
根据get和set访问器是否存在,属性可分成如下类型。 读写(read-write)属性:同时包含 get 访问器和 set 访问器 的属性。 只读(read-only)属性:只具有 get 访问器的属性。将只读属 性作为赋值目标会导致编译时错误。 只写(write-only)属性:只具有 set 访问器的属性。除了作 为赋值的目标外,在表达式中引用只写属性会出现编译时错误。
6.3 事件
6.3.1 委托
委托是一种特殊的类型(class),用途是来实现对一种方法的 “封装”。在某种事件发生时,自动调用该方法。好处显然易见,它使 用户可以自定义自己的方法实现,通过封装,CLR会在相应事件激发时 调用你定义的方法,实现自定义的功能。 C#中的委托类似于C或C++中的函数指针,但两者有本质区别:C或 C++不是类型安全的,但C#中的委托是面向对象的,而且是类型安全的。 从某种角度来讲,委托是一个引用类型,用来封装带有特定签名和返回 类型的方法。
6.2 性
6.2.2 属性的访问
class TestAge { static void Main(string[] args) { age Age = new age(); Console.WriteLine("Please input age"); //设置属性值,可以通过输入非法值检验其有效性验证功能 Age.AttributeAge = Int32.Parse( Console.ReadLine()); //输出属性值 Console.WriteLine("Age is {0}",Age.AttributeAge); Console.ReadLine(); } }
第十章指针(C语言程序设计清华版第三版)
引用。*p1是整型变量,不是指针,*p1可以像一般整型 变量一样使用。
*p a 注意:符号*出现在不同的位置,含义也不同。 1. int * p; 定义变量 2. p=&a;*p=3; a=3
10.1.4.1 指针专用运算符 例10.1.2输入两个整数,按先大后小的顺序输出。程序清单如下:
整数,主存储器的所有存储单元的地址是连续的。
编译系统根据变量的数据类型,为变量分配若干个存储单元
(字节)。
每个字符变量分配一个。
一个变量所占用存储区域的所有字节都有各自的地址,C系统把
存储区域中第一个字节的地址作为变量的地址。 要访问变量中的数据,就要知道该变量的内存地址。
10.1.3 指针变量的定义和初始化
定义指针变量的一般形式为:
基类型 * 指针变量名; 例如: int var=10; int * pointer = &var;
变量名:pointer 地址:1310584
值:1310588
变量名:var 地址:1310588
值:10
图10.1.1 指针变量示意图
运算对象只能是变量名,不能是表达式。&运算结
果就是运算对象(变量)的地址。例如:
int *p1,*p2,a,b[10]; p1=&a; //把整型变量a的地址赋给指针变量p1 p2=&b[0];//把数组元素b[0]的地址赋给指针变量p2
10.1.4.1 指针专用运算符
(2)指向运算符* 指向运算符*的运算对象只能是指针变量,*的运 算结果得到运算对象(指针变量)所指的变量。
10.1.2 指针
a的地址(十进制): 1245052 例10.1.1 变量地址输出示例,程序清单如下: b的地址(十进制): 1245036 #include <stdio.h> b[1]的地址(十进制): 1245040 a的地址(十六进制): 12ff7c void main() b的地址(十六进制): 12ff6c { b[1]的地址(十六进制): 12ff70 int a,b[4]; printf("a的地址(十进制): %d\n",&a); printf("b的地址(十进制): %d\n",b);//b的地址就是b[0]的地 址 printf("b[1]的地址(十进制): %d\n",&b[1]); printf("a的地址(十六进制): %x\n",&a); printf("b的地址(十六进制): %x\n",b); printf("b[1]的地址(十六进制): %x\n",&b[1]); }
C语言课件 清华大学谭浩强版c6
§6.5 函数参数及其传递方式
形参与实参
形式参数:定义函数时函数名后面括号中的变量名 实际参数:调用函数时函数名后面括号中的表达式 说明:
实参必须有确定的值 形参必须指定类型 形参与实参类型一致,个数相同 若形参与实参类型不一致,自动按形参类型转换———函数 调用转换 形参在函数被调用前不占内存;函数调用时为形参分配内存; 调用结束,内存释放
运行结果:9,9
(main)
9 5 9 9 2000 2002
(swap)
2000 2002 ****
...
指针变量在使用前 必须赋值!
…...
整型变量a 整型变量b 指针pointer_1 指针pointer_2 指针p1 指针p2 指针p
函数说明
一般形式: 函数类型 函数名(形参类型 [形参名],….. ); 或 函数类型 函数名(); 作用:告诉编译系统函数类型,参数个数及类型,以便检验 函数定义与函数说明不同 函数说明位置:程序的数据说明部分(函数内或外) 下列情况下,可不作函数说明 若函数返值是char或int型,系统自动按int型处理 被调用函数定义出现在主调函数之前 有些系统(如Borland C++)要求函数说明指出函数返值类型和形 参类型,并且对void 和 int 型函数也要进行函数说明
无参函数 有参函数
使用库函数应注意: 1,函数功能 2,函数参数的数目和顺序,及各参数意义和类型 3,函数返回值意义和类型 4,需要使用的包含文件
Ch7_201.c
§6.2 函数的定义
一般格式
现代风格:
函数返回值类型 缺省int型 无返回值void
合法标识符
函数类型 函数名(形参类型说明表) { 说明部分 语句部分 } 例 例 有参函数(现代风格) 有参函数(现代风格) 例 无参函数 y) 例 x, int int max(int x,int y) max(int 空函数 printstar( ) dummy( ) { {int int z; z; { printf("**********\n"); } { } z=x>y?x:y; z=x>y?x:y; 或 return(z); return(z); printstar(void ) 函数体为空 } } { printf("**********\n"); }
C语言程序设计(向华主编)_第8章_指针
变量名 c i
实型变量 f
数据类型 char int float
地 址 2001 3001 4001
4001 4004
f
图8.1 为变量分配的内存
表8.1 变量与地址对照表
《C语言程序设计》 语言程序设计》
清华大学出版社
第8章
指针
8.1
8.1.2 指针变量的定义
指针的概念
指针变量的定义形式: 指针变量的定义形式: 类型声明符 *变量名; 变量名;
《C语言程序设计》 语言程序设计》
清华大学出版社
第8章
指针
8.3
8.3.1 指向数组的指针
பைடு நூலகம்指针与数组
一个数组占用一段连续的内存单元, 一个数组占用一段连续的内存单元,C语言规定数组名即为这段连续内 存单元的首地址。 存单元的首地址。每个数组元素按其类型的不同占用几个连续的内存 单元,一个数组元素的地址就是它所占用的几个内存单元的首地址。 单元,一个数组元素的地址就是它所占用的几个内存单元的首地址。 定义一个指向数组元素的指针变量的方法,与前面介绍的定义指针变量相同。 例如: int a[10]; int *p; p = &a[0]; 把a[0]元素的地址赋给指针变量p。也就是说,p指向a数组的第0个元素。
《C语言程序设计》 语言程序设计》
清华大学出版社
第8章
指针
8.2
8.2.2 指针的加减运算
指针运算
可以对指针变量加(减)一个整数, 如:p++、p--、p+i、p-i、p+=i、p-=i等。 C语言规定,一个指针变量加(减)一个整数并不是简单地将原值加(减) 该整数,而是将该指针变量的值和它指向的变量所占用的内存单元字节 数加(减),即p+i执行的地址运算为p+c*i,其中,c为指针变量p所指向 的变量的字节数。
精品-清华大学C语言课件 第6章06 顺序程序设计应用
【例6.5】 从键盘中输入一个直角三角形的两边,求出其直角边并将其显示在屏幕上 为了简单起见,设从键盘中输入直角三角形俩直角边a和b,用数学函数hypot来求直角三角形的斜边。
#include <stdio.h> #include <math.h> void main() { float a, b, c; printf("请输入两条直角边:\n"); scanf("%f,%f", &a, &b);/*从键盘中输入两个直角边*/ c = (float)hypot(a, b);/*调用hypot函数,返回斜边值赋给c*/ printf("直角三角形的斜边是:%f\n", c);/*将斜边值输出*/ }
【例6.6】 字母转化,将大写字母转化成小写字母。 在本实例中,要将一个输入的大写字符转化成小写字符,需要对其中的ASCII码的关系有所了解。将
大写字符转化成小写字符的方法就是将大写字符的ASCII码转化成小写字符的ASCII码即可。
#include<stdio.h> int main() { char cUpper;/*定义字符变量,表示大写字符*/ char cLower;/*定义字符变量,表示小写字符*/
puts("请输入大写字母:");/*输出提示信息*/ cUpper=getchar();/*得到用户输入的大写字符*/ puts("转为小写字母是:");/*输出提示信息*/ cLower=cUpper+32;/*将大写字符转化成小写字符*/ printf("%c\n",cLower);/*输出小写字符*/
C语言精髓所在--指针 清华大学出版社
void exchange(int *q1, int *q2, int *q3) { void swap(int *pt1, int *pt2); if(*q1<*q2) swap(q1,q2); if(*q1<*q3) swap(q1,q3); if(*q2<*q3= swap(q2,q3); } void swap(int *pt1, int *pt2) {int temp; temp=*pt1; *pt1=*pt2; *pt2=temp; }
下面都是合法的定义:
float *pointer_3;
char *pointer_4;
可以用赋值语句使一个指针变量得到另一个变
量的地址,从而使它指向一个该变量。 例如: pointer_1=&i; pointer_2=&j;
在定义指针变量时要注意两点: (1) 指针变量前面的“*”,表示该变量的类型为指针型 变量。
#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 in verted:\n″ ); for(i=0;i<10;i++) printf (″%d,″,a[i]); printf (″\n″);}
例如:int a[10]; (定义a为包含 10个整型数据的数组) int *p; (定义p为指向整型 变量的指针变量) p=&a[0]; (把a[0]元 素的地址赋给指针变量p) 也就是使p指向a数组的第0号元素 。
关于清华版《c程序设计》中指向数组的指针的看法
关于清华版《c程序设计》中指向数组的指针的看法指向数组的指针是指向一个数组或多个数组元素的指针。
它们是C程序设计中重要的概念,可以实现高效编程。
C程序设计中的指向数组的指针可以有效简化程序代码。
本文以清华版《C程序设计》中指向数组的指针作为核心,对指向数组的指针的相关概念及其应用场景进行深入的研究。
第二段:关于指向数组的指针,清华版《C程序设计》中具体介绍了指向数组的指针的基本概念、原理及其使用方法。
首先,清华版《C程序设计》中介绍了指向数组的指针的基本概念,指出指向数组的指针可以表示数组的开始元素,可以使用指针完成数组的管理,从而可以有效地管理数组中的元素。
此外,清华版《C程序设计》中还介绍了指向数组的指针的相关原理,即数组名就是指向数组的指针,指针变量可以指向数组的任意位置,并且可以实现数组元素的随机访问,从而可以提高程序性能。
第三段:清华版《C程序设计》中还介绍了指向数组的指针的使用方法。
首先,清华版《C程序设计》中指出,指向数组的指针可以用来实现数组的初始化和赋值,以及数组的输入和输出等操作;其次,清华版《C程序设计》中还介绍了指向数组的指针的特殊用法,如多维数组的指针表示法,以及指向数组的指针的指针等,这些指针特性可以实现高效的程序数据管理。
第四段:指向数组的指针在实际开发中有着重要的应用场景。
例如,在编程实现排序时,使用指向数组的指针可以快速实现排序操作;在数据处理时,使用指向数组的指针可以高效实现数据统计和计算;此外,指向数组的指针还可以用于实现文件的读写和数组的转置等操作,从而高效地处理程序中的数据。
第五段:总之,指向数组的指针是C程序设计中一个重要的概念,它可以有效简化程序代码,并且在实际编程中有着重要的应用场景。
清华版《C程序设计》中对指向数组的指针的相关概念和使用方法给出了详细的介绍,可以为程序设计师提供有用的编程思路和技术支持。
关于清华版《c程序设计》中指向数组的指针的看法
关于清华版《c程序设计》中指向数组的指针的看法清华版《C程序设计》(下称《C程序设计》)是一本经典的编程书籍,它将C语言的知识结构化,从C语言的基础知识、数据结构到各种技巧、算法均有详细的介绍,并且提供了大量的练习题以加深读者的C语言学习。
《C程序设计》在C语言教学界人人皆知,是每一个C语言程序员必备的编程参考书。
在《C程序设计》中也涉及了指向数组的指针,指针是C语言中比较关键的概念,能够极大地提高程序的效率,但同时利用指针也有一定的风险,需要很大的小心和理解才能够使用正确。
针对指向数组的指针,《C程序设计》采用了一种非常严谨的方式来处理,把指针和数组中元素的关系用数学关系来表达,从而让读者更加清楚地了解指针指向数组的原理。
首先利用数学关系来描述指针指向数组,当指针指向数组中某一位置时,指针所在内存地址和数组首地址的关系为:假设指针p指向数组a[i],则有p=&a[i],又有a[i]=*(a+i),所以可以得出*p=*(a+i),p就是指向数组a[i]的指针。
其次,可以利用顺序存储的知识,知道指针p指向数组a[i]时,p+1则一定指向数组a[i+1],所以可以知道*(p+1)=*(a+i+1)。
最后,可以用算术运算来证明,当指针p指向数组a[i]时,p+k则指向数组a[i+k],有*(p+k)=*(a+i+k),即经过k次偏移,指针p指向数组a[i+k]。
由此可见,《C程序设计》中指向数组的指针的记述是非常严谨的,它将数组和指针的关系用数学关系来说明,让读者更加清楚地了解数组和指针之间的关系,同时也让读者能够更加明确地掌握和使用指向数组的指针,从而更加高效地使用C语言来完成一定的任务。
另外,在《C程序设计》中,作者还用许多案例来让读者更加深刻地理解指向数组的指针,比如在介绍指向数组的指针时,作者就用一些简单的实例来演示如何使用指针来访问数组,同时还有一些实际的编程练习,让读者能够练习实现指针操作相关的程序,使读者进一步理解指针指向数组的原理,此外,作者还在文中加入了一些提示,让读者更容易地掌握指向数组的指针。
关于清华版《c程序设计》中指向数组的指针的看法
关于清华版《c程序设计》中指向数组的指针的看法引言:近几年来,随着科技的不断发展,C程序设计这门语言一直是计算机领域中最受欢迎的编程语言之一。
清华版《C程序设计》是中国计算机领域最受欢迎的C程序设计教程之一。
该书有关指向数组的指针的观点受到普遍关注。
本文旨在从技术和逻辑上剖析清华版《C程序设计》中指向数组的指针的看法。
一、什么是指向数组的指针指向数组的指针是指一种指针,它指向一个整个数组或者数组的一部分,可以对数组元素进行访问和操作。
二、清华版《C程序设计》中指向数组的指针的观点1、清华版《C程序设计》将指向数组的指针分为两种:一种是指向整个数组的指针,另一种是指向数组某一元素的指针。
2、指向整个数组的指针可以用来访问数组的所有元素,也可以用来处理数组元素的一些操作。
指向数组某一元素的指针可以用来访问数组的单个元素,也可以用来处理数组元素的一些操作。
3、清华版《C程序设计》强调,指向数组的指针除了可以访问数组的所有元素,还可以作为参数传递给函数,为函数提供多参数输入,大大提高了程序的可扩展性。
三、指向数组的指针在程序设计中的应用1、指向数组的指针可以用于处理数组元素,可以完成数组元素的查找、替换等操作,可以很好地提高程序的性能和易用性。
2、指向数组的指针也可以用于实现程序的简单功能,例如实现两个数组的元素比较,或者实现两个数组的元素的加法运算,等等。
3、指向数组的指针还可以用于复杂的程序,例如用于大规模数据处理,或用于算法和程序优化,等等。
结论:从技术和逻辑上看,清华版《C程序设计》中指向数组的指针的看法是正确的。
指向数组的指针可以充分发挥出数组处理和程序优化的优势,为程序设计带来了解决复杂程序问题的可能性。
程序设计-数组 指针与字符串(五 六)
6.2 指针 —— 6.2.5 指针运算
3
指针变量的关系运算
• 关系运算
▫ 指向相同类型数据的指针之间可以进行各种关系运算。 ▫ 指向不同数据类型的指针,以及指针与一般整数变量之
间的关系运算是无意义的。 ▫ 指针可以和零之间进行等于或不等于的关系运算。 例如:p==0或p!=0
• 赋值运算
▫ 向指针变量赋的值必须是地址常量或变量,不能是普通 整数。但可以赋值为整数0,表示空指针。
C++语言程序设计(第4版),清华大学
6.2 指针 —— 6.2.6 用指针处理数组元素
7
例6-7 (续) 使用数组名指针运算
#include <iostream> using namespace std; int main() {
int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; for (int i = 0; i < 10; i++)
for(int i = 0; i < 3; i++) { for(int j = 0; j < 3; j++) cout << *(*(array2 + i) + j) << " "; //逐个输出二维数组第i行元素值 cout << endl;
} return 0; }
C++语言程序设计(第4版),清华大学
9
6.2.7 指针数组
• 数组的元素是指针型
例:Point *pa[2];
由pa[0],pa[1]两个指针组成
C++语言程序设计(第4版),清华大学
c语言指针
第六讲指针参考书《C程序设计》第九章
本讲主要内容•指针变量
•指向数组元素的指针
•字符指针与字符串
•指针数组
•指向一维数组的指针
•多级指针
•以指针作为函数参数
•指针型函数
•指向函数的指针
指针变量—概念及定义
内存用户数据区•概念
3
6
•定义
2000
指向整型变量的指针
•引用
20003
指针变量
——初始化
•语法形式
存储类型数据类型*指针名=初始地址;•注意事项
例1
指针变量
——算术运算•指针与整数的加减运算
•指针加一,减一运算
指针变量
——关系运算和赋值运算•关系运算
•赋值运算
指向数组元素的指针•定义与赋值
•通过指针引用数组元素
例2
字符指针与字符串•字符指针的定义及使用
•使用字符指针处理字符串
。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
c
char c; int n; float f; c = 3; n = 3; f = 3; // 整数3 // 整数3 // 实数3
0x0012ff7b 0x0012ff7a
0x0012ff79
0x0012ff78 0x0012ff77 0x0012ff76 0x0012ff75
n
0x00
0x00
0x0012ff74
访问第i个数组元素
why bother?
void main( ) { double prices[5], avg; avg = FindAvg(prices, 5); } double FindAvg(double values[], int nValues) { }
main avg
prices
41
第六章 指针
1 2
基本概念 指针变量 指针与数组
3
4
指针与字符串
42
6.3.1 数组元素的访问
数组的定义: int a[5];
a[0] a[1] a[2] a[3] a[4]
空间的分配: a 元素的访问: for(i = 0; i < 5; i++)
{ a[i] = 0;
}
43
通过指针来访问数组元素
double * ―pointer to double‖
相同点?不同点?
15
int x, y, *px;
1024
x = 2;
一些问题: 1. 如何把变量 x 的地址存 放在指针 px 当中?
1020
px
1008
2. 如何使用指针 px 来访问 或修改变量 x 的值?
3. 为何要如此自找麻烦?
1004
指针
pa
数组
a
pa = &a[2]
44
指针的算术和关系运算
指针加一个整数: ptr + k 指针减一个整数: ptr – k 两个指针相减: p1 – p2
指针的关系运算: >、>=、< <=、==、!=
45
• 指针的算术运算是以数据元素为单元;
• int *p; p = (int *)1000; p = p + 2;
int a, b, c, *p, *q;
a = 1;
b = 2; c = 3; p = &a; q = &b; c = *p; p = q; *p = 13;
0x0012FF7C 0x0012FF78 0x0012FF74 0x0012FF70 0x0012FF6C
1 2 13 3 1
0012FF78 0012FF7C 0012FF78
0x00
0x00
0x0012ff74
f
9
什么是指针?
The C Programming Language (K & R):
A pointer is a variable that contains the
memory address of another variable.
10
指针是一种特殊的变量:
1 2
基本概念 指针变量 指针与数组
3
4
指针与字符串
13
6.2.1 指针的定义
指针定义的一般形式: 基类型
例如:
*指针变量名;
int x;
int *p;
/* 定义了一个整型变量 */
/* 定义了一个指向整型变量的指针变量 */
14
现在我们有了三种新的数据类型: int * char * ―pointer to int‖ ―pointer to char‖
1000
y
2 x
16
6.2.2 &运算符
int x, y, *px; x = 2;
1. 如何把变量 x 的地址存 放在指针 px 当中? 1024
1020
px
能否:px = 1000; 1000从何而来? 类型不匹配。
1008 1004 1000
y
2 x
17
我们想要做的事情: px = x 的内存地址; 我们写的语句: px = &x;
38
6.2.5 指针分析
void main() /* 有何问题? */ { int binky; foo(&binky); } void foo(int *tinky) { int slinky = 5; } tinky = &slinky; *tinky = slinky;
39
void main() /* 输出结果是什么? */ { thinking… int* pinky; pinky = bar(); printf("%d", *pinky); } int* bar() { int winky = 5; return(&winky); }
36
void main( ) { double a, b, c, x1, x2; /* 从键盘读入方程式的系数a, b, c */ GetCoefficients(?a, ?b, ?c); /* 求解方程式的两个根x1, x2 */ SolveQuadratic(?a, ?b, ?c, ?x1, ?x2); /* 显示方程式的两个根x1, x2 */ DisplayRoots(?x1, ?x2); }
37
main( ) { double a, b, c, x1, x2; /* 从键盘读入方程式的系数a, b, c */ GetCoefficients(&a, &b, &c); /* 求解方程式的两个根x1, x2 */ SolveQuadratic(a, b, c, &x1, &x2); /* 显示方程式的两个根x1, x2 */ DisplayRoots(x1, x2); }
a
b c p q
24
• 指针常量NULL表示一个指针不指 向任何有效的数据。 • int x, *p; p = &x; *p = 1; p = NULL;
*p = 2;
<stdio.h>
25
一个其值为NULL的指针不同于一个未初始 化的指针。一个指针在定义后,是未被初始 化的,此时若对它进行访问,将会出错。
数据类型(int)
高手的苦恼: 1. 内存有多大? 2. 变量是否可行? 3. 没有名字的单元?
0x0012ff65 0x0012ff64
3 0
a
7
如何访问任意内存单元中的数据? 访问一个数据需要知道:
它的起始地址
它的数据类型
8
0x0012ff7c
0x03 0x00 0x00 0x00 0x03 0x40 0x40
pa = &a;
pa
1000
1000
a
&a
1000
20
6.2.3 *运算符
int x, y, *px; x = 2; px = &x;
2. 如何通过指针 px 来访 问变量 x 的值?
1024
1020
1000
px
1008 1004 1000
y
2 x
21
我们想要做的事情:
y = px所指向的变量的值; 1024
我们写的语句: y = *px; 1020
1000
px
*:指针运算符(或称“间
接访问”运算符) 1008 1004 1000
*px的类型是 int。一般的, 如果px的类型是指向T型变 量的指针类型,则 *px的类 型为T。
2 2
y
x
22
pa = &a;
pa
1000
1000
a *pa
&a
1000
23
26
分析程序
int foobar(int *pi) { *pi = 1024; return *pi; } int main() { int *pi2; int ival = foobar(pi2); printf("%d", ival); }
27
0x0012ff7c
0x03 0x00 0x00 0x00 0x03 0x40 0x40
printf("%d, %d\n", min, max);
}
33
void MinMax(int x, int y, int *p1, int *p2) { *p1 = x; *p2 = y; if(x > y) { *p1 = x; *p2 = y; } min、max的访问? } void main( ) { int a, b, min, max; a = 4; b = 7; MinMax(a, b, &min, &max); printf("%d, %d\n", min, max); }
3
信箱与地址
楼长
4
国家宝藏
heere at the wall
5
Why 指针?
思考:如何访问内存中的数据?
0
1
2
3
4
5
6
7
...
1. 字节为单位 2. 数据长度不同
6
内存
0x0012ff6a
a 变量名 30
0x0012ff69
——变量值
0x0012ff68
0x0012ff67 0x0012ff66
40
void main() { int binky, *pinky; binky = 1; pinky = &binky; moo(*pinky, pinky); } void moo(int tinky, int *winky) { int slinky = 2; *winky = tinky + slinky; }