以前没有整理自己代码的习惯,也没有去在意。不过慢慢发觉,这样子下去,就算学习过的知识,过了一定的时候也会生疏,所以想想还是做下记录,不为以后能一眼回忆起所以学习的知识,不过应该还是能有点加深印象的作用吧。下面是一个Linux下的C语言语法复习的部分,都很基础,随便看看下哈。
首先是主函数main.c。其实就是通过宏定义来选择要编译运行的功能模块,比较粗糙,但是还是挺好用的。
#include "def.h"
static int count = 1;
#define CONFIG_ARRAY 0
#define CONFIG_BASE_DEF 0
#define CONFIG_BIT_OPE 0
#define CONFIG_FILE_BASE 0
#define CONFIG_FILE_BLOCK 0
#define CONFIG_FUNC <span style="white-space:pre"> </span>1
#define CONFIG_TIME 0
#define CONFIG_SAVE 0
#define CONFIG_STRUCT 0
#define CONFIG_SORT 0
int main()
{
#if CONFIG_BASE_DEF //基础部分
const_and_variable(count++); //常量与变量区别
type_def(count++); //几种基本的类型定义
#endif
#if CONFIG_ARRAY //数组部分
print_array(count++); //打印一个数组
string_point(count++); //字符串与指针
string_change(count++); //字符串转换成int类型
#endif
#if CONFIG_FUNC //函数部分
printf("测试功能:回调函数\n");
func_nested(count++); //回调函数
func_parameter(count++);//传入参数的函数
#endif
#if CONFIG_FILE_BASE //文件部分
simple_read(count++); //简单读写
char server_ip[20];
read_ip_from_file(server_ip); //读取文件
printf("server_ip = %s\n",server_ip);
add_ip_from_file(server_ip); //写入文件
#endif
#if CONFIG_FILE_BLOCK //文件块读写
block_write(count++);
block_read(count++);
#endif
#if CONFIG_BIT_OPE //位操作
show_test(count++);
#endif
#if CONFIG_SORT //几种排序方式
test_main(count++);
#endif
return 0;
}
下面把Makefile先粘贴上来吧。
main:main.o array.o base_def.o bit_ope.o file_base.o file_block.o func.o save.o struct.o sort.o
cc -g -o $@ $^
main.o:main.c
cc -g -c $<
array.o:array.c
cc -g -c $<
base_def.o:base_def.c
cc -g -c $<
bit_ope.o:bit_ope.c
cc -g -c $<
file_base.o:file_base.c
cc -g -c $<
file_block.o:file_block.c
cc -g -c $<
func.o:func.c
cc -g -c $<
save.o:save.c
cc -g -c $<
struct.o:struct.c
cc -g -c $<
my_time.o:my_time.c
cc -g -c $<
sorte.o:sorte.c
cc -g -c $<
clean:
rm -f main \
rm -f *.o
然后是函数定义和结构体定义的部分,统一放在同一个def.h头文件下,代码如下。
#ifndef _DEF_H_
#define _DEF_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
//基本类型
long turn_to_2_power(int n); //返回2的N次幂
int const_and_variable(int count); //常量与变量
int type_def(int count); //几种常见类型内存占用大小
//数组部分
int print_array(int count); //打印数组
int string_point(int count); //字符串指针
int string_change(int count); //字符串与基本类型的转换
//函数部分
int func_nested(int count); //回归函数部分
int func_parameter(int count); //参数传递说明
//结构体与指针部分
typedef struct my_data
{
int count;
}my_data_t;
typedef struct node
{
void *data;
struct node *next;
}node_t;
int delete_node(node_t *head,int n);
int delete_node_by_data(node_t *head,void *data);
int add_node_by_index(node_t *head,int index,void *data);
int add_node_back(node_t *head,void *data);
int modify_node_by_data(node_t *head,void *data);
int modify_node_by_index(node_t *head,int index,void *data);
int search_node_ret_index(node_t *head,void *data);
void *search_node_ret_data(node_t *head,void *data);
//位运算部分
int set_to_zero(int *num,int n);
int set_to_one(int *num,int n);
int set_to_zero_exp(int *num,int n);
int set_to_one_exp(int *num,int n);
//系统时间部分
typedef struct my_time
{
int year;
int month;
int day;
int hour;
int min;
int sec;
}my_time_t;
void print_time(); //打印时间
void set_time(my_time_t *t_time);//设置时间
/*
#include <time.h> -- 必须的时间函数头文件
time_t -- 时间类型(time.h 定义)
struct tm -- 时间结构,time.h 定义如下:
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
time ( &rawtime ); -- 获取时间,以秒计,从1970年1月一日起算,存于rawtime
localtime ( &rawtime ); -- 转为当地时间,tm 时间结构
asctime ()-- 转为标准ASCII时间格式:
星期 月 日 时:分:秒 年
*/
//文件读写部分
#define IP_FILE_NAME "server_ip.dat"
#define BLOCK_FILE_NAME "gps_block.dat"
typedef struct block
{
my_time_t recond_time;
char gps_data[100];
}block_t;
int read_ip_from_file(char *ip);
int add_ip_from_file(char *ip);
int simple_read(int count);
int set_block(block_t *my_block,char *content);
int print_block(block_t *my_block);
int block_write(int count);
int block_read(int count);
//排序部分
int test_main(int count);
void sort_maopao(int *a,int n);
void sort_select(int *a,int n);
void sort_quick(int *a,int m,int n);
void sort_insert(int *a,int n);
int searchnum(int *a,int n,int num);
void insert(int *a,int n,int i);
void set_num(int *a,int n);
void select_sort_method(int *a,int n);
void print(int *a,int n);
void swap(int *a,int *b);
#endif
下面是基础的类型定义部分,分为base_def.c。
#include "base_def.h"
long turn_to_2_power(int n)
{
long ret = 1;
while(n--){
ret *= 2;
}
return ret;
}
int const_and_variable(int count)
{
printf("当前功能:常量与变量的区别\n");
printf("const can be modified,but variavle num can't be modified\n\n");
return 0;
}
int type_def(int count)
{
printf("当前功能:常见类型占用的字节大小\n");
unsigned int u_int= -1;
int my_int = -1;
long my_long =-1;
unsigned long my_u_long = -1;
float my_float = -1;
double my_double = -1;
char my_char = '1';
int *p_int;
char *p_char;
float *p_float;
double *p_double;
my_int = turn_to_2_power(10);
printf("sizeof(int) = %d\n",sizeof(int));
printf("sizeof(unsigned int) = %d\n",sizeof(unsigned int));
printf("sizeof(long) = %d\n",sizeof(long));
printf("sizeof(unsigned long) = %d\n",sizeof(unsigned long));
printf("sizeof(float) = %d\n",sizeof(float));
printf("sizeof(double) = %d\n",sizeof(double));
printf("sizeof(char) = %d\n",sizeof(char));
printf("sizeof(*p_int) = %d\n",sizeof(p_int));
printf("sizeof(*p_char) = %d\n",sizeof(p_char));
printf("sizeof(*p_float) = %d\n",sizeof(p_float));
printf("sizeof(*p_double) = %d\n\n",sizeof(p_double));
printf("int: -1 = %d,%x\n",my_int,my_int);
printf("u_int: -1 = %u,%x\n",u_int,u_int);
printf("longt: -1 = %ld,%x\n",my_long,my_long);
printf("u_long: -1 = %u,%x\n",my_u_long,my_u_long);
printf("float: -1 = %.2f,%x\n",my_float,my_float);
printf("double: -1 = %.2lf,%x\n",my_double,my_double);
printf("char: '1' = %c\n\n",my_char);
return 0;
}
接下来应该是if条件,while循环的内容,这个我觉得没有必要专门再拿出来练习,毕竟随便写个程序都会用到。直接跳过,接下来是数组的部分,我只选取读写一部分,因为是基础嘛。下面是array.c。
#include "def.h"
int print_array(int count)
{
printf("当前功能:打印一个数组\n");
int i,j;
int array1[10] = {1,2,3,4,5,6,7,8,9,10};
int array2[3][4] = {{11,12,13,14},{21,22,23,24},{31,32,33,34}};
printf("array1:\n");
for(i = 0; i < 10 ; i++){
printf("%4d",array1[i]);
}
printf("\n");
printf("array2:\n");
for(i = 0; i < 3; i++)
{
for(j = 0; j < 4; j++){
printf("%4d",array2[i][j]);
}
printf("\n");
}
return 0;
}
int string_point(int count)
{
printf("当前功能:字符串与指针\n");
char str1[50],str2[50],str3[50];
printf("输入两个字符串,空格隔开:\n");
scanf("%s%s",str1,str2);
printf("字符串s1:");
puts(str1);
printf("字符串s2:");
puts(str2);
printf("s1+s2(strcat):");
strcpy(str3,str1);
strcat(str3,str2);
puts(str3);
printf("s1(3)+s2(strncpy):");
memset(str3,0,strlen(str3));
strncpy(str3,str1,3);
strcat(str3,str2);
puts(str3);
return 0;
}
int string_change(int count)
{
printf("字符串转换成int类型:\n");
int i;
char buf[50]="";
double d;
i = atoi("123456");
printf("(atoi)i=%d\n",i);
d = atof("123.456");
printf("(atof)d=%lf\n",d);
sscanf("123456","%4s",buf);
printf("(sscanf)buf=%s\n",buf);
sprintf(buf,"%.3f",3.1415626);
printf("(sscanf)buf=%s\n", buf);
return 0;
}
接下来是结构体与指针部分,这部分因为最近一段时间接触的比较多,主要是用单链表的形式来实现增删改查,列出了函数,但是好多没有实现,可以自行脑补加动手补。struct.c如下:
#include "def.h"
int delete_node(node_t *head,int n)
{
int i;
node_t *p,*pre;
pre = p = head;
if( (head == NULL)||(n <= 0) ){
return -1;
}
if(n == 1)
{
if(p->next == NULL){
free(p);
head = NULL;
}
else{
head = head->next;
free(p);
}
return 0;
}
for(i = 1; (i < n) && (p!=NULL); i++){
pre = p;
p = p->next;
}
if(p == NULL)
{
return -1;
}
else
{
if(p->next == NULL){
pre->next = NULL;
}
else{
pre->next = p->next;
free(p);
}
}
}
int delete_node_by_data(node_t *head,void *data)
{
node_t *pre,*p;
my_data_t *p_serch_data = (my_data_t *)data;
my_data_t *p_node_data;
return 0;
}
int add_node_by_index(node_t *head,int index,void *data)
{
return 0;
}
int add_node_back(node_t *head,void *data)
{
return 0;
}
int modify_node_by_data(node_t *head,void *data)
{
return 0;
}
int modify_node_by_index(node_t *head,int index,void *data)
{
return 0;
}
int search_node_ret_index(node_t *head,void *data)
{
return 0;
}
void *search_node_ret_data(node_t *head,void *data)
{
return 0;
}
再然后应该是位运行和文件部分了吧,位运算感觉没有什么必要详细说明,因为用到的时候基本会有相应位的说明,改起来也不会像示例这样生疏,bit_opt.c如下:
#include "def.h"
//把第n位设为0
int set_to_zero(int *num,int n)
{
int a;
a = ~(1 << (n-1));
*num &= a;
return 0;
}
//把第n位设为1
int set_to_one(int *num,int n)
{
int a;
a = (1 << (n-1));
*num |= a;
return 0;
}
//把除第n位位全设为0
int set_to_zero_exp(int *num,int n)
{
int a;
a = (1 << (n-1));
*num &= a;
return 0;
}
//把除第n位位全设为1
int set_to_one_exp(int *num,int n)
{
int a;
a = ~(1 << (n-1));
*num |= a;
return 0;
}
int show_test()
{
int a,b,c,d;
a = 0x01;
b = 0x11;
c = 0xffff;
d = 0x0;
printf("初始数据:%x\n",a);
set_to_one(&a,4);
printf("第4位转换为1后:%x\n",a);
printf("初始数据:%x\n",b);
set_to_zero(&b,4);
printf("第4位转换为0后:%x\n",b);
printf("初始数据:%x\n",c);
set_to_zero_exp(&c,4);
printf("除第4位外全部转换为0后:%x\n",c);
printf("初始数据:%x\n",d);
set_to_one_exp(&d,4);
printf("除第4位外全部转换为1后:%x\n",d);
return 0;
}
先在文件的部分前插入一下系统时间的知识点,即对库中time.h下的部分定义拿出来说明一下下,my_time.c如下:
#include "def.h"
void print_time()
{
time_t cur_time;
struct tm * timeinfo;
time( &cur_time );
timeinfo = localtime ( &cur_time );
printf ( "cur_time = %d-%d-%d %d:%d:%d\n",timeinfo->tm_year+1990,timeinfo->tm_mon,timeinfo->tm_mday,
timeinfo->tm_hour,timeinfo->tm_min,timeinfo->tm_sec);
}
typedef struct my_time
{
int year;
int month;
int day;
int hour;
int min;
int sec;
}my_time_t;
void set_time(my_time_t *t_time)
{
time_t cur_time;
struct tm * timeinfo;
time( &cur_time );
timeinfo = localtime ( &cur_time );
t_time->year = timeinfo->tm_year+1990;
t_time->month = timeinfo->tm_mon;
t_time->day = timeinfo->tm_mday;
t_time->hour = timeinfo->tm_hour;
t_time->min = timeinfo->tm_min;
t_time->sec = timeinfo->tm_sec;
}
/*
#include <time.h> -- 必须的时间函数头文件
time_t -- 时间类型(time.h 定义)
struct tm -- 时间结构,time.h 定义如下:
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
time ( &rawtime ); -- 获取时间,以秒计,从1970年1月一日起算,存于rawtime
localtime ( &rawtime ); -- 转为当地时间,tm 时间结构
asctime ()-- 转为标准ASCII时间格式:
星期 月 日 时:分:秒 年
*/
文件部分我分为两个部分来写,一个简单读写,一个块读写。file_base.c和file_block.c。
#include "def.h"
int read_ip_from_file(char *ip)
{
FILE *fp;
char filename[20];
char data[100];
strcpy(filename,IP_FILE_NAME);
if((fp=fopen(filename,"r+")) == NULL)
{
printf("cannot open file : %s\n",IP_FILE_NAME);
return -1;
}
fscanf(fp,"%s",data);
strcpy(ip,data);
puts(ip);
fclose(fp);
return 0;
}
int add_ip_from_file(char *ip)
{
FILE *fp,*fp_tmp;
char filename[20];
char data[100];
strcpy(filename,IP_FILE_NAME);
if((fp=fopen(filename,"r")) == NULL)
{
printf("cannot open file : %s\n",IP_FILE_NAME);
return -1;
}
if((fp_tmp=fopen("tmp.dat","a+")) == NULL)
{
printf("cannot open file : %s\n","tmp.dat");
return -1;
}
fprintf(fp_tmp,"%s\n",ip);
while(fscanf(fp,"%s",data)!=EOF)
{
fprintf(fp_tmp,"%s\n",data);
puts(data);
}
fclose(fp);
fclose(fp_tmp);
rename("tmp.dat",IP_FILE_NAME);
return 0;
}
int simple_read(int count)
{
FILE *fp;
char ch;
char filename[20];
char data[100];
strcpy(filename,IP_FILE_NAME);
if((fp=fopen(filename,"r+")) == NULL)
{
printf("cannot open file : %s\n",IP_FILE_NAME);
return -1;
}
//fgetc(fp) 读取一个字符
//fputc(ch,fp)写入一个字符
//用fgetc(fp)来实现单个字符的读取
// while( (ch = fgetc(fp))!=EOF){
// putchar(ch);
// }
// putchar('\n');
//用fscanf来实现格式输入,
fscanf(fp,"%s",data);
puts(data);
// fseek(fp,0L,0);
//0表示文件头
// 1表示当前位置
// 2表示文件末尾
//用fgets(str,n,fp)来实现读取n个字符/fputs(str,fp)来实现输出字符串
#if 0
fseek(fp,0L,1);
fputs(" 18606028405",fp);
memset(data,0,100);
fseek(fp,0L,0);
fgets(data,100,fp);
puts(data);
fseek(fp,0L,0);
memset(data,0,100);
fscanf(fp,"%s",data);
puts(data);
memset(data,0,100);
fscanf(fp,"%s",data);
puts(data);
#endif
fclose(fp);
return 0;
}
好吧,刚刚看到,原来以前学习块文件读写的时候用到了系统时间的部分,难怪是先系统时间,然后才是文件的练习。
#include "def.h"
void set_time(my_time_t *t_time)
{
time_t cur_time;
struct tm * timeinfo;
time( &cur_time );
timeinfo = localtime ( &cur_time );
t_time->year = timeinfo->tm_year+1990;
t_time->month = timeinfo->tm_mon;
t_time->day = timeinfo->tm_mday;
t_time->hour = timeinfo->tm_hour;
t_time->min = timeinfo->tm_min;
t_time->sec = timeinfo->tm_sec;
}
int set_block(block_t *my_block,char *content)
{
strcpy(my_block->gps_data,content);
set_time(&my_block->recond_time);
return 0;
}
int print_block(block_t *my_block)
{
printf("%d-%d-%d %d:%d:%d---->%s\n",my_block->recond_time.year,my_block->recond_time.month,my_block->recond_time.day,
my_block->recond_time.hour,my_block->recond_time.min,my_block->recond_time.sec,my_block->gps_data);
return 0;
}
int block_write(int count)
{
FILE *fp;
int i;
char filename[20];
strcpy(filename,BLOCK_FILE_NAME);
block_t to_write[10];
if((fp=fopen(filename,"wb")) == NULL)
{
printf("cannot open file : %s\n",BLOCK_FILE_NAME);
return -1;
}
for(i = 0; i < 10; i++)
{
set_block(&to_write[i],"------>");
if( fwrite(&to_write[i],sizeof(block_t),1,fp)!=1 )
{
printf("cannot write file : %s\n",BLOCK_FILE_NAME);
exit(1);
}
}
fclose(fp);
return 0;
}
int block_read(int count)
{
FILE *fp;
int i;
char filename[20];
strcpy(filename,BLOCK_FILE_NAME);
block_t to_read[10];
if((fp=fopen(filename,"rb")) == NULL)
{
printf("cannot open file : %s\n",BLOCK_FILE_NAME);
return -1;
}
for(i = 0; i < 10; i++)
{
if( fread(&to_read[i],sizeof(block_t),1,fp)!=1 )
{
printf("cannot read file : %s\n",BLOCK_FILE_NAME);
}
print_block(&to_read[i]);
}
fclose(fp);
return 0;
}
还有一个是自己练习的冒泡、选择、插入、快速排序的一个例子,也贴出来吧。sort.c如下:
#include "def.h"
int test_main(int count)
{
int array[10];
set_num(array,10);
print(array,10);
select_sort_method(array,10);
print(array,10);
return 0;
}
void set_num(int *a,int n)
{
int i;
for(i = 0; i < n; i++)
{
a[i] = 20 - i;
}
}
int searchnum(int *a,int n,int num)
{
int i;
for(i = 0; i < n; i++)
{
if( num == a[i] ){
return i;
break;
}
}
return 0;
}
void insert(int *a,int n,int i)
{
if(i >= n){
printf("cannot insert ,because space is not enough\n");
return;
}
printf("Please input a num to insert\n");
scanf("%d",&a[i]);
}
void print(int *a,int n)
{
int i;
// cout<<"数组元素如下:"<<endl;
printf("Output the array\n");
for(i = 0; i < n; i++)
{
printf(" %d ",a[i]);
if( (((i+1) % 5) == 0) && (i != 0) ){
printf("\n");
}
}
}
void select_sort_method(int *a,int n)
{
int select;
printf("\t1->maopao\n\t2->select\n\t3->insert\n\t4->quick\n");
printf("input your select:\n");
scanf("%d",&select);
switch (select)
{
case 1:
sort_maopao(a,n);
break;
case 2:
sort_select(a,n);
break;
case 3:
sort_insert(a,n);
break;
case 4:
sort_quick(a,0,n);
break;
default:break;
}
}
void swap(int *a,int *b)
{
int tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
void sort_maopao(int *a,int n)
{
int i,j;
for(i = 0 ; i < n; i++){
for(j = 0; j < n - 1 - i; j++){
if(a[j] > a[j+1])
{
swap(&a[j],&a[j+1]);
}
}
}
}
void sort_select(int *a,int n)
{
int i,j,min;
for(i = 0 ; i < n; i ++){
min = i;
for(j = i; j < n ; j ++){
if(a[i] > a[j])
{
min = j;
}
}
if(min != i){
swap(&a[i],&a[min]);
}
}
}
void sort_insert(int *a,int n)
{
int i,j;
for(i = 0 ; i < n; i ++){
for(j = i-1; j >= 0 ; j --){
if(a[j] > a[j+1]){
swap(&a[j],&a[j+1]);
}
else {
break;
}
}
}
}
void sort_quick(int *a,int m,int n)
{
int v = a[m];
int i = m,j = n;
if(i < j)
{
while(i < j)
{
while( (a[j] >= v) && (i < j) ){
j--;
}
swap(&a[j],&a[i]);
while( (a[i] <= v) && (i < j ) ){
i++;
}
swap(&a[j],&a[i]);
}
sort_quick(a,m,i-1);
sort_quick(a,i+1,n);
}
}
好了,终于贴完了。试了好几个博客,还没有找到什么贴代码好用的,不过还是没有添加附件的功能,不过将就着吧,我先看看效果,再修改修改去。