Visual Studio 如何设置生成目录

设置例如生成的exe所在的文件路径

Visual C# 项目

项目菜单右键->属性->生成->在 输出 路径框旁边的省略号 浏览 按钮并选择一个新生成输出目录。

Visual C++ 项目

项目菜单右键->属性->配置属性->常规->输出目录 修改为新的输出目录(左边下拉,浏览)

安装项目

项目菜单右键->属性->输出文件名 框中为新的输出目录。

输出目录默认为:$(SolutionDir)$(Configuration)
可以通过编辑查看默认的宏

C标准库 string.h (二)比较函数

string.h 比较函数

  • strcmp 两个字符串相比较
  • strncmp 两个字符串的前N个字节相比较
  • memcmp 两块内存的前N个字节相比较
  • strcoll 与 strxfrm 引用的函数
  • strcoll 确定两个以空字符结尾的字符串再指定区域下的词典顺序
  • strxfrm 将空字符结尾的字符串s2转换为s1处的一个(不重叠的)版本

strcmp

字符串比较函数,用于比较两个字符串的区别

#include <stdio.h>
#include <string.h>

/*
	自实现
*/
int _strcmp(const char *dest, const char *src)
{
	int res = 0;
	while( res == 0 && *src != '\0')
		res = *dest++ - *src++;
	return res;
}

/*
	标准库
*/
int strcmp(const char *s1, const char *s2)
{
	for ( ; *s1 == *s2; ++s1, ++s2 )
		if(*s1 == '\0')
			return (0);

	return ((*(unsigned char *) s1 < *(unsigned char *)s2) ? -1 : +1);
}


int main()
{
	char text[10] = "hello";

	if (_strcmp(text, "hello") == 0)
	{
		printf("it's samen");
	}	
}

标准库实现中,先转成无符号再比较,是为了避免特殊字符出现负数,然后负数不对称的情况,所以先转成无符号再比较。博主是觉得返回1或者-1都没什么意义,所以直接返回相减的结果了。

strncmp

比较两个字符串的前n个字符

#include <stdio.h>
#include <string.h>

/*
	自实现
*/
int _strncmp(const char *s1, const char *s2, size_t n)
{
	const unsigned char *dest = s1, *src = s2;
	while( n-- > 0 && *dest != '\0')
		if (*dest++ - *src++)
			return *dest - *src;
	return 0;
}

/*
	标准库
*/
int strncmp(const char *s1, const char *s2, size_t n)
{
	for( ; 0 < n; ++s1, ++s2, --n)
		if(*s1 != *s2)
			return ((*(unsigned char *)s1 < *(unsigned char *)s2) ? -1 : +1);
		else if(*s1 == '\0')
			return 0;
	return 0;
}

int main()
{
	char hi[] = "hello world";

	if ( _strncmp( hi, "hello", 5 ) == 0) {
		printf("相等n");
	} else {
		printf("不相等n");
	}
}

标准库很是推崇for循环,其实也是有道理的,因为作为计数用的变量 n 以及每次都需要改变的 s1、s2 就可以很明确的放在后面了,或许这个地方for循环也有优化,不过博主还是用while循环自实现一下吧。

memcmp

#include <stdio.h>
#include <string.h>

/*
	自实现
*/
int _memcmp(const void *s1, const void *s2, size_t n)
{
	const unsigned char *dest = s1, *src = s2;
	while( n-- > 0 )
		if (*dest++ - *src++)
			return *dest - *src;
	return 0;
}

/*
	标准库
*/
int memcmp(const void *s1, const void *s2, size_t n)
{
	const unsigned char *su1, *su2;

	for(su1 = s1, su2 = su2; 0 < n; ++su1, ++su2, --n)
		if(*su1 != *su2)
			return ((*su1 < *su2) ? -1 : +1);
	return 0;
}

int main()
{
	char hi[] = "hello world";

	if ( _memcmp( hi, "hello", 5 ) == 0) {
		printf("相等n");
	} else {
		printf("不相等n");
	}
}

/*
	在处理一些特殊字符的时候,他们的值有可能是负数
	C语言中补码形式下,负数与正数不对称,所以使用 unsigned char是很推荐的

	memcmp 与 strncmp 的区别是 memcmp 不会检查字符串是否到结束
*/

strcoll 与 strxfrm

与 locale.h 本地库有关的字符串比较函数,在开始比较之前会按照特定的方式转换字符串然后在进行比较。

xstate.h

#ifndef _SXTATE_H_
#define _SXTATE_H_

// page 100 为了方便区域设置改变时获得操作状态表所需的信息。
/* xstate.h internal header */
	/* macros for finite state machines */
	// 有限状态机的宏

#define ST_CH		0x00ff
#define ST_STATE	0x0f00
#define ST_STOFF	8
#define ST_FOLD		0x8000
#define ST_INPUT	0x4000
#define ST_OUTPUT	0x2000
#define ST_ROTATE	0x1000
#define _NSTATE		16
	/* 类型定义 */

typedef struct{
	const unsigned short *_Tab[_NSTATE];
} _Statab;
	/* 声明*/
extern _Statab _Costate, _Mbstate, _Wcstate;

#endif

xstrxfrm.h

/*
	所有的整理函数都包含内部头文件"xstrxfrm.h"
	该头文件又包含标准头文件<string.h>和内部头文件"xstate.h"
	除此之外,"xstrxfrm.h"定义了类型 _Cosave 并且声明了函数 _Strxfrm
	一个 _Cosave 类型的数据对象在调用 _Strxfrm 之间存储状态信息
*/
#include <string.h>
#include "xstate.h"
	/* type definnitions 类型定义 */
typedef struct{
	unsigned char _State;
	unsigned short _Wchar;
} _Cosave;
	/* declarations 声明 */
size_t _Strxfrm(char *, const unsigned char **, size_t, _Cosave *);

xstrxfrm.c

#include <limits.h>
#include "xstrxfrm.h"

/* 设置默认为 0 的本地配置项 */
_Statab _Costate, _Mbstate, _Wcstate;

size_t _Strxfrm(char *sout, const unsigned char **psin,
					size_t size, _Cosave *ps) // _Cosave 存储状态信息
{
	// translate string to collatable form
	// 翻译字符串到可校对的格式
	char state = ps->_State;
	int leave = 0;
	int limit = 0;
	int nout = 0;
	const unsigned char *sin = *psin;
	unsigned short wc = ps->_Wchar; 	// 宽字节字符累加器

	for( ; ; )
	{   // perform a state transformation
		// 执行状态转换
		unsigned short code;
		const unsigned short *stab;

		if(_NSTATE <= state
			|| (stab = _Costate._Tab[state]) == NULL
			|| (_NSTATE * UCHAR_MAX) <= ++limit
			|| (code = stab[*sin] == 0) )
			break;

		state = (code & ST_STATE) >> ST_STOFF;

		if(code & ST_FOLD)
			wc = wc & ~UCHAR_MAX | code & ST_CH;
		if(code & ST_ROTATE)
			wc = wc >> CHAR_BIT & UCHAR_MAX | wc << CHAR_BIT;
		if(code & ST_OUTPUT && ((sout[nout++]
			= code & ST_CH ? code : wc) == '\0'
			|| size <= nout))
			leave = 1;
		if(code & ST_INPUT)
			if(*sin != '\0')
				++sin, limit = 0;
			else
				leave = 1;
		if(leave)
		{   // return for now
			// 现在返回
			*psin = sin;
			ps->_State = state;
			ps->_Wchar = wc;
			return nout;
		}
	}
	sout [nout++] = '\0';	// error return 错误返回
	*psin = sin;
	ps->_State = _NSTATE;
	return nout;
}

strcoll

#include <stdio.h>
#include "xstrxfrm.h"

typedef struct
{
	char buf[32];
	const unsigned char *s1, *s2, *sout;
	_Cosave state;
} Sctl;

static size_t getxfrm(Sctl *p)
{
	size_t i;

	do {
		p->sout = (const unsigned char *)p->buf;
		i = _Strxfrm(p->buf, &p->s1, sizeof (p->buf), &p->state);
		if (0 < i && p->buf[i-1] == '\0')
			return (i-1);
		else if (*p->s1 == '\0')
			p->s1 = p->s2;
	} while( i == 0 );
	return i;
}

int _strcoll(const char *s1, const char *s2)
{
	size_t n1, n2;
	Sctl st1, st2;
	static const _Cosave initial = {0};

	st1.s1 = (const unsigned char *)s1;
	st2.s2 = (const unsigned char *)s1;
	st1.state = initial;

	st2.s1 = (const unsigned char *)s2;
	st2.s2 = (const unsigned char *)s2;
	st2.state = initial;

	for (n1 = n2 = 0 ; ; )
	{
		int ans;
		size_t n;

		if (n1 == 0)
			n1 = getxfrm(&st1);
		if (n2 == 0)
			n2 = getxfrm(&st2);
		n = n1 < n2 ? n1 : n2;
		if (n == 0)
			return (n1 == n2 ? 0 : 0 < n2 ? -1 : +1);
		else if((ans = memcmp(st1.sout, st2.sout, n)) != 0)
			return ans;

		st1.sout += n, n1 -= n;
		st2.sout += n, n2 -= n;
	}
}

int main()
{
	char hi[] = "中文";

	if ( _strcoll( hi, "中文") == 0) {
		printf("相等n");
	} else {
		printf("不相等n");
	}
}

strxfrm

#include <stdio.h>
#include <stdlib.h>
#include "xstrxfrm.h"
#include "xstate.h"

size_t _strxfrm(char *s1, const char *s2, size_t n)
{
	/* transform s2[] to s1[] by locale-dependent rule */
	size_t nx = 0;
	const unsigned char *s = (const unsigned char *)s2;
	_Cosave state = {0};

	while(nx < n)
	{   // 转化 并 传递
		size_t i = _Strxfrm(s1, &s, n - nx, &state);

		s1 += i, nx += i;
		if(0 < i && s1[-1] =='\0')
			return nx-1;
		else if (*s == '\0')
			s = (const unsigned char *)s2;
	}
	for( ; ; )
	{
		char buf[32];
		size_t i = _Strxfrm(buf, &s, sizeof(buf), &state);

		nx += i;
		if(0<i && buf[i-1] == '\0')
			return nx-1;
		else if(*s == '\0')
			s = (const unsigned char *)s2;
	}
}

int main()
{
	char hi[] = "中文";

	if ( _strxfrm( hi, "中文", 4) == 0) {
		printf("相等n");
	} else {
		printf("不相等n");
	}
}

小结

其实可以发现三个cmp函数最后都是用的无符号字符型来相减的,
原因是为了避免有符号的负数运算。

接着就是 strcmp、strncmp和memcmp的区别了。。

str开头的是专门处理字符串的,如果去处理别的数据需要显示的强转成 char * 。
然后strcmp是一直比较到 s1 结束为止,strncmp 则是比较传入的参数 n 个,不过依旧保留了strcmp的特点,就是 s1 结束的话也会停止。
memcmp 与 strncmp 是非常类似的,区别可以说 memcmp 只比较 n 个不管s1有没有结尾。

strcmp 适合与比较两个可能完全相同的字符串。
strncmp 适合与比较一个字符串与另一个字符串开头的 n 个。
memcmp 适合与比较两个数据(不一定是char类型)的前 n 个字节是否相同。

strxfrm 与 strcoll 会根据 locale.h 中的 LC_COLLATE 来把字符串转换成另外一种形式,然后再比较。目前是一件比较坑的事情,以后研究 locale.h 的时候,我们还会回来的。

js jQuery 对象相互转换

js 的 getElementBy 系列获取不够方便, jQuery的过滤器很好用但是操作多个也不方便? 概念理清,混着用吧

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>对象转换</title>
<script type="text/javascript" src="js/jquery-1.9.1.js"></script>
<style type="text/css">
  #close_img:hover{
    cursor: hand;
  }
</style>

</head>

<body>

<div id="test"  style="width:300px; height:200px; background-color: orange"></div>
<div class="article" style="width:300px; height:200px; background-color: blue"></div>
<div class="article" style="width:400px; height:200px; background-color: skyblue"></div>
<div class="article" style="width:200px; height:200px; background-color: green"></div>

<script type="text/javascript">

// 直接用$() 将js的变量包住即可变成jQuery对象使用
var obj = document.getElementById('test'); 
alert("test 的高度为" + $(obj).height() + "px"); 


// jquery对象转js对象,直接在其后加上[0]即可
var display = $("#test")[0].style.width;
alert("test 的高度为" + display + "px");


// js与jquery对象混用
var list = $(".article");
var content = "";
for (var i = 0; i < list.length; i++) {
	content +="第 "+i+" 篇文章div 高" +
			 $(list[i]).css("height") + " 宽" +
			  $(list[i]).css("width") + "n";
};
alert(content);

</script>

</body>
</html>