首页
动态
归档
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
留言
工具箱
邻居
壁纸
音乐
搜索到
39
篇与
的结果
2022-02-24
C语言链表-学习二十九
链表的概念结构体数组:静态分配存储单元,容易造成内存浪费。链表:是重要的数据结构,它根据需要,动态分配内存单元。特征:头指针变量,存放链表首地址,链表中每个元素称结点。其内容:数据域:可有若干项(整、实、字符、结构体类型等)指针域:下一结点的地址,最后一个结点(表尾)的地址部分为NULL。链表存储数据的空间可以是不连续的,因此对空间的要求和应比较低。链表中结点的空间是在程序执行过程中根据需要随时向系统申请开辟的内存单元,不用时可以随时释放结点所占用的空间。动态分配与数组不同,它不存在空间浪费的问题。例如:void *malloc(unsigned int size)作用:在内存的动态存储区分配一个长度为size的连续空间。void *calloc(unsigned n,unsigned size);作用:在内存动态区分配n个长度为size的连续空间,函数返回指向分配起始地址的指针; 若分配不成功,返回NULL值。void free(void *p)作用:释放由p指向的动态存储区结点之间是通过指针建立先后顺序。链表的插入、删除等操作只要改变个别结点地址部分的指向即可,无需移动大量的数据。对链表的操作必须从头指针开始,然后逐个结点进行访问。链表的声明struct Student { // 结点的数据域 int no; char name[20]; float score; // 结点的指针域 类型是自身结构体类型 struct Student *next; };next是成员名,是指针类型,它指向struct Student数据类型。静态链表在C语言中,静态链表的表现形式为结构体数组,是在程序中定义,不是临时开辟的,也不能用完后释放,每个数组元素包含数据域(data)和指针域(next)。例如#include <stdio.h> struct Student { // 结点的数据域 int no; char name[20]; float score; // 结点的指针域 类型是自身结构体类型 struct Student *next; }; void main() { struct Student head, *p; struct Student stu1 = {10001,"Zhang Yin", 100}; struct Student stu2 = {10002,"Qian Feng", 90}; struct Student stu3 = {10003,"Liu Liang", 91}; head.next = &stu1; // 将stu2的起始地址赋给stu1的next成员 stu1.next = &stu2; stu2.next = &stu3; stu3.next = NULL; for (p = head.next; p!= NULL; p = p->next) { printf("%d\t%s\t%.2f\n",p->no,p->name,p->score); } }动态链表建立链表建立链表是指从无到有的形成一个链表。建立链表的思想就是逐个输入各结点的数据,同时建立结点之间的关系。建立链表的算法概念先开辟一个结点的空间作为头结点,并让头指针指向头结点;然后开辟第一个数据结点,并输入结点数据,将第一结点“挂”在头结点之后;接着开辟第二个数据结点,并输入结点数据,将第二个结点“挂”在第一个结点之后...即按照输入顺序特结点“挂”在一起,形成链表。例子建立一个带有头结点的学生链表,直到输入的学生学号小于等于0时结束。#include <stdio.h> #include <string.h> struct Student { int no; char name[20]; unsigned sex; struct Student *next; }; void main() { void setdata(struct Student *temp); struct Student *creatlink(); void printlink(struct Student *head); struct Student *head; head = creatlink(); printlink(head); } void setdata(struct Student *temp) { printf("No:"); scanf_s("%d", &temp->no); getchar(); printf("Name:"); gets(temp->name); printf("Sex(1:boy;0:girl):"); scanf_s("%d", &temp->sex); } struct Student *creatlink() { int i = 0; struct Student *head, *p, *q; head = (struct Student *)malloc(sizeof(struct Student)); head -> next = NULL; p = head; q = (struct Student *)malloc(sizeof(struct Student)); printf("请输入学生信息:\n"); setdata(q); while ((q->no) > 0) { p->next = q; p = q; q = (struct Student *)malloc(sizeof(struct Student)); printf("请输入学生信息:\n"); setdata(q); } p->next = NULL; return head; } void printlink(struct Student *head) { struct Student *p; printf("-学生信息-\n"); for (p = head->next; p != NULL; p = p->next) { printf("%d\t%s\t%d\n", p->no, p->name, p->sex); } }对链表的删除操作并不真从内存中抹掉,只是把它分离,再前后结点相链接。思路:本例以学号作为删除结点的标志(查找对象)设两个指针变量p1和p2。从head开始,p1依次指向各结点查找num值是否等于要删除结点的学号。每次下移前使p2=p1。学号相等删除该结点,直至查到表尾。struct Student *del(struct Student *head, int no) { struct Student *p1, *p2; if (head == NULL) { printf("\n 链表为空! \n"); return head; } p1 = head; p2 = NULL; while (no != p1->no && p1->next != NULL) { p2 = p1; p1 = p1->next; } if (no == p1->no) { if (p1 == head) { head = p1->next; } else { p2->next = p1->next; } printf("已删除:%d\n", no); } else{ printf("\n没有找到要删除的对象:%d\n", no); } return(head); } 对链表的插入操作思路:找到插入点后,将该点的next值指向新结点,并使新结点的next值等于断点后面结点的首地址。struct Student *insert(struct Student *head, struct Student *stud) { struct Student *p0, *p1, *p2; p1 = head; // 使p1指向第一个结点 p0 = stud; // p0指向要插入的结点 p2 = NULL; if (head == NULL) { // 原来的链表是空表 head = p0; p0 -> next = NULL; // 使p0指向的结点 } else { while ((p0->no > p1->no) && (p1->next != NULL)) { p2 = p1; // 使p2指向刚才p1指向的结点 p1 = p1->next; // p1后移一个结点 } if (p0->no <= p1->no) { if (head == p1) { head = p0; //插到原来第一个结点之前 } else { p2->next = p0; // 插到p2指向的结点之后 } p0->next = p1; } else { p1->next = p0; // 插到最后一个结点之后 p0->next = NULL; } return(head); } }综合例子#include <stdio.h> #include <string.h> struct Student { int no; char name[20]; unsigned sex; struct Student *next; }; void main() { void setdata(struct Student *temp); struct Student *creatlink(); void printlink(struct Student *head); struct Student *del(struct Student *head, int no); struct Student *insert(struct Student *head, struct Student *stud); struct Student *head, *stu; int num; head = creatlink(); printlink(head); printf("请输入要删除的学号:"); scanf_s("%d", &num); while (num != 0) { // 为0退出删除 head = del(head, num); printlink(head); printf("请输入要删除的学号:"); scanf_s("%d", &num); } printf("请输入要插入的信息:\n"); stu = (struct Student *)malloc(sizeof(struct Student)); setdata(stu); while (stu->no != 0) { head = insert(head, stu); printlink(head); printf("请输入要插入的信息:\n"); stu = (struct Student *)malloc(sizeof(struct Student)); setdata(stu); } } void setdata(struct Student *temp) { printf("No:"); scanf_s("%d", &temp->no); getchar(); printf("Name:"); gets(temp->name); printf("Sex(1:boy;0:girl):"); scanf_s("%d", &temp->sex); } struct Student *creatlink() { int i = 0; struct Student *head, *p, *q; head = (struct Student *)malloc(sizeof(struct Student)); head -> next = NULL; p = head; q = (struct Student *)malloc(sizeof(struct Student)); printf("请输入学生信息:\n"); setdata(q); while ((q->no) > 0) { p->next = q; p = q; q = (struct Student *)malloc(sizeof(struct Student)); printf("请输入学生信息:\n"); setdata(q); } p->next = NULL; return head; } void printlink(struct Student *head) { struct Student *p; printf("-学生信息-\n"); for (p = head->next; p != NULL; p = p->next) { printf("%d\t%s\t%d\n", p->no, p->name, p->sex); } } struct Student *del(struct Student *head, int no) { struct Student *p1, *p2; if (head == NULL) { printf("\n 链表为空! \n"); return head; } p1 = head; p2 = NULL; while (no != p1->no && p1->next != NULL) { p2 = p1; p1 = p1->next; } if (no == p1->no) { if (p1 == head) { head = p1->next; } else { p2->next = p1->next; } printf("已删除:%d\n", no); } else{ printf("\n没有找到要删除的对象:%d\n", no); } return(head); } struct Student *insert(struct Student *head, struct Student *stud) { struct Student *p0, *p1, *p2; p1 = head; // 使p1指向第一个结点 p0 = stud; // p0指向要插入的结点 p2 = NULL; if (head == NULL) { // 原来的链表是空表 head = p0; p0 -> next = NULL; // 使p0指向的结点 } else { while ((p0->no > p1->no) && (p1->next != NULL)) { p2 = p1; // 使p2指向刚才p1指向的结点 p1 = p1->next; // p1后移一个结点 } if (p0->no <= p1->no) { if (head == p1) { head = p0; //插到原来第一个结点之前 } else { p2->next = p0; // 插到p2指向的结点之后 } p0->next = p1; } else { p1->next = p0; // 插到最后一个结点之后 p0->next = NULL; } return(head); } }
2022年02月24日
409 阅读
0 评论
0 点赞
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 点赞
1
2
3
4
...
8