- 浏览: 886286 次
- 性别:
- 来自: 杭州
-
文章分类
最新评论
-
hzw2312:
C = sin(MLatA)*sin(MLatB)*cos(M ...
根据地球上任意两点的经纬度计算两点间的距离 -
zhang_sun:
rewind方法的limit又是多少呢?等于capacity? ...
ByteBuffer的flip,clear及rewind区别 -
kalogen:
一种每次都获取到不同的随机数的办法int ranseed=12 ...
J2ME中Random类的使用 -
kalogen:
估计部署在某个端口下吧,仔细检查一下发布的配置文件
Tomcat负载均衡和集群环境的搭建 -
zhuchao_ko:
文件大点就嗝屁了~~~
Axis 1.4 上传二进制文件(base64Binary)
因为移动设备运行速度问题,J2ME开发比较注重程序的复杂度。为了寻求时间复杂度与空间复杂度的一个平衡,通常将程序分为多个页面。多个页面就需要一个管理工具。本文展示了一种经典的J2ME中管理多个页面的调度器。
基础结构
为每一个页面编写一个类,在每一个类中实现以下方法
//无参的构造方法 //执行的run方法 public void run() {} //绘图的paint方法,参数为屏幕的画笔 public void paint(Graphics g) {} //按键时的响应方法,参数为按键消息码 public void keyPressed(int key) {}
调度器应该继承Canvas类,实现Runnable接口,完成以下功能
1、changeState方法
负责一个页面到另一个页面的切换。为了节约资源,应该根据旧的状态量释放当前页面,再根据请求的新状态创建另一个页面。
2、run方法
根据状态量判断当前哪个页面,并调用它(当前页面)的run方法。
3、paint方法
调用当前页面的paint(绘图)方法
4、keyPressed方法
调用当前页面的keyPressed(键盘相应)方法
这些是基本的功能,还可以根据需要添加更多的Canvas类中的方法,实现更多功能。
实现示例
这里演示了ModelLogo,ModelMenu和ModelGame三个页面的切换
public class ZYMIDlet extends MIDlet { static ZYCanvas canvas = null; static ZYMIDlet midlet = null; /**初始动作 不要在构造函数中进行 可能出现问题 * 这主要是因为移动设备的资源性能都有限, * 因此此种程序开发的一个宗旨是“在需要用资源的时候申请,用完立刻释放” * */ public ZYMIDlet() { midlet = this; } /**大多数初始化工作是放在startApp中完成 * midlet创建的时候 执行完构造函数,会调用此函数,midlet进入活跃状态 * midlet从暂停状态 恢复的时候 也会自动调用此函数*/ public void startApp() { if(canvas == null) { canvas = new ZYCanvas(); } Display display = Display.getDisplay(this); display.setCurrent(canvas); } public void pauseApp() {} public void destroyApp(boolean unconditional) {} } class ZYCanvas extends Canvas implements Runnable { public static final byte STATE_LOGO = 0; public static final byte STATE_MENU = 1; public static final byte STATE_GAME = 2; public static int state; public ModelLogo modelLogo; public ModelMenu modelMenu; public ModelGame modelGame; public ZYCanvas() { state = STATE_LOGO; //开启线程 changeState(STATE_LOGO); } /**改变状态:这里可以做一些 上个状态的模块清除资源工作,和 新状态模块的初始化工作*/ public static void changeState(byte new_state) { //可做的事情:清除上一个模块的资源 state = new_state; //可作的事情:创建新状态模块,初始化 } //每80毫秒执行一次 public void run() { long time = System.currentTime(); action(); repaint(); //通知调用paint()函数 serverPaint(); //强制paint执行 long dur = System.currentTime() - time; long test = 80 - dur if(test > 0){ try{Thread.sleep(test);}catch(Exception e){} } } //可以把要做的事情全部放到一个函数中 public void action() { switch(state) { case STATE_LOGO: modelLogo.run();break; case STATE_MENU: modelMenu.run();break; case STATE_GAME: modelGame.run();break; } } //可以把要做的事情全部放到一个函数中 public void paint(Graphics g) { switch(state) { case STATE_LOGO: modelLogo.paint(g);break; case STATE_MENU: modelMenu.paint(g);break; case STATE_GAME: modelGame.paint(g);break; } } public void keyPressed(int key) { switch(state) { case STATE_LOGO: modelLogo.keyPressed(key);break; case STATE_MENU: modelMenu.keyPressed(key);break; case STATE_GAME: modelGame.keyPressed(key);break; } } } /**封装模块*/ class ModelLogo { public ModelLogo(){} public void run() { //运行自己的逻辑 //如果这个状态结束可以调用ZYCanvas.changeState()来改变状态 } public void paint(Graphics g){} public void keyPressed(int key){} } class ModelMenu { public ModelGame(){} public void run() { //运行自己的逻辑 //如果这个状态结束可以调用ZYCanvas.changeState()来改变状态 } public void paint(Graphics g){} public void keyPressed(int key){} } class ModelGame { public ModelGame(){} public void run() { //运行自己的逻辑 //如果这个状态结束可以调用ZYCanvas.changeState()来改变状态 } public void paint(Graphics g){} public void keyPressed(int key){} }
一些问题
通过调度器只需要调用changeState方法就可以在页面直接进行切换。但是实际应用时调度器有一些不足
我们想添加一个页面,需要声明一个状态量,再页面相应的类,然后在调度器每个方法中添加对于新的页面要执行的操作。
很明显的,不符合封装的设计思想。
怎样把调度器封装起来呢?
改进思路
很明显,我们要解决的最主要的问题是当调度器编写时,并不知道未来有一个什么样的页面类将要供调度器调度。
该如何使用未知的类?
我们可以应用java语言反射机制动态加载类来解决这类问题。通常,我们想要创建一个对象,我们采用以下方法
Class c = new Class();
java提供了动态加载类的机制,在运行时通过一个表示类名的字符串查找一个类并加载,还可以产生它的一个实例。使用方法如下
getClass().forName("package.className").newInstance();
只要创建一个调度器对象,再将页面类的类名添加进调度器,调度器使用动态加载类创建页面对象就可以了
改进
通过动态加载类创建的对象是Object类型的,显然这是没有我们想要的run,paint,keyPressed方法的,要通过强制类型转换把Object类型对象装换成含有这些方法的对象。
把它转换成什么类型对象合适,又如何保证用户编写的页面类肯定有这些方法呢?
通过java的接口来保证!
下面编写一个接口,规定用户编写的所有页面必须实现这个接口
package com.shiying.frame; import javax.microedition.lcdui.Graphics; //页面接口 public interface Model { public void run(); public void paint(Graphics g); public void keyPressed(int key); }
要使用动态加载类,应该保存每个页面类的类名字符串,同时还要保存每个页面所对应的状态量。最简单的使用集合来保存
private static Vector stateVector = new Vector(); private static Vector nameVector = new Vector();
为了调用当前类的方法,还要保存当前类的状态和对当前类对象的引用,这个页面应该是Model类型
private static Model model = null; private static byte state;
下面编写一个方法,用来向调度器注册页面
public void addModel(byte stateId, String modelClassName) { stateVector.addElement(new Byte(stateId)); nameVector.addElement(modelClassName); }
当用户发出切换页面的请求后,应该释放当前页面,并启动新的页面
/* * 通过状态查找在表中的位置 */ private static int searchState(byte state) { for (int n=0; nif (((Byte)Framework.stateVector.elementAt(n)).byteValue() == state) { return n; } } return -1; } /**改变状态:这里可以做一些 上个状态的模块清除资源工作,和 新状态模块的初始化工作*/ public static void changeState(byte new_state) { //清除上一个模块的资源 int index = searchState(state); if (index != -1) model = null; //状态转换 state = new_state; //创建新状态模块,初始化 index = searchState(new_state); if (index != -1) { String name = (String)Framework.nameVector.elementAt(index); Class c = null; try { c = Class.forName(name); model = (Model) c.newInstance(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } }
因为每个时刻至多有一个页面对象,所以不需要判断状态,对页面函数调用就非常简单
//每80毫秒执行一次 public void run() { while (true) { long time = System.currentTimeMillis(); action(); repaint(); //通知调用paint()函数 serviceRepaints(); //强制paint执行 long dur = System.currentTimeMillis() - time; long test = 80 - dur; if(test > 0){ try { Thread.sleep(test); } catch (InterruptedException e) { e.printStackTrace(); } } } } //可以把要做的事情全部放到一个函数中 public void action() { if (model != null) { model.run(); } } //可以把要做的事情全部放到一个函数中 public void paint(Graphics g) { if (model != null) { model.paint(g); } } public void keyPressed(int key) { if (model != null) { model.keyPressed(key); } }
编写一个启动调度器的方法,需要指明开启的第一个页面
public void go(byte start) { //开启线程 state = start; changeState(start); Thread th = new Thread(this); th.start(); }
OK,改装结束,整理一下代码
完整代码
// Main.java ////////////////////////////////////// package com.shiying.frame; import javax.microedition.lcdui.Display; import javax.microedition.midlet.MIDlet; import com.shiying.Application.Frame; public class Main extends MIDlet{ static Frame canvas = null; static Main midlet = null; public Main() { midlet = this; } public void startApp() { if(canvas == null) { canvas = new Frame(); } Display display = Display.getDisplay(this); display.setCurrent(canvas); } public void pauseApp() {} public void destroyApp(boolean unconditional) {} public static void shutDown() { midlet.notifyDestroyed(); } } // Model.java ////////////////////////////////////// package com.shiying.frame; import javax.microedition.lcdui.Graphics; //页面接口 public interface Model { public void run(); public void paint(Graphics g); public void keyPressed(int key); } // Framework.java ////////////////////////////////////// package com.shiying.frame; import java.util.Vector; import javax.microedition.lcdui.Canvas; import javax.microedition.lcdui.Graphics; public class Framework extends Canvas implements Runnable { public static Framework canvas = null; private static Vector stateVector = new Vector(); private static Vector nameVector = new Vector(); private static Model model = null; private static byte state; public Framework() { Framework.canvas = this; } public void go(byte start) { //开启线程 state = start; changeState(start); Thread th = new Thread(this); th.start(); } public void addModel(byte stateId, String modelClassName) { stateVector.addElement(new Byte(stateId)); nameVector.addElement(modelClassName); } /* * 通过状态查找在表中的位置 */ private static int searchState(byte state) { for (int n = 0; n < Framework.stateVector.size(); n++) { if (((Byte) Framework.stateVector.elementAt(n)).byteValue() == state) { return n; } } return -1; } /**改变状态:这里可以做一些 上个状态的模块清除资源工作,和 新状态模块的初始化工作*/ public static void changeState(byte new_state) { //清除上一个模块的资源 int index = searchState(state); if (index != -1) model = null; //状态转换 state = new_state; //创建新状态模块,初始化 index = searchState(new_state); if (index != -1) { String name = (String)Framework.nameVector.elementAt(index); Class c = null; try { c = Class.forName(name); model = (Model) c.newInstance(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } } //每80毫秒执行一次 public void run() { while (true) { long time = System.currentTimeMillis(); action(); repaint(); //通知调用paint()函数 serviceRepaints(); //强制paint执行 long dur = System.currentTimeMillis() - time; long test = 80 - dur; if(test > 0){ try { Thread.sleep(test); } catch (InterruptedException e) { e.printStackTrace(); } } } } //可以把要做的事情全部放到一个函数中 public void action() { if (model != null) { model.run(); } } //可以把要做的事情全部放到一个函数中 public void paint(Graphics g) { if (model != null) { model.paint(g); } } public void keyPressed(int key) { if (model != null) { model.keyPressed(key); } } }
如何使用
首先编写的所有页面需要实现Model接口,并且具有公有的无参构造方法
package com.shiying.Application; import javax.microedition.lcdui.Graphics; import com.shiying.frame.Model; /* * 这是一个页面的示例,每一个页面必须实现com.shiying.frame.Model接口 */ public class ModelDemo implements Model { /* * 页面必须具有一个共有的无参构造方法 */ public ModelDemo() { } /* * 这个方法中添加页面对按键消息的响应过程 */ public void keyPressed(int key) { // TODO Auto-generated method stub } /* * 这个方法实现页面绘图过程 */ public void paint(Graphics g) { // TODO Auto-generated method stub System.out.println("Demo paint"); g.drawString("Frame Demo", Frame.canvas.getWidth() / 2, 100, Graphics.HCENTER|Graphics.TOP); } /* * 这个方法实现页面要执行的操作 */ public void run() { // TODO Auto-generated method stub System.out.println("Demo run"); } }
下面编写一个调度器类,这个类是Framework类的子类
这个类需要完成的工作有
1、声明每个页面的状态量
2、注册页面类
3、启动第一个页面
package com.shiying.Application; import com.shiying.frame.Framework; public class Frame extends Framework { /* * 这里声明代表每个页面的状态量(页面ID) */ public static final byte STATE_DEMO = 0; public Frame() { super(); /* * 这里添加页面,需要传入两个参数,页面ID和相应页面类所在位置 */ this.addModel(Frame.STATE_DEMO, "com.shiying.Application.ModelDemo"); /* * 这里设置第一个活跃的页面 */ this.go(Frame.STATE_DEMO); } }
当这个类被创建时,第一个页面会被自动调用。在第一个页面中可以根据需要调用changeState可以切换到下一个页面。
原文地址:http://www.cnblogs.com/S-E-P/archive/2010/10/11/2045052.html
发表评论
-
eclipse中j2me项目引入jar包后,运行时报ClassNotFoundError的解决方法
2014-07-14 17:12 904在j2me项目中引入一个jar包,然后使用jar包里面的类做 ... -
wtk的默认模拟器修改
2014-04-29 00:07 653点击wtk目录下/bin/DefaultDevicew.e ... -
Could not find jar tool executable问题解决
2014-03-21 00:28 1268eclipse 中,在用PROGUARD生成混淆包Obfus ... -
WTK 模拟器的内存修改
2013-10-18 13:15 770在使用WTK模拟器运行较大的程序时偶尔会报内存不足的异常,解 ... -
j2me中sprite的旋转参考点的设定
2013-09-23 15:07 547默认在图片的左上角,可以用defineReferencePix ... -
J2ME用大华模拟器开发的一个小头痛的问题!
2013-08-21 15:06 816throw new UnsupportedOperation ... -
java/lang/OutOfMemoryError:Maximum byte code length (32kB) exceeded .
2013-02-05 17:18 1157Uncaught exception java/lang/ ... -
浅谈J2me游戏如何快速移植到Android
2012-06-12 14:25 814前言 小白:“老大,你让做的三个J2me游戏搞定了,请看DEM ... -
J2ME与Android系统的常用类、方法对比
2012-06-12 11:51 1044J2ME与Android系统的常用类、方法对比 ... -
serviceRepaints方法实现强制刷屏
2012-06-11 12:38 1138SUN在它的API里,说过。Forces any pendin ... -
J2ME中Random类的使用
2012-05-18 15:38 1162J2ME中,由于大部分的游戏都会涉及到随机性的事件,Rando ... -
J2ME程序开发全方位基础讲解
2012-05-17 11:16 958本文转自:http://innovator.samsung ... -
Png图片换色的方法
2012-05-10 16:52 2293对于"索引类型的图片 ... -
打造自由换色的png图片类 .
2012-05-10 16:21 870想像一下,有一个游戏,里面有很多种颜色的人,图片完全一样,只是 ... -
png图片结构分析与加密解密原理[转]
2012-05-10 11:06 3630PNG文件格式分为PNG-24和PNG-8,其最大的区别是PN ... -
NetBeans 字体设置
2012-05-03 11:21 1067最近下载了最新的NetBeans6.8玩玩,其实NetBean ... -
Netbeans 7和Subversion(svn) 1.7
2012-05-02 23:07 2081Netbeans的SVN插件,最后一次更新是07年了,所以它根 ... -
keyPressed接受不到部分按键
2009-04-09 18:04 1254今天测试一个贪吃蛇游戏,结果不管怎样按键,就是不接受到部分数字 ...
相关推荐
平原型生活垃圾填埋场扩容措施研究及应用_刘志刚.pdf
在日常的工作和学习中,你是否常常为处理复杂的数据、生成高质量的文本或者进行精准的图像识别而烦恼?DeepSeek 或许就是你一直在寻找的解决方案!它以其高效、智能的特点,在各个行业都展现出了巨大的应用价值。然而,想要充分发挥 DeepSeek 的优势,掌握从入门到精通的知识和技能至关重要。本文将从实际应用的角度出发,为你详细介绍 DeepSeek 的基本原理、操作方法以及高级技巧。通过系统的学习,你将能够轻松地运用 DeepSeek 解决实际问题,提升工作效率和质量,让自己在职场和学术领域脱颖而出。现在,就让我们一起开启这场实用又高效的学习之旅吧!
在日常的工作和学习中,你是否常常为处理复杂的数据、生成高质量的文本或者进行精准的图像识别而烦恼?DeepSeek 或许就是你一直在寻找的解决方案!它以其高效、智能的特点,在各个行业都展现出了巨大的应用价值。然而,想要充分发挥 DeepSeek 的优势,掌握从入门到精通的知识和技能至关重要。本文将从实际应用的角度出发,为你详细介绍 DeepSeek 的基本原理、操作方法以及高级技巧。通过系统的学习,你将能够轻松地运用 DeepSeek 解决实际问题,提升工作效率和质量,让自己在职场和学术领域脱颖而出。现在,就让我们一起开启这场实用又高效的学习之旅吧!
在日常的工作和学习中,你是否常常为处理复杂的数据、生成高质量的文本或者进行精准的图像识别而烦恼?DeepSeek 或许就是你一直在寻找的解决方案!它以其高效、智能的特点,在各个行业都展现出了巨大的应用价值。然而,想要充分发挥 DeepSeek 的优势,掌握从入门到精通的知识和技能至关重要。本文将从实际应用的角度出发,为你详细介绍 DeepSeek 的基本原理、操作方法以及高级技巧。通过系统的学习,你将能够轻松地运用 DeepSeek 解决实际问题,提升工作效率和质量,让自己在职场和学术领域脱颖而出。现在,就让我们一起开启这场实用又高效的学习之旅吧!
Wallpaper Engine 是一款广受欢迎的动态壁纸软件,允许用户将各种动态、交互式壁纸应用到桌面上。其丰富的创意工坊内容让用户可以轻松下载和分享个性化的壁纸。而“一键提取”功能则是 Wallpaper Engine 中一个非常实用的工具,能够帮助用户快速提取和保存壁纸资源,方便后续使用或分享。
在日常的工作和学习中,你是否常常为处理复杂的数据、生成高质量的文本或者进行精准的图像识别而烦恼?DeepSeek 或许就是你一直在寻找的解决方案!它以其高效、智能的特点,在各个行业都展现出了巨大的应用价值。然而,想要充分发挥 DeepSeek 的优势,掌握从入门到精通的知识和技能至关重要。本文将从实际应用的角度出发,为你详细介绍 DeepSeek 的基本原理、操作方法以及高级技巧。通过系统的学习,你将能够轻松地运用 DeepSeek 解决实际问题,提升工作效率和质量,让自己在职场和学术领域脱颖而出。现在,就让我们一起开启这场实用又高效的学习之旅吧!
在日常的工作和学习中,你是否常常为处理复杂的数据、生成高质量的文本或者进行精准的图像识别而烦恼?DeepSeek 或许就是你一直在寻找的解决方案!它以其高效、智能的特点,在各个行业都展现出了巨大的应用价值。然而,想要充分发挥 DeepSeek 的优势,掌握从入门到精通的知识和技能至关重要。本文将从实际应用的角度出发,为你详细介绍 DeepSeek 的基本原理、操作方法以及高级技巧。通过系统的学习,你将能够轻松地运用 DeepSeek 解决实际问题,提升工作效率和质量,让自己在职场和学术领域脱颖而出。现在,就让我们一起开启这场实用又高效的学习之旅吧!
这是一份非常有意义的实习报告
在日常的工作和学习中,你是否常常为处理复杂的数据、生成高质量的文本或者进行精准的图像识别而烦恼?DeepSeek 或许就是你一直在寻找的解决方案!它以其高效、智能的特点,在各个行业都展现出了巨大的应用价值。然而,想要充分发挥 DeepSeek 的优势,掌握从入门到精通的知识和技能至关重要。本文将从实际应用的角度出发,为你详细介绍 DeepSeek 的基本原理、操作方法以及高级技巧。通过系统的学习,你将能够轻松地运用 DeepSeek 解决实际问题,提升工作效率和质量,让自己在职场和学术领域脱颖而出。现在,就让我们一起开启这场实用又高效的学习之旅吧!
爱华AIWA HS-J9磁带随身听维修服务手册 说明书电路原理图PCB图
在日常的工作和学习中,你是否常常为处理复杂的数据、生成高质量的文本或者进行精准的图像识别而烦恼?DeepSeek 或许就是你一直在寻找的解决方案!它以其高效、智能的特点,在各个行业都展现出了巨大的应用价值。然而,想要充分发挥 DeepSeek 的优势,掌握从入门到精通的知识和技能至关重要。本文将从实际应用的角度出发,为你详细介绍 DeepSeek 的基本原理、操作方法以及高级技巧。通过系统的学习,你将能够轻松地运用 DeepSeek 解决实际问题,提升工作效率和质量,让自己在职场和学术领域脱颖而出。现在,就让我们一起开启这场实用又高效的学习之旅吧!
房屋租赁合同[示范文本].doc
在日常的工作和学习中,你是否常常为处理复杂的数据、生成高质量的文本或者进行精准的图像识别而烦恼?DeepSeek 或许就是你一直在寻找的解决方案!它以其高效、智能的特点,在各个行业都展现出了巨大的应用价值。然而,想要充分发挥 DeepSeek 的优势,掌握从入门到精通的知识和技能至关重要。本文将从实际应用的角度出发,为你详细介绍 DeepSeek 的基本原理、操作方法以及高级技巧。通过系统的学习,你将能够轻松地运用 DeepSeek 解决实际问题,提升工作效率和质量,让自己在职场和学术领域脱颖而出。现在,就让我们一起开启这场实用又高效的学习之旅吧!
单片机 入门学习视频教程 自学资料
在日常的工作和学习中,你是否常常为处理复杂的数据、生成高质量的文本或者进行精准的图像识别而烦恼?DeepSeek 或许就是你一直在寻找的解决方案!它以其高效、智能的特点,在各个行业都展现出了巨大的应用价值。然而,想要充分发挥 DeepSeek 的优势,掌握从入门到精通的知识和技能至关重要。本文将从实际应用的角度出发,为你详细介绍 DeepSeek 的基本原理、操作方法以及高级技巧。通过系统的学习,你将能够轻松地运用 DeepSeek 解决实际问题,提升工作效率和质量,让自己在职场和学术领域脱颖而出。现在,就让我们一起开启这场实用又高效的学习之旅吧!
在日常的工作和学习中,你是否常常为处理复杂的数据、生成高质量的文本或者进行精准的图像识别而烦恼?DeepSeek 或许就是你一直在寻找的解决方案!它以其高效、智能的特点,在各个行业都展现出了巨大的应用价值。然而,想要充分发挥 DeepSeek 的优势,掌握从入门到精通的知识和技能至关重要。本文将从实际应用的角度出发,为你详细介绍 DeepSeek 的基本原理、操作方法以及高级技巧。通过系统的学习,你将能够轻松地运用 DeepSeek 解决实际问题,提升工作效率和质量,让自己在职场和学术领域脱颖而出。现在,就让我们一起开启这场实用又高效的学习之旅吧!
在日常的工作和学习中,你是否常常为处理复杂的数据、生成高质量的文本或者进行精准的图像识别而烦恼?DeepSeek 或许就是你一直在寻找的解决方案!它以其高效、智能的特点,在各个行业都展现出了巨大的应用价值。然而,想要充分发挥 DeepSeek 的优势,掌握从入门到精通的知识和技能至关重要。本文将从实际应用的角度出发,为你详细介绍 DeepSeek 的基本原理、操作方法以及高级技巧。通过系统的学习,你将能够轻松地运用 DeepSeek 解决实际问题,提升工作效率和质量,让自己在职场和学术领域脱颖而出。现在,就让我们一起开启这场实用又高效的学习之旅吧!
auto_gptq-0.5.1.tar.gz
# 踏入C语言的奇妙编程世界 在编程的广阔宇宙中,C语言宛如一颗璀璨恒星,以其独特魅力与强大功能,始终占据着不可替代的地位。无论你是编程小白,还是有一定基础想进一步提升的开发者,C语言都值得深入探索。 C语言的高效性与可移植性令人瞩目。它能直接操控硬件,执行速度快,是系统软件、嵌入式开发的首选。同时,代码可在不同操作系统和硬件平台间轻松移植,极大节省开发成本。 学习C语言,能让你深入理解计算机底层原理,培养逻辑思维和问题解决能力。掌握C语言后,再学习其他编程语言也会事半功倍。 现在,让我们一起开启C语言学习之旅。这里有丰富教程、实用案例、详细代码解析,助你逐步掌握C语言核心知识和编程技巧。别再犹豫,加入我们,在C语言的海洋中尽情遨游,挖掘无限可能,为未来的编程之路打下坚实基础!
结构体 struct关键字用来定义结构体