首页
动态
归档
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
留言
工具箱
邻居
壁纸
音乐
搜索到
32
篇与
的结果
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 点赞
2022-02-17
C语言指针与数组-学习二十三
指针变量作为函数参数函数的参数不仅可以是整型、浮点型、字符型等数据,还可以是指针类型。它的作用是将一个变量的地址传送到另一个函数中。例如:void swap(int *a,int *b)#include <stdio.h> void main() { void swap(int *x, int *y); int a,b; int *a1 = &a; int *b1 = &b; printf("请输入a,b的值:\n"); scanf_s("%d %d", &a, &b); if (a < b) { swap(a1, b1); } printf("max = %d, min=%d\n", a, b); } void swap(int *x, int *y) { int p; p = *x; *x = *y; *y = p; }注意:函数的调用可以(而且只可以)得到一个返回值(即函数值),而使用指针变量作参数,可以得到多个变化了的值。如果不用指针变量是难以做到这一点的。如果想通过函数调用得到n个要改变的值1.在主调函数中设n个变量,用n个指针变量指向它们;2.设计一个函数,有n个指针形参。在这个函数中改变这n个形参的值;3.在主调函数中调用这个函数,在调用时将这n个指针变量作实参,将它们的地址传给该函数的形参;4.在执行该函数的过程中,通过形参指针变量,改变它们所指向的n个变量的值;5.主调函数中就可以使用这些改变了值的变量。例子输入3个整数a,b,c,要求按由大到小的顺序将它们输出。用函数实现。#include <stdio.h> void main() { void exchange(int *x, int *y,int *z); int a,b,c; int *a1 = &a; int *b1 = &b; int *c1 = &c; printf("请输入a,b,c的值:\n"); scanf_s("%d %d %d", &a, &b, &c); exchange(a1,b1,c1); printf("%d, %d, %d\n", a,b,c); } void swap(int *x, int *y) { int p; p = *x; *x = *y; *y = p; } void exchange(int *x, int *y, int *z) { void swap(int *x, int *y); if (*x < *y) { swap(x, y); } if (*x < *z) { swap(x, z); } if (*y < *z) { swap(y, z); } }数组元素的指针一个变量有地址,一个数组包含若干元素,每个数组元素都有相应的地址。指针变量可以指向数组元素(把某元素的地址放到一个指针变量中)。数组元素的指针就是数组元素的地址。引用数组元素时指针的运算在指针指向数组元素时,允许以下运算:一加一个整数(用 + 或 +=),例如:p + 1一减一个整数(用 - 或 -=),例如:p - 1一两个指针相减,如 p1-p2 (只有p1和p2都指向同一数组中的元素时才有意义)如果指针变量p已指向数组中的一个元素p+1指向同一数组中的下一个元素;p-1指向同一数组中的上一个元素。如果p的初值为&a[0],则p+i 和 a+i 就是数组元素a[i]的地址,或者说,它们指向a数组序号为i的元素。例如#include <stdio.h> void main() { int a[5] = {1,2,3,4,5}; int *a1 = &a[0]; // 或者 int *a1 = a printf("%d, %d\n", *a1, a1); a1 = a1 + 2; printf("%d, %d\n",*a1, a1); }当p指向a数组首元素时,数组元素 a[i] 的地址表达式有以下四种: &a[i] a + i p + i &p[i] 当p指向a数组首元素时,数组元素 a[i] 的值表达式有以下四种: a[i] *(a + i) *(p + i) p[i] a 和 p 是有本质的区别:a 是指针常量,其值不可变;p 是指针变量,其值可变。所以,a++、a = p 等都是非法表达式;而 p++、p = a都是合法的表达式。如果 指针p1 和 p2 都指向同一数组p2 - p1 用来计算 p2所指的元素 与 p1所指的元素 之间有多少个元素。两个指针变量相减 的含义是 两个地址之差 除以 每个数组元素所占的字节数。例子#include <stdio.h> void main() { int a[10] = {1,2,3,4,5,6,7,8,9,10}; int *p1 = &a[0]; int *p2 = &a[6]; printf("p1的地址:%d\n",p1); printf("p2的地址:%d\n",p2); printf("%d\n", p2 - p1); printf("%d\n",*p2 - *p1); // int 为4个字节 }*++p,等价于 *(++p),先使 p+1 即指向下一个数组元素,再取 *p 作为此表达式的值。*p++,等价于 *(p++),取 p 作为此 表达式的值,再使 p+1。(*p)++,先取 p 所指向的 元素值 作为 此表达式的值,再将 该元素值加1。++(*p),将 p 所指向的 元素值加1 作为 此表达式的值。#include <stdio.h> void main() { int a[10] = {1,2,3,4,5,6,7,8,9,10}; int *p = &a[0]; printf("%d\n",*p); printf("%d\n",*++p); printf("%d\n",*p++); printf("%d\n",(*p)++); printf("%d\n",++(*p)); }通过指针引用数组元素引用一个数组元素,可用下面两种方法:1.下标法,例如:a[i]2.指针法,例如:*(a+i) 或 *(p+i) 其中a是数组名,p 是指向数组元素的指针变量,其初值 p = a例子有一个整型数组a,有10个元素,要求输出数组中的全部元素。#include <stdio.h> void main() { int a[10] = {1,2,3,4,5,6,7,8,9,10}; int *p; // 下标法 for (int i = 0; i < 10; i++) { printf("%d ", a[i]); } printf("\n"); // 通过数组名计算数组元素地址 for (int i = 0; i < 10; i++) { printf("%d ", *(a+i)); } printf("\n"); // 指针法 for (p=a; p <a+10; p++) { printf("%d ", *p); } printf("\n"); }3种方法的比较:第(1)和第(2)种方法执行效率相同C编译系统是将 a[i] 转换为 *(a+i)处理的,即先计算元素地址。因此用第(1)和第(2)种方法找数组元素费时较多。第(3)种方法比第(1)、第(2)种方法快用指针变量直接指向元素,不必每次都重新计算地址。这种有规律地改变地址值 例如 p++ 能大大提高执行效率。用下标法比较直观,能直接知道是第几个元素。用地址法或指针变量的方法不直观,难以很快地判断出当前处理的是哪一个元素。
2022年02月17日
297 阅读
0 评论
0 点赞
1
2
3
...
7