首页
动态
归档
Github
留言
工具箱
更多
邻居
壁纸
音乐
Search
1
欢迎访问我的日志空间
8,244 阅读
2
C语言读写程序文件-学习三十二
742 阅读
3
WEB音乐播放器源码
712 阅读
4
Typecho - Joe主题魔改版(持续更新)
660 阅读
5
Typecho-1.1/17.10.30-定制版源码
639 阅读
学习笔记
源码库
BUG
第九艺术
登录
Search
标签搜索
学习笔记
C语言
typecho
Java
扫雷
源码
PHP
插件
网站源码
音乐播放器
模板
git
github
bug
XG.孤梦
累计撰写
50
篇文章
累计收到
44
条评论
首页
栏目
学习笔记
源码库
BUG
第九艺术
页面
动态
归档
Github
留言
工具箱
邻居
壁纸
音乐
搜索到
50
篇与
的结果
2022-02-23
C语言结构体数组、指针与函数-学习二十八
结构体数组结构体数组的定义一个结构体变量只能存放一组有关联的数据,比如一个学生的数据,如果要存放多个学生的数据,就要使用结构体数组。在声明了结构体类型之后,结构体数组的定义与基本类型数组的定义完全相同。例如:struct student{ long int no; char name[20]; char sex; float score; }; struct student stu[3];定义了struct student类型的数组,数组名为stu,包含3个数组元素,每个数组元素都是一个struct student类型的结构体变量,分别是stu[0].stu[1].stu[2]。结构体数组的引用产表示下标为i的结构体数组元素的成员no的值stu[i].no;产表示下标为i的结构体数组元素的成员name的首地址(name为char数组)stu[i].name;表示下标为i+1的结构体数组元素的成员sex值stu[i+ 1].sex;产表示下标为i- 1的结构体数组元素的成员score的地址&stu[i- 1].score;结构体数组的初始化结构体数组和基本类型数组一样可以初始化,只是每个元素的初值是由括起来的一组数据,初始化的形式是定义数组的同时,在其后面加上“={初值表列}”。例如:struct student{ int num; char name[20]; char sex; int age; } struct student stu[3]={ {100,"Wang Lin",M',20}, {101,"Li Gang", 'M',19}, {110,"Liu Yan", F,19} }; 例子有3个候选人,每个选民只能投票选一人,要求编一个统计选票的程序,先后输入被选人的名字,进行投票,最后输出各人得票结果。#include <stdio.h> #include <string.h> void main() { struct Person { char name[20]; int count; }leader[3] = { {"Zhangsan",0},{"Lisi",0},{"Wangwu",0} }; int i, j; char leader_name[20]; printf("请输入支持的候选人名字:\n"); for (i = 0; i < 10; i++) { scanf_s("%s", leader_name,20); for (j = 0; j < 3; j++) { // strcmp函数比较字符串是否相同,相同就返回 0 if (strcmp(leader_name, leader[j].name) == 0) { leader[j].count++; } } } printf("\n"); for (i = 0; i < 3; i++) { printf("%s:%d\n", leader[i].name, leader[i].count); } }有n个学生的信息(包括学号、姓名、成绩),要求按照成绩的高低顺序输出各学生的信息。#include <stdio.h> struct Student { int no; char name[20]; float score; }; void main() { struct Student stu[5] = { {10001,"Zhangsan",98.5}, {10002,"Lisi",80.5}, {10003,"Wangwu",80.5}, {10004,"Zhaoliu",100}, {10005,"Xiqi",59} }; struct Student temp; // 定义常量 const int n = 5; int i, j, k; printf("成绩排行榜\n"); for (i = 0; i < n; i++) { for (j = i + 1; j < n; j++) { if (stu[j].score>stu[i].score) { temp = stu[j]; stu[j] = stu[i]; stu[i] = temp; } } } for (i = 0; i < n; i++) { printf("%d %10s %.2f\n",stu[i].no,stu[i].name,stu[i].score); } }结构体指针指向结构体变量的指针指向结构体对象的指针变量既可以指向结构体变量,也可以用来指向结构体数组中的元素。指针变量的基类型必须与结构体变量的类型相同。定义格式:struct 结构体名 *结构体指针变量名例如:struct Student stu; struct Student *pt;赋值pt = &stu;1.结构体类型只能表示一个结构形式,编译程序并不对它分配内存单元。2.定义指向结构体类型的指针变量并确定它的指向后,就可以用结构体指针变量访问所指向的结构体的成员。指针变量访问结构体变量的成员有以下几种形式(1)(*结构体指针变量).成员名 括号不能省略,因为 “.” 运算符优先级高于 “*” 的例如:(*sp).name(2)结构体指针变量 -> 成员名C语言提供了一种简便的结构体指针变量取成员运算 “->”称为指向成员运算符(或箭头运算符),和 “.” 优先级差不多,结合性都是从左往右。例如: sp -> name(&结构体变量) -> 成员名例如:(&stu) -> namae当用结构体变量访问结构体数据成员时用 “.” 运算符比较方便;当用指针访问结构体成员时用 “->” 运算符比较方便。例如sp -> nosp指向结构体变量stu, sp -> no 等价于 stu.nosp -> no++ 指向运算符 “->” 高于 “++” ,等价于 (sp -> no)++ 。先引用sp -> no值,即 stu.no 作为表达式的值;再使其值加1,即stu.no值加1。++sp -> no指向运算符 “->” 高于 “++” ,等价于 ++(sp -> no) 即先使 sp->no 值加1,即 stu.no 值加1;然后引用修改之后的 sp -> no值作为表达式的值。例子#include <stdio.h> struct Student { int no; char name[20]; float score; }; void main() { struct Student *p; struct Student stu = {10001,"Zhangsan",98.5}; p = &stu; printf("学号:%d\n姓名:%s\n成绩:%.2f\n",(*p).no,p -> name,(&stu) -> score); }指向结构体数组的指针可以用指针变量指向结构体数组的元素。例如:有3个学生的信息,放在结构体数组中,要求全部学生的信息。#include <stdio.h> struct Student { int no; char name[20]; float score; }; void main() { struct Student *p; struct Student stu[5] = { {10001,"Zhangsan",98.5}, {10002,"Lisi",80.5}, {10003,"Wangwu",80.5}, {10004,"Zhaoliu",100}, {10005,"Xiqi",59} }; for (p = stu; p<stu+5; p++) { printf("%d %10s %.2f\n",p->no, p->name, p->score); } }用结构体变量和结构体变量的指针作函数结构体作为函数参数对结构体数据操作时,常常需要将结构体变量的成员、结构体变量、结构体数组名或结构体指针作为参数 传递给另一个函数。1.用结构体变量的成员作参数用法和用普通变量作实参是一样的,属于“值传递”方式。应当注意实参与形参的类型保持一致。例如:用 stu[1].num 或 stu[2].name 作函数实参,将实参值传给形参。2.用结构体变量作实参用结构体变量作实参时,将结构体变量所占的内存单元的内容全部按顺序传递给形参。形参也必须是同类型的结构体变量。在函数调用期间形参也要占用内存单元,这种传递方式在空间和时间上开销较大。在被调用函数期间改变形参(也是结构体变量)的值,不能返回主调函数。3.用指向结构体变量(或数组元素)的指针作实参用指向结构体变量(或数组元素)的指针作实参时,将结构体变量(或数组元素)的地址传递给形参。结构体与函数之间的关系主要是:1.结构体作为函数的参数。2.结构体可以作为函数的返回值。例子:有n个结构体变量,内含学生学号、姓名和3门课程的成绩。要求输出平均成绩最高的学生的信息(包括学号、姓名、3门课程成绩和平均成绩)。#include <stdio.h> #define N 3 struct Student { int no; char name[20]; float score[3]; float aver; }; void main() { void input(struct Student stu[]); struct Student max(struct Student stu[]); void print(struct Student stu); struct Student *p; struct Student stu[N]; p = stu; input(p); print(max(p)); } void input(struct Student stu[]) { int i; printf("请输入各学生信息:\n"); for (i = 0; i < N; i++) { scanf_s("%d %s %f %f %f", &stu[i].no, stu[i].name,20, &stu[i].score[0], &stu[i].score[1], &stu[i].score[2]); stu[i].aver = (stu[i].score[0] + stu[i].score[1] + stu[i].score[2]) / 3.0; } } struct Student max(struct Student stu[]) { int i,m=0; int temp; for (i = 0; i < N; i++) { if (stu[i].aver > stu[m].aver) { m = i; } } return stu[m]; } void print(struct Student stud) { printf("学号:%d\n姓名:%s\n三门成绩:%.2f %.2f %.2f\n平均成绩:%.2f\n", stud.no, stud.name, stud.score[0], stud.score[1], stud.score[2], stud.aver); }
2022年02月23日
426 阅读
0 评论
0 点赞
2022-02-22
C语言结构体-学习二十七
结构体类型用户自己建立由不同类型数据组成的组合型的数据结构,它称为结构体。声明一个结构体类型的一般形式为:struct 结构体名 {成员列表};说明:1.可以设计出许多种结构体类型例如:struct Teacherstruct Workerstruct Date 等结构体类型,各自包含不同的成员2.成员可以属于另一个结构体类型例如:struct Date { int month; int day; int year; }; struct Student{ int num; char name[20]; char sex; int age; struct Date birthday; }; 结构体类型变量1.先声明结构体类型,再定义该类型变量。例如:// 声明结构体类型 struct Student{ int num; char name[20]; char sex; int age; }; // 定义该类型变量 // 结构体类型名 结构体变量名 struct Student student1,student2;2.在声明类型的同时定义变量例如:struct Student{ int num; char name[20]; char sex; int age; }student1,student2;3.不指定类型名而直接定义结构体类型变量一般形式为:struct{成员表列}变量名表列; 指定了一个无名的结构体类型。例如:struct { int num; char name[20]; char sex; int age; }student1,student2;说明:1.结构体类型与结构体变量是不同的概念,不要混同。只能对变量赋值、存取或运算,而不能对一个类型赋值、存取或运算。在编译时,对类型是不分配空间的,只对变量分配空间。 内存分配给结构体变量的存储空间是各成员变量所占存储空间的总和。2.结构体类型中的成员名可以与程序中的变量名相同,但二者不代表同一对象。3.结构体变量可以在定义时进行初始化赋值。给结构体变量初始化时,所赋初值按顺序放在一对花括号中。例如:struct Student{ int num; char name[20]; char sex; int age; }student1={2022160123,"Zhang san","男",24},student2;结构体变量的成员的引用结构体变量是构造类型变量,可访问操作的对象有两个。1.结构体变量的成员;2.结构体变量本身,代表组成该变量的所有数据成员。引用结构体变量的成员结构体变量成员的访问形式:结构体变量名 . 成员名例如:student1.name点号 “.” 称为成员运算符,是二目运算符,优先级是第一级,结合性是从左到右。结构体变量的成员可以和普通变量一样参加各种运算例如:student2.num = student1.num++;说明:1.如果成员本身又是一个结构体类型,则要若干个成员运算符,逐级找到最低级的成员才能使用。例如:student2.birthday.day =18;2.可以引用结构体变量成员的地址,此时 “&” 要放在结构体变量名前面。例如:scanf( "%d" ,&student2.num);3.“&” 和 “.” 同时出现时,运算符“.”的优先级高例如:表达式 student1.num++ 等价于 (student1.num)++。4.相同结构体类型的结构体变量可以直接相互赋值。例如:将变量student1的所有成员值一一对应赋值给变量student2的所有成员值student2 = student1;5.结构体变量与基本类型变量不同,不要直接用来进行算术、关系和逻辑等运算,只能将成员逐个进行比较。6.不能对结构体变量进行整体的输入/输出,只能对每个成员逐个输入或输出。7.结构体变量占据的一片连续内存单元的首地址称为该结构体变量的地址,每个成员占据的若干内存单元的首地址称为成员的地址,两个地址均可引用。例子把一个学生的信息(包括学号、姓名、性别、年龄)放在一个结构体变量中,然后输出这个学生的信息。#include <stdio.h> void main() { struct Student { long int num; char name[20]; char sex; int age; }std = { 10001,"Zhang san",'M',20 }; printf("学号:NO.%ld\n姓名:%s\n性别:%c\n年龄:%d\n", std.num,std.name,std.sex,std.age); }输入两个学生的学号、姓名和成绩,输出成绩较高学生的学号、姓名和成绩#include <stdio.h> void main() { struct Student { long int num; char name[20]; float score; }std1,std2; printf("请输入学生信息:\n"); // 对于数组输入,scanf_s要定义缓冲区大小,而且name前边不加&,name本身就是地址 scanf_s("%d%s%f", &std1.num, std1.name,21, &std1.score); scanf_s("%d%s%f", &std2.num, std2.name,21, &std2.score); if (std1.score > std2.score) { printf("学号:NO.%ld\n姓名:%s\n成绩:%.2f\n", std1.num, std1.name, std1.score); } else if (std1.score < std2.score) { printf("学号:NO.%ld\n姓名:%s\n成绩:%.2f\n", std2.num, std2.name, std2.score); } else { printf("学号:NO.%ld\n姓名:%s\n成绩:%.2f\n", std1.num, std1.name, std1.score); printf("学号:NO.%ld\n姓名:%s\n成绩:%.2f\n", std2.num, std2.name, std2.score); } }
2022年02月22日
369 阅读
0 评论
0 点赞
2022-02-21
C语言位运算-学习二十六
运算符使用说明:1.位运算符中,除按位取反运算符“~”外,其他均为二目(元)运算符,即运算符两侧各有一个操作对象;2.位运算的运算对象的数据类型只能是整型或字符型;3.位运算可以与赋值运算符结合,组成位复合赋值运算符符: <<=、=>>、 &=、 ^=、|=按位取反运算语法格式:~ 表达式按位取反运算符(~)的运算规则:对参与运算的表达式的值按位进行“求反”运算。即将表达式值各二进制位上的1变为0,0变为1。按位取反(~)为单目运算符,其优先级别与其他单目运算符相同,并且同级时自右向左结合。例如:int a=1; ~a 即0 0 0 0 0 0 0 1-----------------------------------1 1 1 1 1 1 1 0,因此~a的值得 -2 。例子#include <stdio.h> void main(){ short int a = 1, b; b = ~a; printf("a= %d\nb= %d\n",a, b); }按位与运算语法格式:表达式1 & 表达式2按位与运算符(&)的运算规则:将参加运算的两个表达式值按对应的进制位分别进行“与”运算。两个对应的二进制位都为1时,该位的结果为1;否则为0。例如:3 & 5 即0000 00110000 0101-----------------0000 0001,因此 3&5 的值得 1。注意:负数按补码形式参加按位与运算。使用“按位与(&)”运算符时,要注意与“逻辑与(&&)”运算符的区别。例子#include <stdio.h> void main(){ short int a = 3, b=5,c; c= a & b; printf("c= %d\n",c); }按位或运算语法格式:表达式1 | 表达式2按位或运算符(|)的运算规则:将参与运算的两个表达式值按对应的二进位分别进行“或”运算。当两个对应的二进制位有1位是1时,该位的结果为1;否则为0。例如:3 | 5 即0000 00110000 0101-----------------0000 0111,因此 3|5 的值得 7。注意:负数按补码形式参加按位与运算。使用“按位或(|)”运算符时,要注意与“逻辑或(||)”运算符的区别。例子#include <stdio.h> void main(){ short int a = 3, b=5,c; c= a | b; printf("c= %d\n",c); }按位异或运算语法格式:表达式1 ^ 表达式2按位异或运算符(^)的运算规则:将参与运算的两个表达式值按对应的二进制位分别进行“异或”运算。当两个对应的二进制位值不相同为1;否则为0。例如:3 ^ 5 即0000 00110000 0101-----------------0000 0110,因此 3^5 的值得 6。例子#include <stdio.h> void main(){ short int a = 3, b=5,c; c= a ^ b; printf("c= %d\n",c); }左移语法格式:表达式1 << 表达式2表达式1是被移动的运算对象表达式2是移动的位数左移运算符(<<)的运算规则:将表达式1的值的二进制位每位左移表达式2的值的位数。二进制位向左移动时,移出的高位直接丢弃,低位出现的空位补0。例如:int a=1; a << 2即a=0000 0001-----------------a=0000 0100 因此 a << 2 的值得 4。-例子#include <stdio.h> void main() { int a = 1,b; b = a << 2; printf("b= %d\n", b); }右移语法格式:表达式1 >> 表达式2表达式1是被移动的运算对象表达式2是移动的位数右移后左边的空位上补0还是补1与表达式1的类型以及所使用的机器和编译环境有关右移运算符(>>)的运算规则:将表达式1的值的二进制位每位右移表达式2的值的位数。二进制位向右移动时,正数左补0,负数一般左补1,右边丢弃(即不改变原来的数值符号)。如果是无符号类型,二进制位向右移动时左补0,右边丢弃。右移n位相当于除以2n注意:原来符号是1(负数),左边空位补0还是1,取决于所使用的计算机系统,有的系统补0,有的系统补1。补0的称为“逻辑右移”,也称为简单右移;补1则称为“算术右移”例如:int a=4; a >> 2即a=0000 0100-----------------a=0000 0001 因此 a >> 2 的值得 1。例如:int a=-4; a >> 2即-例子#include <stdio.h> void main() { int a = 4,b; b = a >> 2; printf("b= %d\n", b); }位赋值运算位运算可以和赋值运算结合成位运算赋值运算符。&= 例:a&=b 相当于 a=a&b|= 例:a|=b 相当于 a=a|b>>= 例:a>>=b 相当于 a=a>>b<<= 例:a<<=b 相当于 a=a<<b^= 例:a^=b 相当于 a=a^b
2022年02月21日
309 阅读
0 评论
1 点赞
2022-02-20
C语言字符串与指针-学习二十五
字符串的引用方式字符串是存放在字符数组中的。引用一个字符串,可以用以下两种方法:用字符数组存放一个字符串,可以通过数组名和格式声明 “%s” 输出该字符串也可以通过数组名和下标引用字符串中一个字符。用字符指针变量指向一个字符串常量,通过字符指针变量引用字符串常量。例子#include <stdio.h> void main() { char string[] = "I love China!"; printf("%s\n", string); printf("%c\n", string[7]); // 输出第八个字符 } //通过字符指针输出一个字符串 #include <stdio.h> void main() { char *string = "I love China!"; printf("%s\n", string); printf("%c\n", string[7]); // 输出第八个字符 }将a字符串数组复制到b字符串数组#include <stdio.h> void main() { char a[] = "abcdefg"; char b[20]; int i; for (i = 0; *(a + i) != '\0'; i++) { *(b + i) = *(a + i); } *(b + i) = '\0'; printf("a = %s\n", a); // printf("b = %s\n", b); printf("b = "); for (i = 0; b[i] != '\0'; i++) { printf("%c", b[i]); } printf("\n"); }用指针变量来处理#include <stdio.h> void main() { char a[] = "abcdefg", b[20],*p1,*p2; p1 = a; p2 = b; for (; *p1 != '\0'; p1++) { *p2 = *p1; p2++; } *p2 = '\0'; printf("a = %s\n", a); printf("b = %s\n", b); }字符指针变量和字符数组的比较用字符数组和字符指针变量都能实现字符串的存储和运算;它们二者之间是有区别的,主要有以下几点:1.字符数组由若干个元素组成,每个元素中放一个字符; 而字符指针变量中存放的是地址(字符串第1个字符的地址),而不是将字符串放到字符指针变量中。2.赋值方式不同,可以对字符指针变量赋值,但不能对数组名赋值。char *a; a="I love Chinal"; 正确char str[14]; str[0]='1'; 正确 char str[14]; str = "I love China!"; 错误3.存储单元的内容不同,编译时为字符数组分配若干存储单元以存放各元素的值,而对字符指针变量,只分配一个存储单元。char *a, str[10];a=str; scanf ("%s",a); 正确 char *a; scanf("%s",a); 错误4.指针变量的值是可以改变的,而数组名代表一个固定的值(即数组首元素的地址)不能改变。例子#include <stdio.h> void main() { char *a = "I love China!"; a = a + 7; printf("%s\n", a); // 从第八个字符开始输出 }5.字符数组中各元素的值是可以改变的,但字符指针变量指向的字符串常量中的内容是不可以被取代的。char a[]="House", *b="House";a[2]='r'; 正确 b[2]='r'; 错误6.引用数组元数对字符数组可以用下标法和地址法引用数组元素。例如:a[5]、*(a+5)如果字符指针变量p=a,则也可以用指针变量带下标的形式和地址法引用。例如:p[5]、*(p+5)7.用指针变量指向一个格式字符串,可以用它代替printf函数中的格式字符串。例子#include <stdio.h> void main() { char *format; int a = 10; float b = 3.6; format = "a = %d, b = %f \n"; printf(format, a, b); // 相当于 printf("a = %d, b = %f \n", a, b); }字符指针作函数参数如果想把一个字符串从一个函数“传递”到另一个函数,可以用地址传递的办法,即用字符数组名作参数,也可以用字符指针变量作参数。在被调用的函数中可以改变字符串的内容,在主调函数中可以引用改变后的字符串。例子用函数调用实现字符串的复制。#include <stdio.h> void main(){ // 字符数组名做参数 void string_copy(char from[], char to[]); char a[] = "abcdefg", b[20]; string_copy(a, b); printf("a = %s\n", a); printf("b = %s\n", b); } void string_copy(char from[], char to[]){ int i; for (i=0; from[i]!= '\0'; i++) { to[i] = from[i]; } to[i] = '\0'; }#include <stdio.h> // 字符指针变量做参数 void main(){ void string_copy(char *from, char *to); char *a = "abcdefg", b[20]; char *to = b; string_copy(a, to); printf("a = %s\n", a); printf("b = %s\n", b); } void string_copy(char *from, char *to){ for (; *from != '\0'; from++,to++) { *to = *from; } *to = '\0'; }指向函数的指针在C语言中,一个函数总是占用一段连续的内存区,而函数名就是该函数所占内存区的首地址。我们可以给这个首地址(或称入口地址)赋予一个指针变量,使该指针变量指向该函数。然后通过指针变量就可以找到并调用这个函数。我们把这数的指针变量称为“函数指针变量”。用函数指针变量调用函数函数指针变量的定义一般形式为:类型说明符 (*指针变量名)()类型说明符:表示被指函数的返回值的类型*指针变量名:“*”后面的变量是定义的指针变量():指针变量所指的是一个函数例如:int (*pf)(); 表示 pf 是一个指向函数入口的指针变量,(函数值)是整型。例子#include <stdio.h> // 字符指针变量做参数 void main(){ int max(int, int); int(*p)(int, int); int a, b, c; p = max; scanf_s("%d %d", &a, &b); c = (*p)(a, b); printf("max=%d\n", c); } int max(int x,int y){ int z; z = (x > y) ? x : y; return (z); }
2022年02月20日
256 阅读
0 评论
0 点赞
2022-02-18
C语言多维数组与指针-学习二十四
数组名作函数参数用数组名作函数参数时,因为实参数组名代表该数组首元素的地址,形参应该是一个指针变量。C编译都是将形参数组名作为变量来处理的。实参数组名是指针常量,但形参数组名是按指针变量处理。在函数调用进行虚实结合后,它的值就是实参数组首元素的地址。在函数执行期间,形参数组可以再被赋值。例如:void fun (arr[],int n){ printf("%d\n", *arr); // 输出 a[0]的值 arr=arr+2; printf("%d\n", *arr); // 输出 a[2]的值 }例子将数组a中n个整数按相反顺序存放#include <stdio.h> void main() { void inv(int x[], int n); int i,a[10] = {1,2,3,4,5,6,7,8,9,10}; int *p; for (i = 0; i < 10; i++) { printf("%d ", a[i]); } printf("\n"); inv(a, 10); for (i = 0; i < 10; i++) { printf("%d ", a[i]); } printf("\n"); } void inv(int x[], int n) { int temp, i, j, m = (n - 1) / 2; for (i = 0; i <= m; i++) { j = n - 1 - i; temp = x[i]; x[i] = x[j]; x[j] = temp; } }用指针变量作实参#include <stdio.h> void main() { void inv(int *x, int n); int i,arr[10] = { 1,2,3,4,5,6,7,8,9,10 }, *p; p = arr; // 如果用指针变量作实参,必须先使指针变量有确定的值,指向一个已定义的单元。 for (i = 0; i < 10; i++) { printf("%d ", arr[i]); } printf("\n"); inv(p, 10); for (p = arr; p <arr + 10; p++) { printf("%d ",*p); } printf("\n"); } void inv(int *x, int n) { int temp, *p,*i, *j, m = (n - 1) / 2; p = x + m; i = x; j = x + n - 1; for (; i <= p; i++,j--) { temp = *i; *i = *j; *j = temp; } }用指针方法对10个整数按由大到小顺序排序。#include <stdio.h> void main(){ void sort(int *x, int n); int i, *p, a[10] = {9,8,6,2,3,4,5,1,2,10}; p = a; for (i = 0; i < 10; i++) { printf("%d ", a[i]); } printf("\n"); sort(p, 10); for (i = 0; i < 10; i++) { printf("%d ",*p); p++; } printf("\n"); } 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; } } } }2、多维数组与指针二维数组在内存中存储时,将二维转换为一维形式。C语言中定义的二维数组可以看作是一个一维数组,而这个一维数组的每个元素又是一个一维数组。从二维数组的角度来看,a是二维数组名,a代表整个二维数组的首地址,也是二维数组0行的首地址,等于1000。a+1 代表第一行的首地址,等于1008。a+i 第i行首地址为: a+i×4×2。数组名可以代表数组首地址,所以 a[0] 代表0行0列地址,即 &a0 。a[1] 的值是 &a1 ,a[2] 的值是 &a2 。a, a[0], a[1],a[2]本身不占内存,不存放数据,仅表示一个地址。行元素地址表示:a+0、a+1、a+2 等等;列元素地址表示:a[0]+0、a[0]+1、a[0]+2、a[0]+3 等等元素值: *(a[i]+j) <=> *(*(a+i)+j) <=> a[]i[j]a[i] <=> *(a+i) 等价:第i行第0列的元素地址 &a[i][0]a[i]+j <=> *(a+i)+j 等价:第i行第j列的元素地址 &a[i][j]a[1]+3 <=> *(a+1)+3 等价:第1行第3列的元素地址 &a[1][3]行指针与列指针a+i = &a[i] = a[i] = *(a+i) = &a[i][0],值相等,含义不同。a+i <=> &a[i],表示第i行首地址,指向行a[i] <=> *(a+i) <=> &a[0][0],表示第i行第0列元素地址,指向列例子使用指针的方式输出二维数组元素的值。#include <stdio.h> void main() { float f[3][4] = { {0.0, 0.1, 0.2, 0.3},{1.0, 1.1, 1.2, 1.3},{2.0, 2.1 ,2.2, 2.3} }; float *pf; int i; pf = f[0]; for (i = 0; i < 12; i++) { if (i != 0 && i % 4 == 0){ printf("\n"); } printf("%6.2f", *pf++); } printf("\n"); }表达式 *pf++ 等价于 *(pf++) ,其含义是取 *pf 的值作为表达式的值,再使 pf加1。通过pf值的变化,逐一访问 f数组 中每个元素。顺序输出数组元素方法简单,而指定输出数组元素则要进行地址的计算。例如二维数组为n X m (n为行,m为列)首元素地:址为a[0]a[i][j]在数组中相对位置的计算公式: i * m + j (m为每行元素个数)a0a0a0a0a1a1a1a1a2a2a2a2位移量的计算:a[1][1] = 1*4+1 = 5a[2][3] = 2*4+3 = 11若初值:p=a[0]则:*(p+1*4+1) = *(p+5) = a[1][1]*(p+2*4+3) = *(p+11) = a[2][3]数组下标从0开始便于计算相对位置多维数组的指针变量二维数组指针变量说明一般形式为:类型说明符 (*指针变量名)[长度]例如:int(*p)[4]把二维数组a分解为一维数组a[0],a[1],a[2]之后,设p为指向二维数组的指针变量。例子使用指向一维数组的指针变量输出二维数组元素的值。#include <stdio.h> void main() { float f[3][4] = { {0.0, 0.1, 0.2, 0.3},{1.0, 1.1, 1.2, 1.3},{2.0, 2.1 ,2.2, 2.3} }; float (*pf)[4]; int i,j; pf = f; for (i = 0; i < 3; i++) { for (j = 0; j < 4; j++) { printf("%6.2f", *(*pf+i)+j); } printf("\n"); } }多维数组指针作为函数参数一维数组名可以作为函数参数传递,多维数组名也可以作为函数参数传递。例子3个学生各学4门课,计算总平均分,输出第n个学生成绩#include <stdio.h> void main() { void average(float *p, int n); void search(float(*p)[4], int n); float score[3][4] = { {65, 67, 79, 60}, { 80,87,90,81 }, { 90,99,100,98 } }; average(*score, 12); search(score, 1); } void average(float *p, int n) { float *p_end, sum = 0, aver; p_end = p + n - 1; for (; p <= p_end; p ++) { sum = sum + (*p); } aver = sum / n; printf("平均成绩:%6.2f\n", aver); } void search(float(*p)[4], int n) { int i; printf("第%d学生的成绩:\n", n); for (i = 0; i < 4; i++) { printf("%6.2f ", *(*(p + n) + i)); } printf("\n"); }
2022年02月18日
273 阅读
0 评论
0 点赞
1
...
4
5
6
...
10