弗原創IT教育中心 第4讲指针 指针是C语言中的重要概念,也是C语言的 重要特色。使用指针,可以使程序更加简洁、紧 凑、高效。 41指针和指针变量的概念 42指针变量的定义与应用 4.3数组的指针 44函数的指针
第4讲 指 针 指针是C语言中的重要概念,也是C语言的 指针是C语言中的重要概念,也是C语言的 重要特色。使用指针,可以使程序更加简洁、紧 重要特色。使用指针,可以使程序更加简洁、紧 凑、高效。 4.1 指针和指针变量的概念 指针和指针变量的概念 4.2 指针变量的定义与应用 指针变量的定义与应用 4.3 数组的指针 4.4 函数的指针
弗原創IT教育中心 41指针和指针变量的概念 1内存地址—内存中存储单元的编号 (1)计算机硬件系统的内存储器中,拥有大 量的存储单元(容量为1字节)。 为了方便管理,必须为每一个存储单元编 号,这个编号就是存储单元的“地址”。每个存储 单元都有一个惟一的地址 (2)在地址所标识的存储单元中存放数据。 注意:内存单元的地址与内存单元中的数据 是两个完全不同的概念。 2变量地址—一系统分配给变量的内存单元的 起始地址
4.1 指针和指针变量的概念 指针和指针变量的概念 1.内存地址──内存中存储单元的编号 内存中存储单元的编号 (1)计算机硬件系统的内存储器中,拥有大 )计算机硬件系统的内存储器中,拥有大 量的存储单元(容量为1字节)。 量的存储单元(容量为1字节)。 为了方便管理,必须为每一个存储单元编 为了方便管理,必须为每一个存储单元编 号,这个编号就是存储单元的 号,这个编号就是存储单元的“地址”。每个存储 单元都有一个惟一的地址。 单元都有一个惟一的地址。 (2)在地址所标识的存储单元中存放数据。 )在地址所标识的存储单元中存放数据。 注意:内存单元的地址与内存单元中的数据 注意:内存单元的地址与内存单元中的数据 是两个完全不同的概念。 是两个完全不同的概念。 2.变量地址──系统分配给变量的内存单元的 分配给变量的内存单元的 起始地址
2指针与指针变量 (1)指针——一即地址 个变量的地址称为该变量的指针。通过变量的指针能够 找到该变量 (2)指针变量——专门用于存储其它变量地址的变」 指针变量 num_pointer h的值就是变量num的地址。指针与指针 变量的区别,就是变量值与变量的区别。 (3)为表示指针变量和它指向的变量之间的关系,用指针 运算符“浆表示。 例如,指针变量 num_pointer与它所指向的变量num的关系, 表示为: num_pointer,即米 num_pointer等价 于变量num。 因此,下面两个语句的作用相同: num=3 /*将3直接赋给变量num*/ num_pointer=#/*使 num_pointers指向num* num__pointer=3;/*将3赋给指针变量 num_pointer所指向的变量*
2.指针与指针变量 指针与指针变量 (1)指针──即地址 一个变量的地址称为该变量的指针。通过 一个变量的地址称为该变量的指针。通过变量的指针能够 找到该变量。 (2)指针变量──专门用于存储其它变量地址的变量 专门用于存储其它变量地址的变量 指针变量num_pointer num_pointer的值就是变量num的地址。指针与指针 的地址。指针与指针 变量的区别,就是变量值与变量的区别。 变量的区别,就是变量值与变量的区别。 (3)为表示指针变量和它指向的变量之间 )为表示指针变量和它指向的变量之间的关系,用指针 运算符“*”表示。 例如,指针变量 例如,指针变量num_pointer num_pointer与它所指向的变量 与它所指向的变量num的关系, 表示为: *num_pointer num_pointer,即*num_pointer num_pointer等价于变量num。 因此,下面两个语句的作用相同: 因此,下面两个语句的作用相同: num=3; /*将3直接赋给变量num*/ num_pointer=# /* num_pointer=# /*使num_pointer num_pointer指向num */ *num_pointer=3; *num_pointer=3; /*将3赋给指针变量num_pointer num_pointer所指向的变量*
弗原創IT教育中心 42指针变量的定义与应用 421指针变量的定义与相关运算 案例41指针变量的定义与相关运算示例。 main f int num_int=12,*p_int; /定义一个指向int型数据的指针变量 float num_f=3.14, p-f /定义一个指向foat型数据的指针变量 char num -ch=p, ' p /定义一个指向char型数据的指针变量 pint=& num int;/*取变量 num inth的地址,赋值给pint P-f=&num_f; /*取变量numf的地址,赋值给pf* pch=& num ch;/*取变量 num ch的地址,赋值给pch* printf(num_int=%/od, *p_int=%/od\n, numint,*p_int) printf( num_f=%04.2f, p_f=%04. 2f\n, num_f,*p_6); printf(num_ch=%oC,*p_ch=%ocIn", num_ch,*p-ch 程序运行(12)
4.2 指针变量的定义与应用 指针变量的定义与应用 4.2.1 指针变量的定义与相关运算 指针变量的定义与相关运算 [案例4.1] 指针变量的定义与相关运算示例。 指针变量的定义与相关运算示例。 main() { int num_int num_int=12, *p_int; //定义一个指向int型数据的指针变量 float num_f=3.14, *p_f; float num_f=3.14, *p_f; //定义一个指向float型数据的指针变量 char num_ch=’p’, *p_ch; // ; //定义一个指向char型数据的指针变量 p_int=&num_int num_int; /*取变量num_int num_int的地址,赋值给p_int */ p_f=&num_f; p_f=&num_f; /*取变量num_f的地址,赋值给p_f */ p_ch=&num_ch; /*取变量num_ch的地址,赋值给p_ch */ printf( printf(“num_int num_int=%d, *p_int=%d\n”, num_int num_int, *p_int); printf( printf(“num_f=%4.2f, *p_f=%4.2f =%4.2f, *p_f=%4.2f\n”, num_f, *p_f); , num_f, *p_f); printf( printf(“num_ch=%c, *p_ch=%c\n”, num_ch, *p_ch); } 程序运行(12)
弗原創IT教育中心 程序运行结果 numint=12,pint=12 numf=3.14,*pf=3.14 num ch 程序说明: (1)头三行的变量定义语句——指针变量的定义 与一般变量的定义相比,除变量名前多了一个星号“* (指针变量的定义标识符)外,其余一样 数据类型*指针变量D,*指针变量2… 注意:此时的指针变量pit、pf、pch,并未指向某 个具体的变量(称指针是悬空的)。使用悬空指针很容易破 坏系统,导致系统瘫痪
程序运行结果: num_int num_int=12, *p_int=12 num_f=3.14, *p_f=3.14 num_f=3.14, *p_f=3.14 num_ch=p, *p_ch=p 程序说明: (1)头三行的变量定义语句 )头三行的变量定义语句──指针变量的定义 指针变量的定义 与一般变量的定义相比,除变量名前多了一个星 与一般变量的定义相比,除变量名前多了一个星号“*” (指针变量的定义标识符)外,其余一样: (指针变量的定义标识符)外,其余一样: 数据类型 *指针变量[, *指针变量2……]; 注意:此时的指针变量 :此时的指针变量p_int、p_f、p_ch,并未指向某 个具体的变量(称指针是悬空的)。使用悬空指针很容易破 个具体的变量(称指针是悬空的)。使用悬空指针很容易破 坏系统,导致系统瘫痪。 坏系统,导致系统瘫痪
弗原創IT教育中心 (2)中间三行的赋值语句——取地址运算(& 取地址运算的格式:&变量 例如,& num int、&numf、& num ch的结果,分别为变 量 num int、numf、 num ch的地址 注意:指针变量只能存放指针(地址),且只能是相同类 型变量的地址 例如,指针变量pint、pf、pch,只能分别接收int型、 foat型、char型变量的地址,否则出错 (3)后三行的输出语句——指针运算(*) 使用直接访问和间接访问两种方式,分别输出变量 num int、numf、 num ch的值 注意:这三行出现在指针变量前的星号“*”是指针运算符, 访问指针变量所指向的变量的值,而非指针运算符
(2)中间三行的赋值语句 中间三行的赋值语句──取地址运算(&) 取地址运算的格式: 取地址运算的格式: &变量 例如,&num_int num_int、&num_f、&num_ch的结果,分别为变 的结果,分别为变 量num_int num_int、num_f、num_ch的地址。 注意:指针变量只能存 :指针变量只能存放指针(地址),且只能是相同类 放指针(地址),且只能是相同类 型变量的地址。 型变量的地址。 例如,指针变量 例如,指针变量p_int、p_f、p_ch,只能分别接收int型、 float型、char型变量的地址,否则出错。 型变量的地址,否则出错。 (3)后三行的输出语句 )后三行的输出语句──指针运算(*) 使用直接访问和间接访问两种方式,分别输出变量 接访问和间接访问两种方式,分别输出变量 num_int num_int、num_f、num_ch的值。 注意:这三行出现在指针变量前的星号 :这三行出现在指针变量前的星号“*”是指针运算符, 是指针运算符, 访问指针变量所指向的变量的值,而非指针运算符。 访问指针变量所指向的变量的值,而非指针运算符
弗原創IT教育中心 案例42使用指针变量求解:输入2个整数,按升序(从小 到大排序)输出。 /程序功能:使用指针变量求解2个整数的升序输出*/ main i int numl, num2 int numl_p=&num1, num2_p=&num2, pointer; printf( Input the first number: ) scanf(%/od, num1_p) printf( Input the second number: ) scanf(od, num2_p printf( num1=%od, num2=%/od\n, num1, num2); f(*num1p>*num2p)//如果num1>num2,则交换指针 pointer= num1_p, num1_p= num2_P, num2_p=pointer printf( min=/od, max=/od\n",*num1_p, *num2_p 程序运行(13)
[案例4.2] 使用指针变量求解:输入 使用指针变量求解:输入2个整数,按升序(从小 个整数,按升序(从小 到大排序)输出。 到大排序)输出。 /*程序功能:使用指针变量求解 程序功能:使用指针变量求解2个整数的升序输出 个整数的升序输出*/ main() { int num1,num2; num1,num2; int *num1_p=&num1, *num2_p=&num2, *pointer; *num1_p=&num1, *num2_p=&num2, *pointer; printf( printf(“Input the first number: the first number: ”); scanf( ); scanf(“%d”,num1_p); ,num1_p); printf( printf(“Input the second number: the second number: ”); scanf( ); scanf(“%d”,num2_p); ,num2_p); printf( printf(“num1=%d, num2=%d num1=%d, num2=%d\n”, num1, num2); , num1, num2); if( *num1_p > *num2_p ) // if( *num1_p > *num2_p ) //如果num1>num2 num1>num2,则交换指针 pointer= num1_p, num1_p= num2_p, num2_p=pointer; pointer= num1_p, num1_p= num2_p, num2_p=pointer; printf( printf(“min=%d, max=%d =%d, max=%d\n”, *num1_p, *num2_p); , *num1_p, *num2_p); } 程序运行(13)
弗原創IT教育中心 程序运行情况: Input the first number: 9*num2p(即num1>num2),则交换 指针,使num1p指向变量num2(较小值),num2p指向 变量num1(较大值)。 (2) printf( min=/od, max=0/od\n,*num num2p);语句:通过指针变量,间接访问变量 的值
程序运行情况: 程序运行情况: Input the first number:9 Input the first number:9←┘ Input the second number:6 Input the second number:6←┘ num1=9, num2=6 num1=9, num2=6 min=6, max=9 min=6, max=9 程序说明: (1)第5行的if语句 如果*num1_p>*num2_p num1_p>*num2_p (即num1>num2 num1>num2),则交换 指针,使num1_p指向变量num2(较小值),num2_p指向 变量num1(较大值)。 ( 2 ) printf( printf(“min=%d, max=%d =%d, max=%d\n”, *num1_p, , *num1_p, *num2_p); *num2_p); 语句:通过指针变量,间接访问变量 语句:通过指针变量,间接访问变量 的值
弗原創IT教育中心 本案例的处理思路是:交换指针变量num1_p和 num2p的值,而不是变量mum1和num2的值(变量nunm1和 nun2并未交换,仍保持原值),最后通过指针变量输出 处理结果。 422指针变量作函数参数 1指针变量,既可以作为函数的形参,也可以作函数 的实参。 2指针变量作实参时,与普通变量一样,也是“值传 递”,即将指针变量的值(一个地址)传递给被调用函数 的形参(必须是一个指针变量)。 注意:被调用函数不能改变实参指针变量的值,但 可以改变实参指针变量所指向的变量的值
本案例的处理思路是:交换指针变量 是:交换指针变量num1_p 和 num2_p的值,而不是变量 的值,而不是变量num1和num2的值(变量num1和 num2并未交换,仍保持原值),最后通过指针变量 并未交换,仍保持原值),最后通过指针变量输出 处理结果。 4.2.2 指针变量作函数参数 指针变量作函数参数 1.指针变量,既可以作为函数的形参,也可以作函数 指针变量,既可以作为函数的形参,也可以作函数 的实参。 2.指针变量作实参时,与普通变量一样,也是 指针变量作实参时,与普通变量一样,也是“值传 递”,即将指针变量的值(一个地址)传递给被调用函数 ,即将指针变量的值(一个地址)传递给被调用函数 的形参(必须是一个指针变量)。 的形参(必须是一个指针变量)。 注意:被调用函数不能改变实参指针变量的值,但 :被调用函数不能改变实参指针变量的值,但 可以改变实参指针变量所指向的变量的值。 可以改变实参指针变量所指向的变量的值
弗原創IT教育中心 案例4.3使用函数调用方式改写案例42,要求实参为指针变量 /* Exchanged功能:交换2个形参指针变量所指向的变量的值*/ /形参:2个,均为指向整型数据的指针变量 /*返回值:无 void exchange (int *pointer1, int* 2) i int temp; temp=pointer, pointer= pointer, pointer=temp /*主函数min0* main( int num. num2 /*定义并初始化指针变量nm1p和num2p*/ int num1_p&numl, num2_p=&num2
[案例4.3] 使用函数调用方式改写[案例4.2],要求实参为指针变量。 /*exchange() /*exchange()功能:交换2个形参指针变量所指向的变量的值 */ /*形参:2个,均为指向整型数据的指针变量 */ /*返回值:无 */ void exchange(int exchange(int *pointer1, *pointer1, int *pointer2) *pointer2) { int temp; temp=*pointer1, *pointer1=*pointer2, *pointer2=temp; temp=*pointer1, *pointer1=*pointer2, *pointer2=temp; } /*主函数main()*/ main()*/ main() { int num1,num2; num1,num2; /*定义并初始化指针变量 定义并初始化指针变量num1_p和 num2_p */ num2_p */ int *num1_p=&num1, *num2_p=&num2 *num1_p=&num1, *num2_p=&num2;