c语言经典编程900实例

2024-12-04

c语言经典编程900实例(通用5篇)

c语言经典编程900实例 篇1

C语言高级编程及实例分析

第一章:内存管理

c语言对程序精心编译时,将函数中命令、语句编译成相应序列的机器指令代码,放在代码段;将已初始化的数据,如已赋值的全局变量、静态局部变量等,放在数据段;将未初始化的数据放在BBS段内;将临时数据,如函数调用时传递的参数、局部变量、返回调用时的地址等放在栈段内;而对一些动态变化的数据,如在程序执行中建立的一些数据结构,如链表,动态数组等,则放在堆结构中。

内存管理系统是操作系统的重要部分。C语言中使用malloc()函数和free()函数来分配和释放内存。再次释放已经释放的内存和释放未被分配的内存都会造成系统的崩溃。

1.1.1 PC存储器结构

PC机存储器结构分为主存储器、外存储器和高速缓存几个部分。

1.1.4 内存编译模式

编译模式是指如何在内存中放置程序代码及数据,如何分配堆栈,并确认占用的内存大小及如何存取它们,当指定内存模式以后,语言编译程序将按事先选择好的内存模式编译组织程序。C语言提供了6种编译模式,分别是:微模式,小模式,紧凑模式,中模式,大模式和巨模式。

1.1.5 堆概念和结构

堆是一种动态的存储结构(存储链表,动态数组等),实际上就是数据段的自由存储区。

1.1.6 堆管理函数

1.malloc()函数

用来分配内存。函数原型为void *malloc(unsigned size)

如:int *p;

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

如果要分配100个int型的空间时,表示为:int*p=(int*)malloc(sizeof(int));

2.free()函数

用来释放内存。函数原型为void *free(指针变量)

如:int *p=(int *)malloc(4);

*p=100;

free(p);

3.realloc()函数

用来重调空间的大小,函数声明为:void *realloc(void *block,int size);

block是指向要扩张或缩小的内存空间的指针。Size指定新的大小。

4.calloc()函数

用来分配一个能容纳n个元素,每个元素长度为size的内存空间。函数声明为void *calloc(size_t nelem,size_t elsize)。该函数将分配一个容量为nelem *size大小的空间,并用0初始化该内存区域,即每个地址装入0.该函数将返回一个指向分配空间的指针。如果没有空间可用,则返回NULL指针。若在大数据模式下建立远堆,则可用farmalloc函数。

1.2.2 函数剖析函数init_Heap()

实现了初始化内存分配程序的功能

2函数My_Free()

完成函数释放内存的功能函数Allocate()

实现了分配按指定大小分配内存块的功能

第三章:文件高级操作

字符型(文本型)文件和二进制文件{有什么区别?}

标准库函数

①文件打开(fopen)

函数原型FILE *fopen(char *filename,char *mode)

②文件关闭(fclose)

函数原型int *fclose(FILE *fp)

字节(字符)读写函数fgetc和fputc

字符串读写函数fgets和fputs

数据块读写函数 fread和fwrite

格式会读写函数 fscanf和fprint

①字符串读函数fgets

Char *fgets(char *s,int n,FILE *filepointer);

②字符串写函数fputs

Int fputs(char *s,FILE *filepointer)

③数据块读函数fread

Unsigned fread(void *ptr,unsigned size,unsigned n,FILE *filepointer)④数据块写函数fwrite

Unsigned fwrite(void *ptr,unsigned size,unsigned n,FILE filepointer)

①格式化读fscanf

Int scanf(FILE *filepointer,const char *format,[&a,&b,...])

②格式化写fprintf

Int fprintf(FILE *filepointer,const char *format,[表达式列表,...]);

文件定位操作

①rewind函数

函数原型:void rewind(FILE *filepointer);

功能:将filepointer所指向的文件的位置指针重新置回到文件的开头 ②fseek函数

函数原型:int fseek(FILE *fp,long offset,int whence)

功能:whence 基准点;offset从基准点开始移动的字节数; ③ftell函数

函数原型:long ftell(FILE *filepointer);

功能:返回文件的当前位置;

④feof函数

原型:int feof(FILE *fp);

功能:判断fp所代表的文件是否结束

Stdin 标准输入(键盘)

Stdout 标准输出(显示器)

Stdaux 标准辅助输入输出(异步串行口)

Stdprn 标准打印(打印机)

Stderr标准错误输出(显示器)

简单的来说,++i 和 i++,在单独使用时,就是 i=i+1。而 a = ++i,相当于 i=i+1;a = i;

而 a = i++,相当于 a = i;i=i+1;

C语言面向对象编程学习笔记 篇2

1、在底层驱动函数前加static标识符的作用:

a:加了static后表示该函数失去了全局可见性,只在该函数所在的文件作用域内可见 b:当函数声明为static以后,编译器在该目标编译单元内只含有该函数的入口地址,没有函数名,其它编译单元便不能通过该函数名来调用该函数,这也是对1的解析与说明

2、底层驱动的封装模板

通常将存储类,显示类,AD-DA类的外设驱动函数封装为以下几个函数: Void Open(void);

此函数用于开启外设,通常函数体中包涵IO和外设的初始化 Void Close(void)此函数用于关闭外设,特别是一些在休眠下功耗很大的外设,可用mos管控制其Vcc的通断,以此达到降低系统功耗的目的

Void Read(unsigned int address,unsigned char *data[],unsigned int count)

此函数用于读取数据,参数分别为:address,地址,*data[],存放数据的数组,count,要读取的字节数

Void Write(unsigned int address,unsigned char *data[],unsigned int count)此函数用于写数据,参数功能与读函数中相似。

Void control(unsigned char cmd,unsigned char data)此函数用于控制外设的工作状态,如休眠,低功耗等等

3、命名规则

A、宏定义全部用大写

如:#define OLED_CS PBout(12)B、驱动函数名称大小写,并且动词放置在末尾如

static long _OLED_Close(void)C、结构体的名称,结构体名大写,变量名小写,“驱动”的首字母大写

如:struct OLED_DEVICE oledDevice;

4、关于外设的数据手册

C语言接口与实现实例 篇3

本文地址:www.cnblogs.com/archimedes/p/c-interfaces-implementations.html,转载请注明源地址。

接口

接口只需要指明客户调用程序可能使用的标识符即可,应尽可能地隐藏一些无关的表示细节和算法,这样客户调用程序可以不必依赖于特定的实现细节。这种客户调用程序和实现之间的依赖--耦合----可能会在实现改变时引起错误,当这种依赖性埋藏在一些关于实现隐藏的或是不明确的假设中时,这些错误可能很难修复,因此一个设计良好且描述精确的接口应该尽量减少耦合。

C语言对接口和实现的分离只提供最基本的支持,但是简单的约定能给接口/实现方法论带来巨大的好处。在C中,接口在头文件声明,头文件声明了客户调用程序可以使用的宏、类型、数据结构、变量以及例程。用户使用C语言的预处理指令#include导入接口。

下面的例子说明了本篇文章的接口中所使用的一些约定、接口:

arith.h

该接口的名字为Arith,接口头文件也相应地命名为arith.h,接口的名字以前缀的形式出现在接口的每个标识符中。模块名不仅提供了合适的前缀,而且还有助于整理客户调用程序代码。

Arith接口还提供了一些标准C函数库中没有但是很有用的函数,并为出发和取模提供了良好的定义,而标准C中并没有给出这些操作的定义和只提供基于实现的定义。

实现

一个实现导出一个接口,它定义了必要的变量和函数以提供接口所规定的功能,在C语言中,一个实现是由一个或多个.c文件提供的,一个实现必须提供其导出的接口所指定的功能。实现应包含接口的.h文件,以保证它的定义和接口的声明时一致的。

Arith_min和Arith_max返回其整型参数中的最小值和最大值:

int Arith_max(int x, int y) {

return x > y ? x : y;

}

int Arith_min(int x, int y) {

return x > y ? y : x;

}

Arith_div返回y除以x得到的商,Arith_mod返回相应的余数。当x与y同号的时候,Arith_div(x,y)等价于x/y,Arith_mod(x,y)等价于x%y

当x与y的符号不同的时候,C的内嵌操作的返回值就取决于具体的实现:

eg.如果-13/5=2,-13%5=-3,如果-13/5=-3,-13%5=2

标准库函数总是向零取整,因此div(-13,2)=-2,Arith_div和Arith_mod的语义同样定义好了:它们总是趋近数轴的左侧取整,因此Arith_div(-13,5)=-3,Arith_div(x,y)是不超过实数z的最大整数,其中z满足z*y=x。

Arith_mod(x,y)被定义为x-y*Arith_div(x,y)。因此Arith_mod(-13,5)=-13-5*(-3)=2

函数Arith_ceiling和Arith_floor遵循类似的约定,Arith_ceiling(x,y)返回不小于实数商x/y的最小整数

Arith_floor(x,y)返回不超过实数商x/y的最大整数

完整实现代码如下:

arith.c

抽象数据类型

抽象数据类型(abstract data type,ADT)是一个定义了数据类型以及基于该类型值提供的各种操作的接口

一个高级类型是抽象的,因为接口隐藏了它的表示细节,以免客户调用程序依赖这些细节,

下面是一个抽象数据类型(ADT)的规范化例子--堆栈,它定义了该类型以及五种操作:

stack.h

实现

包含相关头文件:

#include

#include “assert.h”

#include “mem.h”

#include “stack.h”

#define T Stack_T

Stack_T的内部是一个结构,该结构有个字段指向一个栈内指针的链表以及一个这些指针的计数:

struct T {

int count;

struct elem {

void *x;

struct elem *link;

} *head;

};

Stack_new分配并初始化一个新的T:

T Stack_new(void) {

T stk;

NEW(stk);

stk->count = 0;

stk->head = NULL;

return stk;

}

其中NEW是一个另一个接口中的一个分配宏指令。NEW(p)将分配该结构的一个实例,并将其指针赋给p,因此Stack_new中使用它就可以分配一个新的Stack_T

当count=0时,Stack_empty返回1,否则返回0:

int Stack_empty(T stk) {

assert(stk);

return stk->count == 0;

}

assert(stk)实现了可检查的运行期错误,它禁止空指针传给Stack中的任何函数。

Stack_push和Stack_pop从stk->head所指向的链表的头部添加或移出元素:

void Stack_push(T stk, void *x) {

struct elem *t;

assert(stk);

NEW(t);

t->x = x;

t->link = stk->head;

stk->head = t;

stk->count++;

}

void *Stack_pop(T stk) {

void *x;

struct elem *t;

assert(stk);

assert(stk->count > 0);

t = stk->head;

实验三_LINUX的C语言编程 篇4

要求:

1、请查阅资料,掌握vi编辑器的基本使用,包括两种不同模式的区别,如何在两种模式之间切换,以及常用的编辑命令等;

2、使用vi编写一个c程序,要求该程序通过命令行接收用户的输入,其输入参数为FreeBSD系统中的任意文本文件,接收输入后,c程序读取该文件内容,并打印在屏幕上。编辑好后,存为.c文件(如a.c),使用gcc编译该文件,运行结果文件。

3、详细记录学习的内容和实验的整个过程,包括用到的vi命令,c程序源代码,gcc命令,以及执行结果文件的命令等;

4、对整个实验过程进行分析总结,给出详细步骤;

一:vi编辑器的使用

vi 的两种命令模式;

Command(命令)模式,用于输入命令; Insert(插入)模式,用于插入文本;

Visual(可视)模式,用于视化的的高亮并选定正文;

Command 模式是vi或vim的默认模式,如果我们处于其它命令模式时,要通过ESC键切换过来。

当我们按ESC键后,接着再输入:号时,vi会在屏幕的最下方等待我们输入命令; 文件的保存和退出 :w 保存;

:w filename 另存为filename; :wq!保存退出;

:wq!filename 注:以filename为文件名保存后退出; :q!不保存退出;

:x 应该是保存并退出,功能和:wq!相同 光标移动

j 向下移动一行; k 向上移动一行; h 向左移动一个字符; l 向右移动一个字符;

插入模式(文本的插入)i 在光标之前插入; a 在光标之后插入;

I 在光标所在行的行首插入; A 在光标所在行的行末插入;

o 在光标所在的行的上面插入一行; O 在光标所在的行的下面插入一行;

s 删除光标后的一个字符,然后进入插入模式; S 删除光标所在的行,然后进入插入模式; 文本内容的删除操作 x 一个字符;

#x 删除几个字符,#表示数字,比如3x; dw 删除一个单词;

#dw 删除几个单词,#用数字表示,比如3dw表示删除三个单词; dd 删除一行;

#dd 删除多个行,#代表数字,比如3dd 表示删除光标行及光标的下两行; 恢复修改及恢复删除操作; u 撤消修改或删除操作;

查找

/SEARCH 注:正向查找,按n键把光标移动到下一个符合条件的地方; ?SEARCH 注:反向查找,按shift+n 键,把光标移动到下一个符合条件的 替换

:s /SEARCH/REPLACE/g 注:把当前光标所处的行中的SEARCH单词,替换成REPLACE,并把所有SEARCH高亮显示;

:%s /SEARCH/REPLACE 注:把文档中所有SEARCH替换成REPLACE;

:#,# s /SEARCH/REPLACE/g 注:#号表示数字,表示从多少行到多少行,把SEARCH替换成REPLACE;

二:编写程序和编译程序

先在home文件夹下建立test文件夹,用于自己的程序开发。

根据题目要求编写相应程序:

编写完程序后保存。

使用gcc命令编译时发现如下问题:

后来上网查找后发现FreeBSD默认不再使用GCC构建,使用Clang/LIVM替代GCC作为默认的C/C++编译器。

于是使用clang命令进行编译如下:

得到输出文件后,再新建一个test.txt文件用于测试。然后执行可执行文件:./a.out

由上可以看出,在执行编译命令后我并没有指定输出文件的类型和名称,a.out为默认输出的名称和类型,可以使用clang a.c –o test来生成不同类型和名称的输出文件。另外看到提示是输入文件的路径,如果是当前文件下的文件,则可以只输入文件的相对路径,如果在别的文件夹下则需要输入文件的绝对路径。如使用#cp /home/test/test.txt /home/test2.txt复制一个文件到别的目录后读取。测试如下:

三:程序源代码

#include int main(){ FILE *file;//定义文件指针

char path[20];//文件路径字符串

char msg[100];//读入数据缓存区

printf(“please enter the path of your filern”);//输出提示

scanf(“%s”,path);//获取文件路径

file = fopen(path);//打开文件

while(fgets(msg,sizeof(masg)-1,file)!=NULL)//逐行读取文件 直到文件末 { printf(“%s”,msg);//输出读取到的文件内容 } fclose(file);//关闭文件 return 0;//返回 } 四:实验总结和分析

本次实验首次使用vi编辑器编写了一段代码,并成功的编译并运行。首先说一下vi编辑器的使用感受,和window不太一样,它有不同的模式,只有在特定的模式下才能执行相应的命令或者操作。而且我发现了另一个很好用的ee编辑器,使用这个编辑器可以很方便的进行文件的操作,主要是它有很丰富的提示。但是为什么vi编辑器是大家常谈的呢?主要是vi编辑器体积小巧,功能强大,虽然在大的系统工程方面不太好用,但是正常的使用来说还是足够的,几乎所有的类似操作系统都会装有这一编辑器,学会vi编辑器的使用可以使自己在没有别的编辑器的情况下还能进行文件的编辑和系统的配置。这样对于日后的开发有很大的好处。另外在发现FreeBSD中没有安装gcc时,我尝试过给器安装一个gcc编辑器,但是却失败了,截图如下(图1),希望通过后面的学习安装上去。

图1:安装gcc编译器失败

Lua与C语言间的交互实例 篇5

Lua 是一门轻巧、灵活、扩展性很强的脚本语言,它可以很容易的嵌入到其他语言(C/C++)中使用,这主要得益于其提供了功能强大的 C API,这让其跟 C/C++ 间的互调成为一件很轻松的事,

Lua 调用 C

Lua 调用 C 函数,其实就是把 C 函数注册到 Lua 中去,把 C 函数地址传递给 Lua 解释器。这个传递是要遵循一个的协议的,即:

代码如下:

typedef int (*lua_CFunction)(lua_State* L)

Lua 和 C 是通过栈(State)来交互的,Lua 调用 C 函数时,首先 Lua 把数据拷贝到栈上,然后 C 从栈上获取数据,调用结束后将返回结果放到栈中。栈中的每个数据通过索引值进行定位,索引值为正时表示相对于栈底的偏移索引,索引值为负时表示相对于栈顶的偏移索引,索引值以1或-1为起始值,因此栈顶索引值永远为-1 ,栈底索引值永远为1 。栈相当于数据在 Lua 和 C 之间的中转站,每一个 C 函数都有自己的独立的私有栈。

利用 Lua 提供的 C API,调用 C 函数很简单,例如下面例子:

代码如下:

#include

#include “lua.h”

#include “lualib.h”

#include “lauxlib.h”

static int l_sin (lua_State *L)

{

double d = luaL_checknumber(L, 1);

lua_pushnumber(L, sin(d));

return 1;

}

static const struct luaL_Reg mylib [] = {

{“lsin”, l_sin},

{NULL, NULL}

};

int luaopen_mylib(lua_State *L)

{

luaL_openlib(L, “mylib”, mylib, 0);

return 1;

}

把上面代码编译成一个静态资源的 so 文件,加入把上面代码保存在一个名为 mylib.c 的文件下,把它编译成一个名为 libmylib.so 的静态资源文件里,gcc 编译语句如下:

代码如下:

gcc mylib.c -fPIC -shared -o libmylib.so

把上面代码放在 LUA_CPATH 目录下(LUA_CPATH 目录位置说明详看《Lua 学习笔记(4) -- 模块与包》,这里就不多说了),

把 libmylib.so 资源文件加载到模块目录下后,就可以在 Lua 代码里直接加载 require 进来使用,例如如下使用:

代码如下:

require “mytestlib”

上一篇:高一老师给学生的评语下一篇:七年级上册语文预习教案