基本输入输出和复合数据类型

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/qq_25467397/article/details/82223006

基本输入输出

头文件包含:stdio.h

1.格式化输入输出

输出:

printf("格式化控制字符串", 输出项);

“格式化控制字符串”的形式为:
格式化输出函数printf:

%[输出最小宽度][.精度][长度]类型

例如:

double d = 123.456;
print("d=%9.2f", d);

输出结果为:d= 123.46,前面由三个空格因为宽度为9,包含小数点的位数不够前补空格,.2表示精度为小数点后两位,四舍五入。
常见的输出格式符:

d,i         //以十进制形式输出带符号整数(正数不输出符号)
o           //以八进制形式输出无符号整数(不输出前缀0)
x           //以十六进制形式输出无符号整数(不输出前缀0x)
u           //以十进制形式输出无符号整数
f           //以小数形式输出单、双精度浮点数
e           //以指数形式输出单、双精度浮点数
c           //输出单个字符
s           //输出字符串

注意以o, x, u格式输出负数时,取的是模2^32,例如:

int d = -1;
unsigned int b = (1 << 32) - 1;
printf("d=%u,%o,%x, b=%u", d, d, d, b);

输出结果为:

d=4294967295,37777777777,ffffffff, b=4294967295

八进制的37777777777和十六进制的ffffffff均为4294967295。

格式化输入函数scanf:

scanf("格式控制字符串",输入项的地址);

这里的格式控制字符串和printf函数中的相同,但是不能显示非格式字符串,不同点在于:
- 不能指定数据的精度
- 输入long必须使用ld,输入double必须使用lf

例如:

long a;
double b;
scanf("%ld%lf", &a,&b);

常见的复合数据类型

包括class, struct, union, enum
在C++中,classstruct都可以表示类,区别在于默认的数据访问权限和默认类的继承权限struct的默认的数据访问权限和默认类的继承权限都是public,而class则是private,还有一个区别就是模板不再支持struct:

template<struct T>      //不支持的,只能是class或者typename

在C中,struct只能包含数据成员。
structunion的主要区别:
内存struct中的各个变量都独自占有各自的内存空间;union的各个变量则共用相同的一段内存空间,内存的起始位置相同,所以某一个变量的改变会覆盖其它变量值。
struct的占用的内存大小是所有数据成员的大小的和,还需要进行内存对齐
何为内存对齐?
- 每个数据成员的首地址(相对于结构体首地址的偏移量)必须是该数据成员大小的整数倍;特别地,当指定了#pragma pack(n)时, 对齐值为min(基本成员的大小,n),不足要补齐。
- 结构体的总大小必须是最大基本成员的整数倍。

内存对齐的原因
- 平台移植: 某些平台对某些特定类型的数据只能从某些特定地址开始存取,需要保证字节对齐。
- 性能原因:内存对齐,访问效率提升。

64和32位机器的数据类型的大小:

数据类型 32位大小 64位大小
char 1 1
short int 2 2
int 4 4
usigned int 4 4
float 4 4
long 4 8
double 8 8
long long 8 8
unsigned long 4 8
type *(指针类型) 4 8

不同的只有long, unsigned long, type *这三者。举个例子:

struct str {
    char *ch;   //4
    char c;     //1
    int a[3];   //4*3
    double d;   //8
    long l;     //4
}st;

假设为32位机器,那么有:

sizeof(st) = 40 = 4 + 1 + (3) + 4 * 3  + (4) + 8 + 4 + (4)

其中括号中的数字都是用于对齐的。

对于联合体union,由于所有变量共用一个内存位置,所以内存空间的大小为最大变量长度的整数倍,且要大于等于最大成员的存储空间,例如:

union demo {
    int i;
    char ch[5];
}d;
union dem2 {
    int i;
    char ch[9];
}c;

那么会有:

sizeof(d) = 8 = 2 * sizeof(i) >= sizeof(char) * 5
sizeof(d) = 12 = 3 * sizeof(i) >= sizeof(char) * 9

利用union来判断大小端模式
- 大端模式,是指数据的高字节保存在内存的低地址中。
- 小端模式,是指数据的高字节保存在内存的高地址中。

例如:给定一个数0x12345678
箭头表示内存由高地址到低地址:
下图是小端模式:

graph LR;
    0x12-->0x34
    0x34-->0x56
    0x56-->0x78    

大端模式如下:

graph LR;
    0x78-->0x56
    0x56-->0x34
    0x34-->0x12 

利用union判断的代码:

union test {
    int a;
    char c;
}T;
T.a = 1;

如果T.c == 1,说明高字节保存在高地址,即小端模式;否则为大端模式。

枚举类型enum,例如:

enum enumType {
    Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
}WeekDay;

声明enumTyp为枚举类型,声明Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday为枚举量,默认值为0~6,未被初始化的枚举值的值默认将比其前面的枚举值大1,例如:

enum enumType {
    Monday = 1, Tuesday, Wednesday = 1, Thursday, Friday, Saturday, Sunday
}WeekDay;

那么有:
Tuesday = 2, Thursday = 2, Friday = 3, Saturday = 4, Sunday = 5
枚举的取值范围:
- 如果枚举常量均大于0,枚举的范围:[0, 2^n-1]
- 如果存在枚举常量小于等于0,范围为[2^m+1, 2^n-1].

枚举定义的时常量集合,大小为sizeof(int) = 4

基本输入输出部分主要参考了《精通Linux C编程》程国钢编著,复合数据类型部分主要是网上的一些资料博客然后总结的

猜你喜欢

转载自blog.csdn.net/qq_25467397/article/details/82223006