后台组贾浩琛周报(2020.11.23-11.29)

学习内容简要
C语言进度

结构体与指针
浅尝链表

洛谷题目完成度:

1.在刷题时学到的知识点

1.正则表达式
2.qsort函数
3.scanf函数的相关知识

2.对于上周内容的补充

1.tytpedef语句的相关知识
2.带参数的宏
3.指针与结构体

3.浅尝链表

4.洛谷部分题目题解和代码

一,在刷题时学到的知识点
1.正则表达式

使用正则表达式来匹配一段文本中的特定种类字符,是比较常用的一种方式

1.英文字母:[a-zA-Z]
2.数字:[0-9]
3.由数字、26个英文字母或者下划线组成的字符串^\w+$
4.
[A-Z a-z]+ 匹 配 由 26 个 英 文 字 母 组 成 的 字 符 串 [ A − Z ] + 匹配由26个英文字母组成的字符串 [A-Z]+ 26[AZ]+匹配由26个英文字母的大写组成的字符串
[a-z]+$匹配由26个英文字母的小写组成的字符串

2.qsort函数

qsort函数(全称quicksort)。它是ANSI C标准中提供的,其声明在stdlib.h文件中,是根据二分法写的,其时间复杂度为n*log(n)

功能: 使用快速排序例程进行排序
头文件:stdlib.h
用法:void qsort(void* base,size_t num,size_t width,int(__cdeclcompare)(const void,const void*));
参数:
1 待排序数组,排序之后的结果仍放在这个数组中
2 数组中待排序元素数量
3 各元素的占用空间大小(单位为字节)
4 指向函数的指针,用于确定排序的顺序(需要用户自定义一个比较函数)

1.qsort要求提供一个自己定义的比较函数。比较函数使得qsort通用性更好,有了比较函数qsort可以实现对数组、字符串、结构体等结构进行升序或降序排序。
2.如比较函数 int cmp(const void *a, const void *b) 中有两个元素作为参数(参数的格式不能变),返回一个int值,比较函数cmp的作用就是给qsort指明元素的大小是怎么比较的。

3.scanf函数

1.功能:接受用户从键盘中键入的数据,并按照格式控制符的要求进行类型转换,再送到地址表列中对应的变量存储单元。

2.一般形式:scanf(“输入格式串”,输入项地址表列);

3.返回类型:scanf函数返回成功读入的数据项数,读入数据时出现错误或者遇到了“文件结束”则返回EOF。

4.输入格式串:

格式串含义
%dint
%ldlong int
%mdm为指定的输出字段的宽度
%.ndn为指定的输出实数的小数位
%ffloat
%lfdouble
%o八进制int
%x十六进制int
%uunsigned-无符号整型
%lulong unsigned-无符号整型
%e以指数形式输出实数
%g根据数值的大小,自动选f格式或e格式输出实数
%cchar-一个字符
%sstring-一个字符串
%ppointer-指针的值-十六进制整形,相当于0x%x,常用在变量地址的输出
%[scanfset]功能见下方

5.scanf函数输入详解:
(1)用scanf函数输入字符串,以及scanf和gets函数的区别:
①char string[];scanf(“%s”,string);//输入字符串到字符数组,遇到回车键,Tab,空格输入结束。
②char string[];gets(string);//可以接收空格,tab,遇到回车键结束。
(2)scanfset 有两种形式:
①scanf(“%[bulabula~]”,str);//一种是以非 “^” 字符开头的 scanset , 表示在读入字符串时将匹配所有在 scanfset 中出现的字符,遇到非scanfset 中的字符时输入就结束;
②scanf(“%[^bulabula~]”,str);//另外一种形式是以 “^” 字符开头的scanfset ,表示在读入字符串时将匹配所有不在scanfset 中出现的字符,遇到scanfset 中的字符输入就结束。
比如:scanf(“%[^\n]”,str);//表示遇到回车键时字符串输入结束,可接收空格等特殊字符。

scanf函数在输入过程中如遇格式错误会立即停止输入。

二,对于上周内容的补充
1.对typedef语句内容的补充

typedef struct student STUDENT

可以如下定义

typedef struct student
{
	int id;
	char name[20];
	char score[3];
	float aver;
}STUDENT,*STU;typedef struct
{
	...
}STUDENT,*STU;

typedef语句和宏的区别
例如:

#define INTEGER int*
typedef int* INTEGER;
INTEGER a,b;

在此例中,宏定义和类型定义有着本质的区别:
宏定义可以理解为“int *a,b;”
类型定义可以理解为“int *a,int *b;”
宏定义句尾没有分号,若有分号,则分号也作为字符串的一部分被替换到程序中;而类型定义后面是有分号的。

2.带参数的宏
(1)像函数的宏
例如#define cube(x) ((x)*(x)*(x))
(2)带参数的宏的原则

1.一切都要带括号
2.整个值要括号
3.参数出现的每个地方都要括号

示例:

错误定义的宏

#define  RADTOREG(x)  (x*57.29578)
#define  RADTOREG(x)  (x)*57.25978

正确定义的宏

#define RADTOREG(x)  ((x)*57.29578)

在这里插入图片描述

宏可以带多个参数,例如:

#define MIN(a,b)  ((a)>(b)?(b):(a))

允许宏嵌套
带参数的宏在大型程序代码中使用普遍;可以非常复杂,如“产生”函数(在#和##的帮助下);
部分宏会被inline函数替代

3.指针与结构体
必须先定义结构体类型,再定义指向结构体类型数据的指针变量,在引用指针变量前,必须将已存在的结构体变量的地址赋给它,此时该地址变量的值即为该结构体变量的初始地址。例如

typedef struct student
{
	int id;
	char name[20];
	int score;
}STUDENT,*STU;
STUDENT s,*p=&s;

结构体变量的引用有如下三种方法

1.结构体变量名.成员名
2.(*结构体指针变量名).成员名
3.结构体指针变量名->成员名

这样,可以使用以下三种方法访问结构体成员。在“p=&s;”的情况下它们是等价的

(1) s.name:使用结构体变量s访问结构体成员name
(2) (*p).name:使用结构体变量指针p访问结构体成员name
(3) p->name:使用结构体指针变量p访问结构体成员name

说明

(1)在(*p).name访问中,p两侧应加上小括号,因为.的优先级比的优先级高
(2)->由一个减号和一个大于号构成,含义是“指向结构体的”,称为指向成员运算符或指向分量运算符
指针变量也可以用来指向结构体数组中的元素,改变指针变量的值就可以通过它访问结构体数组中的各元素。

有如下程序示例

#include<stdio.h>
#include<stdlib.h>
typedef struct student//结构体类型的定义
{
    int id;
    char name[20];
    int score;
}STUDENT,*STU;
main()
{
	STUDENT st[3]={{10101,"li lin",98},{10102,"zhang fen",87},{10103,"wang min",79}};//结构体数组初始化
    STUDENT *p;//*STU p;也可定义结构体类型指针变量p*
    for(p=st;p<st+3;p++)//将指针p作为循环控制条件
        printf("%-6d%s\t%d\n",p->id,p->name,p->score);
    system("pause");
}

运行结果
在这里插入图片描述
在使用结构体指针时,应注意各种运算符的优先级和结合方向。其中,运算符->,.,(),[]的优先级最高。因此,一下语句的含义是:

(1) p->n++:引用p指向结构体变量中成员n的值,然后n自增。
(2) (p++)->n:引用p指向的结构体变量中成员n的值,然后p自增。
(3) ++p->n:使p指向的结构体变量中成员n的值先自增,再引用n的值。
(4) (++p)->n:使p的值自增,再引用p指向的结构体变量中成员n的值。

用指向结构体的指针做函数参数

三,浅尝链表

1.存储空间的分配和使用
c语言标准函数库提供了四个函数,用来实现内存的动态分配与释放

malloc()
calloc()
realloc()
free()

前三个用于动态存储分配,第四个涉及动态存储释放,最常用的是malloc函数和free函数。
这四个函数的原型说明在stdlib.h头文件和alloc.h头文件中。

(1).函数malloc()–动态分布一段内存空间
malloc()函数的原型是void *malloc(unsigned int size);

其功能是在内存的动态存储区中申请一个长度为size字节的连续存储空。malloc函数会返回一个指针并指向所分配存储空间的起始地址。如果没有足够的内存空间可分配,则会返回空指针NULL。

说明:函数值为指针类型,由于基类型是void,因此如果要把这个指针值赋给其他类型指针变量,应进行相应的强制类型转换。
malloc函数的参数中 经常使用C语言提供的运算符sizeof(),通过它来计算申请空间的大小。不同机器中同一类型所占字节可能不同,所以用sizeof可以使程序适应不同的机器,便于程序的移植。例如:

int *p=(int *)malloc(sizeof(int));

申请一个int型长度的存储空间,并将其分配到的存储空间地址转化为int 类型地址,再赋给所定义的指针变量p,基类型字节数为int型所占的空间为2或4(因机器而异)。再例如:

struct stud *p=(struct stud*)malloc(sizeof(struct stud));

申请可存放struct stud结构体类型数据的空间,并将其地址存入指针p中,当struct stud结构体类型的定义改变时,申请空间的大小也会随之而变,程序的适应性增强。

下面是一个使用malloc函数动态分配空间的示例

#include<stdio.h>
#include<stdlib.h>
void main()
{
	int *pi=(int *)malloc(sizeof(int));//分配空间
	*pi=100;//使用该空间保存数据
	printf("%d\n",*pi);//输出数据
}

在该程序中,使用malloc函数分配了内存空间,通过指向该内存空间的指针,使用该空间保存数据,最后显示该数据,表示保存数据成功。程序的运行结果为100。

(2).函数calloc()–动态分配连续内存空间
calloc()函数的原型是void*calloc(unsigned int n,unsigned int size);

其功能是在内存内申请n个长度为size字节的存储空间,并返回该存储空间的起始地址。如果没有足够的内存空间可分配,则函数返回值为空指针NULL。该函数主要用于动态数组申请存储空间,n为元素的个数,size为元素存储长度。例如:

int  *p=(int *)calloc(10,sizeof(int));

该语句的含义为申请10个int类型长度的存储空间,并将分配到的存储空间地址转换为int类型地址,并将其首地址赋给所定义的指针变量p。此后就可以将p作为10个元素的整型数组来使用,此数组没有数组名,只能用指针变量p来访问。该语句的功能也可以用malloc()函数来实现:int *p=(int *)malloc(sizeof(int *10));

下面是一个用calloc分配数组内存的例子

#include<stdio.h>
#include<stdlib.h>
void main()
{
	int i;//循环变量i
    char *ch1=(char*)malloc(26*sizeof(char));//使用malloc动态分配一个长度为26字符的字符数组
    char *ch2=(char*)calloc(26,sizeof(char));//使用calloc动态分布一个长度为26字符的字符数组
    for(0;i<26;i++)//为两个字符数组赋值
    {
        ch1[i]=65+i;//ch1是大写字符数组
        ch2[i]=97+1;//ch2是小写字符数组
    }
    
    for(i=0;i<26;i++)
    {
        printf("%c",ch1[i]);
        printf("\n");
    }
    
    for(i=0;i<26;i++)
    {
        printf("%c",ch2[i]);
        printf("\n");
    }
    system("pause");
}

(3).函数realloc()–改变指针指向空间的大小
realloc函数的原型为void *realloc(void *ptr,size_t size);
其功能是改变ptr指针指向大小为size的空间。设定size的大小可以是任意的,也就是说可以比原来的数值大,也可以比原来的数值小。返回值是一个指向新地址的指针,如果出现错误,则返回NULL。例如,改变一个浮点型空间大小为整型大小,代码如下:

double *p=(double *)malloc(sizeof(double));
int *q=realloc(p,sizeof(int));

其中,p是指向分配的浮点型空间,然后使用realloc函数改变p指向空间的大小,其大小设置为整形,然后将改变后的内存空间的地址返回赋值给q指针。如下代码使用realloc函数重新分配内存。

#include<stdio.h>
#include<stdlib.h>
void main()
{
    int *q;
    double *p=(double*)malloc(sizeof(double));//申请double类型变量所占内存空间
    printf("%p\n",p);//打印首地址
    printf("%d",sizeof(*p));//打印空间大小
    q=realloc(p,sizeof(int));//重新分配内存
    printf("%p\n",q);//打印首地址
    printf("%d",sizeof(*q));//打印空间大小
}

说明

%p格式输出的是指针本身的值,也就是指针指向的地址值。该输出为16进制形式,具体输出值取决于指针指向的实际地址值。

该程序运行结果为
在这里插入图片描述
(4).free()–释放存储空间
free()函数原型为void free (void *p)

其功能是将指针变量p指向的存储空间释放,交还给系统。无返回值。

说明:
p只能是程序中此前最后一次调用malloc或者calloc函数所返回的地址。

例如:

int *p,*q=(int *)malloc(10*sizeof(int));
p=q;
q++;
free(p);//将p指向的,此前调用malloc函数申请的存储地址释放

如果改用free(q)则会报错,因为执行q++后,q已经改变。

以下代码为使用free函数释放内存空间的示例

#include<stdio.h>
#include<stdlib.h>
void main()
{
    int *p;
    p=(int *)malloc(sizeof(int));
    *p=100;
    printf("%d\n",*p);
    free(p);
    printf("%d\n",*p);
    system("pause");
}

运行结果为
在这里插入图片描述

2.链式存储结构----链表
定义:链表是一种采用动态存储分配方式的数据结构。使用动态数组存放数据时可以根据实际元素个数动态调整数组大小,但分配的存储空间必须是连续的,并且在插入或者删除等操作过程中涉及到大量元素的移动。
在这里插入图片描述
在链表中,有一个头指针变量(图9.1中的head),用这个指针变量保存一个地址。从图中箭头可知,该地址为一个变量的地址,也就是说头指针指向一个变量,这个变量称为元素。在链表中,每个元素包括两部分:数据部分和指针部分。数据部分用来存放元素所包含的数据,指针部分用来指向下一个元素。最后一个元素的指针指向NULL,表示指向的地址为空。
在链表中,第一个节点前虚加一个头节点,头指针指向头节点,头结点的指针指向第一个实际有效节点,该节点称为首元节点。头节点的数据域可以不使用。对带头结点的链表,空表还保留着头节点。带头结点的链表比不带头节点的链表在创建,插入和删除等操作时代码更简洁。

(1).动态链表:链表中节点的分配和回收都是动态的
(2).静态链表:把线性表的元素存放在数组中,且每个元素除了存放数据信息外,还要存放下一个元素的位置,即下一个元素所在的数组单元的下标。静态链表虽然是采用数组实现的,但这些元素在物理上可能是连续存放的,也可能不是连续的,它们之间通过逻辑关系来连接。

静态链表的结构定义如下:

#define Maxsize 10
typedef int Datatype;
typedef struct SNode
{
	Datatype data;
	int next;//游标cursor
}Snode,StaticList[Maxsize+1];

在这里插入图片描述
3.单链表

如果在链表中,每个结点只有一个指针,所有结点都单线连接,除了末尾指结点指针为空外,每个结点都指向下一个结点,一环扣一环形成一条线性链,称此链表为单向线性链表或简称单链表。

单链表的特点:

(1).有一个head指针变量,它存放头结点的地址,称之为头指针
(2).头结点的指针域head->next,存放首元结点的地址
(3).每个结点都包含一个数据域和一个指针域,数据域存放用户需要的实际数据,指针域存放着下一个结点的地址。从头指针head开始,head指向头结点,头结点指向首元节点,首元节点指向第二个结点,…,直到最后一个结点。所有结点都是单线联系环环相扣。
(4).最后一个结点不再指向其他结点,称为“表尾结点”,其指针域为空指针“NULL”,表示链表到此结束。指向表尾结点的指针称为尾指针。
(5).链表各结点之间的顺序关系由指针next来确定,并不要求逻辑上相邻的结点在物理上也相邻,也就是说,链表依靠指针相连并不需要占用一片连续的内存空间。
(6).随着处理数据量的增加,链表可以不受程序中变量定义的限制无限的延长(仅受内存总量的限制)。在插入和删除操作中,只需修改相关结点指针域的链接关系,不需要像数组那样大量地改变数据的实际存储位置。链表的使用,使程序的内存利用率和时间效率大大提高。

(1)单链表的初始化

由于链表的每个结点都包含数据域和指针域,即每个结点都要包含不同类型的数据,所以结点的数据类型必须选用结构体类型。该类型可以包括多个类型成员,必须有一个成员的类型是指向本结构体类型的指针类型。对于这种结构体类型,允许递归定义。

例如,创建一个链表表示一个班级,结点表示学生,它的结点结构体类型定义如下:

typedef struct node
{
	char name[20];
	int number;
	struct node *next;//next的类型是指向本结构体类型的指针类型
}Node,*LinkList;

其中,Node是结构体类型,LinkList是结构体指针类型。LinkList head 相当于Node *head,也相当于struct node *head。
单链表的初始化就是创建一个头结点,头结点的数据域可以不使用,头结点的指针域为空,表示空单链表,如图
在这里插入图片描述
单链表初始化代码如下:

LinkList InitList()
{
	LinkList head;//定义头指针变量
	head=(Node *)malloc(sizeof(Node));//头指针指向分配的头结点内存空间
	head->next=NULL;//头结点的指针域为空
	return head;//返回头结点的地址,即头指针
}

(2)单链表的建立

热门文章

编程学习 ·

mysql8 windows版密码忘记如何重新设置?

本机安装位置:D:\Program Files (x86)\java\mysql-8.0.13-winx64重设密码具体过程:还好有一个navicat的连接可以打开,查看其中的用户名和主机名称(一般默认是这个,改了又忘了的话我也没办法了)打开cmd,用管理员的身份运行,先关闭mysql(net stop mysql);然后进入mysql8所…
编程学习 ·

使用pip离线安装python扩展包依赖模块

简答来说就是从一台有网的主机下载好,放到离线主机上,用pip实现1.查看安装了哪些pip3 freeze网上一般都是pip3 freeze >requirements.txt 这就是查看安装了那些,然后存到文件里面2.就是把安装好的打包了,上面那个文件存的就是要打包的,我们完全可以直接,在里面写好想…
编程学习 ·

Linux 练习 - 文本处理三剑客之AWK

1、文件 ip_list.txt 如下格式,请提取 ”.solin.com” 前面的主机名部分并写入到回到该文件中 1 blog.solin.com 2 www.solin.com … 999 study.solin.com [root@centos7 ~]# awk -F "[ .]" {print $2} ip_list.txt >> ip_list.txt2、统计 /etc/fstab 文件中每…
编程学习 ·

CnPlugin是PL/SQL Developer工具插件使用

CnPlugin是PL/SQL Developer工具插件,支持PL/SQL Developer 7.0以上版本。1、安装2、拷贝文件安装结束后,得到一个 CnPlugin.dll 和 “CnPlugin”的文件夹,把这两个拷贝到 PL/SQL Developer的安装路径下的 “PlugIns”目录下,重启PL/SQL Develop可以使用了,打开的时候 会在…
编程学习 ·

OpenCV的初步解读

OpenCV的初步解读图像读取:cv2.imread(path,flag)`` flag:如何读取图片:cv2.IMREAD_COLOR:读取彩色图像。图像的透明度会被忽略(默认参数)。 cv2.IMREAD_GRAYSCALE:读取灰度图像。 flag=-1, 8位深度,原通道 flag=0, 8位深度 1通道 flag=1, 8位…
编程学习 ·

Spring——Bean scope

Spring framework 支持6个范围(scope),其中4个只能在用web-aware时才能使用。当然,你也可以创建自定义范围。singleton : spring默认就是singleton,即在注册该bean的时候,会把这个bean存储到单列bean缓存,以后对该bean的所有的后续请求和引用都会返回缓存中的这一个bean…
编程学习 ·

个推图可视化应用实践

个推资深前端开发专家 东风图可视化应用是数据可视化的一个重要组成部分。图指的是知识图谱(Knowledge Graph),此概念于2012年由Google正式提出,旨在帮助Google优化搜索引擎返回的结果,提升用户搜索质量及体验。个推作为专业的数据智能服务商,在图可视化应用方面也进行了…
编程学习 ·

Less 基础

1. 维护CSS的弊端 CSS是一门非程序式语言,没有变量、函数、SCOPE(作用域)等概念。CSS需要书写大量看似没有逻辑的代码,CSS冗余度是比较高的。 不方便维护及扩展,不利于复用。 CSS没有很好的计算能力 非前端开发工程师来讲,往往会因为缺少CSS编写经验而很难写出组织良好且易…
编程学习 ·

电商新手做亚马逊要怎样开始?

"说到互联网创业,很多人的第一个想到的是淘宝,但是很多人并不清楚,经过十几年的发展淘宝已经很难再进入了,利润也是下降到了最低,很多的卖家都在寻找机会做转型,而你一个毫无经验的小白现在进入,基本可以说很难生存,近年来,我国的跨境电子商务进入迅猛的发展阶段,…
编程学习 ·

线程池:ThreadPoolExecutor

github地址: https://github.com/lishanglei/thread-pool.git 源码 public ThreadPoolExecutor(int corePoolSize, //核心线程数int maximumPoolSize,//最大线程数量long keepAliveTime, //线程存活时间TimeUnit unit, //线程存活时间单位 BlockingQueue<Runnable> w…
编程学习 ·

IIs7上传文件大小光设置web.config还不行

打开你系统盘(我是C盘),找到 C:\Windows\System32\inetsrv\config\schema目录,该目录下有一个IIS_schema.xml修改这个:<attribute name="maxAllowedContentLength" type="uint" defaultValue="30000000" />"单位byte
编程学习 ·

spring+mybatis日志

spring4默认日志是log4j, spring5默认日志是JUL spring4下使用JCL时,如果有log4j的jar,用的具体实现类是log4j,否则用的具体实现类是JUL spring4下使用JCL时,用的具体实现类是JUL1、spring4下日志加载顺序//循环for(int i=0; i<classesToDiscover.length && resu…
编程学习 ·

CDH Hue连接Hbase报错

问题描述 安装好CDH集群后,在Hue中查看HBase信息时,Hue界面报错如下: Api 错误:TSocket read 0 bytesHue日志报错: exceptions_renderable ERROR Potential trace: [(/opt/cloudera/parcels/CDH-6.3.2-1.cdh6.3.2.p0.1605554/lib/hue/apps/hbase/src/hbase/api.py, 46,…
编程学习 ·

mPaaS 插件正式上架 Jetbrains Market Place

今天 mPaaS 插件终于正式上架 Jetbrains Market Place 啦!!!它从一个简单的集成工具开始慢慢变成了围绕 mPaaS SDK 为核心的周边生态。越来越自信地开始以「产品」的形式展现在开发者面前。下载链接:https://plugins.jetbrains.com/plugin/14486-mpaasmPaaS for Android St…
编程学习 ·

UGUI获取自适应UI元素的宽高

对于使用了layout的布局元素来说,并不能直接通过rectTransfrom来获取搞元素的weight和height 不过Unity中有对应API可以帮助我们获取 通过LayoutUtility中的静态方法我们可以获取对应的一些信息 GetFlexibleHeight 返回布局元素的灵活高度。GetFlexibleSize 返回布局元素的灵活…
编程学习 ·

SwiftUI 2020年WWDC演示示例

整体效果代码实现 文件目录SandwichesApp.swift import SwiftUI@main struct SandwichesApp: App {// 定义一个私有的状态对象 store@StateObject private var store = SandwichStore()var body: some Scene {WindowGroup {// 将store传递给列表页ContentView(store: store)}} …
编程学习 ·

【牛客网】写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。

题目 写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。 需要掌握 1、异或运算 两个数不相同,结果为1。两个数相同,结果为0。 2、与运算 两位同时为“1”,结果才为“1”,否则为0 3、左移 将一个二进制操作数对象按指定的移动位数向左移,左边溢…