C语言小项目之电影粗劣信息系统

C语言小项目之电影粗劣信息系统

一、头文件编写:(Test_1.h)

#ifndef _TEST_1_H_
#define _TEST_1_H_

//#ifdef __cplusplus
//extern "C" {
//#endif
/*C语言中的基本数据类型:char
 *                short int long
 *                float double
 *                unsigned
 *                long long...
 *
 *                c语言中默认int为signed即最高为符号位
 *
 *                另外c语言中的跳转判断:
 *                                for(;;)
 *                                do while
 *                                while
 *                                goto "tag"
 *
 *                在修饰变量的时候,static修饰的静态局部变量只执行一次,而且延长了局部变量的生命周期,直到程序运行结束以后才释放
 *                static修饰全局变量的时候,这个全局变量只能在本文件中访问,不能在其它文件中访问,即便是extern外部声明也不可以
 *                static修饰一个函数,则这个函数的只能在本文件中调用,不能被其他文件调用
 *
 *                c语言中字符串表示:
 *                             一:字符数珠 char xxx[x]
 *                             二:字符指针 char* str
 *
 *                数组名即表示数组的首地址
 *                EOF:end of file文件结尾
 *                关键字:extern---》表示变量或者函数在别处定义
 * */
#define TSIZE 45//电影名字的数组长度--->define的用法 定义名  数值 注意的是不带分号;结尾
struct film {
    char title[TSIZE];
    int rating;
};

typedef struct film Item;

typedef struct node {
    struct node *next;
    Item item;
} Node;

typedef struct node *List;

/*枚举的常量是int类型
 * 默认值从0开始...
 * zero->0表示false
 *  one->1表示true
 */
typedef enum JudgeInt {
    zero, one
} judgeInt;

//函数原型
void initializeList(List *pList); //初始化链表

/**
 * 判断链表是否为空
 * */
judgeInt listIsEmpty(const List *pList);

judgeInt listIsFull(const List *pList); //判断链表是否满了

unsigned int listItemCount(const List *pList); //链表中已存在的数据总数

judgeInt addItem(Item item, List *pList); //添加链表项

void traverse(const List *pList, void (*pfunction)(Item item)); //将函数pFunction作用于链表中的每一项

void emptyList(List *pList); //清空链表,释放内存

//#ifdef __cplusplus
//}
//#endif

#endif

二、头文件的实现:(Test_1.c)

#include "Test_1.h"
#include <stdlib.h>
#include <stdio.h>

/**
 * static定义的局部函数
 * */
static void copyToNode(Item item,Node *pNode);

void initializeList(List *pList){
    *pList=NULL;
}

judgeInt listIsEmpty(const List *pList){
    if(pList==NULL){
        return one;
    }else{
        return zero;
    }
}

//感觉有问题???----判断是否申请的内存超过一个节点的大小
judgeInt listIsFull(const List *pList){
    Node *pt;
    judgeInt temp;
    pt=(Node*)malloc(sizeof(Node));
    if(pt==NULL){
        temp=one;
    }else{
        temp=zero;
    }
    return temp;
}

unsigned int listItemCount(const List *pList){
    Node *head=*pList;
    unsigned int count;
    while(head!=NULL){
        ++count;
        head=head->next;
    }
    return count;
}

judgeInt addItem(Item item,List *pList){

    Node *pNew=(Node*)malloc(sizeof(Node));
    Node *scan=*pList;
    if(pNew==NULL){
        return zero;
    }
    copyToNode(item,pNew);
    pNew->next=NULL;
    if(scan==NULL){
        *pList=pNew;
    }else{
        while(scan->next!=NULL){
            scan=scan->next;
        }
        scan->next=pNew;
    }
    return one;
}

/**
 * 涉及到函数指针,让链表中的所有节点都执行该函数
 * */
void traverse(const List *pList,void(*pfunction)(Item item)){
    Node *head=*pList;
    while(head!=NULL){
        (*pfunction)(head->item);
        head=head->next;
    }
}

void emptyList(List *pList){
    Node *pTemp;
    while(*pList!=NULL){
        pTemp=(*pList)->next;
        free(*pList);
        *pList=pTemp;
    }
}

static void copyToNode(Item item,Node *pNode){
    pNode->item=item;
}

三、简单的控制台显示main函数编写:(Test_One_1.c)

#include <stdio.h>
#include <stdlib.h>
#include "Test_1.h"

void showMovies(Item item);
char* s_gets(char* st,int n);

int main(void){
    List movies;
    Item temp;
    initializeList(&movies);
    //如果是满的
    if(listIsFull(&movies)==one){
        fprintf(stderr,"没有可用的内存\n");
        exit(EXIT_FAILURE);//异常退出
    }
    puts("please enter first movie title:");//输出到控制台,自动换行(‘\0’换成回车换行)
    while(s_gets(temp.title,TSIZE)!=NULL && temp.title[0]!='\0'){//如果输入的是空行则退出
        puts("please enter your rating<0-10>:");
        scanf("%d",&temp.rating);
        while(getchar()!='\n'){
            continue;
        }
        //如果添加失败的话
        if(addItem(temp,&movies)==zero){
            fprintf(stderr,"分配内存出现问题\n");
            break;
        }
        if(listIsFull(&movies)==one){
            fprintf(stderr,"这次真的满了\n");
            break;
        }
        puts("please enter next movie title (empty line to stop):");
    }

    /*显示*/
    if(listIsEmpty(&movies)==one){
        printf("没有数据哦!");
    }else{
        printf("这里显示电影列表:\n");
        traverse(&movies,showMovies);
    }
    /*清理*/
    emptyList(&movies);
    printf("再见!\n");
    return 0;
}

//供traverse的通过调用--->使用函数指针
void showMovies(Item item){
    printf("Movie: %s Rating: %d\n",item.title,item.rating);
}

/**
 * 没看懂
 * */
char* s_gets(char* st,int n){
    char *ret_val;//是否读取到文件结尾
    char *find;//查找换行符,如果有则用‘\0’代替
    ret_val=fgets(st,n,stdin);//stdin标准输入,把键盘输入送入缓存区显示在控制台上,读取n-1个字符,最后一个字符置空字符,会保留一行结尾的换行符
    if(ret_val){
        find=strchr(st,'\n');//不存在则返回NULL,否则返回首次匹配到的地址
        //如果存在‘\n’说明结束了把st中的换行符替换成空字符->字符串
        //如果不存在
        if(find){
            *find='\0';
        }else{
            //getchar有缓存,输入多个,会从缓存中获取
            while(getchar()!='\n')//将用户输入的字符回显到屏幕
                continue;//处理后续内容
        }
    }
    return ret_val;
}

四、使用JNI编译:

一、Android.mk的编写:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

#LOCAL_MODULE := student_manager_system
LOCAL_MODULE := movie_test_executable

LOCAL_SRC_FILES := src/Test_1.c \
                   src/Test_One_1.c


#LOCAL_C_INCLUDE := src \
                   $(LOCAL_PATH)/include

#添加PIE
LOCAL_CFLAGS += -pie -fPIE
LOCAL_LDFLAGS += -pie -fPIE

#optional表示在user eng tests版本下都编译
LOCAL_MODULE_TAGS := optional

include $(BUILD_EXECUTABLE)

二、Application.mk编写:(本例只指定了armeabi平台)

APP_ABI :=armeabi

三、我的编译方式:

1、使用eclipse目录结构如图:

这里写图片描述

2、进入jni目录中

按住shift+鼠标右键,会出现命令行选项,点击进入后输入:ndk-build.cmd即可编译(前提是你已经下载解压好ndk10及以上的版本,把build路径添加到系统环境变量path中),成功编译后会在生成libs和obj文件,所需的可执行文件或者so文件在
libs的armeabi下。

3、如何执行使用?

放在安卓系统的/system/bin下,执行./xxxx你的文件名回车即可

四、我要说的感谢的话

感谢没有放弃,感谢我还清醒,感谢所有支持我的人,谢谢!^__^

猜你喜欢

转载自blog.csdn.net/zb52588/article/details/79703639