为啥要在linux/unix下进行c/c++编程?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为啥要在linux/unix下进行c/c++编程?相关的知识,希望对你有一定的参考价值。

看到很多的书都是些在linux/unix下进行c或者c++编程的,但是在这种主要支持命令行的系统下进行编程好像比在图文并茂的windows下麻烦啊,不管是写代码还是调试都显得更麻烦,为什么还要在这两个系统下进行这种编程呢?

这个要看具体行业和需求的,简单的来说,如果客户就在linux下运行程序,难道你不给他开发这下面的程序吗?
由于linux的内核是开放的,所以从稳定性和可信任度上来说,比windows要更让人信任一些,所以很多金融类的银行证券公司,后台服务器肯定都是linux/unix的。
而且这些系统的相对病毒也比较少,也比windwos更安全。
参考技术A 图形界面的背后也是很多命令执行的结果,这就好比是你写代码调用一个别人给的接口来实现打印功能,结果人家这个接口不提供这个功能,还不让你自己实现,那你怎么办?
图形界面面向的人群更适合一些初级人群,你要用C在图形界面下写个小程序玩玩那是比较方便,但是一旦开发大型程序呢?你需要的各种调试方法及命令人家界面因为不太常用都不给你实现那你不是干着急没办法啊,这就体现出linux的好出来了,哪,命令方法我都给你了,你自己随便用吧,就是多了点学起来费劲,但是学会了那可是怎一个方便了得
参考技术B 这个,得从为什么还需要有 xNIX 之类的操作系统说起?
有需要用 xNIX 的地方,就一定有需要用 c/c++ 在这些平台下编程的地方。

xNIX 用命令行是他的文化之一,一个GUI的窗口,再怎么样也只能安排有限个菜单,
或者按钮来执行有限的操作;但是用命令行就不同了,一行文字就可以有无数种
操作可以表示,更别说不同命令之间的搭配使用了。
所以,千万别去讨厌 xNIX 的命令行。尝试它,习惯它,并最终喜欢它。
参考技术C 不懂你为啥说linux麻烦, 感觉windows才麻烦, 哪里都麻烦

为啥要在条件中使用赋值?

【中文标题】为啥要在条件中使用赋值?【英文标题】:Why would you use an assignment in a condition?为什么要在条件中使用赋值? 【发布时间】:2010-09-14 04:34:03 【问题描述】:

在许多语言中,赋值在条件下是合法的。我一直不明白这背后的原因。为什么要写:

if (var1 = var2) 
  ...

代替:

var1 = var2;
if (var1) 
  ...

【问题讨论】:

这个问题真的与语言无关吗?哪些语言会受此影响?我知道 C 和 C++ 是,还有什么? 【参考方案1】:

我今天在用 Arduino(C 语言)编程时使用它。

案例

我有一个发射器和一个接收器。 发送器想要发送数据,直到它被接收到。我想在进程完成后设置一个标志。

while (!(newtork_joined = transmitter.send(data))) 
Serial.println("Not Joined");

这里:

"transmitter.send" - 传输成功时返回真 “newtork_joined” - 是我成功时设置的标志

结果

    传输不成功时,不设置标志,while循环为真,一直执行

    成功时,设置标志,while循环为假,我们退出

不漂亮吗?

【讨论】:

【参考方案2】:

原因是:

    性能改进(有时)

    更少的代码(总是)

举个例子:有一个方法someMethod(),在if条件下你要检查方法的返回值是否为null。如果没有,您将再次使用返回值。

If(null != someMethod())
    String s = someMethod();
    ......
    //Use s

这会影响性能,因为您要调用相同的方法两次。而是使用:

String s;
If(null != (s = someMethod())) 
    ......
    //Use s

【讨论】:

这是什么语言?它不会在 C# 或 C++ 中编译(“If”的大写)。【参考方案3】:

我发现它对于返回可选项的函数非常有用(boost::optional 或 C++17 中的 std::optional):

std::optional<int> maybe_int(); // function maybe returns an int

if (auto i = maybe_int()) 
    use_int(*i);

这减少了我的变量的范围,使代码更紧凑并且不妨碍可读性(我发现)。

指针也一样:

int* ptr_int();

if (int* i = ptr_int()) 
    use_int(*i);

【讨论】:

顺便说一句,如果你想限制变量的范围,你可以使用 if with initializers :)【参考方案4】:

我发现它在通常涉及错误检测等的操作链中最有用。

if ((rc = first_check(arg1, arg2)) != 0)

    report error based on rc

else if ((rc = second_check(arg2, arg3)) != 0)

    report error based on new rc

else if ((rc = third_check(arg3, arg4)) != 0)

    report error based on new rc

else

    do what you really wanted to do

替代方案(不使用条件中的赋值)是:

rc = first_check(arg1, arg2);
if (rc != 0)

    report error based on rc

else

    rc = second_check(arg2, arg3);
    if (rc != 0)
    
        report error based on new rc
    
    else
    
        rc = third_check(arg3, arg4);
        if (rc != 0)
        
            report error based on new rc
        
        else
        
            do what you really wanted to do
        
    

通过延长错误检查,替代方案可以在页面的 RHS 之外运行,而条件分配版本不会这样做。

错误检查也可以是“操作”——first_action()second_action()third_action()——当然,不仅仅是检查。也就是说,可以在功能管理的过程中检查它们的步骤。 (在我使用的代码中,最常见的函数是前置条件检查,或函数工作所需的内存分配,或类似的思路)。

【讨论】:

是的,我确实这样做是为了避免过度嵌套,然后在网上搜索,看看这是否是一种常见的做法。最后我决定反对它,因为我实际上只有一个 else 案例,但这似乎是将作业置于条件中的正当理由。 同事讨厌它!对我来说,至少在大多数情况下,它比一棵巨树或许多回报更易于维护。我更喜欢函数的单次返回... 一个合理的例子,伴随块使模式明显,不言自明。但是,好吧,块内(“伪”)代码看起来有点难看,而反向样式(将 what you really want to do 放在最后)并不是那么好。跨度> 【参考方案5】:

简短的回答是Expression-oriented 编程语言允许更简洁的代码。他们不会强迫你separate commands from queries。

【讨论】:

在 if()、while() 和其他类似语句中强制执行没有赋值的编码是一场持久战。 C/C++ 因其副作用而臭名昭著,这通常会变成错误,尤其是当我们添加 ++ 和 -- 运算符时。 第一个链接没用:C或C++好像不是这样的语言。【参考方案6】:

另一个好处是在使用 gdb 的过程中。 在下面的代码中,如果我们单步执行,错误代码是未知的。

while (checkstatus() != -1) 
    // process

相当

while (true) 
    int error = checkstatus();
    if (error != -1)
        // process
    else
        //fail

现在在单步中我们可以知道 checkstatus() 的返回错误代码是什么。

【讨论】:

你的意思是它可以在调试代码时对临时更改有所帮助?【参考方案7】:

如果你无意中尝试使用赋值作为真值,GCC 可以帮助你检测(使用 -Wall),以防它建议你写

if ((n = foo())) 
   ...

即使用额外的括号表示这确实是您想要的。

【讨论】:

很高兴知道。我希望你的同事以同样的方式阅读它。 我?天哪,我永远不会尝试将赋值用作真值。我指的是 GCC 的建议。 GCC 也可以编译Fortran。或许要明确说明编程语言?【参考方案8】:

例如,在 PHP 中,它对于遍历 SQL 数据库结果很有用:

while ($row = mysql_fetch_assoc($result)) 
    // Display row

这看起来比:

$row = mysql_fetch_assoc($result);
while ($row) 
    // Display row
    $row = mysql_fetch_assoc($result);

【讨论】:

这还具有 $row 没有超出该循环的简洁副作用,因此可以更快地进行垃圾收集(无论如何都执行 GC 的语言)。【参考方案9】:

循环比 if 语句更有用。

while( var = GetNext() )

  ...do something with var 

否则必须写出来

var = GetNext();
while( var )

 ...do something
 var = GetNext();

【讨论】:

我同意 - 但会写: while ((var = GetNext()) != 0) ... 没有三思而后行,部分原因是如果我不使用默认编译,GCC 会抱怨选项。 是的。假设您正在使用一种支持 for 循环声明的语言,并且您还没有在循环之外使用 var。 在某些语言中,例如 ANSI C,范围规则不允许这种方法,@KerrekSB @wirrbel:你的意思是 1989 年的 ANSI C?就像他们有蒸汽机和打孔卡的时候一样?可能是这样,但这是否相关? 该警告并不是因为在一段时间内分配有任何问题,而是因为在您真正打算进行比较时进行分配是一个常见的错误。如果您想摆脱警告,您可以执行与 @Jonathan Leffler 建议的 JS 等效的操作。就我个人而言,我可能会这样做,因为我非常不信任 JavaScript 的真实规则:) 在 C# 和 Java 等某些语言中也应该注意这是唯一的方法。【参考方案10】:

当您编写while 循环而不是if 语句时,该习语更有用。对于if 声明,您可以按照您的描述将其分解。但如果没有这个结构,你要么不得不重复自己:

c = getchar();
while (c != EOF) 
    // ...
    c = getchar();

或使用循环半结构:

while (true) 
    c = getchar();
    if (c == EOF) break;
    // ...

我通常更喜欢循环半形式。

【讨论】:

对于while 循环,最好使用:do c = getchar(); ... while (c != EOF); 可以使用for 循环代替:for (char c = getchar(); c != EOF; c= getchar()) /* do something with c */ ——这是最简洁的,for 总是对我说“循环”,风格上。小缺点是您必须指定返回 c 两次的函数。【参考方案11】:

如果你调用一个函数会更有用:

if (n = foo())

    /* foo returned a non-zero value, do something with the return value */
 else 
    /* foo returned zero, do something else */

当然,你可以把 n = foo();在单独的语句 then if (n),但我认为上面是一个相当易读的习语。

【讨论】:

我认为你应该把它括在括号中,否则 gcc 会抱怨:警告:建议在赋值周围使用括号作为真值 [-W括号] 像这样:if ((n = foo())) // 对返回值做一些事情 else // foo 返回零/NULL,做其他事情 【参考方案12】:

如果您调用的函数返回要处理的数据或指示错误(或您已完成)的标志,这将很有用。

类似:

while ((c = getchar()) != EOF) 
    // process the character


// end of file reached...

就我个人而言,这是一个我不太喜欢的成语,但有时替代方案更难看。

【讨论】:

以上是关于为啥要在linux/unix下进行c/c++编程?的主要内容,如果未能解决你的问题,请参考以下文章

unix/linux下通过c/c++获取内存大小的方法。

如何在 Linux/Unix/Mac 下清除 DNS 查询缓存

为啥要在 XSS 预防中将 & 转换为 & ?

如何查看静态库内容 Unix/Linux

eclipse 一个项目中 要建4个包,为啥建的包不是在同一目录(src)下。。而是要在Libraries下。。

为啥我们要在 C 中如此频繁地对结构进行 typedef 呢?