1. sizeof()与strlen()区别
2. 结构体对齐方式
3. C++中char 类型的一个问题
4. 四舍五入计算
5. 枚举使用
1. sizeof()与strlen()区别
(1) sizeof是C/C++中的一个运算符,其作用是返回一个对象或者类型在内存中所占用的字节数。sizeof不能返回动态地被分配的数组的大小。sizeof在编译期完成。
(2) strlen是C语言中的库函数,所在头文件为#include <string.h>其函数原型为*unsigned int strlen(char s); 其中s为指定的字符串。
注意:strlen只能用char *作为参数,它求的是字符串的实际长度,方法是从开始到遇到第一个’\0’结束。strlen()是函数,在运行期间完成。
/* 用sizeof()返回元素字节数 */
// 数据类型
a = sizeof(char); // char - 1个字节
b = sizeof(short int); //short int - 2个字节
c = sizeof(int); //int - 4个字节
d= sizeof(long); //long - 4个字节
e = sizeof(long long); //long long - 8个字节
// 数组
int pt[10];
int length = sizeof(pt); //length = 40;
char pt[20] = "0123456789";
int a = sizeof(pt); //a = 20
int b = strlen(pt); //b = 10 strlen计算的是字符串的实际长度
char pt2[] = "0123456789";
int c = sizeof(pt2); //c = 11;
int d = strlen(pt2); //d = 10;
/* 上面结果为a = 10,这是因为strlen计算的是字符串的实际长度,以第一个'\0'为结束符;b = 20,这是因为sizeof计算的是分配的数组str[20]所占的空间大小,不受里面存储内容的影响。*/
// 结构体
typedef struct stu1
{
int a;
char b;
int c;
}People;
People people_01;
int a = sizeof(people_01); //a = 12 结构体4字节对齐
对于一个整型数组,要求用户输入数据,但是数据长度未知,如何实现输入,并得到数据长度??
分析:sizeof()——可以计算数据长度,但计算的是数据在内存中分配的长度,此处为有效数据的长度。不满足条件;
strleng()——可以计算字符串数组有效长度,但不能计算整形数组有效长度。不满足条件。
(1) 定义终止数据,当输入终止数据时,停止输入循环;
(2) 当输入有效数据时,把有效数据放入数组,并更新有效数组长度;
for (i = 0;i < 100;i++)
{
cin >> tempIn; //输入数据存入临时变量
if (tempIn != 99999) //以9999作为输入终止标志
{
num[i]= tempIn;
length++; //有效数据,数据有效长度递增1
}
else
{
break; //跳出循环
}
}
输入不确定长度字符串的实现
C++中可以中cin.getline();来输入不定长度字符串,以换行符结束;
判断字符是否是 结束符 '\0'来计算递增长度变量或直接利用strlen()来求字符串长度;
2. 结构体对齐方式
typedef struct stu1
{
int a;
char b;
int c;
}People;
People people_01;
int a = sizeof(people_01); //a = 12 结构体4字节对齐
int 型占4个字节,char 型占1个字节,那么people_01应该占用2*4+1也就是9个字节啊。那为什么回事12个字节呢?
结构体中的成员可以是不同的数据类型,成员按照定义时的顺序依次存储在连续的内存空间。和数组不一样的是,结构体的大小不是所有成员大小简单的相加,需要考虑到系统在存储结构体变量时的地址对齐问题。
先介绍一个相关的概念——偏移量。偏移量指的是结构体变量中成员的地址和结构体变量地址的差。结构体大小等于最后一个成员的偏移量加上最后一个成员的大小。显然,结构体变量中第一个成员的地址就是结构体变量的首地址。第一个成员a的偏移量为0。第二个成员b的偏移量是第一个成员的偏移量加上第一个成员的大小(0+4),其值为4;第三个成员c的偏移量是第二个成员的偏移量加上第二个成员的大小(4+1),其值为5。
然而,在实际中,存储变量时地址要求对齐,编译器在编译程序时会遵循两条原则:
(1)结构体变量中成员的偏移量必须是成员大小的整数倍(0被认为是任何数的整数倍)
(2)结构体大小必须是所有成员大小的整数倍,也即所有成员大小的公倍数。
上面的例子中前两个成员的偏移量都满足要求,但第三个成员的偏移量为5,并不是自身(int)大小的整数倍。编译器在处理时会在第二个成员后面补上3个空字节,使得第三个成员的偏移量变成8。结构体大小等于最后一个成员的偏移量加上其大小,上面的例子中计算出来的大小为12,满足要求。
struct stu2
{
int k;
short t;
};
成员k的偏移量为0;成员t的偏移量为4,都不需要调整。但计算出来的大小为6,显然不是成员k大小的整数倍。因此,编译器会在成员t后面补上2个字节,使得结构体的大小变成8从而满足第二个要求。
由此可见,结构体类型需要考虑到字节对齐的情况,不同的顺序会影响结构体的大小。
可以使用**#pragma pack(n)**改变对齐方式。编译器会从“n”和”结构体中最长的数据类型长度“中选较小的那个作为对齐标准
如#pragma pack(1),相当于取消对齐,那么结构体people_01所占字节数就为9了。
3. C++中char 类型的一个问题
在C/C++中,char 类型的数据也是以数据存储的,只不过该数字对应特定的字符;
/* C语言中 uc可以输出 以10进制、16进制输出存储的数值*/
unsigned char uc;
uc = 50;
printf("%d\n",uc); //50
printf("%x\n",uc); //32
unsigned char uc;
uc = 50;
cout << dec << uc << endl; // 2 ASCII
cout << hex << uc << endl; // 2
cout << dec << (int)uc << endl; //50
cout << hex << (int)uc << endl; //32
为什么在C++中char字符不能以数据形式输出???如果不能输出数字量,那C++ 中signed char 和unsigned char 又有什么作用?
虽然C++中char字符以字符形式输出,但在计算过程中,还是以数字参与运算
如
char a = 1;
int b = 3;
cout << (b + a) << endl; //输出4
4. 四舍五入计算
(1) 小数四舍五入取整
average = int(average + 0.5); //四舍五入取整
(2) 保留两位小数点
value = int(value * 100 + 0.5) / 100;
6. 枚举变量使用规则
(1) 枚举类型时C/C++中的一种基本数据类型有,和 整型、浮点型、字符型一样。
enum Week { Sun = 7, Mon = 1, Tes, Wed, Thu, Fri, Sat };
Week begin, end;
cin >> begin;//直接输入枚举变量,错误
begin = 1; //整数赋值给枚举变量,错误
begin = Mon; //将枚举常量赋值给枚举变量,正确
begin = end; //相同类型的枚举变量赋值,正确
begin = (Week)1; //整数强制类型转换后赋值,正确
int a = begin; //将枚举变量赋值给整数,正确
int b = Mon; //将枚举常量赋值给整数,正确
int c= Sun-Mon; //枚举变量可以直接参加数学运算,结果为数值类型,正确
cout << begin; //直枚输出枚举变量,正确