C++2结构体,输入与输出函数

2023年2月16日09:58:24

一、C语言与c++中的不同之:输入与输出

C++中既可以使用C语言中的输入输出函数也可以用Cin和Cout进行输入与输出,不需要格式控制。

# include<iostream>
using namespace std;
int main()
{
	printf("hello world\n");
	cout << "change world" << endl;
	return 0;
}

(1)endl代表换行(也可以使用\n换行)

(2)需要包含输入输出流的头文件# include<iostream>

(3)需要在开头加入using namespace std;如果不加入,编译器会识别不了,采用以下方式,即加入命名空间即使不加入也可以识别:

# include<iostream>
//using namespace std;
int main()
{
	printf("hello world\n");
	std::cout << "change world" <<std:: endl;
	return 0;
}

也可以将cout和endl引入标准空间来改正消除这个错误:

# include<iostream>
//using namespace std;
using std::cout;
using std::endl;
int main()
{
	printf("hello world\n");
	cout << "change world" <<endl;
	return 0;
}

(4)、C语言中需要给出格式化的部分,c++中则不需要给出格式化的部分(输出浮点型等都直接给出值即可)

# include<iostream>
using namespace std;
int main()
{
	printf("%d %c %lf", 1, '1', 1.0);
 	cout << 1<<" "<<'1'<<" "<<1.0<<endl;
	//等同于
	/*cout << 1 << endl;
	cout << '1' << endl;
	cout << 1.0<< endl;*/
	return 0;
}

在C语言的格式化部分若是出现错误,会影响其他的格式化部分都出现错误。

printf函数返回值为成功输出字符的个数

scanf传的参数是不定的,最开始为格式化部分。若是给定接收的参数没有初始化 ,编译器会认为未初始化不安全,产生错误。如下:

int main()
{
	int a, b;
	scanf("%d,%d",a, b);
	system("pause");
	return 0;
}

初始化后继续执行会异常中断,因为要传地址

int main()
{
	int a=0, b=0;
	scanf("%d,%d",&a, &b);
	system("pause");
	return 0;
}

scanf的返回值为成功输入的参数个数

在C++中使用cin,cout

从控制台顺着输入输出流流入参数中:cin>>a;cout>>b。而且不需要关注其类型。

二、C语言中结构体的认识:

1、什么是结构体?

结构体是一系列数据的集合,这些数据可能描述了一个物体,也可能是对一个问题的抽象。

2、一般在什么情况下需要用到结构体?

(1)内置类型已经无法满足实际需求;

(2)参数打包:参数过多,一个一个的传递不方便,把参数打包在一块;

3、什么是内存对齐?为什么要内存对齐?怎样对齐?

在C语言中,若是没有重定义,必须用stuct 结构体名 实参名 来定义实参。而在c++中在可以用 结构体名 实参名 来定义实参而不需要加struct。

内存对齐”应该是编译器的“管辖范围”。编译器为程序中的每个“数据单元”安排在适当的位置上。但是C语言的一个特点就是太灵活,太强大,它允许你干预“内存对齐”。如果你想了解更加底层的秘密,“内存对齐”对你就不应该再透明了。对于内存对齐问题,主要存在于struct和union等复合结构在内存中的分布情况,许多实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们要求这些数据的首地址的值是某个数M(通常是4或8);对于内存对齐,主要是为了提高程序的性能,数据结构,特别是栈,应尽可能在自然边界上对齐,经过对齐后,cpu的内存访问速度大大提升。

Windows中默认对齐数为8,Linux中默认对齐数为4;

为什么要内存对齐:内存对齐的原因

(1、平台原因(移植原因)
             A   不是所有的硬件平台都能访问任意地址上的任意数据的;

       B    某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
( 2、性能原因:

             A   数据结构(尤其是栈)应该尽可能地在自然边界上对齐。

             B   原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。

 对齐规则:1、结构体中每个成员  2、结构体整体

(1)第一个成员在与结构体变量偏移量为0的地址处。(在一个对齐的位置上)

(2)其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
注意:对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值,min(对齐参数,sizeof(成员))。VS中默认的值为8,gcc中的默认值为4
(3)结构体总大小为最大对齐数(每个成员变量除了第一个成员都有一个对齐数)的整数倍。min(对齐参数,类型最大成员所占字节数)
(4)如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

4、对齐参数如何设置?可以设置为按照任意字节对齐吗?

法1、

# pragma pack(对齐数)

#pragma pack()//恢复

法2、项目---》属性---》c/c++----》代码生成---》设置结构成员对齐数,更改默认设置:此方法一旦实现,整个工程的对齐数都将发生更改。

对齐参数不能任意设置,只能是内置类型已有的字节数,如:char(1)、short(2),int(4),double(8)…不能是3,5…任意数。

5、如何知道结构体中某个成员相对于结构体起始位置的偏移量?

宏offsetof可以求出结构体中某个成员相对于结构体起始位置的偏移量

#pragma pack(4)
struct A
{
	int a;
	char b;
	double c;
	char d;
};
#pragma pack()
int main()
{
	A a;
	cout << offsetof(A, c) << endl;
	cout << sizeof(A) << endl;
 	return 0;
}

实现一个宏(offsetof)或者函数实现结构体中某个成员相对于结构体起始位置的偏移量

6、变长的结构体:

(1)intfo和其他的结构成员在同一块空间,info的空间可以为0,通过malloc申请需要的空间大小

struct student
{
	char _name[20];
	int _age;
	char _gender;
	int _len;
	char _info[0];//柔性数组
};

(2)info与其他的结构体成员不在同一块空间,最小为4个字节,因为char *字符指针占4个字节。

struct student
{
	char _name[20];
	int _age;
	char _gender;
	int _len;
	char* _info;
};

7、位段,联合体

8、大小端问题?如何来测试大小端(多种方式)?

大小端:

测试方式:

9、C语言与c++中结构体的相同和不同之处:

(1)定义实体的方式不同;

(2)初始化结构体的成员:C语言中一般用一个函数进行初始化,不可以将函数写道结构体里面(结构体里面不可以放函数);而在c++中结构体里面可以放函数。

结构体的一个实例:

struct student
{
	char _name[20];
	int _age;
	char _gender[3];
	void SetInfo(char *name, int age, char *gender)
	{
		strcpy(_name, name);
		_age = age;
		strcpy(_gender, gender);
	}
	void PrintStudent()
	{
		cout << _name << " " << _age << " " << _gender << endl;
	}
};
int main()
{
	student s1, s2;
	s1.SetInfo("将旧", 28, "女");
	s2.SetInfo("卡卡", 3, "男");
	s1.PrintStudent();
	s2.PrintStudent();
	return 0;
}

  • 作者:xuruhua
  • 原文链接:https://blog.csdn.net/xuruhua/article/details/80650620
    更新时间:2023年2月16日09:58:24 ,共 3347 字。