指针,数组,内存分配,结构体_第1页
指针,数组,内存分配,结构体_第2页
指针,数组,内存分配,结构体_第3页
指针,数组,内存分配,结构体_第4页
指针,数组,内存分配,结构体_第5页
已阅读5页,还剩48页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

补充内容指针的本质指针是变量指针的值就是内存单元(变量)的地址

inti=100;

int*p=&i;int**pi=π0x0012ff4c0x0012ff640x0012ff640x0012ff4c0x0012ff48100pipi指针的类型“一个int型的指针”,指的是“一个类型为int*的指针”,编译器认为这样的一个指针指向的内存单元为2字节,并将其内容解释成int类型的值p++等价于p=p+1*sizeof(int)字符型的指针是?int**p中p的类型是什么?指针的类型(续)类型名和*结构形成了新的指针类型,但*是和后面的变量结合

int*a,b,c和int*a,b,c的写法效果一样,只有a是int型的指针,而b和c仍是int型的变量在c中,大多数是将指针定义为语言中固有的数据类型,而在DS中我们将遇到的指针类型更加多样化。指针的类型(续)判断一个指针是否有效?

if(p!=NULL)指针的初始化?如果指针变量是全局变量,则系统会默认将其值设为NULL,但如果指针变量是局部变量,系统不会给它赋初值,程序员必须明显指明其初值,否则会导致不可预测的结果.指针的类型(续)指针不管是全局还是局部的,都应当在声明它的时候初始化,要么赋予一个有效的地址,要以赋予NULL

int*pint=NULL; pint=0x1992;(这样做的结果是什么??)指针的运算int*p1,*p2;p++;p--;p+=5;p-=5;p2-p1;p2=p1;>,<,>=,<=,!=,==&(取址),*(取值)main(){

int*p1,*p2,*p,a,b;

scanf("%d,%d",&a,&b);p1=&a;p2=&b;

if(a<b){p=p1;p1=p2;p2=p;}

printf("\na=%d,b=%d\n\n",a,b);

printf("max=%d,min=%d\n",*p1,*p2);}Swap(int*p1,int*p2)

{inttemp;

temp=*p1;

*p1=*p2;

*p2=temp;

}main(){

int

a,b;

int*pointer-1,*pointer-2;

scanf("%d,%d",&a,&b);

pointer-1=&a;pointer-2=&B;if(a<b)Swap(pointer-1,pointer-2);

printf("\n%d,%d\n",a,b);}习题要求使用指针和子函数完成以下程序:输入3个整数a、b、c

,按大小顺序输出。指针的传递可以将函数的参数声明为指针,此时,函数接受的参数是内存单元的地址而不是内存单元的值会带来什么样的影响?数组的本质任何数组,不论是静态声明还是动态创建的,其所有元素在内存中都是连续字节存放的数组的本质(续)数组下标数组下标从0开始,到元素个数减1为止,下标必须是整数或整数表达式,在引用数组元素时,编译器通过下标值来计算所引用元素在内存中的地址。

a[3]=100

以上图为例,计算出a+3*sizeof(int)

得到0x004284FC,将原来的46改写为100数组的本质(续)数组名 数组名本身就标识了一个地址,数组名的值就是数组第一个元素的内存单元首地址,即:a==&a[0],这样,可以通过同类指针迭代来遍历整个数组(如int*p=a;)?思考:p和a都标识数组的首元素地址,但是有什么不同?数组的本质(续)引用数组元素的方法:(1)下标法(2)指针法数组的本质(续)另一方面,不能通过数组名来访问整个数组,除非它是带有\0结束符的字符数组(即字符串)。由于这个原因,任何两个数组之间不能直接赋值

inta[10]={0,1}

intb[10]={0,1,2,3,4,5,6,7,8,9} a=b;//错误数组的本质(续)想将一个数组的值赋给另一个数组,必须按元素逐个赋值,或者使用内存拷贝函数memcpy()

main(){

inta[]={1,2};

intb[]={5,6,7,8};

inti;

clrscr(); memcpy(a,b,4);

for(i=0;i<2;i++)

printf("%d",a[i]);}数组的初始化指定数组的元素个数

inta[10];不指定数组的元素个数,而直接初始化

inta[]={1,2,3,4,5,6}; (等价于:inta[6];a[0]=1;a[1]=2;…)数组的初始化同时指定元素个数并初始化

inta[6]={1,2,3,4,5,6};

inta[100]={1};常见错误inta[5]={1,2,3,4,5,6};inta[10]={5,,12,2};注意防止越界系统不会对数组的边界进行检测,防止越界是程序员个人的事二维数组二维数组在C语言中以“行序优先”来存储元素,即在存储时,先存储一行,再存第二行。inta[5][3],当我们访问a[4][1]时,实际上编译器是*((a+4*3)+1),在定义二维数组时,编译器为了计算其地址必须知道该数组的列数,而不必知道行数。数组传递传值、传址★传值:将数组元素作为参数传递★传址:将数组的地址作为参数传递数组传递数组不能从函数的return语句中返回,如何实现数组元素值的双向传递?--传址。传值--如果想按值来传递数组,可以传递数组元素,或者可以将数组封装起来,例如放到结构体中做为一个成员,因为结构体默认是按值传递的。字符数组字符数组就是元素为字符变量的数组。字符数组与字符串?字符串是以\0为结束符的字符数组,因此字符数组不一定就是字符串。如果用一个字符串常量来初始化一个字符数组,数组的长度至少要比字符串常量的长度大1,用来保存‘\0’。字符数组(续)chararr1[]={‘a’,’b’,’\0’,’d’,’e’};chararr2[]=“hello”;char*p=“hello”;printf(“%d”,sizeof(arr1));printf(“%d”,strlen(arr1));printf(“%d”,sizeof(arr2));printf(“%d”,strlen(arr2));printf(“%d”,strlen(p));字符指针C可用char*表示字符串 main(){ chars[]={‘a’,‘b’,‘c’,’\0’},*p=s; char*pchar="abc“;

printf("%s",p);

printf(“%s“,s);

printf("%s",pchar);}字符串复制和比较字符串复制必须使用strcpy或strncpy,不能用=复制,那样是字符指针的赋值。同样不要用==和>=,!=比较两个字符串,而应用strcmp,strncmp;例题:例10.5输出数组中的全部元素。假设有一个a数组,整型,有10个元素。要输出各元素的值有三种方法:(1)下标法。main(){

inta[10];

inti;for(i=0;i<10;i++)

scanf("%d",&a[i]);

printf("\n");for(i=0;i<10;i++)

printf("%d",a[i]);}(2)通过数组名计算数组元素地址,找出元素的值。

main(){

inta[10];

inti;for(i=0;i<10;i++)

scanf("%d",a+i);

printf("\n");for(i=0;i<10;i++)

printf("%D",*(a+i));}(3)用指针变量指向数组元素。main(){

inta[10];

int*p,i;

for(p=a;p<a+10;p++)

scanf("%d",p);

printf("\n");for(p=a;p<(a+10);p++)

printf("%d",*p);}例题将字符串a复制为字符串bmain(){chara[]="iamaboy.",b[20];

inti;

for(i=0;*(a+i)!=′\0′;i++)*(b+i)=*(a+i);*(b+i)=′\0′;

printf("stringais:%s\n",a);

printf("stringbis:");for(i=0;b[i]!=′\0′;i++)

printf("%c",b[i]);

printf("\n");}main(){chara[]="IamaBoy.",B[20],*p1,*p2;

inti;p1=a;p2=B;for(;*p1!=′\0′;p1++,p2++)*p2=*p1;*p2=′\0′;

printf("stringais:%S\n",a);

printf("stringBis:");for(i=0;B[i]!=′\0′;i++)

printf("%C",B[i]);

printf("\n");}结构体将基本数据组合起来列成更大的结构数据类型,这就是结构体,也可以叫做用户自定义数据类型。例子:三维系统中的座标结构体的定义Struct

addr{ charname[30]; charstreet[40]; charcity[20]; unsignedlongintzip;};//一个结构定义体就是一条语句结构体变量定义//以新定义的addr为新的数据类型struct

addr{ charname[30]; charstreet[40]; charcity[20]; unsignedlongintzip;}addr_a,addr_b,addr_c;如何定义结构体和结构体变量?访问结构元素每个结构元素都可由句点操作符/成员操作符访问

addr_a.zip=12345;

printf(“%d”,addr_a.zip);也可通过指向运算符->访问结构元素。结构体的使用Struct

struct_type{

inta,b; charch;};Main(){

struct

struct_type

arg;

arg.a=1000; f1(arg);}f1(structstruct_type

parm){

printf(“%d”,parm.a)}结构指针Struct

addr*addr_pointer;//结构指针有两种用途(1)对函数的引用调用;(2)建立链表和其它动态数据结构

通过结构指针访问结构成员:

printf(addr_pointer->name);

printf(*addr_);结构体例题1有一个结构体变量stu,内含学生学号、姓名和3门课的成绩。要求在main函数中赋以值,在另一函数print中将它们打印输出。今用结构体变量作函数参数。#include<string.h>#defineFORMAT"%d\n%s\n%f\n%f\n%f\n"structstudent{intnum;charname[20];floatscore[3];};main(){ voidprint(structstudent);

structstudentstu;

stu.num=12345;

strcpy(stu.name,"LiLi");stu.score[0]=67.5;stu.score[1]=89;stu.score[2]=78.6;

print(stu);}voidprint(structstudentstu){

printf(FORMAT,stu.num,,stu.score[0],stu.score[1],stu.score[2]);

printf("\n");}解法2:使用结构体指针改用指向结构体变量的指针作实参。可以在上面程序的基础上作少量修改即可#defineFORMAT"%d\n%s\n%f\n%f\n%f\n"

structstudent{intnum;charname[20];floatscore[3];}stu={12345,"LiLi",67.5,89,78.6};main(){ voidprint(structstudent*);/*形参类型修改成指向结构体的指针变量*/

print(&stu);/*实参改为stu的起始地址*/}

voidprint(structstudent*p)/*形参类型修改了*/{

printf(FORMAT,p->num,p->name,p->score[0],p->score[1],p->score[2]);/*用指针变量调用各成员之值*/

printf("\n");}实验二:个人通讯录试设计一个个人通讯录,能够在通讯录中插入,删除,按名字查找联系人的信息.要求: 1、使用结构体数组来存放联系人的信息 2、对联系人信息的插入、删除、查找均设计成独立的子函数用typpedef类型定义typedef可用于对已定义的数据类型产生一个别名,但并不产生新的数据类型。例:typedef

int

INT;

INTi,j;回顾如何使用typedef定义结构体变量及结构体指针!!用typpedef类型定义structstudent{ …… ……};typedef

structstudentSTU;STUs1,s2,*Ps1,*ps2;typedef

structstude

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论