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你的文件名回車即可
四、我要說的感謝的話
感謝沒有放棄,感謝我還清醒,感謝所有支持我的人,謝謝!^__^