C语言
sizeof
sizeof是C/C++中的一个操作符,简单的说其作用就是返回一个对象或者类型所占的内存字节数。
int i = 0;
int isize = 0;
isize = sizeof(i);
printf("%d\n", isize);
isize = sizeof i;
printf("%d\n", isize);
isize = sizeof(int);
printf("%d\n", isize);
isize = sizeof(2);
printf("%d\n", isize);
字节对齐
1 8 16 24 32
-------- ------- ------- --------
| int1 | int1 | int1 | int1 |
-------- ------- ------- --------
| | | | int2 |
-------- ------- ------- --------
| int2 | int2 | int2 | |
-------- ------- ------- --------
| ....
一般编译器实现对齐的方法
Actual Align = min ( n, Natual Align ) /*公式 1*/
n:用户指定一个Align值
Natual Align:基本数据类型的自然对齐方式,与该数据类型的大小相等
复杂数据类型的对齐值定义如下:
struct 结构的Align值等于该结构所有成员的 Actual Align 值中最大的一个Align 值,注意:成员的Align值是它的实际Align值,array 数组的Align值等于该数组成员的 Actual Align 值union 联合的Align值等于该联合最大成员的 Actual Align 值。
编译器是如何根据一个类型的Align值来分配存储空间
一个结构成员的offset等于该成员Actual Align值的整数倍如果凑不成整数倍就在其前加padding
一个结构的大小等于该结构Actual Align值的整数倍如果凑不成整数倍就在其后加padding
#pragma pack(4) /*指定Align为4*/
typedefstruct tagTEST_ST1
{
char m_ch1;
int m_lo1;
char m_ch2;
} TEST_ST1_S;
#pragma pack()
现在 Align of TEST_ST1_S = 4 ,
sizeof(TEST_ST1_S) = 12 ( 4 * 3 )
定义的变量在内存中的排列如下 FF 为 padding
00 -- -- -- 04 -- -- -- 08 -- -- -- 12 -- -- --
01 FF FFFF 01 01 01 01 01FFFFFF
m_ch1 m_lo1 m_ch2
#pragma pack(2) /*指定Align为 2*/
typedef struct tagTEST_ST2
{
char m_ch3;
TEST_ST1_S m_test;
} TEST_ST2_S;
#pragma pack()
现在 Align of TEST_ST2_S = 2
sizeof(TEST_ST2_S) = 14 (2 + 4 * 3 )
定义的变量在内存中的排列如下
00 -- -- -- 04 -- -- -- 08 -- -- -- 12 -- -- --
02 FF 01FF FFFF 01 01 01 01 01FF FFFF
m_ch3 m_ch1 m_lo1 m_ch2
字节序
业界存在两种字节序标准:BigEndian和LittleEndian,即大字节序和小字节序。所谓大字节序就是高位在低字节,低位在高字节;小字节序则反之。Power PC是大字节序,X86是小字节序,有些CPU可以通过寄存器设置支持不同的字节序,例如MIPS
字节序问题广泛存在于设备与设备之间、单板与单板之间、单板与底层芯片之间,只要两个处理单元的字节序不同,这个问题就存在。为了解决不同字节序的处理单元之间的通信问题,业界定义了主机序和网络序的概念,网络序主要用于信息传递,一般不用于计算,其字节顺序与大字节序一致;主机序是在一个主机内部的字节序,可以是大字节序或小字节序。
字节序最常见的操作是字节序转换,操作系统提供的字节序转换包括:
uint32_t htonl(uint32_t hostlong); /* 将无符号长整形从主机序转换为网络序 */
uint16_t htons(uint16_t hostshort); /* 将无符号短整形从主机序转换为网络序 */
uint32_t ntohl(uint32_t netlong); /* 将无符号长整形从网络序转换为主机序 */
uint16_t ntohs(uint16_t netshort); /* 将无符号短整形从网络序转换为主机序 */
注意:字符型(char)变量不存在字节序问题。
函数指针
#include <stdio.h>
#define SEC_FREE(p)\
if (NULL != p)\
{\
free(p);\
p = NULL;\
}
typedef int (*ADD)(int, int);
typedef struct tagTEST
{
ADD m_pfnAdd;
}TEST_S;
int Add(int a, int b)
{
return a+b;
}
void main()
{
TEST_S test;
test.m_pfnAdd = Add;
printf("output: %d\r\n", test.m_pfnAdd(10, 20));
}
定义宏释放内存
#define SEC_FREE(p)\
if (NULL != p)\
{\
free(p);\
p = NULL;\
}
条件编译
一般情况下,源程序中所有的代码都参加编译。但是有时希望对其中一部份内容只在满足一定条件才进行编译,也就是对一部份内容指定编译条件,这就是条件编译。定义形式:
1,#ifdef(或#ifndef) 标识符
程序段1
#else
程序段2
#endif
2,#if表达式
程序段1
#else
程序段2
#endif
实例:
a.h的内容如下:
#ifndef _A_H
#define _A_H
#define MAX_PATH 256
#endif
b.H的内容如下:
#include <a.h>
#ifndef _B_H
#define _B_H
#define PI 3.14
#endif
d.c的代码如下:
#include <b.h>
#include <a.h>
#include <stdio.h>
int main()
{
printf(“hello world”)
return 0;
}
在d.c中a.h被包含了多次,用预编译指令可以防止头文件的重复处理,在经过预处理后的d.c中仅仅包含一份a.h
常见函数
getline
功能:读取从键盘输入的字符序列,并将其以字符串形式(以“\0”)存入字符数组中。
头文件:iostream
例子:
const int MAX = 80;
char name[MAX];
cin.getline(name, MAX, '\n');//Read a string until '\n'
//cin.getline(name, MAX);
setw
功能:如例子,在输出流中每个数值的前面插入了setw()操作符,以便输出值在6个字符宽的字段中显示。
头文件:iomanip
例子:
#include <iomanip>
#include <iostream>
using std::setw;
using std::cout;
using std::endl;
void main()
{
int num1 = 1234, num2 = 5678;
cout << endl;
cout << setw(6) << num1 << setw(6) << num2;
cout << endl;
}
strcpy
功能:把从src地址开始且含有NULL结束符的字符串赋值到以dest开始的地址空间。
原型声明:extern char *strcpy(char *dest,const char *src);
头文件:#include <string.h>
说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
返回指向dest的指针。
C++
字符转换
CString和string
//std::string转CString
std::string str("Hello,world!");
CString cstr(str.c_str());
//CStringz转std::string,不能再UNICODE编码下
//std::string strin(cstr.GetBuffer());
//cstr.ReleaseBuffer();
//CString转std::string
CString strMFC = _T("Hello!");
CStringA stra(strMFC.GetBuffer(0));
strMFC.ReleaseBuffer();
std::string str2(stra.GetBuffer());
stra.ReleaseBuffer();
BSTR和LPTSTR
BSTR bstr(_T("Hello!"));
LPTSTR lpStr(bstr);
LPTSTR lpStr1(_T("Hello!"));
BSTR bstr1(lpStr1);
CString转BSTR
BSTR COCX属性Ctrl::GetAgentSkillsMediaType(LONG lMediaType)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CString strResult;
// TODO: 在此添加调度处理程序代码
return strResult.AllocSysString();
}