程序结构 三种基本结构 顺序、选择和循环 C程序的组织单位 函数 数据类型 基本数据类型: 2、3.5、'a' int、float 和double、char int a; 空类型 &a? void 构造数据类型: 数组:int a[10]; float b[20];double d[10]; char c[10]; 指针(pointer) 请问圣马士教堂在哪? 一、指针概述 'a' 61 1001 1001 03 1002 3 1002 00 1003 1003 变量c的地址1003处的内容是什么? 1004 00 1004 若为char c; 00 地址1000处的内容是什么? 1005 1005 3.5 则c=00='\0'; 60 地址1001处的内容是什么? 1006 若为int c; 1006 40 地址1003处的内容是什么? 则c=0000,为0 1007 1007 'B'41 若为float c; 地址: 内存中每一个存储单元有一个 编号,称为地址 则c=40600000为3.5 1000 1000 二、 指针变量 什么是变量? 内存中一块命名的临时区域 如果要存储整型数据,用什么来保存? 整型变量:2个字节 int a; 变量的地址:指针 如果有一个变量的地址需要保存,用什么? 指针变量的定义 int * p 基类型 *指针变量名 p 1004 变量c的地址1003处的内容是什么? 若为char c; 则c=00='\0'; 若为int c; 则c=0000,为0 若为float c; 则c=40600000为3.5 指针变量的访问 1、指针变量取值 p= &c; p 1003 q 1003 1000 1001 1002 1003 1004 q=p; 2、引用指针变量 1005 1006 *p=3; 如何通过p访问1003处的内容? p的值是什么? *p 1007 61 03 00 00 03 00 60 40 41 c 指针变量的访问 int *p,*q,*r,a,b; a=3;b=4; p=&a; q=&b; printf("%d,%d\n",*p,*q); r=p;p=q;q=r; r printf("%d,%d\n",*p,*q); a 3 b 4 p &a q &b a &a p 3 b 4 &a q &b 例8-1 读程序 main() { int x=10,*p;float y=234.5,*pf; p=&x;pf=&y; printf(“x=%d,y=%f\n”,x,y); printf(“p=%lu,pf=%lu\n”,p,pf); *p=*p+10; *pf=*pf+123.4; printf(“------------y\n”); printf(“x=%d,y=%f\n”,x,y); printf(“p=%lu,pf=%lu\n”,p,pf); } 例8-2 main() { int *p,*s,a; a=*p+*s; printf(“a=%d\n*p=%lu\n*s=%lu”,a,p,s); } 指针变量的运算 int c,*p;c=3;p=&c; p 1006 1004 1000 1001 1002 1003 1004 1005 1006 1007 1、&*p与*&c &*p等价于&c,即1004 3 3 *&c等价于c即3 printf("%d",*p++); printf("%d",*--p); 3、*p++与*++p 2、p++与++p *p++??*(p++) p++??先用p,然后p=p+类型字节 ++p??p=p+类型字节,再用p *++p??*(++p) 61 03 00 00 03 00 40 41 指针变量的运算 p 1004 1000 1001 4、p+2=? 1002 若是:int *p,则为 1003 1008 1004 若是:char *p,则为 1005 1006 一个指针变量的值加上一个整型 1006 数据,则为一个新的地址,地址值1007 为原值+整数*字节数 61 03 00 00 03 00 40 41 指针变量的运算 p 1004 1000 1001 5、q-p=? q 1006 1002 若是:int *p,*q,则为 1003 1 1004 若是:char *p,*q,则为 1005 2 一个指针变量的值减去另一个指针 1007 变量的值为两个地址间的数据个数 1006 61 03 00 00 03 00 40 41 指针变量的初始化 #include 指针变量的正确使用 (1)先定义 void main() void main() (2)再初始化 {{int *p; (3)然后再引用 int *p, *q,a; *p=5; 初始化方法: p=&a;q=p; printf("*p=%d\n",*p); (1)变量地址给指针变量 *p=3;(*q)--; (2)某个已初始化的指针 }} 变量赋给同类型指针变量 (3)使用malloc或calloc 指针基本知识 int *p,*q; int a; char c; p=&a; q=&c; q=p; int *p,a; p=&a; a=3; printf("%d",*p); *p=5; printf("%d",a); 初始化方法练习 若有定义:char *p1,*p2,*p3,*p4,ch; 则不能正确赋值的程序语句是: A、p1=&ch;scanf("%c",p1); B、p2=(char *)malloc(1);scanf("%c",p2); C、p3=getchar(); D、p4=&ch;*p4=getchar(); 例8-3 main() { int i=0,*pi=&i; float f=0,*pf=&f; long l=0,*pl=&l; printf(“pi=%lu,pi+1=%lu\n”,pi,pi+1); printf(“pi=%lu,pi-1=%lu\n”,pi,pi-1); printf(“pf=%lu”,pf); pf++; printf(“%lu”,pf); pl--; printf(“%lu”,pl); } 指针变量做参数 读下列程序,写出运行结果 void swap(int *p,int *q) { int t; t=*p;*p=*q;*q=t; } main() {int a=3,b=4; swap(&a,&b); printf("%d,%d",a,b); } 996 q 1004 998 p 1006 1000 3 t 1004 b 1006 a 3 4 4 3 s w a p m a i n 指针变量做参数 指针变量做形参时,对应实参为数据类型 与该指针变量基类型相同的变量的地址 ? 指针变量做形参时,参数传递的形式仍为 值传递 ? 在函数调用过程中,通过对实参变量的间 接访问,改变了对应形参的值 ? 指针变量做参数 swap(int *p,int *q) {int *t; t=p;p=q;q=t; } main() { int a=3,b=4; swap(&a,&b); printf("%d,%d",a,b); } a t &a p &b q &a 3 b 4 a 3 b 4 p &a q &b 指针变量做参数 swap(int *p,int *q) {int t; t=*p;*p=*q;*q=t; } main() { int a=3,b=4; swap(&a,&b); printf("%d,%d",a,b); } a t 3 p &b q &a 4 b 3 a 3 b 4 p &a q &b 指针变量做参数 swap(int p,int q) {int t; t=p;p=q;q=t; } main() { int a=3,b=4; swap(a, b); printf("%d,%d",a,b); } 3 a t 3 p 4 b 4 q 3 a 3 b 4 p 3 q 4 想要使用函数来交换两个变量的值,可通过什么 方法完成? 1、指针变量做形参,间接访问实参变量交换 2、全局变量 通过函数带回返回值的方法? (1)全局变量 (2)return (最多1个) (3)指针变量做形参 (4)数组做形参 三、数组与指针 数组的存储与访问 1、一维数组的存储与访问 数组名代表数组的首地址 a,&a[0]或1000 a[1]的地址是: &a[1]或a+1或1002 a[1]的内容: 2,a[1],*(a+1) 1000 1 2 3 4 5 6 7 8 a 数组的存储与访问 1000 1 1002 2 1004 3 a[0] 1 2 3 1006 5 a[1] 5 6 7 1008 6 a[2] 9 10 11 1010 7 1012 9 a的值为:1000 1014 10 a[0]的值为:1000 *(a+0) a+0 1016 11 a[1]的值为:1006 *(a+1) a+1 a[2]的值为:1012 *(a+2) a+2 2、二维数组的存储与访问(int a[3][3])(二维数组也是一个一 维数组) 指向一维数组的指针 a 1 100 p 100 102 2 3 4 5 6 7 8 9 10 int a[10],*p; p=a; printf("%d",*p); p++; printf("%d",*p); 指向一维数组的指针 利用指针,为数组从键盘输入值,并输出 int a[10],*p,i; p=a; p for(i=0;i<10;i++,p++) scanf("%d",________); p=a; for(i=0;i<10;i++) printf("%d",*p++); 1、设变量定义为“int a[4]={1,3,7,9},*p=a+2; 则*p的值为_____。 2、若有以下说明和语句,且I>=0&&I<10, 则下面()是对数组元素的错误引用 int a[]={1,2,3,4,5,6,7,8,9,0},*p,I; p=a; A、*(a+I) B、p+I C、a[p-a] D、 *(&a[I]) 四、字符串与指针 char s[10],*p; p=s+2; Len=strlen(p); strcpy(p,p+1); p I N A \0 I N A \0 \0 C H C H 字符串的输入输出方法 char str[10],*p=str; 1、 scanf("%s",str); gets(str); scanf("%s",p); gets(p); strcpy(str,"abcde"); strcpy(p,"abcde"); 2、输出 printf("%s,%s",str,p); puts(str); puts(p); 字符串赋初值的方法 char char char char char str[]={'a','b','c','d','e','\0'}; str[6]={'a','b','c','d','e'}; str[]={"abcde"}; str[]="abcde"; *p="abcde"; 指向字符串的指针变量作为函数形参变量 设计一个compare函数可比较两个字符串 int compare (char *s1,char *s2) { while(*s1!='\0' && *s2!='\0 && *s1==*s2) {s1++;s2++} return *s1-*s2; } printf("%d",compare("aa","bb")); 字符串指针作为函数参数 设计一个函数len可求一个字符串的长度, 要求使用指针作为函数参数,并进行调用, 打印字符串"abcde"的长度。 int len (char *s) { int k=0; while(*s!='\0') printf("%d", { k++;s++;} len("abcde"); return k; } 指向指针的指针 int a,*p,**q; a=3; p=&a; q=&p; printf("%d,%d,%d",a,*p,**q); 指针用法小结 1、int *p; 2、int *p[10]; 3、int (*p)[10]; 4、int *p(); 5、int (*p)() 6、int **p; 1、指向整型变量的指针变量 2、指向整型变量的指针数组 3、指向一维整型数组的指针 4、返回整型指针的函数 5、指向函数的指针 6、指向指针的指针 main函数的参数 main函数的参数: 没有 或 有两个 两个参数: 1、整型变量(argc):存放运行程序时输 入的实参个数。 2、指向字符串的指针数组(argv):存放 运行程序时输入的各个实参字符串。 main函数的参数 例main参数应用举例。 #include main(int argc, char *argv[]) { int i; printf(“arguments number is:%d”,argc-1); for(i=1;i=0&&I<10,则下 面()是对数组元素的错误引用 int a[]={1,2,3,4,5,6,7,8,9,0},*p,I; p=a; A、*(a+I) B、p+I C、a[p-a] D、 *(&a[I]) 7、下面程序的输出结果为: void main() { char *p,s[]="ABCD"; for(p=s;p main() { char *p="abcde\0fg\0"; printf("%d",strlen(p)); } 5 若有如下定义和语句 请写出通过指针p 取出字符'g'的表达式 char s[13]= "abcdefghijk",*p=s; *(p+6) 程序阅读题 void main() {char str1[]="23abc"; #include "string.h" code(str1); func(char str[]) printf("%s\n",str1); {int num=0; } a while(*(str+num)!='\0') code(char *s) num++; {while(*s!='\0') return num; 字符串长度 { {if('a'<=*s&&*s<='z'|| d 计数 } 6 'A'<=*s&&*s<='Z') void main() { *s=*s+3; { char str[10],*p=str; if(*s>'z'||*s>'Z'&&*s<'a') gets(p); *s-=26; printf("%d",func(p));} } s++; A12axyz 23def 输入abcdef回车 } void ss(char *s,char t) { while(*s) {if(*s==t) *s=t-'a'+'A'; s++; }} void main() {char str1[100]="abcddfefdbd",c='d'; ss(str1,c); printf("%s",str1); } 程序填空 89 56 32 30 28 27 3 下面的函数f(v,x,&n)将x插入到已从大到小排序好 的数组v中,插入x后数组的元素仍然有序,n表 示数组v中已排好序的数组元素个数 int *n void f(int v[],int ,__________) { int k; for(k=*n-1;___________;k--) k>=0&&v[k]