第8章_指针

合集下载

C++程序设计 第八章 指针和引用

C++程序设计  第八章 指针和引用
C++

在程序运行时变量和函数都存放在内存中,通过变量名来访问数据、通过函数名来调用函数都是直接访问方式。还有另一种间接访问方式就是用指针。指针的本质是内存地址。指针往往用于说明函数的形参,使实参能通过指针传递,以提高函数调用的效率。利用指针能动态地使用内存,以提高内存使用效率。指针也能用来表示数据关联,以构成复杂的数据结构。指针是C程序中最常见的类型。引用是C++扩展的新概念,主要用于函数形参和返回类型。本章将详细介绍指针和引用的概念及应用。
首先,这6个变量的地址是按递减次序排列,这是因为局部变量都存储在堆栈中,堆栈是先入后出的。先入栈的数据存放在较大地址位置,后入栈的数据存放在较小地址位置。如果这些变量改为全局变量,它们的排列次序就会颠倒过来。
其次,尽管变量s只占2字节,变量c只占1字节,但却分别占用4字节空间。这是因为按字对齐(32位数据)能提高CPU访问内存的效率,而且一次压栈和出栈操作也是以32位数据为单位,代价是浪费一些内存。如果这些变量改为全局变量,它们将按实际大小存储。
怎样能知道一个变量在运行时刻的内存地址?把取地址运算符&放在变量前面就得到它的首地址。例如b是一个变量,那么&b就表示它的地址。下面例子能看到一组局部变量的首地址。
例8-1显示一组局部变量的首地址。
#include<iostream.h>
void main(){
bool b = true;
char c = 'c';
其中,<类型名>是这个指针变量所指向的对象的类型,简称指针类型,它可以是任何一种类型。*表示这个变量是一个指针变量。这个变量的类型就是“<类型名>*”。<变量名>是一个标识符。指针变量可以进行初始化,等号之后给出一个变量的地址,要求这个变量的类型与指针类型相符。

《C语言程序设计》第8章指针

《C语言程序设计》第8章指针
}
10.3.3 指针变量和数组作函数参数 数组名作形参时,接收实参数组的起始地址;
作实参时,将数组的起始地址传递给形参数组。
引入指向数组的指针变量后,数组及指向数 组的指针变量作函数参数时,可有4种等价形式 (本质上是一种,即指针数据作函数参数):
(1)形参、实参都用数组名 (2)形参、实参都用指针变量 (3)形参用指针变量、实参用数组名 (4)形参用数组名、实参用指针变量
(4)指针变量的++、--与&、*的结合
对于指针变量的++、--与&、*的结合 使用,关键要注意按照运算符的优先级和 结合性进行。
例如: int a=2, *p; p=&a;
•表达式:(*p)++,按运算符的优先级,等价于 a++。其含义为:取出指针变量p所指向的内存单 元的值(即a的值),a的值加1,送回a的内存单 元,a的值变为3,p的值未发生变化,仍然指向 变量a。
程序说明:printf("%s\n",s);语句 通过指向字符串的指针变量s,整体引
用它所指向的字符串的原理:系统首先输出s 指向的第一个字符,然后使s自动加1,使 之指向下一个字符;重复上述过程,直至遇到 字符串结束标志。
main() { char string[ ]=”I love Beijing.”; printf(“%s\n”,string); }
3.数组元素的引用 数组元素的引用,既可用下标法,也可用
指针法。
10.3.2 通过指针引用数组元素 如果有“int a [10],*p=a;” ,则: (1)p+i和a+i都是数组元素a [i]的地址。
(2)*(p+i)和*(a+i)就是数组元素a [i]。 int a [3]; a [0]——*a a [1]——*(a +1) a [2]——*(a +2)

C语言程序设计知识点—第8章 指针结构体与预处理命令

C语言程序设计知识点—第8章 指针结构体与预处理命令
比较两个指针 #include<stdio.h> void main () { int *ptrnum1, *ptrnum2; int value = 1; ptrnum1 = &value; value += 10; ptrnum2 = &value; if (ptrnum1 == ptrnum2) printf("\n 两个指针指向同一个地址\n"); else printf("\n 两个指针指向不同的地址\n"); }
指针使用示例 2 void main() { int num1 = 50, num2 = 100; int *ptr1, *ptr2; ptr1 = &num1; printf(" num1 的值是: %d", *ptr1); printf("\n num1 的地址是: %x \n", ptr1); ptr2 = &num2; printf("\n num2 的值是: %d", *ptr2); printf("\n num2 的地址是: %x \n", ptr2); *ptr2 = *ptr1; printf("\n 重新赋值后 num2 的值是: %d", *ptr2); printf("\n 重新赋值后 num2 的地址是: %x\n", ptr2); }
C 语言程序设计知识点
主讲教师:杨剑
第 8 章:指针、结构体与预处理命令
1. 本章目标
理解指针的概念 定义指针变量 掌握对指针的操作 理解指针和数组的关系 理解结构体的概念和定义 理解预处理指令
2. 内存地址
内存是一个连续编址的空间,每一个存储单元都有一个固定的编号,称为内存地址。 内存地址通常用 16 进制数表示。

C二级 第8章 指针

C二级 第8章 指针

1.以下定义语句中正确的是A) int a=b=0; B) char A=65+1,b='b';C) float a=1,*b=&a,*c=&b; D) double a=0.0; b=1.1;参考答案:B【解析】A选项语句中b变量还没有定义不能直接用于给a变量赋值。C选项语句中*b、*c表示的是一个实型变量的地址,不能再将&b赋值给指针型变量c。D选项语句中a=0.0后面应该为逗号,不能是分号。2.有以下程序#include <stdio.h>void f(int *p,int *q);main(){ int m=1,n=2,*r=&m;f(r, &n);printf("%d,%d",m,n);}void f(int *p,int *q){ p=p+1;*q=*q+1;}程序运行后的输出结果是A) 2,3 B) 1,3 C) 1,4 D) 1,2参考答案:B【解析】在f(int *p,int*q)函数中,执行p=p+1是将p所对应的地址加1,而*q=*q+1是将q所指向的n的地址所对应的值加1,所以m的得知所对应的值没有变,而n的值则为3了。

因此B选项正确。

3.以下叙述中正确的是A) 如果p是指针变量,则&p是不合法的表达式B) 如果p是指针变量,则*p表示变量p的地址值C) 在对指针进行加、减算术运算时,数字1表示1个存储单元的长度D) 如果p是指针变量,则*p+1和*(p+1)的效果是一样的参考答案:C【解析】B选项中,如果p是指针变量,则*p表示变量p所指向的地址的值;A选项中,如果p是指针变量,则&p表示变量p的地址;D选项中,如果p是指针变量,*p+1表示将p所指的值加上1,而*(p+1)表示的是先将指针右移一位再取所指向变量的值。

因此C选项正确。

4.以下叙述中正确的是A) 基类型不同的指针变量可以相互混用B) 函数的类型不能是指针类型C) 函数的形参类型不能是指针类型D) 设有指针变量为double *p,则p+1 将指针p移动8个字节参考答案:D【解析】B选项中,所谓函数类型是指函数返回值的类型。

高树芳C语言程序设计--第八章

高树芳C语言程序设计--第八章

30
8.5 知识拓展
案例8-11 指针的高级应用 [案例任务] 阅读下列程序 ,分析运行结果,了解指 针的各种应用。
程序代码
31
8.5 知识拓展
相关知识:
1.有关指针的数据类型小结 2.案例说明 3.main函数的参数
32
12
8.2 指针变量
[课堂训练8-1] void swap(int *p1,int *p2) { int *t; t=p1; p1=p2; p2=t; }
1.分析下面的程序,写出运行结果。 #include <stdio.h> void main() { void swap(int *p1,int *p2); int *p1,*p2,a=6,b=8; p1=&a; p2=&b; printf(" 交换前:*p1=%d,*p2=%d\n",*p1,*p2); swap(p1,p2); printf(" 交换后:*p1=%d,*p2=%d\n",*p1,*p2); }
17
8.3 指针与数组
案例8-6 [案例任务]
冒泡排序
使用指针指向一维整型数组,使用冒泡排 序法对数组元素从小到大排序并输出。
程序代码
18
8.3 指针与数组
相关知识: 1.冒泡排序法 2.指针变量的其他运算
19
8.3 指针与数组
案例8-7 [案例任务]
逆置一维数组
使用数组名或指针变量作为函数形参与实 参,完成一维数组元素的逆置。请分析程 序运行结果,并对两个方法进行比较。
6
8.2 指针变量
案例8-2 用指针交换两整数 案例8-3 用指针比较两数大小 案例8-4 用指针参数交换两整数

c语言第8章练习题--指针

c语言第8章练习题--指针

1、int *p 的含义是(B)A.p是一个指针, 用来存放一个整型数B.p是一个指针, 用来存放一个整型数据在内存中的地址C.p是一个整型变量D. 以上都不对2、以下函数用来求出两整数之和,并通过形参将结果传回,请填空。

void func(int x,int y, ___int*____ z){ *z=x+y; }3、有如下程序段(B)int *p,a=10,b=1;p=&a; a=*p + b;执行该程序段后,a的值是A. 12B. 11C. 10D. 编译出错4、若己定义:int a[9],*p=a;并在以后的语句中未改变p的值,不能表示a[1]地址的表达式是( C)A) p+1B) a+1C) a++D) ++p5、以下程序运行后的输出结果是(A)void main( ){ int a[ ]={1,2,3,4,5,6,7,8,9,0},*p;for(p=a;p<a+10;p++) printf("%d,",*p);}A)1,2,3,4,5,6,7,8,9,0,B)2,3,4,5,6,7,8,9,10,1,C)0,1,2,3,4,5,6,7,8,9,D)1,1,1,1,1,1,1,1,1,1,6、下面程序的输出是(D)void prtv(int *x)printf("%d\n", ++*x);}main(){ int a=25;prtv(&a);}A) 23 B) 24 C) 25D) 267、有以下函数(B)char fun(char *p){ return p; }该函数的返回值是A) 无确切的值B) 形参p中存放的地址值C) 一个临时存储单元的地址D) 形参p自身的地址值8、下列程序的输出结果是(7)#include<stdio.h>void fun (int *p1, int *p2){ if (*p1>*p2) printf ("%d\n",*p1);else printf ("%d\n",*p2);}void main ( ){ int a=3,b=7;fun (&a, &b);}9、下列程序的运行结果是(B)void fun(int *a, int *b){ int *k;k=a; a=b; b=k;}main(){ int a=3, b=6, *x=&a, *y=&b;fun(x,y);printf("%d %d", a, b);}A) 6 3 B) 3 6 C) 编译出错D) 0 010、以下程序调用findmax函数返回数组中的最大值(B)findmax(int *a,int n){ int *p,*s;for(p=a,s=a; p-a<n; p++)if ( ) s=p;return(*s);}main(){ int x[5]={12,21,13,6,18};printf("%d\n",findmax(x,5));}在下划线处应填入的是(B)A) p>s B) *p>*s C) a[p]>a[s] D) p-a>p-s11、下列程序段的输出结果是(A)void fun(int *x, int *y){ printf("%d %d", *x, *y); *x=3; *y=4;}main(){ int x=1,y=2;fun(&y,&x);printf("%d %d",x, y);}A) 2 1 4 3 B) 2 1 3 4 C) 1 2 1 2 D) 2 1 1 212、以下程序执行后输出的结果是___84________。

第8章 指针

第8章 指针

已说明过,且变量类型应与指针类型一致。
可以用一个已赋初值的指针去初始化另一 个指针变量。 不要用一个局部变量去初始化 static 型指针。
4、间接引用指针
与指针有关的两个运算符 & 取地址运算符 * 实例: 指针运算符(或称“间接引用”运算符)
void main(){
int a=10; int *pointer_1; pointer_1 = &a; cout<< * pointer_1;

8.1 指针概念
8章
指针
8.5 const指针
8.6 指针与函数
8.2 指针运算
8.3 指针与数组
8.7 字符指针
8.4 堆内存分配
8.9 命令行参数
本章介绍C++的指针。C++语言拥有在运行时获得变量的地址和操作地址 的能力,这种用来操纵地址的特殊类型变量就是指针,指针对于成功地进 行c++语言程序设计是至关重要的。学习本章后要求能够使用指针,能够用 指针给函数传递参数,理解指针、数组和字符串之间的紧密联系,能够声 明和使用字符串数组,正确理解命令行参数。
值。 实例:ch8_9.txt
【 8.5 const指针】
指向常量的指针(常量指针):
在指针定义语句前加上const,表示指向的对象是常量。 不能通过指针来改变所指对象的值,但指针本身可以改 变,可以指向另外的对象。 例: const int a=78;
const int b=28; int c=18; const int *pi=&a; *pi=58; pi=&b; *pi=68; pi=&c; *pi=88; c=98;

指 针

指  针

2. 一维数组元素的地址表示法
由于数组名(设为a)为数组的首地址常量, 用它组成的地址表达式可以表示所有元素的地址, 用这些地址(指针)的指向操作表达式即可表示所 有元素: 元素的地址 元素 a≡&a[0] *a≡a[0] a+1≡&a[1] *(a+1)≡a[1] … … a+i≡&a[i] *(a+i)≡a[i] … … 在表示元素的两种方法中,a[i]为下标法,*(a+i) 为地址法
(3) 通过标准函数获得地址值 (4) 给指针变量赋“空”值,如:p=NULL ;
8.1.3 指针的运算及引用
2.指向运算和指针变量的引用 (1) 指向运算符* *运算符作用在指针(地址)上,代表该指针所指向的存储 单元(及其值),实现间接访问,因此又叫“间接访问运算 符”。如: int a=5, *p; p=&a;printf("%d",*p); *P的值为5,与a等价。*运算符为单目运算符,与其他的单 目运算符具有相同的优先级和结合性(右结合性)。根据*运 算符的作用,*运算符和取地址运算符 & 互逆: *(&a)==a &(*p)==p (2) 指针变量的引用 知道了指针变量的作用以及相关的运算符以后,我们就可 以引用指针变量了
8.1.4 指针作为函数参数
被调函数中的形参:指针变量 主调函数中的实参:地址表达式,一般为变 量的地址或取得变量地址的指针变量 例8-3同例8-2,要求用函数调用交换变量的值。
swap(int *p1, int *p2) { int t; t=*p1; *p1=*p2; *p2=t; } main() { int i1, i2; printf("Enter two numbers:\n"); scanf("%d%d", &i1, &i2); if(i1<i2) swap(&i1, &i2); printf("i1=%d,i2=%d\n",i1, i2); }
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

8.8 字符指针和字符数组的比较
字符数组和字符指针变量二者之间的区别主要 有以下几点: (1) 字符数组由若干个元素组成,每个元素中放 一个字符,而字符指针变量中存放的是地址 (字符串第1个字符的地址),决不是将字符串 放到字符指各个元素赋值 不能用以下办法对字符数组赋值: char str[14]; str=″I love China!″; 而对字符指针变量,可以采用下面方法赋值: char*a; a=″I love China!″;
8.7 字符指针作函数参数
例 用函数调用实现字符串的复制
void copy_string(char *from, char *to) { for(;*from!='\0';from++,to++) {*to=*from;} *to='\0'; }
#include <stdio.h> void main() { char *a="I am a teacher."; char b[]="You are a student."; char *p=b; printf("string a=%s\nstring b=%s\n",a,p); printf("copy string a to string b:\n "); copy_string(a,p); printf("\nstring a=%s\nstring b=%s\n",a,b); }
• • • • • • • • • • • • • •
#include <stdio.h> void main() { int i,a[10]={3,7,9,11,0,6,7,5,4,2}; printf("原始数组:\n"); for(i=0;i<10;i++) printf("%d ",a[i]); printf("\n"); inv(a,10); printf("逆序后:\n"); for(i=0;i<10;i++) printf("%d ",a[i]); printf("\n"); }
(4) 定义了一个字符数组,在编译时为它分配内 存单元,它有确定的地址。而定义一个字符指针 变量时,给指针变量分配内存单元,在其中可以 放一个字符变量的地址。
例如: char str[10]; scanf(″%s″,str);
(5) 指针变量的值是可以改变的,例如: #include <stdio.h> void main() {char*a=″I love China!″; a=a+7; printf(″%s″,a); }
• void inv(int *x,int n) • { • int temp,*i,*j,*p,m=(n-1)/2; • i=x,j=x+n-1,p=x+m; • for(;i<=p;i++,j--) • { • temp=*i; • *i=*j; • *j=temp; • } • }
如果想在函数中改变一个数组中的元素的值,实参 与形参的对应关系有以下4种情况: • (1) 形参和实参都用数组, 如: • void f(int x[ ],int n) • void main() • {… • { • } • int a[10]; • … • f(a,10); • }
8.5.2
数组指针作函数参数
void f(int arr[],int n) { …… } void main() { int array[10]; …… f(array,10); …… }
例 将数组a中n个整数按相反顺序存放
• void inv(int x[ ],int n) • { • int temp,i,j,m=(n-1)/2; • for(i=0,j=n-1;i<=m;i++,j--) • { • temp=x[i]; • x[i]=x[j]; • x[j]=temp; • } • }
8.6 指针与字符串
8.6.1字符串的表示形式
(1) 用字符数组存放一个字符串,然后输出该字符串。 #include <stdio.h> void main() { char string[]=″I love China!″; printf(″%s\n″,string); }
(2) 用字符指针指向一个字符串 可以不定义字符数组,而定义一个字符指针。用字符 指针指向字符串中的字符。
#include <stdio.h> void main()
{char*string=″ I love China!″;
printf(″%s\n″,string); }

将字符串a复制为字符串b
#include <stdio.h> void main() { char a[]="this is a string.",b[20]; char *a="this is a string.",b[20]; int i; for(i=0;a[i]!='\0';i++) for(i=0;*(a+i)!='\0';i++) b[i]=a[i]; *(b+i)=*(a+i); b[i]=‘\0’; *(b+i)='\0'; printf("字符串a为:%s\n",a); printf("字符串b为:%s\n",b); }
(2) 实参用数组名,形参用指针变量。如: void main() void f(int *x,int n) { { int a[10]; … … f(a,10); } }
(3)实参形参都用指针变量。例如: void main() void f(int *x,int n) { { int a[10], *p=a; …… …… f(p,10); } }

输出二维数组任一行任一列元素的值
#include <stdio.h> void main() { int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23}; int (*p)[4],i,j; p=a; printf("请输入要显示的元素的坐标值:\n"); scanf("%d%d",&i,&j); printf("a[%d][%d]=%d\n",i,j,*(*(p+i)+j)); }
含义 二维数组名,指向一维数组 a[0],即0行首地址
地 址 2000
a[0], *(a+0), *a a+1,&a[1] a[1],*(a+1)
a[1]+2, *(a+1)+2, &a[1][2] *(a[1]+2), *(*(a+1)+2), a[1][2]
0行0列元素地址
2000
1行0列元素a[1][0]的地址
也可以设指针变量,用它的值的改变来指向字符串 中的不同的字符。
#include <stdio.h> void main() { char a[ ]="this is a string.",b[20],*p1,*p2; p1=a;p2=b; for(;*p1!='\0';p1++,p2++) *p2=*p1; *p2='\0'; printf("字符串a为:%s\n",a); printf("字符串b为:%s\n",b); }
(3)对字符指针变量赋初值: char *a=″I love China!″; 等价于 char*a; a=″I love Chian!″; 而对数组的初始化: char str[14] ={″I love China!″}; 不能等价于 char str[14] ; str[] = ″I love China!″;
(4) 实参为指针变量,形参为数组。如: void main( ) void f(int x[ ],int n) { { int a[10],*p=a; …… …… f(p,10); } }
例 用选择法对10个整数按由大到小顺序排序
• • • • • • • • • • • • • • • #include <stdio.h> void sort(int x[],int n) { int i,j,k,t; for(i=0;i<n-1;i++) { k=i; for(j=i+1;j<n;j++) if(x[j]>x[k]) k=j; if(k!=i) { t=x[i]; x[i]=x[k]; x[k]=t; } } }
8.5.3 指向多维数组的指针和指针变量
1. 多维数组元素的地址 可以认为二维数组是“数组的数组” 例如: int a[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}}; 则二维数组a是由3个一维数组所组成的。 设二维数组的首行的首地址为2000,则
表 示 形 式 a
(6) 若字符指针变量p指向字符串,就可以用指针变 量带下标的形式引用所指的字符串中的字符。 例如: char *a=″I love China!″; printf(“%c”,a[3]);
(7) 字符数组中各元素的值是可以改变的(可以对它 们再赋值),但字符指针变量指向的字符串中的内 容是不可以被取代的(不能对它们再赋值)。 例如: char a[]=”House”; char *b=” House”; a[2]=’r’; /* 合法,r取代u */ b[2]=’r’; /* 非法,字符串常量不能改变 */
相关文档
最新文档