笔记 时间2012年2月15日14:35:30
win 孙鑫笔记
第一节 windows 程序原理介绍
windowsapi application programming interface
关于消息和队列 MSDN 微软提供的帮助文件 专业全 MSDN开发帮助ty文档
typedef struct tagMSG //MSG 的宏定义
{
HWND hwnd//资源的标识;
UINT //无符号的整型 message;
WPRAM wParam;//char code
LPARAM lParam;//kebord
DWORD time;//消息传递的时间
POINT pt;//光标位置
}
windows 主函数
intWINAPI WinMain{
HINSTANCE hInstance;
HINSTANCE HprevInstance
LPARAM IpcmdLine;
int nCmdShow;
}
class style
{
WNDCLASS wndclass;
wndclass.hh
点点滴滴
strcpy(s1,s2)字符串复制 将2考到1 s1<--s2
strcat(s1,s2)字符串连接 s
strlen(s)字符串长度计算 不算NULL的长度
strcmp(s1,s2)字符串比较!!!
strchar(s1,ch)?
strstr?
字符串的读写
Getchar(str)
Gets(str) 到NULL停止
Putchar(str)
Puts(str)
Printf(“%s”,str)
Scanf(“%s”,str)
指针相当于定以后的数组 数组不需要初始化就可以去使用
字符串 要使用放在const区
字符串比较 是比的内容不是地址strcmp()
数组字符串定义后面不带NULL
Char【20】=“he”是占三个字符长度
Char 【20】=“h”“e”占两个字节
字符长度跟数组的长度不一样字符数组占用的空间是有的
Sizeof计算其内部占用的内存空间
但是里面存在的值未知
Strlen计算的值是字符串的长度
指针定义跟数组定义是一样的 都是指向一定长度单位的数组
引用地址应当非常的小心 因为改变内存的东西 很恐怖
返回值是1 的时候表示继续 函数的返回值 还有 任何的返回值
返回值是 0表示结束
数组名字本身就是地址
所以在printf的时候不需要再对数组名字(即首地址再取地址)
在定义函数的时候一定要给这么写 int a,b;不要忘记
两个变量之间有逗号;
在接收的时候一定要给接收变量分配一个地址
而在输出的时候需要的是这个变量的名字!
Int a = 5;????????????5占用了a存放的是5
每个 变量都有一个名字 还有内存空间所存的值 还有就是这个变量的地址
这几个属性!!!!!!!!!!!!!!!!!!!!!
用数组接收字符串的时候注意其格式
chara[10]= “CHONGMINGREN”
chara[10]={“cuowude”}
用strlen测试长度的时候并没有包括到NULL所占字符长度
而且NULL还是不只占用一个字节
Strlen 准确测出字符的长度
Sizeof 严格测出占用的空间
时间 2012年1月7日0:15:49
指针本身无类型 当有指向的时候才有类型有意义 才可以被调用
时间2012年1月7日8:21:09
指针
指针的优点
1. 灵活修改实参
2. 支持动态内存的分配
3. 提高效率
4. 实现缓冲方式文件存取
指针的意义 不定义是不存在 定以后才存在
内存冯诺一曼结构 线性结构
指针是数据的小名在另外一个空间中存储
指针也是个变量在内存中有一个地方保存他
Int * P;指向整型值的指针变量!
P++
指针的强制类型转换
Printf(“%p”,p)
强制类型转换-------------------
Void * p;
(int*)(*p)强奸*p
只有积类型指针才可以转化
基类型
Void * f(*p)
{void * p;
Return p;}
Void *可以接受任何类型的指针参数 不报失败 void*f(void *p){returnp;}
时间 2012年1月7日13:06:47
指针
Void * f(*p){return p;} 只有在函数中才可以定义指针类型;
typedef void SHOW(void *); 定义函数指针 引用直接调用 SHOW;
typedefvoid SHOW(void *);
show(void*datap){ void *newdatap =(int*)datap printf(“show theis :”,*newdatap}
先宏定义函数指针 用一个类似结构体的方式调用函数指针。
在show函数中的指针式空类型 这样的好处是可以以多种方式调用输出 只不过要先进行强制类型装换 intnewa = (faloat a);
Void np = (int ) p; 括号先运算表示结构体转换
时间 2012年1月7日20:25:28
字符串的接收
Gets puts
Getchar
指针在使用的时候必须先初始化 定义只能随机给个值
但是随着程序的增大 的时候内存空间先指向安全的位置 到程序变大的时候
会出现异常;
数组名是一个指针常量 而指针则是变量 这就是指针对数组的优势
指针数组
Char p[10]=”kjasjdlk” 等价于Char *p=”safkjlk” /*完全等价*/
Char *p[]=”kjsafj” 指针数组
引用函数指针 SHOW *show;
定义空指针
void * F(void *f );return; f}
引用函数指针 ff(show f)
Main.c
#include "darray.h"
#include <stdio.h>
void show(void *d)
{
int *p = (int*)d;
printf("%d",*p); // 输出地址d所储存的数据 让 *d 以int型号访问
}
int main()
{DARRAY *arr = NULL; //在整个函数调用之前初始化
inta;
arr = init_darray(4); //返回一个指向结构体的指针 返回值是个结构体的首地址;
返回这个arr 就可以调用 结构体中的任何内容!!!
在这个函数中对结构体进行定义 数据的个数 和
每个数据的大小 非常的有用 非常实惠
a=5;insert_darray(arr,&a); //传递进去结构体的首地址 和 输入数据临时地址
a=6;insert_darray(arr,&a); //将临时地址内容插入到结构体中
a=7;sd -----*insert_darray(arr,&a);
travsel(arr,show);putchar('\n');
return0;
}
darry.h
#ifndef _DARRAY_H_
#define _DARRAY_H_
#include <stdlib.h>
#include <string.h>
typedef struct darray_st DARRAY;
typedef void SHOW(void *); //定义函数指针 以SHOW调用
struct darray_st {
intsize;
intcount;
void*datap;
};
DARRAY* init_darray(int);
int insert_darray(DARRAY*,void*);
void travsel(DARRAY *,SHOW *);
#endif
Darry.c
#include "darray.h"
DARRAY* init_darray(int size) /接收每个data的大小
{
DARRAY*tmp = malloc(sizeof(DARRAY));
tmp->size= size;
tmp->count= 0;
tmp->datap= malloc(size);
returntmp;
}
// 返回一个指针 指向结构体的指针
int insert_darray(DARRAY *arr,int *data)
{
arr->datap= realloc(arr->datap,arr->size*(arr->count+1));
memcpy(arr->datap+arr->count,data,arr->size);
arr->count++;
return0;
}
void travsel(DARRAY *arr,SHOW *show)
{
int i;
for(i=0;i<arr->count;i++)
{
show(arr->datap+arr->size*i);
}
在 定义函数的时候一定要确定这个函数对数据做了什么 需要什么数据 穿进去
什么数据返回来 才有用
采用malloc realloc 可以将数据永久的保存在 堆中
这两个函数是有返回值的
A=malloc(用数字表示的 字节数) 给a分配 的字节数
A是个地址
Malloc是和指针配合使用 构成数组的
Memcpy(要拷贝到的地址,从哪拷贝,拷贝几个)
Memcpy( 新地址,源地址,长度)
Realloc() 给已分配的地址再分配地址
BOOK . h
#ifndef _BOOK_H_
#define _BOOK_H_
#include "darray.h"
struct book_st{
int bid;
char bname[20];
float price;
};
typedef struct book_st BOOK;
void print(void *);
int cmp_book(void *,void *);
int insert_book(DARRAY *,BOOK);
void display(DARRAY *);
void menu();
static BOOK input();
int delete_book(DARRAY *,int);
void loadFile(DARRAY *);
void saveFile(DARRAY *);
#endif
Book.c
#include "book.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char filename[100]="data.txt";
void print(void *p)
{
BOOK *b = (BOOK*)p;
printf("%d\t%s\t%5.2f\n",b->bid,b->bname,b->price);
}
int insert_book(DARRAY *lib,BOOK b)
{
return insert_darray(lib,&b);
}
void display(DARRAY *lib)
{
travsel(lib,print);
}
static BOOK input()
{
BOOK book;
printf("book info:");
scanf("%d %s %f",&book.bid,book.bname,&book.price);
return book;
}
int cmp_book(void *p1,void *p2)
{
BOOK *l = (BOOK*)p1;
int *b = (int*)p2;
return l->bid - *b;
}
void menu()
{
char cmd[10];
int bid=-1;
DARRAY *darr=init_darray(sizeof(BOOK));
BOOK book;
loadFile(darr);
while(1)
{
printf("please input (add,show,del,exit) command:");
fflush(stdin);
scanf("%s",cmd);
if(!strcmp(cmd,"add"))
{
book=input();
insert_book(darr,book);
}
else if(!strcmp(cmd,"show"))
{
display(darr);
}
else if(!strcmp(cmd,"exit"))
{
saveFile(darr);
destory(darr);
exit(0);
}
else if(!strcmp(cmd,"del"))
{
printf("please book id:");
scanf("%d",&bid);
delete_book(darr,bid);
}
}
}
void loadFile(DARRAY *darr)
{
BOOK book;
int ret=0;
FILE *fp=fopen(filename,"r");
while(1)
{
if(-1!=fscanf(fp,"%d %s %f\n",&book.bid,book.bname,&book.price))
{
insert_darray(darr,&book);
}
else
{
break;
}
}
fclose(fp);
}
FILE *wfp;
void sf(void *p)
{
BOOK *b = (BOOK*)p;
fprintf(wfp,"%d %s %5.2f\n",b->bid,b->bname,b->price);
}
void saveFile(DARRAY *darr)
{
wfp = fopen(filename,"w");
travsel(darr,sf);
fclose(wfp);
}
int delete_book(DARRAY *darr,int id)
{
delete_darray(darr,&id,cmp_book);
}
Main。C
#include "book.h"
int main()
{
menu();
return 0;
}
Carry。H
#ifndef _DARRAY_H_ //定义头文件
#define _DARRAY_H_ //定义头文件
struct darray_st{
int size;
int count;
char *datap; //定义结构体中数据的指针
};
typedef void (*SHOW)(void *); //定义函数指针
指针是用SHOW对函数进行调用
typedef int (*CMP)(void *,void *);//定义一个指针
typedef struct darray_st DARRAY; //定义一个结构体
DARRAY* init_darray(int); 定义一个结构体指针 并且 返回值是一个结构
返回值是一个结构体指针
int insert_darray(DARRAY*,void*); 定义一个没有返回值的函数
void travsel(const DARRAY *,SHOW); 定义一个遍历函数
void destory(DARRAY*); 销毁一个malloc
void delete_darray(DARRAY *,void *,CMP);
#endif
Carry.c
#include "darray.h"
#include <stdlib.h>
#include <string.h>
DARRAY * init_darray(int size) //定义一个结构体
{
DARRAY *tmp = malloc(sizeof(*tmp));//给结构体分配内存空间
Malloc不仅给分配大小 返回值还表达了指向
if(!tmp) ///如果不是空
{
return NULL;
}
tmp->size = size;
tmp->count = 0;
tmp->datap = (char *)malloc(size); 强制转换为字符流
return tmp; 指针初始化(类型 大小)malloc来分配大小
通常把返回值赋给别人以便方便的使用
}
int insert_darray(DARRAY *arr,void *data) //插入新数据
{
arr->datap = realloc(arr->datap,arr->size*(arr->count+1));
if(!arr->datap) //????
{
return 1; //????
}
memcpy(arr->datap+(arr->size*arr->count),data,arr->size);
将新数据考到新地址
arr->count++;
每拷贝一次 次数加1
return 0;
}
void travsel(const DARRAY *arr,SHOW s) //数据不变
// const int *A=num;A=bum;*A=5; //修饰指向的对象,A可变,A指向的变量的值不可变
int const *A; //修饰指向的对象,A可变,A指向的变量的值不可变
int *const A=#A=bum;//修饰指针A, A不可变,A指向的地址可变
const int *const A; //指针A和A指向的对象都不可变
{
int i;
for(i = 0; i < arr->count; i++ )
{
s(arr->datap+arr->size*i);
}
}
void destory(DARRAY *darr)
{
free(darr->datap);
free(darr);
}
void delete_darray(DARRAY *darr,void *data,CMP cmp)
{
int i,j;
for( i = 0; i < darr->count; i++ )
{
if(!cmp(darr->datap + (darr->size*i),data))
{
break;
}
}
for(j=i;j<darr->count;j++)
{
memcpy( darr->datap + darr->size * i,darr->datap + darr->size * (i+1),darr->size );
}
darr->count--;
realloc(darr->datap, darr->size*darr->count );
}
Standard input stream stdin 标准输入字符流
Flash stdard 刷新数据
Strcmp 字符串比较
Fopen (“文件名”,“读写类型”)!
在于处理的时候都是以字符串形式存在的;
宏定义求运算表达式
而函数调运 占用存储空间 不好弄啊;
条件编译
保证 函数的调用只有一次
只包含一次
不是无数次包涵
结构体可以整体赋值 即 book1 =book2
Scanf 交互函数 停留在此的
Output
指针变量没赋值 就开始赋值救是错的 先初始化 并且
Malloc 告诉你哪里有你用的地址
哪里可以用
(*arr).count ===== arr->count 都是引用指向值
结构体首地址 +1是表示指向 结构体中下一个单元???
基础知识回顾
Const int a; 表示a 的值只是可读 不可以改变更不可以赋值
Static 静态变量 限定调用的范围
Extern 声明全局可调用
寄存器变量由cpu直接调用速度很快 一个cpu有十六个寄存器变量
指针必须初始化 由于 指向不明比较危险 可能 给 cpu改乱了
Sizeof(数据类型)
Gcc -E 文件
Gcc -S text.i -O test.s 看汇编
Gcc -C test.c -O test.o 看二进制文件
Gcc -O test.o 生成运行的文件名
基础的知识
Char = ‘a’;不加双引号容易产生歧义
Gdb调试程序
尚观课堂笔记重点内容
char 占 1个字节 (0~255) 。一字节是 256位变量是一种使用方便的占位符,用于引用计算机内存地址。变量是相对于常量来说的,常量是本身就有数值的,不能被赋值或修改,而变量就是在编程过程中可以被赋值的量,就象我们小学的未知数x,y一样。源文件--------.i文件---------.O文件--------可执行文件
CPU MMU(内存管理单元)
内存 如何存储数值
Static 静态变量 是 ?????
源文件--------.i文件---------.O文件--------可执行文件
CPU MMU(内存管理单元)
内存 如何存储数值
变量是一种使用方便的占位符,用于引用计算机内存地址。变量是相对于常量来说的,常量是本身就有数值的,不能被赋值或修改,而变量就是在编程过程中可以被赋值的量,就象我们小学的未知数x,y一样。char 占 1个字节 (0~255) 。一字节是 256位源文件--------.i文件---------.O文件--------可执行文件
CPU MMU(内存管理单元)
内存 如何存储数值
Long 与 int的 区别 int 在16位的计算机是2个字节 16位 long 还是 4个字节 32位
Do{
}while();
//一般情况下用于某些常处于运行状态的应用程序
3.静态变量 全局变量(static)
变量前边加个“static”,就摇身变成了静态变量,其存储方式为静态存储,静态变量一定是静态存储形式,但是静态存储形式的不一定就是静态局部变量,例如全局变量也是静态存储形式。
4.自动变量(auto)和寄存器变量(register)、外部变量(extern)
用时自动产生, 但不会自动初始化, 随函数调用的结束, 这个变量也就自动消失了, 下次调用此函数时再自动产生, 还要再赋值, 退出时又自动消失。
extern称为外部变量。为了使变量除了在定义它的源文件中可以使用外, 还要 被其它文件使用。因此, 必须将全程变量通知每一个程序模块文件, 此时可用 extern来说明。
通过以上的程序可以理解不同的存储类型的作用范围不同,在程序设计中如何灵活的使用各种不同的存储类型是能够使程序更灵活。
5.Const修饰符
C语言中的const一直是C语言初学者最头疼的问题,这是因为const在不同位置有不同作用,在不同情况下有不同用法。这让初学者摸不清头脑。今天,和大家一起研究一下const,让它的每个情况都“深入人心”!
3.静态变量 全局变量(static)
变量前边加个“static”,就摇身变成了静态变量,其存储方式为静态存储,静态变量一定是静态存储形式,但是静态存储形式的不一定就是静态局部变量,例如全局变量也是静态存储形式。
4.自动变量(auto)和寄存器变量(register)、外部变量(extern)
用时自动产生, 但不会自动初始化, 随函数调用的结束, 这个变量也就自动消失了, 下次调用此函数时再自动产生, 还要再赋值, 退出时又自动消失。
extern称为外部变量。为了使变量除了在定义它的源文件中可以使用外, 还要 被其它文件使用。因此, 必须将全程变量通知每一个程序模块文件, 此时可用 extern来说明。
通过以上的程序可以理解不同的存储类型的作用范围不同,在程序设计中如何灵活的使用各种不同的存储类型是能够使程序更灵活。
5.Const修饰符
C语言中的const一直是C语言初学者最头疼的问题,这是因为const在不同位置有不同作用,在不同情况下有不同用法。这让初学者摸不清头脑。今天,和大家一起研究一下const,让它的每个情况都“深入人心”!
volatile修饰符
volatile 告诉编译器i是随时可能发生变化的,每次使用它的时候必须从i的地址中读取,因而编译器生成的可执行码会重新从i的地址读取数据放在k中。
而优化做法是,由于编译器发现两次从i读数据的代码之间的代码没有对i进行过操作,它会自动把上次读的数据放在k中。而不是重新从i里面读。这样以来,如果i是一个寄存器变量或者表示一个端口数据就容易出错,所以说volatile可以保证对特殊地址的稳定访问,不会出错。可变参数列表指针就是保存内存地址的变量指针就是保存内存地址的变量空指针
(一)栈:在函数调用时,第一个进栈的是被调用函数下一行的内存地址。其次是函数的参数,假如参数多于一个,那么次序是从右往左。最后才是函数的局部变量。
4.函数指针(基本上作函数的参数)
这种方式的文件操作有一个重要的结构FILE,FILE在stdio.h中定义如下:
int level; /* fill/emptylevel of buffer */
unsigned flags; /* Filestatus flags */
unsigned char hold; /*Ungetc char if no buffer */
unsigned char _FAR *buffer;/* Data transfer buffer */
unsigned char _FAR *curp; /*Current active pointer */
unsigned istemp; /*Temporary file indicator */
short token; /* Used forvalidity checking */
} FILE; /* This is the FILE object */
FILE这个结构包含了文件操作的基本属性,对文件的操作都要通过这个结构的指针来进行,此种文件操作常用的函数见下表函数 功能
bExtern 与 static 一内一外
4.函数指针(基本上作函数的参数)
这种方式的文件操作有一个重要的结构FILE,FILE在stdio.h中定义如下:
int level; /* fill/emptylevel of buffer */
unsigned flags; /* Filestatus flags */
unsigned char hold; /*Ungetc char if no buffer */
unsigned char _FAR *buffer;/* Data transfer buffer */
unsigned char _FAR *curp; /*Current active pointer */
unsigned istemp; /*Temporary file indicator */
short token; /* Used forvalidity checking */
} FILE; /* This is the FILE object */
FILE这个结构包含了文件操作的基本属性,对文件的操作都要通过这个结构的指针来进行,此种文件操作常用的函数见下表函数 功能
今天装了Ubuntu,但是发现不能上网,开始排查问题:
1、首先确定网络连接是否正确,所用的网线是否可以正常工作
2、查看网卡是否能正常工作,检测的方法如下:
a、ping 127.0.0.1
b、ping 静态网关地址
c、ping 主机名(hostname就可以看到主机名)
3、看网卡地址是否配置正确(ifconfig命令看本地主机的网卡信息,和DNS、Default getway、Sever地址进行比对,看网卡地址是否正确)
我的设备问题出在第三个方面,然后修改网卡的配置信息,使用命令如下:(当然利用图形窗口完全可以,我这里只是为了学习Linux而用的)
一、使用命令设置ubuntu的ip地址
1.修改配置文件blacklist.conf禁用IPV6:
sudo vi /etc/modprobe.d/blacklist.conf
2.在文档最后添加 blacklist ipv6,然后查看修改结果:
cat /etc/modprobe.d/blacklist.conf
3.设置IP(设置网卡eth0的IP地址和子网掩码)
sudo ifconfig eth0 192.168.2.1 netmask 255.255.255.0
4.设置网关
sudo route add default gw 192.168.2.254
5.设置DNS 修改/etc/resolv.conf,在其中加入nameserver DNS的地址1 和 nameserver DNS的地址2 完成。
6.重启网络服务(若不行,请重启ubuntu:sudo reboot):
sudo /etc/init.d/networking restart
7.查看当前IP:
ifconfig
二、直接修改系统Ubuntu Linux配置文件
网络Ubuntu Linux配置文件是:/etc/network/interfaces
打开后里面可设置DHCP或手动设置静态ip。前面auto eth0,让网卡开机自动挂载。
1. 以DHCP方式配置网卡
编辑文件/etc/network/interfaces:
sudo vi /etc/network/interfaces
并用下面的行来替换有关eth0的行:
# The primary network interface - use DHCP to find our address
auto eth0
iface eth0 inet dhcp
用下面的命令使网络设置生效:
sudo /etc/init.d/networking restart
也可以在命令行下直接输入下面的命令来获取地址
sudo dhclient eth0
2. 为网卡配置静态IP地址
编辑文件/etc/network/interfaces:
sudo vi /etc/network/interfaces
并用下面的行来替换有关eth0的行:
# The primary network interface
auto eth0
iface eth0 inet static
address 192.168.2.1
gateway 192.168.2.254
netmask 255.255.255.0
#network 192.168.2.0
#broadcast 192.168.2.255
将上面的ip地址等信息换成你自己就可以了.用下面的命令使网络设置生效:
sudo /etc/init.d/networking restart
3. 设定第二个IP地址(虚拟IP地址)
编辑文件/etc/network/interfaces:
sudo vi /etc/network/interfaces
在该文件中添加如下的行:
auto eth0:1
iface eth0:1 inet static
address x.x.x.x
netmask x.x.x.x
network x.x.x.x
broadcast x.x.x.x
gateway x.x.x.x
根据你的情况填上所有诸如address,netmask,network,broadcast和gateways等信息:
用下面的命令使网络设置生效:
sudo /etc/init.d/networking restart
4. 设置主机名称(hostname)
使用下面的命令来查看当前主机的主机名称:
sudo /bin/hostname
使用下面的命令来设置当前主机的主机名称:
sudo /bin/hostname newname
系统启动时,它会从/etc/hostname来读取主机的名称。
5. Ubuntu Linux配置DNS
首先,你可以在/etc/hosts中加入一些主机名称和这些主机名称对应的IP地址,这是简单使用本机的静态查询。要访问DNS 服务器来进行查询,需要设置/etc/resolv.conf文件,假设DNS服务器的IP地址是192.168.2.2, 那么/etc/resolv.conf文件的内容应为:
search chotim.com
nameserver 192.168.2.2
6.手动重启网络服务:
sudo /etc/init.d/networking restart
当然ubuntu是带图形界面的,所以上面关于一些地址的设置也可以像windows一样通过设置来完成,在窗口上方System—>Preference下面找相应的配置选项;另外用命令行修改配置文件用到vi命令时如果不熟悉命令的操作修改起来会很不方便,所以可以选择采用gedit来编辑配置文件。
indent -npro -kr -i8 -ts8-sob -l80 -ss -ncs -cp1 源文件.c
3.Makefile编写
Rm–rf main main.o main.s main.i
$(TARGETS): $(shellpwd)/$(SRC_DIR)/$(SOURCE)
@$(ECHO)creating... $(TARGETS) please waiting..
@$(CC)$^ $(PARAM) $(shell pwd)/bin/$(TARGETS) $(CFLAGS)
GDB调试
Gdb 文件名
S
S
S
Bt
Info local
声明常量 inconst int a=5;声明常量等于5;
1.void 类型
许多初学者对C/C++语言中的void及void指针类型不甚理解,因此在使用上出现了一些错误。本文将对void关键字的深刻含义进行解说,并详述void及void指针类型的使用方法与技巧。
void的字面意思是“无类型”,void *则为“无类型指针”,void *可以指向任何类型的数据。void几乎只有“注释”和限制程序的作用,因为从来没有人会定义一个void变量,让我们试着来定义:
这行语句编译时会出错,提示“illegal useof type 'void'”。不过,即使void a的编译不会出错,它也没有任何实际意义。
void真正发挥的作用在于:(1)对函数返回的限定;(2) 对函数参数的限定。
众所周知,如果指针p1和p2的类型相同,那么我们可以直接在p1和p2间互相赋值;如果p1和p2指向不同的数据类型,则必须使用强制类型转换运算符把赋值运算符右边的指针类型转换为左边指针的类型。例如:
其中p1 = p2语句会编译出错,提示“'=' : cannot convert from 'int *' to 'float *'”,必须改为:
而void *则不同,任何类型的指针都可以直接赋值给它,无需进行强制类型转换:
提示“'=' : cannot convert from 'void *' to 'int *'”。
在C语言中,凡不加返回值类型限定的函数,就会被编译器作为返回整型值处理。但是许多程序员却误以为其为void类型。例如:
int main(int argc, char* argv[]){
printf ( "2 + 3 = %d", add ( 2, 3));
因为在C++中,函数参数为void的意思是这个函数不接受任何参数。
所以,无论在C还是C++中,若函数不接受任何参数,一定要指明参数为void。
按照ANSI(American National Standards Institute)标准,不能对void指针进行算法操作,即下列操作都是不合法的:
//ANSI标准之所以这样认定,是因为它坚持:进行算法操作的指针必须是确定知道其指向数据类型大小的。
但是大名鼎鼎的GNU(GNU's Not Unix的缩写)则不这么认定,它指定void *的算法操作与char *一致。
在实际的程序设计中,为迎合ANSI标准,并提高程序的可移植性,我们可以这样编写实现同样功能的代码:
(char *)pvoid++; //ANSI:正确;GNU:正确
(char *)pvoid += 1; //ANSI:错误;GNU:正确
GNU和ANSI还有一些区别,总体而言,GNU较ANSI更“开放”,提供了对更多语法的支持。但是我们在真实设计时,还是应该尽可能地迎合ANSI标准。
规则四 如果函数的参数可以是任意类型指针,那么应声明其参数为void *
典型的如内存操作函数memcpy和memset的函数原型分别为:
void * memcpy(void *dest, const void *src, size_t len);
void * memset ( void * buffer, int c, size_t num );
memset ( intarray, 0, 100*sizeof(int) ); //将intarray清0
int intarray1[100], intarray2[100];
memcpy ( intarray1, intarray2, 100*sizeof(int) ); //将intarray2拷贝给intarray1
有趣的是,memcpy和memset函数返回的也是void *类型,标准库函数的编写者是多么地富有学问啊!
下面代码都企图让void代表一个真实的变量,因此都是错误的代码:
void体现了一种抽象,这个世界上的变量都是“有类型”的,譬如一个人不是男人就是女人(还有人妖?)。
小小的void蕴藏着很丰富的设计哲学,作为一名程序设计人员,对问题进行深一个层次的思考必然使我们受益匪浅。
2.内联函数
8c语言实现面向对象
计算机中为什么要用补码表示一个数 ??
Iden –kr –i8
1.修饰符
1.1修饰符const 区别static 预编译是访问不到的!!
1.2 Extern 和 auto
World 简单的编辑用到的快捷键 和插入符号
汇编 语言
因为汇编是通过CPU和内存跟硬件对话的,所以我们不得不先了解一下CPU和内存:(关于数的进制问题在此不提)
DEBUG的的A命令可以汇编出简单的COM文件,所以DEBUG编写的程序一定要由地址 100h(COM文件要求)开始才合法。FOLLOWME,SETP BY SETP(步步回车):
2.输入 MOV DL,1 ; 将数值 01h 装入 DL 寄存器
3.输入 MOV AH,2 ; 将数值 02h 装入 DL 寄存器
4.输入 INT 21 ; 调用DOS 21号中断2号功能,用来逐个显示装入DL的字符
5.输入 INT 20 ; 调用DOS 20号中断,终止程序,将控制权交回给 DEBUG
ㄖ ←输出结果其实不是它,因WORD97无法显示原结果,故找一赝品将就着。
我们可以用U命令将十六进制的机器码反汇编(Unassemble)成汇编指令。你将发现每一行右边的汇编指令就是被汇编成相应的机器码,而8086实际上就是以机器码来执行程序。
DEBUG可以用R命令来查看、改变寄存器内容。CS:IP寄存器,保存了将执行指令地址。
AX=0000BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1FEDES=1FED SS=1FED CS=1FED IP=0100 NV UP EI PL NZ NA PONC
输入N SMILE.COM ;我们得告诉DEBUG程序长度:程序从100开始到106,故占用7
;字节。我们利用BX存放长度值高位部分,而以CX存放低位部分。
2.输入RBX ;查看 BX 寄存器的内容,本程序只有7个字节,故本步可省略
现在,我们再来剖析一个可以将所有ASCII码显示出来的程序。
MOVDL,00 ;装入第一个ASCII码,随后每次循环装入新码
INC DL ;INC:递增指令,每次将数据寄存器 DL 内的数值加 1
LOOP0105 ;LOOP:循环指令,每执行一次LOOP,CX值减1,并跳
当我们想任意显示字符串,如:UNDERSTAND?,则可以使用DOS21H号中断9H号功能。输入下行程序,存盘并执行看看:
1975:0100 BA 09 01 B4 09 CD 21 CD-20 75 6E 64 65 72 73 74 ......!. underst
1975:0110 61 6E 64 24 8B 46 F8 89-45 04 8B 46 34 00 64 19 and$.F..E..F4.d.
1975:0120 89 45 02 33 C0 5E 5F C9-C3 00 C8 04 00 00 57 56 .E.3.^_.......WV
1975:0130 6B F8 0E 81 C7 FE 53 8B-DF 8B C2 E8 32 FE 0B C0 k.....S.....2...
1975:0140 74 05 33 C0 99 EB 17 8B-45 0C E8 D4 97 8B F0 89 t.3.....E.......
1975:0150 56 FE 0B D0 74 EC 8B 45-08 03 C6 8B 56 FE 5E 5F V...t..E....V.^_
1975:0160 C9 C3 C8 02 00 00 6B D8-0E 81 C3 FE 53 89 5E FE ......k.....S.^.
1975:0170 8B C2 E8 FB FD 0B C0 75-09 8B 5E FE 8B 47 0C E8 .......u..^..G..
现在,我们来剖析另一个程序:由键盘输入任意字符串,然后显示出来。db 20指示DEBUG保留20h个未用的内存空间供缓冲区使用。
MOVDX,0116 ;DS:DX = 缓冲区地址,由DB伪指令确定缓冲区地址
MOVDL,0A ;由于功能Ah在每个字符串最后加一个归位码(0Dh由 Enter
MOVAH,02 ;产生),使光标自动回到输入行的最前端,为了使新输出的
INT 21 ;字符串不会盖掉原来输入的字符串,所以利用功能2h加一
MOVAH,09 ;9h功能遇到$符号才会停止输出,故字符串最后必须加上
INT 21 ;$,否则9h功能会继续将内存中的无用数据胡乱显示出来
下面我们用MASM写一个与用DEBUG写的第一个程序功能一样的程序。
Microsoft (R) Macro Assembler Version 5.10
Copyright (C) Microsoft Corp 1981, 1988. All rights reserved.
Objectfilename [SMILE.OBJ]: ←是否改动输出OBJ文件名,如不改就ENTER
Sourcelisting [NUL.LST]: ← 是否需要列表文件(LST),不需要就ENTER
Cross-reference [NUL.CRF]: ←是否需要对照文件(CRF),不需要则ENTER
50162 + 403867 Bytes symbol space free
0Warning Errors ←警告错误,表示编译器对某些语句不理解,通常是输入错误。
0 SevereErrors ←严重错误,会造成程序无法执行,通常是语法结构错误。
Microsoft (R) Overlay Linker Version 3.64
Copyright (C) Microsoft Corp 1981, 1988. All rights reserved.
Run File[SMILE.EXE]: ← 是否改动输出EXE文件名,如不改就ENTER
ListFile [NUL.MAP]: ← 是否需要列表文件(MAP),不需要则ENTER
Libraries [.LIB]: ←是否需要库文件,要就键入文件名,不要则ENTER
LINK :warning L4021: no stack segment← 由于COM文件不使用堆栈段,所以错误信息
assumecs:prognam ;把上面定义段的段基址放入 CS
mov dl,0; 装入第一个ASCII码,随后每次循环装入新码
inc dl;INC:递增指令,每次将数据寄存器 DL 内的数值加 1
loopnext ; 循环指令,执行一次,CX减1,直到CX为0,循环停止
start:mov dl,1 ;装入第一个ASCII码,随后每次循环装入新码
我们的第一个模块是BINIHEX,其主要用途是从8086的BX寄存器中取出二进制数,并以十六进制方式显示在屏幕上。注意:子程序如不能独立运行,实属正常。
rotate:mov cl,4 ;利用CL当计数器,记录寄存器数位移动次数
rolbx,cl ;循环寄存器BX的内容,以便依序处理4个十六进制数
printit:mov dl,al ;把ASCII码装入DL
jnzrotate ;JNZ:当零标志未置1,则跳到指定地址。即:不等,则转移
第二个模块DECIBIN用来接收键盘打入的十进制数,并将它转换成二进制数放于BX 寄存器中,供模块1BINIHEX使用。
subal,30h ;al减去30H,结果存于al中,完成ASCII码转二进制码
CBW 实际结果是:若AL中的值为正,则AH填入00h;反之,则AH填入FFh。XCHG常用于需要暂时保留某个寄存器中的内容时。
当然,还得一个子程序(CRLF)使后显示的十六进制数不会盖掉先输入的十进制数。
现在我们就可以将BINIHEX、DECIBIN及CRLF等模块合并成一个大程序了。首先,我们要将这三个模块子程序略加改动。然后,再写一段程序来调用每一个子程序。
mov cx,4;循环次数入cx;由于子程序要用到cx,故子程序要将cx入栈
repeat:call decibin;调用十进制转二进制子程序
movah,4ch ; 调用DOS21号中断4c号功能,退出程序,作用跟INT 20H
int 21H; 一样,但适用面更广,INT20H退不出时,试一下它
decibinproc near push cx ;将cx压入堆栈,;
┇ exit: pop cx ;将cx还原; retdecibin endp binihex proc near push cx
┇ pop cx retbinihex endp crlf proc near
┇ pop cx retcrlf endpdecihex ends end
汇编语言超浓缩教程到这要告一段落了,希望能奠定你独立设计的基础。而更多更好的技巧则全依赖你平时的积累了。祝你成功
制作MP3中的mciSendstring字符串
mciSendString "open mName type MPEGVideo Aliasmovie parent %u Style %u notify",0&, 0, 0
type MPEGVideo 是指打开MPEG,AVI等类型,如果不加这一句,就是打开WAV,MP3等
Alias movie 定义了该操作的别名为movie,后续操作只要指明别名即可
mciSendString "play movie", 0&, 0,0
mciSendString "play movie fullscreen",0&, 0, 0 '全屏播放
mciSendString "pause movie", 0&, 0, 0
mciSendString "resumemovie", 0&, 0, 0
mciSendString "stopmovie", 0&, 0, 0
mciSendString "close movie", 0&, 0, 0
mciSendString "step movie", 0&, 0,0
mciSendString "step movie reverse", 0&,0, 0
mciSendString "step movie by " & str(N),0&, 0, 0
mciSendString "status movie position", st,len(st), 0
mciSendString "status movie length", st,len(st), 0
mciSendString "status movie mode", ST,Len(ST), 0
If Left(ST, 7) = "stopped" Then (处理代码) '播放完毕
mciSendString "play movie repeat", 0&,0, 0
mciSendString "status movie volume", V, 0, 0'V是获取的音量大小值。
mciSendString "setaudio movie volume to "& V, &0, 0, 0 'V是设置的音量值
mciSendString "status movie brightness", B,0, 0 'B是获取的亮度值。
mciSendString "setvideo movie brightness to" & B, &0, 0, 0 'B是设置的亮度值
mciSendString "seek movie to ", P1, 0, 0 'P1是当前起始位置,单位:毫秒
mciSendString "seek movie to start", 0&,0, 0 '定位到开头位置
mciSendString "play movie", 0&, 0, 0 '定位后再播放
mciSendString "play movie FROM P1 toP2",0&, 0, 0 'P1是起始位置,P2是停止位置。单位:毫秒
mciSendString "seek movie to end", 0&,0, 0 '定位到最后位置
mciSendString "open AVI 文件名 parent hWnd style child", 0&, 0, 0
执行上述命令之后,影片会被放置在控件的左上角,且影片的大小不受控件大小的影响,如果想要改变
影片播放的位置及大小,可以在執行 play 指令前先执行 put 指令,格式如下:
mciendString "put AVI 文件名 window at X Y [Width Height]", 0&, 0, 0
其中 X 及 Y 参数须填入位置,而 Width 及 Height 参数则填入影片显示出來的宽度及高度
mciSendString "set wave bitpersample 8","", 0, 0
mciSendString "set wave samplespersec11025", "", 0, 0
mciSendString "set wave channels 2","", 0, 0
MCISENDSTRING "set wave format tagpcm","", 0, 0
mciSendString "close movie",0&,0,0
mciSendString "open new type WAVEAudio aliasmovie",0&,0,0
mciSendString "record movie",0&,0,0
mciSendString "stop movie",0&,0,0
mciSendString "save movieC:""123.wav",0&,0,0
mciSendString "close movie",0&,0,0
mciSendString "set cdaudio door open","", 0, 0 '打开
mciSendString "set cdaudio door close","", 0, 0 '关闭
==============================================================================
1.void 类型
1.概述
许多初学者对C/C++语言中的void及void指针类型不甚理解,因此在使用上出现了一些错误。本文将对void关键字的深刻含义进行解说,并详述void及void指针类型的使用方法与技巧。
2.void的含义
void的字面意思是“无类型”,void *则为“无类型指针”,void*可以指向任何类型的数据。void几乎只有“注释”和限制程序的作用,因为从来没有人会定义一个void变量,让我们试着来定义:
void a;
这行语句编译时会出错,提示“illegal use of type 'void'”。不过,即使void a的编译不会出错,它也没有任何实际意义。
void真正发挥的作用在于:(1)对函数返回的限定;(2) 对函数参数的限定。
众所周知,如果指针p1和p2的类型相同,那么我们可以直接在p1和p2间互相赋值;如果p1和p2指向不同的数据类型,则必须使用强制类型转换运算符把赋值运算符右边的指针类型转换为左边指针的类型。例如:
float *p1;
int *p2;
p1 = p2;
其中p1 = p2语句会编译出错,提示“'=' : cannot convert from 'int *' to'float *'”,必须改为:
p1 = (float *)p2;
而void *则不同,任何类型的指针都可以直接赋值给它,无需进行强制类型转换:
void *p1;
int *p2;
p1 = p2;
但这并不意味着,void *也可以无需强制类型转换地赋给其它类型的指针。因为“无类型”可以包容“有类型”,而“有类型”则不能包容“无类型”。道理很简单,我们可以说“男人和女人都是人”,但不能说“人是男人”或者“人是女人”。下面的语句编译出错:
void *p1;
int *p2;
p2 = p1;
提示“'=' : cannot convertfrom 'void *' to 'int *'”。
3.void的使用
下面给出void关键字的使用规则:
规则一 如果函数没有返回值,那么应声明为void类型
在C语言中,凡不加返回值类型限定的函数,就会被编译器作为返回整型值处理。但是许多程序员却误以为其为void类型。例如:
add ( int a, intb ){
return a + b;
}
int main(intargc, char* argv[]){
printf ( "2 + 3 = %d", add ( 2,3) );
}
程序运行的结果为输出:
2 + 3 = 5
这说明不加返回值说明的函数的确为int函数。
林锐博士《高质量C/C++编程》中提到:“C++语言有很严格的类型安全检查,不允许上述情况(指函数不加类型声明)发生”。可是编译器并不一定这么认定,譬如在Visual C++6.0中上述add函数的编译无错也无警告且运行正确,所以不能寄希望于编译器会做严格的类型检查。
因此,为了避免混乱,我们在编写C/C++程序时,对于任何函数都必须一个不漏地指定其类型。如果函数没有返回值,一定要声明为void类型。这既是程序良好可读性的需要,也是编程规范性的要求。另外,加上void类型声明后,也可以发挥代码的“自注释”作用。代码的“自注释”即代码能自己注释自己。
规则二 如果函数无参数,那么应声明其参数为void
在C++语言中声明一个这样的函数:
intfunction(void){
return 1;
}
则进行下面的调用是不合法的:
function(2);
因为在C++中,函数参数为void的意思是这个函数不接受任何参数。
我们在Turbo C 2.0中编译:
#include"stdio.h"
fun(){
return 1;
}
main(){
printf("%d",fun(2));
}
编译正确且输出1,这说明,在C语言中,可以给无参数的函数传送任意类型的参数,但是在C++编译器中编译同样的代码则会出错。在C++中,不能向无参数的函数传送任何参数,出错提示“'fun' : function does not take 1parameters”。
所以,无论在C还是C++中,若函数不接受任何参数,一定要指明参数为void。
规则三 小心使用void指针类型
按照ANSI(AmericanNational Standards Institute)标准,不能对void指针进行算法操作,即下列操作都是不合法的:
void * pvoid;
void++; //ANSI:错误
void += 1; //ANSI:错误
//ANSI标准之所以这样认定,是因为它坚持:进行算法操作的指针必须是确定知道其指向数据类型大小的。
//例如:
int *pint;
int++; //ANSI:正确
int++的结果是使其增大sizeof(int)。
但是大名鼎鼎的GNU(GNU's NotUnix的缩写)则不这么认定,它指定void *的算法操作与char *一致。
因此下列语句在GNU编译器中皆正确:
void++; //GNU:正确
void += 1; //GNU:正确
void++的执行结果是其增大了1。
在实际的程序设计中,为迎合ANSI标准,并提高程序的可移植性,我们可以这样编写实现同样功能的代码:
void * pvoid;
(char *)pvoid++;//ANSI:正确;GNU:正确
(char *)pvoid +=1; //ANSI:错误;GNU:正确
GNU和ANSI还有一些区别,总体而言,GNU较ANSI更“开放”,提供了对更多语法的支持。但是我们在真实设计时,还是应该尽可能地迎合ANSI标准。
规则四 如果函数的参数可以是任意类型指针,那么应声明其参数为void *
典型的如内存操作函数memcpy和memset的函数原型分别为:
void *memcpy(void *dest, const void *src, size_t len);
void * memset (void * buffer, int c, size_t num );
这样,任何类型的指针都可以传入memcpy和memset中,这也真实地体现了内存操作函数的意义,因为它操作的对象仅仅是一片内存,而不论这片内存是什么类型。如果memcpy和memset的参数类型不是void *,而是char *,那才叫真的奇怪了!这样的memcpy和memset明显不是一个“纯粹的,脱离低级趣味的”函数!
下面的代码执行正确:
//示例:memset接受任意类型指针
intintarray[100];
memset (intarray, 0, 100*sizeof(int) ); //将intarray清0
//示例:memcpy接受任意类型指针
int intarray1[100],intarray2[100];
memcpy (intarray1, intarray2, 100*sizeof(int) ); //将intarray2拷贝给intarray1
有趣的是,memcpy和memset函数返回的也是void *类型,标准库函数的编写者是多么地富有学问啊!
规则五 void不能代表一个真实的变量
下面代码都企图让void代表一个真实的变量,因此都是错误的代码:
void a; //错误
function(void a);//错误
void体现了一种抽象,这个世界上的变量都是“有类型”的,譬如一个人不是男人就是女人(还有人妖?)。
void的出现只是为了一种抽象的需要,如果你正确地理解了面向对象中“抽象基类”的概念,也很容易理解void数据类型。正如不能给抽象基类定义一个实例,我们也不能定义一个void(让我们类比的称void为“抽象数据类型”)变量。
4.总结
小小的void蕴藏着很丰富的设计哲学,作为一名程序设计人员,对问题进行深一个层次的思考必然使我们受益匪浅。
5.该函数有四个参数:
第一个参数:要发送的命令字符串。字符串结构是:[命令][设备别名][命令参数].
第二个参数:返回信息的缓冲区,为一指定了大小的字符串变量.
第三个参数:缓冲区的大小,就是字符变量的长度.
第四个参数:回调方式,一般设为零
返回值:函数执行成功返回零,否则返回错误代码.
6.
函数指针是怎么调用函数的??
BOOLMain_OninitDialog(HWND hwnd,HWND hwndFocus,LPARAM)
HWND combox = GetDialgItm(hwnd IDC_COMBO1);
ComboBOX_Isertstring(combox,-1.TEXT(“北京“);
ComboBOX_Isertstring(combox,-1.TEXT(“北京“);
ComboBOX_Isertstring(combox,-1.TEXT(“北京“);
SendMassage()
如鹏网 c干大事
intAPIENTRY WinMain{HINSTANCE hInstance.
HINSTANCE hPreInrestance.
LPSTR lpCmdLine.
int cmdShow
}
{
MessageBox(NULL//句柄,TEXT(“世界你好”),TEXT(“问好”),MB_OK//显示的按钮)->显示使用宏常量表示的 对话框的显示按钮图标MB_ICONQUSTION等量进行定义 .icon 图标);
return 0;
}
vc是c语言的开发工具 只是一种开发c 和c++的工具
{
int ret = MessageBox(NULL,T,T,MB_OK);
if(ret==IDYES) { MessageBox();}
else { Message(NULL,T,T,MB_OK);}
}
int APIENTRY WinMain(
HINSTANCE hInstance,
HINSTANCE hPreInstance,
LPSTR lpCmdLine
int cmdShow
)
干大事视频笔记
wsprintf(nstr,“格式”,formerstr);
sprintf(nstr,“格式”,formeerstr);
他们的作用是在win32接口中时用字符串表示所有的东西;
输出文本必须是字符串的形式;这样做才合法;
wsprintf(NUM3,”%i”,i3) 记牢; 格式化 文本格式化 格式化比较两个文本输入是否合法
计算器核心代码
#include "stdafx.h"
#include <windows.h>
#include <windowsx.h>
#include "MainDlg.h"
BOOL WINAPI Main_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)//iwillcallyou! //dontcallme,iwillcallyou!
{
switch(uMsg)
{
HANDLE_MSG(hWnd, WM_INITDIALOG, Main_OnInitDialog);
HANDLE_MSG(hWnd, WM_COMMAND, Main_OnCommand);
HANDLE_MSG(hWnd,WM_CLOSE, Main_OnClose);
}
return FALSE;
}
BOOL Main_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
{
return TRUE;
}
void Main_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
switch(id)
{
case IDC_OK:
{
TCHAR NUM1[256];
TCHAR NUM2[256];
TCHAR NUM3[256];
GetDlgItemText(hwnd,IDC_EDIT1,NUM1,sizeof(NUM1));
GetDlgItemText(hwnd,IDC_EDIT2,NUM2,sizeof(NUM2));
int i1 = atoi(NUM1);
int i2 = atoi(NUM2);
int i3;
TCHAR NUM1temp[256];
TCHAR NUM2temp[256];
wsprintf(NUM1temp,"%i",i1);
wsprintf(NUM2temp,"%i",i2);
if(strcmp(NUM1,NUM1temp)!=0)
{
MessageBox(hwnd,TEXT("第一个数格式错误!"),TEXT("警告"),MB_OK);
return;
}
if(strcmp(NUM2,NUM2temp)!=0)
{
MessageBox(hwnd,TEXT("第二个数格式错误 !"),TEXT("警告"),MB_OK);
return;
}
i3 = i1+i2;
wsprintf(NUM3,"%i",i3);
SetDlgItemText(hwnd,IDC_EDIT3,NUM3);
}
break;
default:
break;
}
}
void Main_OnClose(HWND hwnd)
{
EndDialog(hwnd, 0);
}
比较是否为整数
BOOLIsInt(TCHAR * str)
{
int i=atoi(str); //先转换为整数
TCHAR strtemp[255];
wsprintf(strtemp,"%i",i);//整数写入再写入字符串
if(strcmp(str,strtemp)!=0)//比较是否是整数 在计算机中所有的显示都是以字符串实现的 是数字字符串的话就不会有任何的改变,反之就会有改变!字符串是否相等!
{
return FALSE;
}
else
{
return TRUE;
}
}
#include "stdafx.h"
#include <windows.h>
#include <windowsx.h>
#include "resource.h"
#include "MainDlg.h"
BOOL WINAPI Main_Proc(HWND hWnd, UINT uMsg,WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
HANDLE_MSG(hWnd, WM_INITDIALOG, Main_OnInitDialog);
HANDLE_MSG(hWnd, WM_COMMAND, Main_OnCommand);
HANDLE_MSG(hWnd,WM_CLOSE,Main_OnClose);
}
return FALSE;
}
BOOL Main_OnInitDialog(HWND hwnd, HWNDhwndFocus, LPARAM lParam)
{
HWND hwndComBox1 = GetDlgItem(hwnd,IDC_COMBO1);
ComboBox_InsertItemData(hwndComBox1,-1,TEXT("+"));
ComboBox_InsertItemData(hwndComBox1,-1,TEXT("-"));
ComboBox_InsertItemData(hwndComBox1,-1,TEXT("*"));
ComboBox_InsertItemData(hwndComBox1,-1,TEXT("/"));
returnTRUE;
}
BOOLIsInt(TCHAR *str)
{
int i=atoi(str);
TCHARstrtemp[256];
wsprintf(strtemp,"%i",i);
if (strcmp(str,strtemp)==1)
{
returnFALSE;
}
else
{
returnTRUE;
}
}
void Main_OnCommand(HWND hwnd, int id, HWND hwndCtl,UINT codeNotify)
{
switch(id)
{
caseIDC_OK:
{
TCHARstr1[256];
TCHARstr2[256];
GetDlgItemText(hwnd,IDC_EDIT1,str1,sizeof(str1));
GetDlgItemText(hwnd,IDC_EDIT2,str2,sizeof(str2));
inti1 = atoi(str1);
inti2 = atoi(str2);
inti3=0;
HWNDhwndComBox1=GetDlgItem(hwnd,IDC_COMBO1);
intcurIndex = ComboBox_GetCurSel(hwndComBox1);
switch(curIndex)
{
case0:
{
i3=i1+i2;
}
case1:
{
i3=i1-i2;
}
break;
case2:
{
i3=i1*i2;
}
break;
case3:
{
i3=i1/i2;
}
break;
}
TCHAR str3[256];
if(IsInt(str1)==FALSE)
{
MessageBox(hwnd,TEXT("第一个数输入数据不合法"),TEXT("警告"),MB_OK);
}
if(IsInt(str2)==FALSE)
{
MessageBox(hwnd,TEXT("第二个数输入数据不合法"),TEXT("警告"),MB_OK);
}
itoa(i3,str3,10);
SetDlgItemText(hwnd,IDC_EDIT3,str3);
}
break;
default:
break;
}
}
void Main_OnClose(HWND hwnd)
{
EndDialog(hwnd, 0);
}
计算器 增删该查
#include"stdafx.h"
#include<windows.h>
#include<windowsx.h>
#include"resource.h"
#include"MainDlg.h"
BOOL WINAPIMain_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
HANDLE_MSG(hWnd, WM_INITDIALOG,Main_OnInitDialog);
HANDLE_MSG(hWnd, WM_COMMAND,Main_OnCommand);
HANDLE_MSG(hWnd,WM_CLOSE,Main_OnClose);
}
return FALSE;
}
BOOLMain_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
{
HWND hwndComBox1 =GetDlgItem(hwnd,IDC_COMBO1);
ComboBox_InsertItemData(hwndComBox1,-1,TEXT("+"));
ComboBox_InsertItemData(hwndComBox1,-1,TEXT("-"));
ComboBox_InsertItemData(hwndComBox1,-1,TEXT("*"));
ComboBox_InsertItemData(hwndComBox1,-1,TEXT("/"));
return TRUE;
}
BOOL IsInt(TCHAR*str)
{
int i =atoi(str);
TCHAR strtemp[256];
wsprintf(strtemp,"%i",i);
if (strcmp(str,strtemp)==1)
{
return FALSE;
}
else
{
return TRUE;
}
}
voidMain_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
switch(id)
{
case IDC_OK:
{
TCHAR str1[256];
TCHAR str2[256];
GetDlgItemText(hwnd,IDC_EDIT1,str1,sizeof(str1));
GetDlgItemText(hwnd,IDC_EDIT2,str2,sizeof(str2));
int i1 = atoi(str1);
int i2 = atoi(str2);
int i3=0;
HWNDhwndComBox1=GetDlgItem(hwnd,IDC_COMBO1);
int curIndex =ComboBox_GetCurSel(hwndComBox1);
switch (curIndex)
{
case 0:
{
i3=i1+i2;
}
case 1:
{
i3=i1-i2;
}
break;
case 2:
{
i3=i1*i2;
}
break;
case 3:
{
i3=i1/i2;
}
break;
}
TCHAR str3[256];
if (IsInt(str1)==FALSE)
{
MessageBox(hwnd,TEXT("第一个数输入数据不合法"),TEXT("警告"),MB_OK);
return;
}
if (IsInt(str2)==FALSE)
{
MessageBox(hwnd,TEXT("第二个数输入数据不合法"),TEXT("警告"),MB_OK);
return;
}
itoa(i3,str3,10);
SetDlgItemText(hwnd,IDC_EDIT3,str3);
}
case IDC_BUTTONADD:
{
TCHAR str[256];
GetDlgItemText(hwnd,IDC_EDITADD,str,sizeof(str));
HWNDhwndedit=GetDlgItem(hwnd,IDC_COMBO1);
ComboBox_InsertItemData(hwndedit,-1,str);
SetDlgItemText(hwnd,IDC_EDITADD,TEXT(""));
}
case IDC_BUTTONDEL:
{
HWNDhwndedit=GetDlgItem(hwnd,IDC_COMBO1);
int CurSel=ComboBox_GetCurSel(hwndedit);
ComboBox_DeleteString(hwndedit,CurSel);
}
case IDC_BUTTONSER:
{
TCHAR strToSerch[256];
GetDlgItemText(hwnd,IDC_EDITSER,strToSerch,sizeof(strToSerch));
HWNDhwndser=GetDlgItem(hwnd,IDC_COMBO1);
int iCount =ComboBox_GetCount(hwndser);
int i;
BOOL bFound = FALSE;
{
TCHAR str[256];
ComboBox_GetLBText(hwndser,i,str);
if(lstrcmp(str,strToSerch)==0)
{
bFound =TRUE;
ComboBox_GetCurSel(hwndser,i);
}
}
if(bFound)
{
MessageBox(hwnd,TEXT("找到了"),TEXT("哈哈"),MB_OK);
}
}
break;
default:
break;
}
}
voidMain_OnClose(HWND hwnd)
{
EndDialog(hwnd, 0);
}
c语言精彩编程百例
一些c语言需要巩固的知识
2012-1-18 19:36:59
转义字符\ 常量字符串“” 常量字符‘’
break 和continue的区别
一个是跳出本次循环一个是结束整个for或者while的很多次循环
比如while(1){int a++;if(a>100),break;}全部结束.
比如for(int i=0;i++;i<100){if(i<0)continue;}本次结束
MP3代码加注释
// mp3.cpp : Defines the entry point forthe application.
mp3.c
#include "stdafx.h" //包涵的头文件
int APIENTRY WinMain(HINSTANCEhInstance, //这里的句柄
HINSTANCE hPrevInstance, //父句柄
LPSTR lpCmdLine, //pointer to command line命令行字符串主要指参数
int nCmdShow) // show state of window窗口显示状态,隐藏、最大化等。
{
InitCommonControls(); //注册并初始化通用控件窗口类
DialogBox(hInstance,MAKEINTRESOURCE(IDD_MAIN),NULL,MainProc);
//生命一个图书
return0;
}
Stdafx.c
#include "stdafx.h"
#include <stdio.h>
#include <mmsystem.h>
#include <stdlib.h>
#pragma comment(lib,"winmm.lib")
BOOL CALLBACK MainProc (HWND hDlg, UINTmessage, WPARAM wParam, LPARAM lParam)
{
staticTCHAR buf[255]="";
staticint sound_value = 500;
switch(message)
{
caseWM_INITDIALOG:
{
}
return(TRUE);
caseWM_CLOSE:
{
mciSendString("closemp3",NULL,0,NULL);
EndDialog(hDlg,0);
}
return(TRUE);
caseWM_COMMAND:
switch(LOWORD(wParam))
{
caseID_OPEN:
{
OPENFILENAME ofn;
ZeroMemory(&ofn,sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.lpstrFilter= "mp3\0 *.mp3\0";
ofn.lpstrFile= buf;
ofn.lpstrFile[0]='\0';
ofn.nMaxFile= sizeof(buf);
if(GetOpenFileName(&ofn))
{
SetDlgItemText(hDlg,IDC_MP3_LIST,buf);
TCHARcmd[1000];
sprintf(cmd,"open%s alias mp3",buf);
mciSendString(cmd,NULL,0,NULL);
charstr[100]="";
mciSendString("statusmp3 volume",str,100,NULL);
sound_value= atoi(str);
}
}
return(TRUE);
caseID_PLAY:
mciSendString("playmp3",NULL,0,NULL);
return(TRUE);
caseID_PAUSE:
mciSendString("pausemp3",NULL,0,NULL);
return(TRUE);
caseID_STOP:
mciSendString("stopmp3",NULL,0,NULL);
return1;
caseID_SOUND_ADD:
if(sound_value<1000)
{
sound_value+=100;
sprintf(buf,"setaudiomp3 volume to %d",sound_value);
mciSendString(buf,0,0,0);
sprintf(buf,"音量大小:%d",sound_value);
SetDlgItemText(hDlg,SOUND_SHOW,buf);
}
return1;
caseID_SOUND_SUB:
if(sound_value>0)
{
sound_value-=100;
sprintf(buf,"setaudiomp3 volume to %d",sound_value);
mciSendString(buf,0,0,0);
sprintf(buf,"音量大小:%d",sound_value);
SetDlgItemText(hDlg,SOUND_SHOW,buf);
}
return1;
}
return(FALSE);
}
return(FALSE);
}
Stdafx.h
// stdafx.h : include file for standardsystem include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#if!defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_)
#defineAFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <windowsx.h>
#include "resource.h"
#include <COMMCTRL.H>
#include <commdlg.h>
#pragmacomment(lib,"comctl32.lib")
BOOL CALLBACK MainProc (HWND hDlg, UINTmessage, WPARAM wParam, LPARAM lParam);
#endif
======================================================
数据结构2012年2月6日9:19:29
数据结构2012年2月6日9:21:44
线性结构
阿夫曼二叉树
图型结构
gdb调试
bt
I locals
s
bt 1 查看1
display tmp
printf tmp
结构体第一节 链表
next = 0 elm = 0 head=008地址 值是9 next =null(0) assert 声明开辟空间 指向另外一个地址tmp是指针 e=9 while(null)循环停止 next tmp 018 第一个tmp008 栈消失 堆存在 指针指向下一个地址 链表逻辑连续 物理上存储是不连续的 访问指针中的数据用à
while (cur->next)//把当前节点指针移动到最后
{
cur=cur->next;
}
动态库 使用链表
将链表导入动态库 使用makeinstall 安装动态库
数据结构郝斌
结构体中引用 使用的是book.bid
传递进去的一定要是地址才可以改变值
gowithme justlikabird
if (动态数组为空)
提示用户
else
输出有效数组
如何判断数组为空bool isempty
if(0=count) return ture
typedef 起别名
typedef struct book BOOK.
p指向节点 新的节点
q指针指向节点
p的指针域
p指向的结构体才有指针域
p->pnext 存放的是地址
p->fornt 存放的是地址
r=p->pNext;p->pNext=q;q->pNext=r;
q->pNext=p->pNext;p->pNext=q;
linklist
#include<stdio.h>
#include<malloc.h>
typedef struct NODE
{
int data;
struct Node*pNext;
}NODE,*PNODE;
int main(void)
{
PHONE pHead=NULL;
pHead=create_list();
traverse_list(pHead);
return 0;
}
PHONE create_list()
{
int len;
int i;
int val;
PNODE pHead=(PNODE)malloc(sizeof(NODE));
if(NULL==pHead)
{
printf()
}
printf(“输入需要生成链表节点的个数:len=”)
scanf(“%d”,&len);
for(i=0;i<len;i++)
{
printf(“输入第%d个节点的值:”,i+1);
scanf(“%d”,&val);
}
}
PHONE tranverse_list(PNODE pHead)
{
}
动态分配的值可以被保留
静态的分配值是随机 出站进站被返回给了内存
笔记 时间2012年2月15日14:35:30相关推荐
- 从四大造字法看文字所承载的文化_对央视“汉字的魅力”讲授之管见(《天津教育报》2012年6月15日)...
对央视"汉字的魅力"讲授之管见 张奎文 2012年2月20日,收看中央电视台第四套"中文国际频道",由刘芳菲主持的"文明之旅"栏目,特邀著名 ...
- FireFox2.0夏威夷时间2006年10月24日14:00准时发布
FireFox2.0夏威夷时间2006年10月24日14:00准时发布 下载地址: http://www.mozilla.com/en-US/firefox/ 感觉tab做的漂亮多了! ^-^
- 神经网络贷款风险评估(base on keras and python ) 原创 2017年08月18日 14:35:17 标签: python / 神经网络 / keras 300 用我
神经网络贷款风险评估(base on keras and python ) 原创 2017年08月18日 14:35:17 标签: python / 神经网络 / keras / 300 编辑 删除 ...
- 武汉大学无线传感实验床项目招标公告(开标时间2015年1月15日)
根据国家采购与招投标法律法规的有关规定,武汉大学拟对计算机学院无线传感实验床项目进行公开招标,欢迎具备相应资质和实力的供应商参加投标.现将有关事项公告如下: 一.招标范围: (主要技术指标:见附件) ...
- (更新时间)2021年5月15日 Nginx服务器 Nginx面试题
Nginx面试题 1.什么是Nginx? Nginx是一个 轻量级/高性能的反向代理Web服务器,他实现非常高效的反向代理.负载平衡,他可以处理2-3万并发连接数,官方监测能支持5万并发,现在中国使用 ...
- (更新时间)2021年5月15日 SqlServer数据库 SqlServer面试题
数据库SqlServer笔试题 文章目录 数据库SqlServer笔试题 一.数据库基础知识(通用)篇 1.说说主键.外键.超键.候选键 2.为什么用自增列作为主键? 3.触发器的作用是什么? 4.什 ...
- 三星Galaxy Note 4.0.3 N7000单刷PDA官方港版ROM下载(2012年5月15日发布)
本ROM提取自官方升级服务器,未做任何修改. ROM下载:N7000OZSLPF_XXLR1_HOME(港行ROM 4.0.3).7z Samsung Kies 中已经开始推送: 升级后的系统信息: ...
- 2012年4月15日
很遗憾的在周五晚上开始发烧,发到周日早上结束,连给我向公司请个病假的机会也没有,真是无语啊~ 这个周末,基本没有干什么正事,下午的时候,听了耶鲁<金融市场>第九个课程,是由David Sv ...
- 崔希凡JavaWeb笔记day19-day21(2016年10月4日17:35:51)
难点:jdbc分页查询,以及filter的几个案例 笔记分享如下 链接:http://pan.baidu.com/s/1o8NbI3o 密码:4fnc
- 惠州全国计算机证书,广东惠州学院2017年9月计算机等级考试报名时间:6月15日-30日...
惠州学院信息科学技术学院2017年下半年(第49次)全国计算机等级考试(简称NCRE,下同)报考工作于6月15日开始,具体事项如下: 一.考试时间.科目及考试系统 (一)考试时间:2017年9月23日 ...
最新文章
- 后氧传感器正常数据_氧传感器正常数据流
- 洛谷P1194 买礼物
- 两个充电宝能互充电吗_国人鬼才设计,手掌大智能芯片充电宝能暖手、充电、补光镜三合一...
- git 工具_Github开源工具分享之自托管GIT服务工具Gogs
- 数据结构---B-(B)、B+的总结
- 移动端照片上传、头像裁剪完整功能,兼容iphone,android (一)
- 一些SharePoint 2007开发的在线课程
- 使用PHP开发你必须得注意的要点
- Vue packages version mismatch: 版本冲突;Error: EPERM: operation not permitted
- 动态规划C语言实现之最长公共子序列(LCS)
- autojs遍历当前页面所有控件_解放双手,手机自动化神器-AutoJS的使用
- 建设 Web3,现在最需要 Web2 的移民?
- KDD2016论文精品解读(二)
- 畜牧业的论文发表一般多少钱
- element表格固定表头每列宽度,最右侧固定后,溢出出现滚动条内容和表头不能同时移动
- css过渡-动画-变换
- 去掉json的双引号_JSON 去掉转义字符,value去掉双引号
- 大智慧F10离线文件下载—大智慧V5.997下载
- OpenGLES glUniform1i用法
- 【项目总结】stm32红外循迹蓝牙超声波小车