C/C++随笔

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);
字节对齐
为什么要对齐
当一个 int 型数如图中 int1 在内存中的位置正好与内存的字边界对齐时 CPU 存取这个数只需访问一次内存,而当一个 int 型数如图中 int2 在内存中的位置跨越字边界时 CPU 存取这个数就需多次访问内存

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



字节序

       业界存在两种字节序标准:BigEndianLittleEndian,即大字节序和小字节序。所谓大字节序就是高位在低字节,低位在高字节;小字节序则反之。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.ca.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();
} 


 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值