❶ NiO是什么
Java NIO框架MINA用netty性能和链接数、并发等压力测试参数好于mina。
特点:
1。NIO弥补了原来的I/O的不足,它再标准java代码中提供了高速和面向块的I/O
原力的I/O库与NIO最重要的区别是数据打包和传输方式的不同,原来的I/O以流的方式处理数据,而NIO以块的方式处理数据;
2.NIO以通道channel和缓冲区Buffer为基础来实现面向块的IO数据处理,MINA是开源的。
JavaNIO非堵塞应用通常适用用在I/O读写等方面,我们知道,系统运行的性能瓶颈通常在I/O读写,包括对端口和文件的操作上,过去,在打开一个I/O通道后,read()将一直等待在端口一边读取字节内容,如果没有内容进来,read()也是傻傻的等,这会影响我们程序继续做其他事情,那么改进做法就是开设线程,让线程去等待,但是这样做也是相当耗费资源的。
Java NIO非堵塞技术实际是采取Reactor模式,或者说是Observer模式为我们监察I/O端口,如果有内容进来,会自动通知我们,这样,我们就不必开启多个线程死等,从外界看,实现了流畅的I/O读写,不堵塞了。
Java NIO出现不只是一个技术性能的提高,会发现网络上到处在介绍它,因为它具有里程碑意义,从JDK1.4开始,Java开始提高性能相关的功能,从而使得Java在底层或者并行分布式计算等操作上已经可以和C或Perl等语言并驾齐驱。
如果至今还是在怀疑Java的性能,说明思想和观念已经完全落伍了,Java一两年就应该用新的名词来定义。从JDK1.5开始又要提供关于线程、并发等新性能的支持,Java应用在游戏等适时领域方面的机会已经成熟,Java在稳定自己中间件地位后,开始蚕食传统C的领域。
原理:
NIO 有一个主要的类Selector,这个类似一个观察者,只要我们把需要探知socketchannel告诉Selector,我们接着做别的事情,当有事件发生时,他会通知我们,传回一组SelectionKey,我们读取这些Key,就会获得我们刚刚注册过的socketchannel,然后,我们从这个Channel中读取数据,放心,包准能够读到,接着我们可以处理这些数据。Selector内部原理实际是在做一个对所注册的channel的轮询访问,不断的轮询(目前就这一个算法),一旦轮询到一个channel有所注册的事情发生。比如数据来了,他就会站起来报告,交出一把钥匙,让我们通过这把钥匙来读取这个channel的内容。在使用上,也在分两个方向,一个是线程处理,一个是用非线程,后者比较简单。
❷ 用Nio技术实现c/s结构程序
服务端程序:
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;
public class NioServer {
public static final int SERVERPORT=5555;
public static final String[] USERNAME={"1","2","3","4","5","jack","tom"};
public static final String PASSWORD="1";
public static final String ISACK="ACK";
public static final String ISNAK="NAK!";
// Selector selector;//选择器
// SelectionKey key;//key。 一个key代表一个Selector 在NIO通道上的注册,类似主键;
// //取得这个Key后就可以对Selector在通道上进行操作
private ByteBuffer echoBuffer = ByteBuffer.allocate( 1024 );// 通道数据缓冲区
public NioServer(){
}
public static void main(String[] args) throws IOException {
NioServer ns=new NioServer();
ns.BuildNioServer();
}
public void BuildNioServer() throws IOException{
/////////////////////////////////////////////////////////
///////先对服务端的ServerSocket进行注册,注册到Selector ////
/////////////////////////////////////////////////////////
ServerSocketChannel ssc = ServerSocketChannel.open();//新建NIO通道
ssc.configureBlocking( false );//使通道为非阻塞
ServerSocket ss = ssc.socket();//创建基于NIO通道的socket连接
//新建socket通道的端口
ss.bind(new InetSocketAddress("127.0.0.1",SERVERPORT));
Selector selector=Selector.open();//获取一个选择器
//将NIO通道选绑定到择器,当然绑定后分配的主键为skey
//SelectionKey skey =
ssc.register( selector, SelectionKey.OP_ACCEPT );
////////////////////////////////////////////////////////////////////
//// 接收客户端的连接Socket,并将此Socket也接连注册到Selector ////
///////////////////////////////////////////////////////////////////
while(true){
int num = selector.select();//获取通道内是否有选择器的关心事件
if(num<1){continue; }
Set selectedKeys = selector.selectedKeys();//获取通道内关心事件的集合
Iterator it = selectedKeys.iterator();
while (it.hasNext()) {//遍历每个事件
try{
SelectionKey key = (SelectionKey)it.next();
//有一个新联接接入事件,服务端事件
if ((key.readyOps() & SelectionKey.OP_ACCEPT)
== SelectionKey.OP_ACCEPT) {
// 接收这个新连接
ServerSocketChannel serverChanel = (ServerSocketChannel)key.channel();
//从serverSocketChannel中创建出与客户端的连接socketChannel
SocketChannel sc = serverChanel.accept();
sc.configureBlocking( false );
// Add the new connection to the selector
// 把新连接注册到选择器
//SelectionKey newKey =
sc.register( selector, SelectionKey.OP_READ );
it.remove();
System.out.println( "Got connection from "+sc );
}else
//读客户端数据的事件,此时有客户端发数据过来,客户端事件
if((key.readyOps() & SelectionKey.OP_READ)
== SelectionKey.OP_READ){
// 读取数据
SocketChannel sc = (SocketChannel)key.channel();
while(sc.read(echoBuffer)> 0){ ;}
echoBuffer.flip();
byte [] content = new byte[echoBuffer.limit()];
echoBuffer.get(content);
String result=new String(content);
doPost(result,sc);
echoBuffer.clear();
it.remove();
}
}catch(Exception e){}
}
}
}
Hashtable table=new Hashtable();
public void doPost(String str,SocketChannel sc){
boolean isok=false;
int index=str.indexOf('|');
if(index>=0){ //index>0 有"|"符号,代表登陆,没有表示普通聊天
String name=str.substring(0,index);
String pswd=str.substring(index+1);
if(pswd==null){pswd="";}
if(name!=null){
if(pswd.equals(PASSWORD) ){
isok=false;
for(int i=0;i<USERNAME.length;i++){
if(USERNAME[i].equals(name)){
isok=true;
break;
}
}
}else{
isok=false;
}
}else{
isok=false;
}
String result="";
if(isok){
result="ACK";
//加入到用户通道列表中
User user=new User();
user.password=pswd;
user.name=name;
user.sc=sc;
table.put(user.name, user);
}else{
result="NAK!";
}
ByteBuffer bb = ByteBuffer.allocate( result.length() );
bb.put(result.getBytes());
bb.flip();
try {
sc.write(bb);
} catch (IOException e) {
e.printStackTrace();
}
bb.clear();
}else{ //普通聊天
//遍历所有己注册通道,向所有人发消息(包括发送者自己)
System.out.println("通道数:"+table.size());
Enumeration en=table.elements();
while(en.hasMoreElements()){
User user=(User)en.nextElement();
SocketChannel channel=user.sc;
if(user!=null && channel!=null && channel.isConnected()){
System.out.println("发送:str"+str);
ByteBuffer bb = ByteBuffer.allocate( str.length() );
bb.put(str.getBytes());
bb.flip();
try {
channel.write(bb);
} catch (IOException e) {
e.printStackTrace();
}
bb.clear();
}else{
if(user!=null && user.name!=null){
table.remove(user.name);
}
}
}
}
}
public class User{
public String name="";
public String password="";
public boolean isLogin=false;
public SocketChannel sc=null;
}
}
客户端:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class UserClient implements ActionListener{
JFrame jf;
JPanel jp;
JLabel label_name;
JLabel label_pswd;
JTextField userName;
JButton jb;
JPasswordField paswrd;
JLabel hintStr;
public UserClient (){
jf=new JFrame("XXX 登陆系统");
jp=new JPanel();
jf.setContentPane(jp);
jf.setPreferredSize(new Dimension(350,220));
jp.setPreferredSize(new Dimension(350,220));
jp.setBackground(Color.gray);
label_name=new JLabel();
label_name.setPreferredSize(new Dimension(150,30));
label_name.setText("请输入帐户(数字或英文):");
userName=new JTextField();
userName.setPreferredSize(new Dimension(150,30));
jp.add(label_name);
jp.add(userName);
label_pswd=new JLabel();
label_pswd.setPreferredSize(new Dimension(150,30));
label_pswd.setText("请输入密码:");
jp.add(label_pswd);
paswrd=new JPasswordField();
paswrd.setPreferredSize(new Dimension(150,30));
jp.add(paswrd);
jb=new JButton("OK");
jb.setPreferredSize(new Dimension(150,30));
jb.setText("确 定");
jb.addActionListener( this);
jp.add(jb);
hintStr=new JLabel();
hintStr.setPreferredSize(new Dimension(210,40));
hintStr.setText("");
hintStr.setForeground(Color.RED);
jp.add(hintStr);
jf.pack();
jf.setVisible(true);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private String name;
private String pswd;
public void actionPerformed(ActionEvent e) {
if(e.getSource()==jb){
name=userName.getText().trim();
pswd=new String(paswrd.getPassword());
if(pswd==null){
pswd="";
}else{
pswd=pswd.trim();
}
if(name!=null && name.length()>0){
hintStr.setText("正在验证客户端,请稍候...");
start();
}
}else
if(e.getSource()==clear){//清屏
text.setText("");
}else
if(e.getSource()==send){//发送
String msg=this.jtf.getText();
if(msg!=null){
if(msg.trim().length()>0){
msg=" "+name+" said:"+msg+"\r\n";
sendMessage(msg);
jtf.setText("");
}
}
}
}
OutputStream os;
Socket s;
InputStream is;
public void start(){
//建立联网线程
new Thread(new Runnable(){
public void run() {
try {
s=new Socket("127.0.0.1",5555);
//写
os=s.getOutputStream();
os.write(name.getBytes());
os.write('|');//用户名与密码用"|"分隔
os.write(pswd.getBytes());
os.flush();
//读内容
Thread.sleep(1000);
is=s.getInputStream();
int len=is.available();
System.out.println("len:"+len);
byte[] bytes=new byte[len];
is.read(bytes);
String resut=new String(bytes);
System.out.println("resut:"+resut);
if(resut.equals("ACK")){
hintStr.setText("验证成功,欢迎光临!");
//TODO 这里通过返回结果处理
handleLoginResult();
}else{
paswrd.setText(null);
hintStr.setText("用户名或密码错误,请重新输入");
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
}
}
}).start();
}
////////////////////////////////////////////////////////////////////
//处理登陆结果,出新界面
//登陆后新界面的元素组件定义在这里,注意,
//现在随便弄的,你要改漂亮些
////////////////////////////////////////////////////////////////////
JTextArea text;
JButton send;
JButton clear;
JTextArea jtf;
public void handleLoginResult(){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.jp.removeAll();//清空所有组件;
jf.setSize(800,600);
jp.setSize(800,600);
jf.setPreferredSize(new Dimension(800,600));
jp.setPreferredSize(new Dimension(800,600));
//加聊天内容框
text=new JTextArea();
text.setBackground(Color.WHITE);
text.setForeground(Color.BLUE);
text.setPreferredSize(new Dimension(750,450));
jp.add(text);
//加发送内容框
jtf=new JTextArea();
jtf.setPreferredSize(new Dimension(750,50));
jp.add(jtf);
//加按钮
send=new JButton("发送");
clear=new JButton("清屏");
send.setPreferredSize(new Dimension(100,30));
clear.setPreferredSize(new Dimension(100,30));
jp.add(send);
jp.add(clear);
send.addActionListener(this);
clear.addActionListener(this);
jf.pack();
jf.repaint();
//开始读线程
readMessage();
}
//////////////////////////////////////////////////////
//发送消息线程
//////////////////////////////////////////////////////
public void sendMessage(String msg){
final String toSend=msg;
new Thread(
new Runnable(){
public void run(){
if(s==null ){
return;
}
//写
try {
System.out.println("发送:"+toSend);
os.write(toSend.getBytes());
os.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
).start();
}
/////////////////////////////////////////////////////////
//读取线程,死循环,不停读取
public boolean isRunning=true;
public void readMessage( ){
new Thread(
new Runnable(){
public void run(){
while(isRunning){
if(s==null ){
return;
}
try {
InputStream is=s.getInputStream();
int len=is.available();
//System.out.println("len:"+len);
byte[] bytes=new byte[len];
is.read(bytes);
String resut=new String(bytes);
//System.out.println("resut:"+resut);
if(resut!=null && resut.length()>0){
System.out.println("收到!!!resut:"+resut);
text.append(resut);
}
} catch (IOException e) {
e.printStackTrace();
}
//睡眠2秒
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
).start();
}
public static void main(String[] args) {
new UserClient();
}
}
❸ 怎样学好c语言
我相信,这可能是很多朋友的问题,我以前也有这样的感觉,编程编到一定的时候,发现能力到了瓶颈,既不深,也不扎实,半吊子。比如:你长期地使用Java和.NET ,这些有虚拟机的语言对于开发便利是便利,但是对于程序员来说可能并不太好,原因有两个:
虚拟机屏蔽了操作系统的系统调用,以及很多底层机制。
大量的封装好的类库也屏蔽了很多实现细节。
一段时间后,你会发现你知其然,不知所以然。。我以前在CSDN上写过一篇《Java NIO类库Selector机制解析(上,下,续)》,在那篇文章中我说提到过(有讥讽的语气)Java的程序员不懂底层实现,所以很难把技术学得更扎实。此时,一部分程序员会不自然地想学学底层的技术,很自然的,C语言就被提了上来。
下面是我给这位朋友的一些建议:
鼓励并为你叫好。我鼓励你想要去学C语言的想法和精神,很多人都觉得C语言好学,其实并不然。(你可以看看《C语言的迷题》)现在的这个社会更多地去关注那些时髦的技术,而忽略了这个流行了40+年的C语言。一门技术如果能够流行40多年,这才是你需要去关注和学习的技术,而不是那些刚出来的技术(过度炒作的技术,Windows编程史)。这才是踏踏实实的精神。
不要找借口。这一条路走下来并不容易,不要给自己找借口。我最不喜欢听到的就是“很忙,没有时间”这样的借口。我以前在银行做项目,早9点到晚10点,周一到周六,我一样可以每天抽1个小时来看书和专研,一年下来也能精读5、6本书。我现在的工作项目和招聘任务很紧张,刚生的小孩只有自己和老婆两人带,还需要准备讲课,但是我还是能够找到时间看文章写文章维护酷壳。所以,我可以告诉你,“时间就像乳沟,只要你肯挤,就一定会有”。
学好C语言和系统编程。我认为,学好编程有四个方面:语言、算法和数据结构、系统调用和设计。
语言。我可以告诉你C语言有两大主题你要好好学,一个是内存管理,一个是指针!这个世界上90%以上的C/C++出的严重性错误全是和这两个有关。不要看谭浩强的那本书,那本是本烂书。推荐这本书给你《C程序设计语言(第2版·新版)》
算法和数据结构。我认为,用C语言实现算法和数据结构莫过于最爽的事情。推荐你看这本书——算法:C语言实现(第1~4部分)基础知识、数据结构、排序及搜索(原书第3版),还有那本经典的《算法导论》
系统编程。Windows下推荐两本书——《Windows 程序设计 》和《Windows核心编程》,Unix/Linux下推荐两本书——《Unix高级环境编程》和《Unix网络编程卷1,套接字》《Unix网络编程卷2,进程间通信》尤其是《Unix网络编程》这本书,一通百通,无论Windows还是Unix/Linux,都是一样的。
系统设计。关于设计方面,我全力推荐《Unix编程艺术》,看完以后,你就明白什么是真正的编程文化了。然后,当你看到Windows的Fans的某些言论时,你就知道什么叫一笑了之了。
如果你能在2-3年内精读完这些书,并全部融会贯通,那么你就明白什么是一览众山小的感觉了!我足足花了5年时间才算是真正全部读完这些书的。最后,祝你好运!努力!
——-更新:2011/03/29 20:00——-
我想,这篇文章主要想告诉大家这么几件事:
编程编到一定时候,你就需要了解底层系统的机制,否则,知其然不知所以然。
我没有否定非C的程序员的逻辑,真正的逻辑是——如果你想要了解底层机制,请学习C语言和操作系统。
40多年的Unix/C影响深远。包括影响了Windows。如果你想一通百通,一定要了解Unix。那是计算机文化真正的根。
不要肤浅地去思考问题。比如,不要以为一个DBA就不会考虑数据库引擎的内存页面的问题。也不要以为Web程序员就不需要了解后台的服务器和脚本的运行性能以及TCP/IP的问题。
❹ C语言 阻塞,非阻塞和多线程有什么关系
阻塞是在传统的网络编程中我们依赖于ServerSocket,Socket进行通信,大致的框架就是ServerSocket调用accept方法,等待客户端的连接,如果连接进来的时候则创建一个服务器端socket,客户端和服务器端socket建立好InputStream 和outputStream通道进行通信,在这个网络IO的过程中inputStream的read 和outputStream的write方法都可能发送阻塞。为了减少这种阻塞对其他连接的影响,一般都会在服务器端为每个连接开辟一个新的线程,或者使用线程池技术来避免线程的创建销毁同时又一定程度支持并发量。然而这种情况下,如果发生大量的read 或者write阻塞线程池的效率会大大降低,而且操作系统也额外需要频繁的处理cpu的切换。
非阻塞式通信实际是对上述模式的扩展,它的核心思想是为传统的socket加入事件监听的功能,操作系统可以在socket和serversocket上进行事件监听,一旦监听的对象发生了连接和可读可写的事件,监听器就会对注册了事件的对象返回相应的通知。在javaNIO中实现这一套的机制就是把socket 和ServerSocket重写成为SocketChanel,ServerSocketChanel,他们的底层仍然使用socket实现,所以原则上javaNIO包可以完全实现阻塞和非阻塞两种编程模式。事件监听的功能由Selection类完成,他使用select方法一直阻塞式监听注册了的事件是否发生,对于每一个发生的事件,他都会返回一个selectionKey,通过这个key我们就可以确定这个事件的发生源(socket)和相关信息。对于ServerSocketChanel,Socketchanel分别对应了不同的事件,serverChanel只有OP_ACCEPT代表是否可以接受连接,而socketChanel则有OP_CONNECT、read、write事件。笔者认为与阻塞IO相比他的优势在于可以避免read 和write的阻塞,因为这个比较具有实际意义的。比如是一个网络文件传输系统,read方法可能会因为网络原因发生多次阻塞,使用非阻塞IO read的话线程可以立即返回去处理其他任务。
多线程是在进程中进一步去划分的独立单元。
❺ 关于计算机编程c语言,java,自学看哪些书比较浅显易懂
加入不是想直接找工作的话建议从c语言学起,入门推荐C primer plus第六版,虽然有些厚,但是比起国内的一些书好了很多,入门后看c和指针以及一些数据结构的书。java的话可以看java核心技术。最好边看书边看看讲解视频。
❻ NIO和TIJ是什么
JDK 1.4版本(包括之后的版本)最显着的新特性就是增加了NIO(New IO),能够以非阻塞的方式处理网络的请求,这就使得在Java中只需要少量的线程就能处理大量的并发请求了。但是使用NIO不是一件简单的技术,它的一些特点使得编程的模型比原来阻塞的方式更为复杂。
在JDK 1.4的新特性中,NIO无疑是最显着和鼓舞人心的。NIO的出现事实上意味着Java虚拟机的性能比以前的版本有了较大的飞跃。在以前的JVM的版本中,代码的执行效率不高(在最原始的版本中Java是解释执行的语言),用Java编写的应用程序通常所消耗的主要资源就是CPU,也就是说应用系统的瓶颈是CPU的计算和运行能力。在不断更新的Java虚拟机版本中,通过动态编译技术使得Java代码执行的效率得到大幅度提高,几乎和操作系统的本地语言(例如C/C++)的程序不相上下。在这种情况下,应用系统的性能瓶颈就从CPU转移到IO操作了。尤其是服务器端的应用,大量的网络IO和磁盘IO的操作,使得IO数据等待的延迟成为影响性能的主要因素。NIO的出现使得Java应用程序能够更加紧密地结合操作系统,更加充分地利用操作系统的高级特性,获得高性能的IO操作。
JIT Compiler(Just-in-time Compiler) 即时编译 最早的Java建置方案是由一套转译程式(interpreter),将每个Java指令都转译成对等的微处理器指令,并根据转译后的指令先后次序依序执行,由于一个Java指令可能被转译成十几或数十几个对等的微处理器指令,这种模式执行的速度相当缓慢。 针对这个问题,业界首先开发出JIT(just in time)编译器。当Java执行runtime环境时,每遇到一个新的类别(class:类别是Java程式中的功能群组),类别是Java程式中的功能群组-JIT编译器在此时就会针对这个类别进行编译(compile)作业。经过编译后的程式,被优化成相当精简的原生型指令码(native code),这种程式的执行速度相当快。花费少许的编译时间来节省稍后相当长的执行时间,JIT这种设计的确增加不少效率,但是它并未达到最顶尖的效能,因为某些极少执行到的Java指令在编译时所额外花费的时间可能比转译器在执行时的时间还长,针对这些指令而言,整体花费的时间并没有减少。 基于对JIT的经验,业界发展出动态编译器(dynamic compiler),动态编译器仅针对较常被执行的程式码进行编译,其余部分仍使用转译程式来执行。也就是说,动态编译器会研判是否要编译每个类别。动态编译器拥有两项利器:一是转译器,另一则是JIT,它透过智慧机制针对每个类别进行分析,然后决定使用这两种利器的哪一种来达到最佳化的效果。动态编译器针对程式的特性或者是让程式执行几个循环,再根据结果决定是否编译这段程式码。这个决定不见得绝对正确,但从统计数字来看,这个判断的机制正确的机会相当高。事实上,动态编译器会根据“历史资料”做决策,所以程式执行的时间愈长,判断正确的机率就愈高。以整个结果来看,动态编译器产生的程式码执行的速度超越以前的JIT技术,平均速度可提高至50%。
❼ c语言socket客户端怎么发送到mina nio
按 格式,生成相应的unsigned char [] 数据,传送就是了
~
~
~
~
~
❽ C语言中buffer到底是什么意思是数组缓冲区为什么一般C程序中都不定义他直接拿来用呢
Buffer是NodeJS的重要数据类型,很有广泛的应用。代表原始堆的分配额的数据类型。在NodeJS中以类数组的方式使用。
在Buffer类的描述中,Buffer被定义为用于特定基本类型数据的容器,且是特定基本类型的线性优先元素序列。
Buffer提供了一个字节缓冲区,它可以从channels中读取数据到Buffer,也可以将Buffer中的数据写入到channels,所以NIO被定义为面向缓冲区编程,而IO则是被定义为面向流的编程。
当一个缓存中的数据被多次读取,实际上就减少了该数据从慢速设备中读取的量,这就存在某种算法去选择什么数据需要保存在cache中,因为尽可能多的让cache命中能提高性能。
(8)c语言nio扩展阅读
Buffer类的四个变量
1、capacity
容量,必须初始化的值(因为底层是数组)
2、limit
上界,缓冲区的临界区,即最多可读到哪个位置
3、position
下标,当前读取到的位置(例如当前读出第5个元素,则读完后,position为6)
4、mark
标记,备忘位置
❾ c语言中的union是什么意思啊
c语言中的union是联合体,就是一个多个变量的结构同时使用一块内存区域,区域的取值大小为该结构中长度最大的变量的值。
声明一个struct类型,为date,有一个实例变量today,如果int的大小占4个字节,第一句输出12,union表示可以有多种方法来看待这个数据类型,里面的的数据是共享内存空间的,大小应该是union中最大的类型,第二句输出8。
所在函数库为【ctype.h】
int isalpha(int ch) 若ch是字母('A'-'Z','a'-'z')返回非0值,否则返回0
int isalnum(int ch) 若ch是字母('A'-'Z','a'-'z')或数字('0'-'9')
返回非0值,否则返回0
intisascii(int ch) 若ch是字符(ASCII码中的0-127)返回非0值,否则返回0
intiscntrl(int ch) 若ch是作废字符(0x7F)或普通控制字符(0x00-0x1F)
以上内容参考:网络-C语言函数
❿ C语言union的用法
1、我们利用C语言定义一个简单的Union共用体结构。