数据结构学习
动态数组
堆空间示意图
根据示意图,我们知道如果需要在堆空间开辟三类空间存储数据,一个是管理动态数组的结构体,一个是指针数组本身,一个是每个数组元素本身。如果只是测试,那么数组元素指针对应的数据,可以存在栈空间中,不用开辟堆空间进行存储。
一个文件中实现(C99标准编译)
包含对数组的遍历,增加,删除,查找,扩容
//#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//动态数组的结构体
struct dynamicArray{
void **pAddr; //维护在堆区真实数组指针
int m_capacity; //数组容量
int m_size; //数组元素的个数
};
struct Person{
char name[64];
int age;
};
//初始化数组,并返回动态数组的头指针
// 指针函数,返回一个结构体
struct dynamicArray *init_DynamicArray(int capacity){
if (capacity<=0)
{
return NULL;
}
struct dynamicArray *array =(struct dynamicArray*)malloc(sizeof(struct dynamicArray)); //指针类型转换
//判断内存是否申请成功
if (array==NULL)
{
return NULL;
}
//设置容量
array->m_capacity=capacity;
//设置大小
array->m_size=0;
//维护在堆区数组的指针 (在堆空间设置了一个m_capacity大小的空间,让pAddr指向它)
array->pAddr = (void **)malloc(sizeof(void*)*array->m_capacity);
return array;
}
//插入功能(void * data :待插入的元素)
void insert_dynamicArray(struct dynamicArray *array,int pos,void * data){
if (array==NULL)
{
return;
}
if (data==NULL)
{
return;
}
if (pos<0 || pos>array->m_size)
{
//无效的位置,进行尾插
pos=array->m_size;
}
//先判断是否已经满载,如果满载,动态开辟
if (array->m_size==array->m_capacity)
{
//申请一个更大的空间
int newCapacity = array->m_capacity*2;
//创建新的空间
void ** newSpace =(void **)malloc(sizeof(void*)*newCapacity);
//将原有的数据拷贝到新的空间下
memcpy(newSpace,array->pAddr,sizeof(void*)*array->m_capacity);
//释放原有的空间
free(array->pAddr);
//更改指针的指向
array->pAddr=newSpace;
//更新容量的大小
array->m_capacity=newCapacity;
}
//插入新的元素
//从最后一个位置开始,依次移动数据,后移
//int i;
for (int i=array->m_size-1;i>=pos;i--)
{
array->pAddr[i+1]=array->pAddr[i];
}
//将新元素插入到指定的位置
array->pAddr[pos]=data;
//更新目前数组的大小
array->m_size++;
}
//删除数组中的元素
void remove_DynamicArrayById(struct dynamicArray *array,int pos){
if (array==NULL)
{
return;
}
if (pos<0 || pos > (array->m_size-1))
{
//无效的位置,直接return
return;
}
//从pos位置开始,到数组尾部,数据进行前移,逻辑上删除
for (int i = pos; i < array->m_size-1; i++)
{
array->pAddr[i]=array->pAddr[i+1];
}
array->m_size--;
}
//删除数组中的元素,通过值
void remove_DynamicArrayByValue(struct dynamicArray *array,void * data,int(*myCompare)(void *,void *)){
if (array==NULL)
{
return;
}
if (data==NULL)
{
return;
}
for (int i = 0; i < array->m_size; i++)
{
//(array->pAddr[i])->name==data->name 因为两个指针没法比较,我们需要比较值,就让用户自己传入函数比较
if (myCompare(array->pAddr[i],data))
{
remove_DynamicArrayById(array,i);
break;
}
}
}
//销毁数组
void destroy_DynamicArray(struct dynamicArray *array){
if (array==NULL)
{
return;
}
//先释放数组元素申请的空间
if (array->pAddr!=NULL)
{
free(array->pAddr);
array->pAddr=NULL;
}
//释放动态数组
free(array);
array=NULL;
}
//myCompare函数的实现
int myCompare(void *data1,void *data2){
struct Person * p1=data1;
struct Person * p2=data2;
return strcmp(p1->name,p2->name) == 0 && p1->age == p2->age; //vs编辑器有时候反应太慢,明明是对的,但是报错
}
//void(*myForeach)(void *) ,指针函数(传入无类型的数据,让用户自己去打印)
void foreach_DynamicArray(struct dynamicArray *array,void(*myForeach)(void *)){
if (array==NULL)
{
return ;
}
if(myForeach==NULL){
return ;
}
//int i;
for (int i=0;i<array->m_size;i++)
{
myForeach(array->pAddr[i]); //把数组的首地址传进入,交给用户自己去打印(myForeach属于回调函数)
}
}
void myPrintPerson(void * data){
struct Person *p = (struct Person*)data; //感觉像强制类型转换
printf("姓名:%s 年龄:%d\n",p->name,p->age);
}
void test01(){
//创建动态数组
struct dynamicArray *arr = init_DynamicArray(5);
//准备五个person数据
struct Person p1={"亚瑟",18};
struct Person p2={"王昭君",12};
struct Person p3={"赵云",38};
struct Person p4={"张飞",19};
struct Person p5={"关羽",17};
struct Person p6={"宫本",16};
//将数据插入到动态数组中
printf("当前的容量为:%d\n",arr->m_capacity);
insert_dynamicArray(arr,0,&p1);
insert_dynamicArray(arr,0,&p2);
insert_dynamicArray(arr,0,&p3);
insert_dynamicArray(arr,2,&p4);
insert_dynamicArray(arr,10,&p5);
insert_dynamicArray(arr,1,&p6);
//遍历数组(目前的结果:赵云,宫本,王昭君,张飞,亚瑟,关羽)
foreach_DynamicArray(arr,myPrintPerson);
printf("插入后数组的容量为:%d\n",arr->m_capacity);
//测试,删除index为1处的元素
printf("删除的后的数组元素:\n");
remove_DynamicArrayById(arr,1);
foreach_DynamicArray(arr,myPrintPerson);
//根据传入的对象,比如,一个结构,张飞删除
struct Person p={"张飞",19};
remove_DynamicArrayByValue(arr,&p,myCompare);
printf("-----------------根据结构体的值删除-------------------\n");
foreach_DynamicArray(arr,myPrintPerson);
//销毁数组
destroy_DynamicArray(arr);
arr=NULL;
printf("-----------------销毁动态数组-------------------\n");
foreach_DynamicArray(arr,myPrintPerson);
}
int main(){
test01();
system("pause");
return EXIT_SUCCESS;
}
单向链表
实现链表的创建,插入,查找(位置与值),删除,清空,销毁
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//链表节点
struct LinkNode{
void * data; //数据域(可以看作Java中的对象)
struct LinkNode *next; //指针域
};
//定义节点的数据域
struct Person{
char name[64];
int age;
};
//链表结构体
struct LList{
struct LinkNode pHeader; //头节点
int m_Size; //链表长度
};
typedef void* LinkList; //将void*定义为LinkList,隐藏指针 (void*应该理解为无类型指针,不能理解为无返回值)
//初始化链表
LinkList init_LinkList(){
struct LList * myList = malloc(sizeof (struct LList)); //动态开辟一个堆空间存储管理链表得结构体,并用myList指针,指向这个堆空间
if(myList==NULL){
return NULL;
}
//初始化链表得结构体
myList->pHeader.data=NULL;
myList->pHeader.next=NULL;
myList->m_Size=0;
return myList;
}
//插入节点,LinkList list=void* ,指的是传入管理链表结构体得指针,pos插入得位置,data待插入得节点
void insert_LinkList(LinkList list,int pos,void* data){
if(list==NULL){
return;
}
if(data==NULL){
return;
}
struct LList *myList = list; //由于我们typedef了LinkList为一个无类型指针,需要进行类型转换,、
if(pos<0 || pos> myList->m_Size){
//插入得位置不合理,就执行尾插
pos=myList->m_Size;
}
//创建零时节点
struct LinkNode *pCurrent=&myList->pHeader; //拿到链表的头节点地址
//通过循环找到插入位置的前驱节点
for (int i = 0; i < pos; ++i) {
pCurrent = pCurrent->next;
}
//创建出新的节点
struct LinkNode *newNode = malloc(sizeof(struct LinkNode));
newNode->data = data;
newNode->next = NULL;
//将新节点插入到链表中
newNode->next=pCurrent->next;
pCurrent->next=newNode;
myList->m_Size++; //更新链表长度
}
//删除节点 --按照位置删除
void removeByPos_LinkList(LinkList list,int pos){
if(list==NULL){
return;
}
struct LList *myList = list;
if(pos<0 || pos>myList->m_Size-1){
return;
}
//通过一个临时指针来遍历到pos ,先要找到删除节点的前驱节点
struct LinkNode *pCurrent = &myList->pHeader;
for (int i = 0; i < pos; ++i) {
pCurrent=pCurrent->next;
}
//删除节点
//缓存待删除的节点
struct LinkNode *pDel = pCurrent->next;
//建立关系
pCurrent->next=pDel->next;
free(pDel);
pDel=NULL;
myList->m_Size--;
}
int myCompare(void * data1,void * data2){
struct Person * p1=data1;
struct Person * p2=data2;
return strcmp(p1->name,p2->name)==0 && p1->age==p2->age;
}
//删除节点 --按照z值删除
void removeByValue_LinkList(LinkList list,void * data,int(*myCompare)(void *,void *)){
if(list==NULL){
return;
}
if(data==NULL){
return;
}
struct LList * myList=list; //还原结构体
//创建两个赋值指针变量
struct LinkNode *pPrev = &myList->pHeader;
struct LinkNode *pCurent = pPrev->next; // myList->pHeader.next(both ok)
//先根据比较的内容,找到其内容的前驱节点
for (int i = 0; i < myList->m_Size-1; ++i) {
if(myCompare(pCurent->data,data)){
//更改指针指向
pPrev->next=pCurent->next;
//释放掉要删除的节点
free(pCurent);
pCurent=NULL;
break;
}
//将两个辅助指针后移
pPrev=pCurent; //pPrev=pPrev->nex (both ok)
pCurent=pCurent->next;
}
//更新长度
myList->m_Size--;
}
//清空链表,保留头节点,其余的节点释放掉
void clear_LinkList(LinkList list){
if(list==NULL){
return;
}
struct LList *myList=list;
struct LinkNode *pCurrent=myList->pHeader.next;
for (int i = 0; i < myList->m_Size; ++i) {
//先要记住下一个节点
struct LinkNode *pNext=pCurrent->next;
free(pCurrent);
pCurrent=pNext;
}
myList->pHeader.next=NULL;
myList->m_Size=0;
}
//销毁一个链表
void destory_LinkList(LinkList list){
if(list==NULL){
return;
}
//先清空链表
clear_LinkList(list);
free(list);
list=NULL;
}
//遍历节点
void foreach_LinkList(LinkList list,void(*myPrint)(void *)){
if(list==NULL){
return;
}
struct LList * myList = list;
struct LinkNode *pCurrnet = myList->pHeader.next; //知道第一个有数据的节点
//printf("当前的链表长度为:%d\n",myList->m_Size);
for (int i = 0; i < myList->m_Size; ++i) {
myPrint(pCurrnet->data);
pCurrnet=pCurrnet->next;
}
}
//提供一个接口给用户打印链表的长度
int getSize_LinkList(LinkList list){
if(list==NULL){
return -1;
}
struct LList *myList=list;
return myList->m_Size;
}
void myPrintPerson(void * data){
struct Person * p =data;
printf("姓名:%s,年龄:%d\n",p->name,p->age);
}
void test01(){
LinkList list = init_LinkList();
//struct LList *myList =list;
//定义几个节点
//准备五个person数据
struct Person p1={"亚瑟",18};
struct Person p2={"王昭君",12};
struct Person p3={"赵云",38};
struct Person p4={"张飞",19};
struct Person p5={"关羽",17};
struct Person p6={"宫本",16};
//将数据插入到链表中
// printf("当前的链表长度为:%d\n",myList->m_Size);
insert_LinkList(list,0,&p1);
insert_LinkList(list,0,&p2);
insert_LinkList(list,1,&p3);
insert_LinkList(list,0,&p4);
insert_LinkList(list,1,&p5);
insert_LinkList(list,100,&p6);
// 张飞 关羽 王昭君 赵云 亚瑟 宫本
printf("当前列表的长度:%d\n", getSize_LinkList(list));
foreach_LinkList(list,myPrintPerson);
//删除赵云
removeByPos_LinkList(list,3);
printf("------------------------\n");
//张飞 关羽 王昭君 亚瑟 宫本
printf("当前列表的长度:%d\n", getSize_LinkList(list));
foreach_LinkList(list,myPrintPerson);
//删除关羽
struct Person p={"关羽",17};
removeByValue_LinkList(list,&p,myCompare);
printf("------------------------\n");
//张飞 王昭君 亚瑟 宫本
printf("当前列表的长度:%d\n", getSize_LinkList(list));
foreach_LinkList(list,myPrintPerson);
//清空链表
clear_LinkList(list);
printf("------------------------\n");
printf("当前列表的长度:%d\n", getSize_LinkList(list));
foreach_LinkList(list,myPrintPerson);
//销毁链表
destory_LinkList(list);
}
int main(){
//测试
test01();
system("pause");
return EXIT_SUCCESS;
}
企业级链表实现(管理链表的结构体只维护一个指针域,用户流出地址空间用于存储下一个节点地址)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct LinkNode{
//只有指针域
struct LinkNode * next;
};
struct Person{
struct LinkNode next; //这里其实就是利用结构体开辟前四个字节,存储下一个节点的地址
char name[64];
int age;
};
//管理链表的结构体
struct LList{
struct LinkNode pHeader; //链表的头节点
int m_Size;
};
typedef void* LinkList;
//链表初始化
LinkList init_LinkList(){
struct LList *myList= malloc(sizeof(struct LList));
if(myList==NULL){
return NULL;
}
myList->pHeader.next=NULL;
myList->m_Size=0;
return myList;
}
//插入节点
void insert_LinkList(LinkList list,int pos,void * data){
if(list==NULL){
return;
}
if(data==NULL){
return;
}
struct LList *myList=list;
if(pos<0 || pos> myList->m_Size-1){
pos = myList->m_Size; //不满足条件就尾插
}
//
struct LinkNode *myNode = data; //data是用户的对象(不只四个字节),但是LinkNode只有指针域(四个字节),系统提取前四个字节自动转换成节点结构体
//寻找到前置节点位置
struct LinkNode *pCurrent = &myList->pHeader;
for (int i = 0; i < pos; ++i) {
pCurrent = pCurrent->next;
}
//交换地址
myNode->next=pCurrent->next;
pCurrent->next=myNode;
//更新链表长度
myList->m_Size++;
}
//通过传入的位置移除节点
void removeByPos_LinkList(LinkList list,int pos){
if(list==NULL){
return;
}
struct LList *myList = list;
if(pos<0 || pos>myList->m_Size-1){
return;
}
struct LinkNode *pCurrent = &myList->pHeader;
for (int i = 0; i < pos; ++i) {
pCurrent=pCurrent->next;
}
//先缓存下一个节点
struct LinkNode *pDel =pCurrent->next;
//更新连接关系
pCurrent->next=pDel->next;
//free(pDel); 因为peron的指针域,在栈中,并不需要手动释放堆内存(链表中并没有维护数据域)
pDel=NULL;
//节点减一
myList->m_Size--;
}
//通过传入的值进行删除
void removeByValue_LinkList(LinkList list,void * data,int(*myCompare)(void*,void*)){
if(list==NULL){
return;
}
if(data==NULL){
return;
}
struct LList *myList = list;
struct LinkNode *pPrev = &myList->pHeader; //从第一个有数据的点开始
struct LinkNode *pCurrent = myList->pHeader.next;
for (int i = 0; i < myList->m_Size; ++i) {
if(myCompare(pCurrent,data)){ //返回值为1,执行删除操作
pPrev->next=pCurrent->next;
pCurrent=NULL;
break;
}
pPrev=pCurrent;
pCurrent=pCurrent->next;
}
myList->m_Size--;
}
int myCompare(void *data1,void *data2){
struct Person *p1=data1;
struct Person *p2=data2;
return strcmp(p1->name,p2->name)==0 && p1->age==p2->age;
}
void destroy_LinkList(LinkList list){
if(list==NULL){
return;
}
free(list);
list=NULL;
}
//遍历链表
void foreach_LinkList(LinkList list,void(*myPrintLinkNode)(void *)){
if(list==NULL){
return;
}
struct LList *myList = list;
struct LinkNode *pCurrent = myList->pHeader.next;
for (int i = 0; i < myList->m_Size; ++i) {
myPrintLinkNode(pCurrent); //???????
pCurrent=pCurrent->next;
}
}
void myPrintLinkNode(void * data){
struct Person *p =data; //???????????
printf("姓名:%s 年龄:%d\n",p->name, p->age);
}
void test(){
LinkList list = init_LinkList();
struct Person p1={NULL,"aaa",10};
struct Person p2={NULL,"bbb",11};
struct Person p3={NULL,"ccc",12};
struct Person p4={NULL,"ddd",13};
struct Person p5={NULL,"eee",14};
insert_LinkList(list,0,&p1);
insert_LinkList(list,0,&p2);
insert_LinkList(list,1,&p3);
insert_LinkList(list,0,&p4);
insert_LinkList(list,100,&p5);
//ddd bbb ccc aaa eee
foreach_LinkList(list,myPrintLinkNode);
//删除测试
printf("----------------------------\n");
removeByPos_LinkList(list,1);
//ddd ccc aaa eee
foreach_LinkList(list,myPrintLinkNode);
//根据值删除测试
printf("----------------------------\n");
struct Person test ={NULL,"aaa",10};
removeByValue_LinkList(list,&test,myCompare);
//ddd ccc eee
foreach_LinkList(list,myPrintLinkNode);
//销毁链表
printf("----------------------------\n");
destroy_LinkList(list);
}
int main() {
test();
system("pause");
return EXIT_SUCCESS;
}
栈 (数组实现)
栈不可以被遍历,因为一旦去遍历栈中所有元素,就会移除栈容器中的所有的元素
遍历算法:属于非质变算法。不重复遗漏访问容器中的所有数据
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 1024
//定义栈的结构体
struct SStack{
void * data[MAX]; //数组
int m_Size;
};
typedef void* seqStack;
//开始编写stack的接口
//初始化栈
seqStack init_Stack(){
struct SStack *myStack=malloc(sizeof (struct SStack)); //先给管理栈的结构体开辟空间
if(myStack==NULL){
return NULL;
}
//清空数组中的每个元素
memset(myStack->data,0, sizeof(void*)*MAX); //将数组中的每个元素赋值为0
myStack->m_Size=0;
return myStack;
}
//入栈
void push_SeqStack(seqStack stack,void * data){
if(stack==NULL){
return;
}
//判断栈是否已经满了,如果满了,不能入栈
struct SStack *myStack = stack;
if(myStack->m_Size==MAX){
return;
}
myStack->data[myStack->m_Size]=data; //入栈插入
myStack->m_Size++; //更新栈大小
}
//出栈
void pop_SeqStack(seqStack stack){
if(stack==NULL){
return ;
}
//如果是空栈,不执行出栈
struct SStack *myStack = stack;
if(myStack->m_Size==0){
return ;
}
// void *data = myStack->data[myStack->m_Size-1];
// memset(myStack->data[myStack->m_Size-1],0,sizeof(void *));
myStack->data[myStack->m_Size-1]=NULL;
myStack->m_Size--;
}
//获取栈顶元素
void* top_SeqStack(seqStack stack){
if(stack==NULL){
return NULL;
}
struct SStack *myStack=stack;
if(myStack->m_Size<=0){
return NULL;
}
return myStack->data[myStack->m_Size-1];
}
//返回栈大小
int size_SeqStack(seqStack stack){
if(stack==NULL){
return -1;
}
struct SStack *myStack=stack;
return myStack->m_Size;
}
//判断栈是否为空(0为空,1非空)
int isEmpty(seqStack stack){
if(stack==NULL){
return -1; //真
}
struct SStack *myStack=stack;
if(myStack->m_Size<=0){
return 1; //真
} else{
return 0; //假
}
}
//销毁栈
void destroy_SeqStack(seqStack stack){
if(stack==NULL){
return;
}
free(stack);
stack=NULL;
}
//添加数据进行测试
struct Person{
char name[64];
int age;
};
void test01(){
seqStack stack = init_Stack();
//准备五个person数据
struct Person p1={"亚瑟",18};
struct Person p2={"王昭君",12};
struct Person p3={"赵云",38};
struct Person p4={"张飞",19};
struct Person p5={"关羽",17};
struct Person p6={"宫本",16};
//全部入栈
push_SeqStack(stack,&p1);
push_SeqStack(stack,&p2);
push_SeqStack(stack,&p3);
push_SeqStack(stack,&p4);
push_SeqStack(stack,&p5);
while (isEmpty(stack)==0){ //如果栈不为空,进行访问栈顶的元素,并且出栈
struct Person *p = top_SeqStack(stack);
printf("姓名:%s 年龄:%d\n",p->name,p->age);
pop_SeqStack(stack);
}
//栈的大小
int size = size_SeqStack(stack);
printf("当前栈的大小为%d\n",size);
destroy_SeqStack(stack);
}
int main(){
test01();
printf("hello,world! 1");
return 0;
}
栈的链式存储实现
#include <stdio.h>
#include <stdlib.h>
//#include <string.h>
//clion智能之处,指针变量指向会变成箭头,结构体才会变成.
//栈节点,只维护指针域
struct stackNode{
struct stackNode *next;
};
//维护栈的结构体
struct LStack{
struct stackNode pHeader;
int m_Size;
};
typedef void* LinkStack;
//初始化栈
LinkStack init_LinkStack(){
struct LStack *myLinkStack= malloc(sizeof(struct LStack));
if(myLinkStack==NULL){
return NULL;
}
myLinkStack->pHeader.next=NULL;
myLinkStack->m_Size=0;
return myLinkStack;
}
//入栈(插头作为栈顶)
void push_LinkStack(LinkStack stack,void * data){
if(stack==NULL){
return;
}
if(data==NULL){
return;
}
struct LStack *myStack = stack;
//先判断是否满栈(链表没有满栈的说法)
// if(myStack->m_Size){
//
// }
struct stackNode *newNode = data;
newNode->next = myStack->pHeader.next;
myStack->pHeader.next = newNode;
myStack->m_Size++;
}
//出栈
void pop_LinkList(LinkStack stack){
if(stack==NULL){
return;
}
//空栈直接返回
struct LStack *myStack = stack;
if(myStack->m_Size<=0){
return;
}
//有元素,做出栈操作
struct stackNode *temp = myStack->pHeader.next; //临时存储首个有值的节点
myStack->pHeader.next=temp->next;
//temp=NULL;
myStack->m_Size--;
}
//返回栈顶元素
void* top_LinkStack(LinkStack stack){
if(stack==NULL){
return NULL;
}
struct LStack *myStack = stack;
if(myStack->m_Size<=0){
return NULL;
}
return myStack->pHeader.next;
}
//返回栈大小
int size_LinkStack(LinkStack stack){
if(stack==NULL){
return -1;
}
struct LStack *myStack = stack;
return myStack->m_Size;
}
//判断是否为空(非0是空,0就是非空)
int isEmpty(LinkStack stack){
if(stack==NULL){
return -1;
}
struct LStack *myStack=stack;
if(myStack->m_Size<=0){
return 1;
}
return 0;
}
//销毁栈
void destory_LinkStack(LinkStack stack){
if(stack==NULL){
return;
}
free(stack);
stack=NULL;
}
struct Person{
struct stackNode next;
char name[64];
int age;
};
void test02(){
LinkStack stack = init_LinkStack();
//准备五个person数据
struct Person p1={NULL,"亚瑟",18};
struct Person p2={NULL,"王昭君",12};
struct Person p3={NULL,"赵云",38};
struct Person p4={NULL,"张飞",19};
struct Person p5={NULL,"关羽",17};
//struct Person p6={NULL,"宫本",16};
push_LinkStack(stack,&p1);
push_LinkStack(stack,&p2);
push_LinkStack(stack,&p3);
push_LinkStack(stack,&p4);
push_LinkStack(stack,&p5);
while (isEmpty(stack)==0){ //如果栈不为空,进行访问栈顶的元素,并且出栈
struct Person *p = top_LinkStack(stack);
printf("姓名:%s 年龄:%d\n",p->name,p->age);
pop_LinkList(stack);
}
//栈的大小
int size = size_LinkStack(stack);
printf("当前栈的大小为%d\n",size);
destory_LinkStack(stack);
}
int main(){
test02();
printf("hello,world! 2");
return 0;
}
clion使用技巧小记
问题:初次使用clion的时候,整个项目中只能存在一个主函数,对于最初的学习并不友好,我们想的是在学习过程中,在一个project中存在多个main函数,并运行之。
其实解决方法很简单,如图
我们只需要,项目下新建文件夹,将.C源文件创建好后,在同级下新建一个CMakeLists.txt文件,
在txt文件中,添加
include_directories(.)
add_executable(A stackFinishByArray.c )
add_executable(B stackFinishByLinkList.c)
add_executable(),为添加的可以执行的条目,A和B随意起个你知道的名字,作为stackFinishByArray.c和stackFinishByLinkList.c文件的启动名字。这样,stackFinishByArray.c和stackFinishByLinkList.c就都可以包含一个main函数了。
但是同时注意,在第一级的project下有一个系统给我们创建的CMakeLists.txt文件,里面会自动生成如下内容:
我们需要将系统创建的CMakeLists.txt文件的add_executable()注释掉。
还有,我们的二级目录stackFinishByArray,需要添加到系统生成的CMakeLists.txt文件中,即
ADD_SUBDIRECTORY(stackFinishByArray)
这样,就可以在学习阶段,创建并运行多个main函数了,不用学习一个部分再去创建多个project的了。麻烦的很。