C/C++ 学习手札(一)

2024-01-15 19:08
文章标签 c++ 学习 手札

本文主要是介绍C/C++ 学习手札(一),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

出于需要,最近研究C/C++。简单熟悉一下这个让我遗忘多年的语言。作为学习,在这里记录。同时对比C与C++的差别。
C的代码:

#include <stdio.h>
#include <stdlib.h>

/**
* 定义一个结构体
*/
struct Location {
int x; // 横坐标
int y; // 纵坐标
} location;

int main(void) {
printf("输入X坐标:\t\n");

int x;
scanf("%d", &x);

location.x = x;

printf("输入Y坐标:\t\n");

int y;
scanf("%d", &y);
location.y = y;

printf("X坐标是:\t%d\n", location.x);
printf("Y坐标是:\t%d\n", location.y);

// 做倒三角打印
int i;

for (i = 0; i < y; i++) {
printf("%d\t", i + 1);

int j;
for (j = i; j < x; j++) {
printf("* ");
}
printf("\n");
}

return EXIT_SUCCESS;
}

这里使用了结构体[b]Location[/b],并生成了一个实例[b]location[/b]。通过[b]scanf[/b]向x、y输入数字。以[b]location.x = x;[/b]方式将数值赋值给结构体[b]location[/b]的变量[b]x[/b]。由此可以看出结构体就是现在面向对象的基础,尤其是数据对象的前身。 :D

我们希望打印操作能够独立出来,成为一个函数,可以这么写:

// 声明函数
void print(int x, int y);

c是面向过程的计算机语言,要在主函数内调用其他函数,必须要在主函数前声明函数,要么就直接把函数按照调用次序逆次由上到下排序。即便是面向对象的C++,也是如此。

/**
* 倒三角打印
*/
void print(int x, int y) {
int i;

for (i = 0; i < y; i++) {
printf("%d\t", i + 1);

int j;
for (j = i; j < x; j++) {
printf("* ");
}
printf("\n");
}


整体代码如下:

#include <stdio.h>
#include <stdlib.h>

/**
* 定义一个结构体
*/
struct Location {
int x; // 横坐标
int y; // 纵坐标
} location;

// 声明函数
void print(int x, int y);

int main(void) {
printf("输入X坐标:\t\n");

int x;
scanf("%d", &x);

location.x = x;

printf("输入Y坐标:\t\n");

int y;
scanf("%d", &y);
location.y = y;

printf("X坐标是:\t%d\n", location.x);
printf("Y坐标是:\t%d\n", location.y);

// 做倒三角打印
print(x, y);

return EXIT_SUCCESS;
}

/**
* 倒三角打印
*/
void print(int x, int y) {
int i;

for (i = 0; i < y; i++) {
printf("%d\t", i + 1);

int j;
for (j = i; j < x; j++) {
printf("* ");
}
printf("\n");
}
}


对比C++的代码:

#include <iostream>

using namespace std;

// 定一个类
class Location {
private:
int x; // 横坐标
int y; // 纵坐标
public:
Location() {
}
Location(int x, int y) {
this->x = x;
this->y = y;
}
int getX() {
return x;
}
void setX(int x) {
this->x = x;
}
int getY() {
return y;
}
void setY(int y) {
this->y = y;
}
};

int main() {
// 声明
Location location;

cout << "输入X坐标:\t";

int x;
cin >> x;
location.setX(x);

cout << "输入Y坐标:\t";

int y;
cin >> y;
location.setY(y);

cout << "X坐标是:\t" << location.getX() << endl;
cout << "Y坐标是:\t" << location.getY() << endl;

// 做倒三角打印
int i;

for (i = 0; i < y; i++) {
cout << i + 1 << "\t";

int j;
for (j = i; j < x; j++) {
cout << "* ";
}
cout << endl;
}

return 0;
}

这里的[b]location[/b]就是一个类[b]Location[/b]的实例了。同样是赋值操作,对[b]x[/b]赋值调用[b]location.setX(x);[/b]方法,而内部实现是[b]this->x = x;[/b]明显的指针特色[color=red][b]->[/b][/color]而不是[color=red][b].[/b][/color]。这个时候有了私有变量的概念,上面C的代码中的[b]location.x[/b]就不合适了。必须使用[b]location.getX()[/b]方法输出[b]x[/b]的值。仍然让我使用起来不舒服的是[b]cin[/b] 与 [b]cout[/b] ,为什么在C++面向对象的语言里,却不能以方法的方式实现,还是要使用这样的特定的字符串来([b]>>[/b] 与 [b]<<[/b])控制呢?真的很别扭。特别是在熟悉Java的实现后,你会觉得C++有的时候很别扭。如果我要重新定义一个公有的方法,除了上述的方式,可以这样做:

#include <iostream>

using namespace std;

class Location {
private:
int x, y;
public:
Location() {
}
Location(int x, int y);
int getX() {
return x;
}
void setX(int x) {
this->x = x;
}
int getY() {
return y;
}
void setY(int y) {
this->y = y;
}
};
Location::Location(int x, int y) {
this->x = x;
this->y = y;
}
// 省略

现在类中定义方法[b]Location(int x, int y);[/b]然后在类外实现该方法:

Location::Location(int x, int y) {
this->x = x;
this->y = y;
}

上述是一个构造方法,如果要返回值的值类型要定义在方法最前面,如:

int Location::getX() {
return y;
}


我们把打印操作改成函数实现,[color=red]注意:在C++里如果一个函数被高频度执行,声明为内联函数([b]inline[/b]),可以提高执行效率![/color]

// 声明函数
inline void print(int x, int y);

C++一样没有跳出C的特色,要在主函数调用前声明函数。 :(

/**
* 倒三角打印
*/
inline void print(int x, int y) {
int i;

for (i = 0; i < y; i++) {
cout << i + 1 << "\t";

int j;
for (j = i; j < x; j++) {
cout << "* ";
}
cout << endl;
}
}


给出全部代码:

#include <iostream>

using namespace std;

/**
* 定义一个类
*/
class Location {
private:
int x; // 横坐标
int y; // 纵坐标
public:
Location() {
}
Location(int x, int y) {
this->x = x;
this->y = y;
}
int getX() {
return x;
}
void setX(int x) {
this->x = x;
}
int getY() {
return y;
}
void setY(int y) {
this->y = y;
}
};

// 声明函数
inline void print(int x, int y);

int main() {
// 声明
Location location;

cout << "输入X坐标:\t";

int x;
cin >> x;
location.setX(x);

cout << "输入Y坐标:\t";

int y;
cin >> y;
location.setY(y);

cout << "X坐标是:\t" << location.getX() << endl;
cout << "Y坐标是:\t" << location.getY() << endl;

// 做倒三角打印
print(x, y);

return 0;
}

/**
* 倒三角打印
*/
inline void print(int x, int y) {
int i;

for (i = 0; i < y; i++) {
cout << i + 1 << "\t";

int j;
for (j = i; j < x; j++) {
cout << "* ";
}
cout << endl;
}
}

学过Java的人觉得很别扭。呵呵,我也一样。 :D


最后,让我们看看这2个程序的最终输出:

输入X坐标: 9
输入Y坐标: 9
X坐标是: 9
Y坐标是: 9
1 * * * * * * * * *
2 * * * * * * * *
3 * * * * * * *
4 * * * * * *
5 * * * * *
6 * * * *
7 * * *
8 * *
9 *


换成Java实现:

import javax.swing.JOptionPane;

public class Location {
private int x;
private int y;

/**
* @return the x
*/
public int getX() {
return x;
}

/**
* @param x
* the x to set
*/
public void setX(int x) {
this.x = x;
}

/**
* @return the y
*/
public int getY() {
return y;
}

/**
* @param y
* the y to set
*/
public void setY(int y) {
this.y = y;
}

/**
* @param args
*/
public static void main(String[] args) throws Exception {
Location location = new Location();

int x = Integer.parseInt(JOptionPane.showInputDialog("输入X坐标:"));
int y = Integer.parseInt(JOptionPane.showInputDialog("输入Y坐标:"));
location.setX(x);
location.setY(y);
location.print(x, y);
}

/**
* 倒三角打印
*
* @param x
* @param y
*/
public void print(int x, int y) {
for (int i = 0; i < y; i++) {
System.out.print(i + 1 + "\t");
for (int j = i; j < x; j++) {
System.out.print("* ");
}
System.out.println();
}

}
}

呵呵,用Java实现,感觉就是好! :D

相关链接:
[url=http://snowolf.iteye.com/blog/402483]C/C++ 学习手札(一)[/url]
[url=http://snowolf.iteye.com/blog/410102]C/C++ 学习手札(二)[/url]
[url=http://snowolf.iteye.com/blog/410984]C/C++ 学习手札(三)[/url]

这篇关于C/C++ 学习手札(一)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/609907

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

C++包装器

包装器 在 C++ 中,“包装器”通常指的是一种设计模式或编程技巧,用于封装其他代码或对象,使其更易于使用、管理或扩展。包装器的概念在编程中非常普遍,可以用于函数、类、库等多个方面。下面是几个常见的 “包装器” 类型: 1. 函数包装器 函数包装器用于封装一个或多个函数,使其接口更统一或更便于调用。例如,std::function 是一个通用的函数包装器,它可以存储任意可调用对象(函数、函数

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

06 C++Lambda表达式

lambda表达式的定义 没有显式模版形参的lambda表达式 [捕获] 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 有显式模版形参的lambda表达式 [捕获] <模版形参> 模版约束 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 含义 捕获:包含零个或者多个捕获符的逗号分隔列表 模板形参:用于泛型lambda提供个模板形参的名

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]