1(关于printf的输出)
#include <stdio.h>
int main(void) {
int a=12345;
printf("A-%d\n", printf("B-%d\n", printf("C-%d\n", a)));
/*
C-12345
B-8
A-4
*/
return 0;
}
输出:
2(结构体成员变量)
结构体:成员变量、成员函数
#include <stdio.h>
struct Vec2f { float x, y; }; //结构体类型,有两个float类型的成员变量x和y
//================================================================== Above, maybe, in different files
void add(Vec2f* result, Vec2f _v0, Vec2f _v1) { //函数
result->x = _v0.x + _v1.x;//"->"是间接对结构体成员变量进行访问
result->y = _v0.y + _v1.y;
}
void sum(Vec2f& result, Vec2f _v0, Vec2f _v1) { // & <---new !!!
result.x = _v0.x + _v1.x; //"."是直接对结构体成员变量进行访问
result.y = _v0.y + _v1.y;
}
void show(const Vec2f& _v) { // const <---new !!!(const是 constant 的缩写,恒定不变的,只能读,不能改变)
printf("(%.2f, %.2f)\n", _v.x, _v.y);
}
//=================================================================== Maybe, in different files
int main(void) {
Vec2f v0, v1, v2, v3;
v0.x = 1.2f; v1.x = 2.1f;
v0.y = 3.4f; v1.y = 4.3f;
add(&v2, v0, v1); // <---attention !!!
show(v2);
sum(v3, v0, v1);//v3在函数中的变化会被带回
show(v3);
return 0;
}
输出:
3(封装,把数据和对数据的操作放在一个结构体中)
#include <stdio.h>
struct Vec2f {
float x, y;
void show(void) {
printf("%f %f\n", x, y);
}
// v.add(v0,v1);
// vv = v.add(v0,v1);
Vec2f& add(Vec2f _v0, Vec2f _v1) { //!!!: \&\///
x = _v0.x + _v1.x;
y = _v0.y + _v1.y;
return *this; // caution: why ?
}
Vec2f& add(Vec2f _v) { // <---new !!! with same func-name as the above, at all !!
x += _v.x;
y += _v.y;
return *this;
}
//以上有两个同名的函数,不同的是参数数量不同
//实际调用时,看函数参数的数量进行选择
};
int main(void) {
Vec2f v0, v1;
v0.x = 1.2f; v1.x = 2.1f;
v0.y = 3.4f; v1.y = 4.3f;
v0.add(v1); v0.show(); v1.show();
v0.add(v1, v0); v0.show();
v1 = v0.add(v1); v0.show(); v1.show();
return 0;
}
输出:
不知道为什么是16.299999而不是16.300000 。我专门试了一下:
float a=4.3,b=12.0;
printf("%f\n",a+b);
输出结果也是16.299999,这应该是和二进制什么的有关系的吧。
注意:
(1)const 只能用,不能改
(2)规定每一个结构体中都有一个this指针指向它自己,*this就是指向的具体的值。上述程序中的return *this是为了防止调用的位置有将函数赋值给某变量的形式:
(3)在函数的参数中参数名称前的&,表示“引用”,作用是返回的不是一个临时开辟进行存储的空间内容(临时变量),而就是它自己!
(4)C语言中不允许函数同名,而C++中允许,只要函数的参数不同就可以。这一现象叫做多态(这一现象只是C++中多态的一种)。
4(引用,没有值传递的过程)
#include <stdio.h>
struct Vec2f {
float x, y;
// Vec2f vv;
// vv.add(v0,v1);
Vec2f& add(const Vec2f& _v0, const Vec2f& _v1) { // \const and \& and \return
x = _v0.x + _v1.x;
y = _v0.y + _v1.y;
return *this;
}
Vec2f& add(const Vec2f& _v) {
x += _v.x;
y += _v.y;
return *this;
}
void show(void) const { // <---new !!!
printf("%f %f\n", x, y);
}
};
int main(void) {
Vec2f v0, v1;
v0.x = 1.2f; v1.x = 2.1f;
v0.y = 3.4f; v1.y = 4.3f;
v0.add(v1); v0.show(); v1.show();
v0.add(v1, v0); v0.show();
v1 = v0.add(v1); v0.show(); v1.show();
return 0;
}
输出同上。
注意:
(1)函数被const 标志后,不能修改成员数据;函数被const标志后,只能调用被const标志的函数。
(2)函数参数带有标记&,意味着“引用”(reference),形参变成了实参的别称(同一个东西,同一块内存空间)。
5(类和对象,理解private和public以及构造函数、析构函数)
#include <stdio.h>
class Vec2f { // <---new !!!
private: // <--- to hide inner-info
float x, y;
public: // <---
Vec2f() {printf("$$\n");}
Vec2f(float _x, float _y) { //构造函数,与类同名
printf("@@\n");
x = _x; y = _y;
}
~Vec2f() { printf("kill me!\n"); } //!!无参数 析构函数
};
int main(void) {
Vec2f v0 ; //<========== 实例化
Vec2f v1 (3.4f, 4.3f);
return 0;
}
输出:
注意:
(1)构造函数与结构体同名,一般可用来进行初始化。
(2)根据类构造对象时,其后参数的不同,调用不同的构造函数。
(3)析构函数的标志为~,可用来释放空间。
6(类和对象,将类中的函数写在类外面,加上帽子)
#include <stdio.h>
class Vec2f { //把所有的声明写在一起,使结构体更加的紧凑清晰
private:
float x, y;
public:
Vec2f(void) : x(0), y(0) {}; //构造函数 int a = 0; int a(0); 速度更快
//Vec2f(void) { x=y=0; }; //构造函数,等价与上面的操作
Vec2f(float _x, float _y); //构造函数
~Vec2f(); // 析构函数
Vec2f& add(const Vec2f& _v);
void show(void);
};
Vec2f::Vec2f(float _x, float _y) : x(_x), y(_y) //构造函数
{}
Vec2f::~Vec2f() { //!!无参数 析构函数
printf("kill me!\n");
}
Vec2f& Vec2f::add(const Vec2f& _v) {
x += _v.x;
y += _v.y;
return *this;
}
void Vec2f::show(void) {
printf("%f %f\n", x, y);
}
int main(void) {
Vec2f v0 (1.2f, 2.1f);
Vec2f v1 (3.4f, 4.3f);
Vec2f v2;
v0.add(v1);
v0.show();
v1.show();
v2.show();
return 0;
}