今天一个新同学来问一个典型的预处理的问题,我当年也碰到这样的问题,贴出来,让更多的人能直接搜到
预处理命令
# 和 ## 操作符是和#define宏使用的. 使用# 使在#后的首个参数返回为一个带引号的字符串. 例如, 命令
#define to_string( s ) # s
将会使编译器把以下命令
cout << to_string( Hello World! ) << endl;
理解为
cout << "Hello World!" << endl;
使用##连结##前后的内容. 例如, 命令
#define concatenate( x, y ) x ## y
...
int xy = 10;
...
将会使编译器把
cout << concatenate( x, y ) << endl;
解释为
cout << xy << endl;
理所当然,将会在标准输出处显示'10'.
语法:
#line line_number "filename"
|
#line命令是用于更改__LINE__ 和 __FILE__变量的值. 文件名是可选的. __LINE__ 和 __FILE__ 变量描述被读取的当前文件和行. 命令
#line 10 "main.cpp"
更改行号为10,当前文件改为"main.cpp".
语法:
__LINE__
__FILE__
__DATE__
__TIME__
_cplusplus
__STDC__
|
下列参数在不同的编译器可能会有所不同, 但是一般是可用的:
- __LINE__ 和 __FILE__ 变量表示正在处理的当前行和当前文件.
- __DATE__ 变量表示当前日期,格式为month/day/year(月/日/年).
- __TIME__ 变量描述当前的时间,格式为hour:minute:second(时:分:秒).
- _cplusplus 变量只在编译一个C++程序时定义.
- __STDC__ 变量在编译一个C程序时定义,编译C++时也有可能定义.
今天同学的u盘读不出数据来了,提示未格式化,在线搜了一
下,找到一个名叫winhex的工具。挺好用的,大家有这样的
问题的时候可以用一下。
猜想一下winhex的恢复指定类型文件工作原理
struct stBitMap
{
uint fileType;
uint ver;
uint size;
uint createDate;
}
假如上面是一个位图的文件结构头部分,那么winhex逐步扫
描文件块比较 和这个结构里比较
1 unsigned char i;
2 i=-20;
3
上面一段很简单的代码,如果输出会是什么 呢?
今天群里的新学c++同学问我,unsighed char 和char 有啥区别,上面的输出会有什么 不同
在这里,我先鄙视一下自己,我直观的理解为通常的 首位符号位,然后丢下的就是输入无符号的。好吧,估计各位看官说我太菜,但确实是输出的结果和我想的不大一样,如果各位没明白我说的是什么问题,可以试一下。然后回来看下面的内容。
。
In an unsigned type, all the bits represent the value.
If a type is defined for a particular machine to use 8 bits, then the
unsigned version of this type could hold the values 0 through 255.
无符号型中,所有的位都表示数值。如果在某种机器中,定义一种类型使用 8 位表示,那么这种类型的
unsigned 型可以取值 0 到 255。
The C++ standard does not define how signed types are
represented at the bit level. Instead, each compiler is free to decide how it
will represent signed types. These representations can affect the range
of values that a signed type can hold. We are guaranteed that an 8-bit
signed type will hold at least the values from 127 through 127; many
implementations allow values from 128 through 127.
C++ 标准并未定义 signed 类型如何用位来表示,而是由每个编译器自由决定如何表示
signed 类型。这些表示方式会影响 signed 类型的取值范围。8 位 signed
类型的取值肯定至少是从 -127 到 127,但也有许多实现允许取值从 -128 到 127。
Under the most common strategy for representing signed
integral types, we can view one of the bits as a sign bit. Whenever the sign bit
is 1, the value is negative; when it is 0, the value is either 0 or a positive
number. An 8-bit integral signed type represented using a sign-bit can
hold values from 128 through 127.
表示 signed 整型类型最常见的策略是用其中一个位作为符号位。符号位为 1,值就为负数;符号位为
0,值就为 0 或正数。一个 signed 整型取值是从 -128 到 127。
Assignment to Integral Types
整型的赋值
The type of an object determines the values that the object can
hold. This fact raises the question of what happens when one tries to assign a
value outside the allowable range to an object of a given type. The answer
depends on whether the type is signed or unsigned.
对象的类型决定对象的取值。这会引起一个疑问:当我们试着把一个超出其取值范围的值赋给一个指定类型的对象时,结果会怎样呢?答案取决于这种类型是
signed 还是 unsigned 的。
For unsigned types, the compiler must adjust the out-of-range value so that it will fit.
The compiler does so by taking the remainder of the value modulo the number of
distinct values the unsigned target type can hold. An object that is an
8-bit unsigned char, for example, can hold values from 0 through 255
inclusive. If we assign a value outside this range, the compiler actually
assigns the remainder of the value modulo 256. For example, we might attempt to
assign the value 336 to an 8-bit signed char. If we try to store 336 in
our 8-bit unsigned char, the actual value assigned will be 80, because
80 is equal to 336 modulo 256.
对于 unsigned 类型来说,编译器必须调整越界值使其满足要求。编译器会将该值对
unsigned 类型的可能取值数目求模,然后取所得值。比如 8 位的 unsigned char,其取值范围从 0 到
255(包括 255)。如果赋给超出这个范围的值,那么编译器将会取该值对 256 求模后的值。例如,如果试图将 336 存储到 8 位的
unsigned char 中,则实际赋值为 80,因为 80 是 336 对 256 求模后的值。
For the unsigned types, a negative value is always out
of range. An object of unsigned type may never hold a negative value.
Some languages make it illegal to assign a negative value to an
unsigned type, but C++ does not.
对于 unsigned 类型来说,负数总是超出其取值范围。unsigned
类型的对象可能永远不会保存负数。有些语言中将负数赋给 unsigned 类型是非法的,但在 C++ 中这是合法的。
|
In C++ it is perfectly legal to assign a negative number to an
object with unsigned type. The result is the negative value modulo the
size of the type. So, if we assign 1 to an 8-bit unsigned char, the
resulting value will be 255, which is 1 modulo 256.
C++ 中,把负值赋给 unsigned
对象是完全合法的,其结果是该负数对该类型的取值个数求模后的值。所以,如果把 -1 赋给8位的 unsigned char,那么结果是
255,因为 255 是 -1 对 256 求模后的值。
|
When assigning an out-of-range value to a signed type,
it is up to the compiler to decide what value to assign. In practice, many
compilers treat signed types similarly to how they are required to
treat unsigned types. That is, they do the assignment as the remainder
modulo the size of the type. However, we are not guaranteed that the compiler
will do so for the signed types.
当将超过取值范围的值赋给 signed 类型时,由编译器决定实际赋的值。在实际操作中,很多的编译器处理
signed 类型的方式和 unsigned
类型类似。也就是说,赋值时是取该值对该类型取值数目求模后的值。然而我们不能保证编译器都会这样处理 signed 类型。
以上摘自 c++ primer,惭愧,还是再细细的从头品一次这书吧。
IF (@ID NOT IN (@IDS))
begin
---do
end
大部分时间我们用IN ,NOT IN在WHERE子句里,这样直接用好么,有什么问题,欢迎讨论
一、字符转换函数
1、ASCII()
返回字符表达式最左端字符的ASCII 码值。在ASCII()函数中,纯数字的字符串可不用‘’括起来,但含其它字符的字符串必须用‘’括起来使用,否则会出错。
2、CHAR()
将ASCII 码转换为字符。如果没有输入0 ~ 255 之间的ASCII 码值,CHAR() 返回NULL 。
3、LOWER()和UPPER()
LOWER()将字符串全部转为小写;UPPER()将字符串全部转为大写。
4、STR()
把数值型数据转换为字符型数据。
STR (<float_expression>[,length[, <decimal>]])
length 指定返回的字符串的长度,decimal 指定返回的小数位数。如果没有指定长度,缺省的length 值为10, decimal 缺省值为0。
当length 或者decimal 为负值时,返回NULL;
当length 小于小数点左边(包括符号位)的位数时,返回length 个*;
先服从length ,再取decimal ;
当返回的字符串位数小于length ,左边补足空格。
二、去空格函数
1、LTRIM() 把字符串头部的空格去掉。
2、RTRIM() 把字符串尾部的空格去掉。
三、取子串函数
1、left()
LEFT (<character_expression>, <integer_expression>)
返回character_expression 左起 integer_expression 个字符。
2、RIGHT()
RIGHT (<character_expression>, <integer_expression>)
返回character_expression 右起 integer_expression 个字符。
3、SUBSTRING()
SUBSTRING (<expression>, <starting_ position>, length)
返回从字符串左边第starting_ position 个字符起length个字符的部分。
四、字符串比较函数
1、CHARINDEX()
返回字符串中某个指定的子串出现的开始位置。
CHARINDEX (<’substring_expression’>, <expression>)
其中substring _expression 是所要查找的字符表达式,expression 可为字符串也可为列名表达式。如果没有发现子串,则返回0 值。
此函数不能用于TEXT 和IMAGE 数据类型。
2、PATINDEX()
返回字符串中某个指定的子串出现的开始位置。
PATINDEX (<’%substring _expression%’>, <column_ name>)其中子串表达式前后必须有百分号“%”否则返回值为0。
与CHARINDEX 函数不同的是,PATINDEX函数的子串中可以使用通配符,且此函数可用于CHAR、 VARCHAR 和TEXT 数据类型。
五、字符串操作函数
1、QUOTENAME()
返回被特定字符括起来的字符串。
QUOTENAME (<’character_expression’>[, quote_ character]) 其中quote_ character 标明括字符串所用的字符,缺省值为“[]”。
2、REPLICATE()
返回一个重复character_expression 指定次数的字符串。
REPLICATE (character_expression integer_expression) 如果integer_expression 值为负值,则返回NULL 。
3、REVERSE()
将指定的字符串的字符排列顺序颠倒。
REVERSE (<character_expression>) 其中character_expression 可以是字符串、常数或一个列的值。
4、REPLACE()
返回被替换了指定子串的字符串。
REPLACE (<string_expression1>, <string_expression2>, <string_expression3>) 用string_expression3 替换在string_expression1 中的子串string_expression2。
4、SPACE()
返回一个有指定长度的空白字符串。
SPACE (<integer_expression>) 如果integer_expression 值为负值,则返回NULL 。
5、STUFF()
用另一子串替换字符串指定位置、长度的子串。
STUFF (<character_expression1>, <start_ position>, <length>,<character_expression2>)
如果起始位置为负或长度值为负,或者起始位置大于character_expression1 的长度,则返回NULL 值。
如果length 长度大于character_expression1 中 start_ position 以右的长度,则character_expression1 只保留首字符。
六、数据类型转换函数
1、CAST()
CAST (<expression> AS <data_ type>[ length ])
2、CONVERT()
CONVERT (<data_ type>[ length ], <expression> [, style])
1)data_type为SQL Server系统定义的数据类型,用户自定义的数据类型不能在此使用。
2)length用于指定数据的长度,缺省值为30。
3)把CHAR或VARCHAR类型转换为诸如INT或SAMLLINT这样的INTEGER类型、结果必须是带正号或负号的数值。
4)TEXT类型到CHAR或VARCHAR类型转换最多为8000个字符,即CHAR或VARCHAR数据类型是最大长度。
5)IMAGE类型存储的数据转换到BINARY或VARBINARY类型,最多为8000个字符。
6)把整数值转换为MONEY或SMALLMONEY类型,按定义的国家的货币单位来处理,如人民币、美元、英镑等。
7)BIT类型的转换把非零值转换为1,并仍以BIT类型存储。
8)试图转换到不同长度的数据类型,会截短转换值并在转换值后显示“+”,以标识发生了这种截断。
9)用CONVERT() 函数的style 选项能以不同的格式显示日期和时间。style 是将DATATIME 和SMALLDATETIME 数据转换为字符串时所选用的由SQL Server 系统提供的转换样式编号,不同的样式编号有不同的输出格式。
七、日期函数
1、day(date_expression)
返回date_expression中的日期值
2、month(date_expression)
返回date_expression中的月份值
3、year(date_expression)
返回date_expression中的年份值
4、DATEADD()
DATEADD (<datepart>, <number>, <date>)
返回指定日期date 加上指定的额外日期间隔number 产生的新日期。
5、DATEDIFF()
DATEDIFF (<datepart>, <date1>, <date2>)
返回两个指定日期在datepart 方面的不同之处,即date2 超过date1的差距值,其结果值是一个带有正负号的整数值。
6、DATENAME()
DATENAME (<datepart>, <date>)
以字符串的形式返回日期的指定部分此部分。由datepart 来指定。
7、DATEPART()
DATEPART (<datepart>, <date>)
以整数值的形式返回日期的指定部分。此部分由datepart 来指定。
DATEPART (dd, date) 等同于DAY (date)
DATEPART (mm, date) 等同于MONTH (date)
DATEPART (yy, date) 等同于YEAR (date)
8、GETDATE()
以DATETIME 的缺省格式返回系统当前的日期和时间。
首先学习两个函数
1.substring 返回字符、binary、text 或 image 表达式的一部分。
基本语法:SUBSTRING ( expression , start , length )
expression:字符串、二进制字符串、text、image、列或包含列的表达式
start:整数,指定子串的开始位置 注:SQL中"1"表示字符串中的第一个字符,而.NET中"0"表示第一个字符
length:整数,指定子串的长度(要返回的字符数或字节数)
2.patindex 返回指定表达式中某模式第一次出现的起始位置;如果在全部有效的文本和字符数据类型中没有找到该模式,则返回零。
基本语法:PATINDEX ( '%pattern%' , expression )
pattern:字符串。可以使用通配符,但 pattern 之前和之后必须有 % 字符(搜索第一个和最后一个字符时除外)。pattern 是短字符数据类型类别的表达式
expression:表达式,通常为要在其中搜索指定模式的列,expression 为字符串数据类型
declare @a varchar(50)
set @a='2009年7月15日星期五'
select substring(@a,1,4) --获取年份2009
declare @b int
set @b=patindex('%日%',@a) --获取'日'这个字符在字符串中的位置,即10
select substring(@a,6,@b-5) --获取日期'7月15日'
|
使用游标类型执行的速度
adOpenForwardOnly > adOpenDynamic > adOpenKeyset > adOpenStatic
游标类型有以下四种类型:
1、 AdOpenForwardOnly (默认值)一次只能向前移动一行。
2、 AdOpenKeyset 打开键集类型游标。
3、 AdOpenDynamic 打开动态类型游标
4、 AdOpenStatic 打开静态类型游标。
AdOpenForwardOnly和AdOpenStatic这两种游标使得记录集只读,它表示创建数据的一个快照。后者比前者灵活,因为它可以允许任意方向移动。
AdOpenKeyset允许任意移动,并且允许更改记录集。其他用户对记录集的添加和删除,这个游标反映不出来。但它能反映出其他用户对记录集的更改。
AdOpenDynamic允许所有操作,其他用户对记录集的添加、删除、更改在此记录集中
都是可见的。
LockType= adLockOptimistic
Options 省略
大家需要注意的是:当使用AdOpenKeyset时,要求记录集中每条记录都有唯一的关键字。否则,执行的结果就不是您所要的所有记录了。
清楚了游标类型,再来看看锁类型LockType
AdLockReadOnly (默认值)只读 --- 不能改变数据。
AdLockPessimistic 悲观锁(逐个)--- 为确保成功完成编辑记录所需的工作,
在编辑时立即锁定数据源的记录。
AdLockOptimistic 乐观锁(逐个)--- 只在调用Update 方法时才锁定记录。
AdLockBatchOptimistic 乐观批更新---用于批更新模式(与立即更新模式相对)。
对于悲观锁、乐观锁的解释:
乐观的锁策略是把记录必须加锁的时间减到最短,当用户对记录的内容进行编辑时,乐观锁不起作用,其他用户可以访问和编辑数据,但当其中的一个用户想要更新数据时,记录就会加上锁;
悲观的锁策略是当第一个用户打开记录进行编辑的时候,记录就会加锁,直到使用记录的用户解除锁时锁才不起作用。一旦悲观锁起作用,其他的用户就看不到数据,直到该锁被解除;
对于AdLockBatchOptimistic,只能与AdOpenKeyset游标一起使用。它在更新时不会立即把更新过的记录写入到数据源中,而是把对许多条记录所做的改动先放在客户计算机中,然后把更新过的记录作为一批写入数据源
RadioButton的分组是按TabStop来分的,第一个Group为true 直到碰到下一个Group为true前,一直是一组