c
文章平均质量分 85
守望之名
这个作者很懒,什么都没留下…
展开
-
神奇,C代码竟然能当成shell脚本一样“直接”执行!
前言我们都知道,写完了的C代码是需要编译链接之后才能运行的(也许你不需要手动点击编译,但是IDE可能帮你做了这件事),那么能不能让C代码像执行shell脚本或者Python脚本一样,直接可运行呢?类似于:$./main.c就可以直接运行了。看起来虽然没啥用,但是感觉有点小刺激。小试牛刀对于文本内容,系统首先会尝试当成shell进行解释执行,这一点还不明白的朋友,建议先阅读《为什么执行命令开头需要./》。不过话又说回来,.c最终要编译成可执行文件,如果想要它直接...原创 2020-05-24 17:49:54 · 455 阅读 · 0 评论 -
C语言数组下标-1你见过吗?
不知道你有没有见过-1作为数组下标的,我算是见到了。当然这一点在Python之类的语言中毫不稀奇。下标-1的代码这里redis源码中的一部分:sdssdsMakeRoomFor(sdss,size_taddlen){void*sh,*newsh;size_tavail=sdsavail(s);size_tlen,newlen;chartype,oldtype=s[-1]&SDS_TYPE_MASK;...原创 2020-05-16 18:21:40 · 9021 阅读 · 0 评论 -
C语言为什么只需要包含stdio.h就能使用里面声明的函数?
有人问:C语言为什么只需要include<stdio.h>就能使用里面声明的函数?这是一个看起来非常简单的问题,但是很多初学者,甚至学了很久的人都可能没有搞明白。为什么包含即可用?要明白包含即可用的原因,就必须讲到C语言代码是如何变成可执行文件的了,这里可以参考《hello程序是如何变成可执行文件的》。这里使用#include指令,在预编译之后,相当于把文件里面的内容都放到.c中了。//hello.c#include<stdio.h>intmai...原创 2020-05-10 21:23:46 · 5009 阅读 · 0 评论 -
一行注释也能影响代码运行?别不信!
来源:公众号【编程珠玑】作者:守望先生ID:shouwangxiansheng没想到吧,一行注释也能影响运行结果也许你在某个段子里听说过,某行注释删掉后,程序竟然不能预期执行?真的会这样么?你还别不信。见证“奇迹” 1//来源:公众号【编程珠玑】 2//作者:守望先生 3#include<stdio.h> 4#include<math....原创 2020-04-12 08:37:49 · 8874 阅读 · 18 评论 -
几个简单但你可能忽略的C知识点
C语言main函数的写法标准中,只有下面两种写法:intmain(void){/**body**/}以及intmain(intargc,char*argv[]){/**body**/}而C++的第二种与C类似,第一种是这样的:intmain(){/**body**/}参考《C语言的main函数到底该怎么写》...原创 2020-01-04 08:53:00 · 1874 阅读 · 0 评论 -
你可能没有实现一个正确的atoi函数
前言我们都知道,atoi函数用于将一个字符串转换成整数。atoi函数看起来似乎很容易实现,你甚至可以很快写出一个版本,但是是否符合要求呢?简易版本最简单的考虑,就是遍历字符串,每遇到一个数字就加上原来的值乘以10。例如字符串“1234”转整数是这样的计算流程: 遇到字符1,得到结果1; 遇到字符2,得到结果1 * 10 + 2,即12; 遇到字符3,得到结果1...原创 2019-03-22 00:01:00 · 736 阅读 · 0 评论 -
一个奇怪的编译链接问题
前言链接是代码生成可执行文件中一个非常重要的过程。我们在使用一些库函数时,有时候需要链接库,有时候又不需要,这是为什么呢?了解一些链接的基本过程,能够帮助我们在编译时解决一些奇怪的问题。比如,下面就有一种奇怪的现象。一个奇怪的链接问题程序功能很简单,计算e的n次方。程序清单如下(代码一):#include<stdio.h>#include<math.h>int...原创 2019-03-02 09:25:14 · 448 阅读 · 0 评论 -
快速排序深度优化详解
更多详情见原文:快速排序优化详解正如它的名字所体现,快速排序是在实践中最快的已知排序算法,平均运行时间为O(NlogN),最坏的运行时间为O(N^2)。算法的基本思想很简单,然而想要写出一个高效的快速排序算法并不是那么简单。基准的选择,元素的分割等都至关重要,如果你不清楚如何优化快速排序算法,本文你不该错过。算法思想快速排序利用了分治的策略。而分治的基本基本思想是:将原问题划分为若干与原问...原创 2019-02-24 17:25:36 · 26326 阅读 · 3 评论 -
C语言经典书籍
语言方面:C Primer Plus第五版c程序设计语言C11标准文档 c标准库c和指针c陷阱和缺陷C专家编程Unix环境高级编程UNIX网络编程卷1:套接字联网APIUNIX网络编程_卷2_进程间通信 数据结构与算法:数据结构与算法分析:c语言描述算法导论算法 操作系统:现代操作系统深入理解linux内核鸟哥的...原创 2019-02-22 18:41:19 · 2012 阅读 · 0 评论 -
如何自己实现一个栈
前言栈是一种应用广泛的数据结构,例如函数的调用就需要使用栈,其实我们在介绍《快速排序优化详解》的时候也使用到了栈结构。栈最鲜明的特点就是后进先出,一碟盘子就是类似这样的结构,最晚放上去的,可以最先拿出来。本文将介绍的是如何自己实现一个栈结构。栈的操作栈的常见操作有出栈(POP),从栈中弹出一个元素;入栈(PUSH),将一个元素压入栈中,访问栈顶元素(TOP),判断栈是否为空等。栈的...原创 2019-03-18 00:01:00 · 8671 阅读 · 0 评论 -
函数参数的传值和传指针有什么区别?
来源:公众号【编程珠玑】作者:守望先生前言我们可能听过C语言中的传值和传指针,在其他语言中,也有传引用一说,那么他们到底有什么区别呢?如果你还不能准确地分辨,就该好好了解一下了。传值我们在初学C语言的时候就被老师教过,下面的方式是无法交换a和b的值的:#include<stdio.h>voidswap(inta,intb){...原创 2019-06-21 07:31:00 · 960 阅读 · 2 评论 -
记64位地址截断引发的挂死问题
来源:公众号【编程珠玑】作者:守望先生https://www.yanbinghu.com/2019/06/25/47531.html前言最近要将整个项目的代码从原先的只支持32位变成同时支持32位和64位,这个过程中遇到一个很不容易定位的挂死问题,花了不少时间才定位解决,因此分享给大家。32位和64位代码区别在分享之前,需要了解一下32位和64位程序代码有何区别,它的主要区...原创 2019-06-26 07:31:00 · 564 阅读 · 1 评论 -
“偷梁换柱”的库打桩机制
原文地址:https://www.yanbinghu.com/2019/07/28/59484.html前言假如由于调试需要,你希望原先代码中的malloc函数更换为你自己写好的malloc函数,该怎么办呢?如何对程序进行”偷梁换柱“?打桩机制LInux链接器有强大的库打桩机制,它允许你对共享库的代码进行截取,从而执行自己的代码。而为了调试,你通常可以在自己的代码中加入一些调试信息,例如...原创 2019-08-01 12:42:10 · 1896 阅读 · 3 评论 -
字节对齐不慎引发的挂死问题
前言之前程序是32位的,切到64位之后,一些隐藏的问题就暴露了。这不,一个由字节对齐导致的挂死问题就出来了。字节对齐和64位关于字节对齐,可参考《理一理字节对齐的那些事》,而之前也分享过另一个切64位之后出现的问题,有兴趣的可以查看《记64位地址截断引发的挂死问题》。本文背景本文出现的场景是,系统需要解析JSON文件,但是出现部分功能解析正常,部分挂死,并且32位程序正常,而64位程序...原创 2019-08-08 21:44:06 · 1201 阅读 · 1 评论 -
如何优雅地处理命令行参数?
原文地址: https://www.yanbinghu.com/2019/08/17/57486.html前言我们在Linux用到的命令常常支持很多参数,那么如何写一个程序,也像Linux命令一样支持很多参数呢?有什么什么优雅的处理方法?命令行参数在介绍如何处理命令行参数之前,简单介绍一下命令行参数,已经了解的朋友可以跳过此小节。我们用一段代码,打印传给程序的每一个参数//来源:公众...原创 2019-08-19 18:48:49 · 893 阅读 · 2 评论 -
const关键字到底该怎么用
前言我们都知道使用const关键字限定一个变量为只读,但它是真正意义上的只读吗?实际中又该如何使用const关键字?在解答这些问题之前,我们需要先理解const关键字的基本使用。本文说明C中的const关键字,不包括C++。基本介绍const是constant的简写,是不变的意思。但并不是说它修饰常量,而是说它限定一个变量为只读。修饰普通变量例如:constint...原创 2019-01-29 21:06:35 · 497 阅读 · 0 评论 -
面试官问你斐波那契数列的时候不要高兴得太早
前言假如面试官让你编写求斐波那契数列的代码时,是不是心中暗喜?不就是递归么,早就会了。如果真这么想,那就危险了。 递归求斐波那契数列递归,在数学与计算机科学中,是指在函数的定义中使用函数自身的方法。斐波那契数列的计算表达式很简单:F(n) = n; n = 0,1F(n) = F(n-1) + F(n-2),n >= 2;因此,我们能很快根据表达式写出递...原创 2019-01-08 19:07:41 · 1897 阅读 · 4 评论 -
使用curl_easy_setopt造成阻塞
使用curl_easy_perfotm造成阻塞,主要有以下几种情况1.设置选项该选项的含义为:整个下载必须在60s内完成,否则,操作会超时。但是超时之后,仅仅是下载或者上传停止,线程并不会结束而是会阻塞于此。2.设置选项该选项含义为,下载速度不能低于50000字节/秒,如果低于该值,会停止下载,并试图断开连接。但是,同样的,线程将会阻塞于此3.下原创 2017-10-05 10:02:01 · 2187 阅读 · 0 评论 -
父进程异常退出时,确保子进程退出
前言父进程异常退出时,如果子进程未退出,或者对于父进程的退出不知情,将会导致子进程变成孤儿进程,更严重的情况是,如果父进程需要使用端口,而父进程异常退出,父进程再次启动时,会发现其子进程占用其端口。原因是,子进程继承了原来父进程的端口。因此必须保证,父进程异常退出是,子进程也能够退出。如下面的程序,对系统的system函数进行了改写。 bakRun.sh#!/bin/bashdeclare -i原创 2017-09-10 11:56:02 · 8923 阅读 · 2 评论 -
系统调用和库函数的区别
原文地址系统调用和库函数的区别前言从用户的角度来看,系统调用和库函数似乎没有什么区别,它们都是以C函数的形式出现,并且两者都为应用程序提供服务。但从实现者角度来看,它们之间是有根本的区别。那么,它们之间到底有哪些不同呢?在说明之前,先简单了解以下系统调用和库函数。系统调用系统调用指运行在用户空间的程序向操作系统内核请求需要更高权限运行的服务。它通过软中断向内核态发出一个明确的请求。...原创 2018-05-27 22:15:57 · 7731 阅读 · 2 评论 -
inux下使用gtest框架进行c/c++测试(二)-gmock环境搭建
原文地址:linux下使用gtest框架进行c/c++测试(二)-gmock环境搭建前言google mock(以下简称gmock)也是google的开源项目,可在测试时进行“狸猫换太子” ,配合了gtest使用,测试效果可更佳。准备gtest框架在github网站下载gtest框架https://github.com/google/googletest解压后,进入googltetest目录。目录...原创 2018-06-02 13:30:44 · 2141 阅读 · 0 评论 -
变长参数探究
前言变长参数,指的是函数参数数量可变,或者说函数接受参数的数量可以不固定。实际上,我们最开始学C语言的时候,就用到了这样的函数:printf,它接受任意数量的参数,向终端格式化输出字符串。本文就来探究一下,变长参数函数的实现机制是怎样的,以及我们自己如何实现一个变长参数函数。在此之前,我们先来了解一下参数入栈顺序是怎样的。函数参数入栈顺序我们可能知道,参数入栈顺序是从右至左,是不...原创 2018-09-22 15:06:37 · 445 阅读 · 0 评论 -
c语言的main函数到底怎么写的
前言main函数是程序启动后执行的第一个函数。从开始学习C语言到现在,我们似乎看到了很多个版本的main函数,那么哪一种才是正确的呢?我们先来看看目前有哪些版本。main函数版本第一种,没有返回值,没有入参:main()在C89标准中,这种写法是可以接受的,但使用现在的编译器编译时,会报告警,并且会将其返回值默认为int。实际上,如果函数没有显式声明返回类型,那么编译...原创 2018-10-13 09:05:52 · 1228 阅读 · 0 评论 -
C语言入坑指南-整型的隐式转换与溢出
前言我们知道整型有无符号数和有符号数之分。如果我们对无符号数和有符号数处理不当,就可能造成难以预测的结果,尤其是在作为循环条件的时候,可能导致死循环。整型之间的运算还可能导致出现另外一个问题-溢出。本文将分别介绍它们。隐式类型转换我们看一下下面的程序:#include <stdio.h>#include <string.h>int main(void)...原创 2018-11-10 18:26:49 · 752 阅读 · 0 评论 -
C语言入坑指南-缓冲区溢出
前言缓冲区溢出通常指的是向缓冲区写入了超过缓冲区所能保存的最大数据量的数据。如果说之前所提到的一些问题可能只是影响部分功能的实现,那么缓冲区溢出将可能会造成程序运行终止,被不安全代码攻击等严重问题,因此我们不得不特别重视。一个缓冲区溢出的例子对于下面的程序:#include <stdio.h>#include <string.h>int main(vo...原创 2018-11-08 21:03:02 · 8108 阅读 · 4 评论 -
C语言入坑指南-被遗忘的初始化
前言什么是初始化?为什么要初始化?静态变量和局部变量的初始化又有什么区别?实际应用中应该怎么做?本文将一一回答这些问题。什么是初始化初始化指的是对数据对象或者变量赋予初始值。例如:int value = 8; //声明整型变量并初始化为8int arr[] = {1,2,3}; //声明整型数组arr,并初始化其值为1,2,3为什么要初始化我们来看一个示例程序。te...原创 2018-11-14 20:26:22 · 567 阅读 · 0 评论 -
如何对1千万个整数进行快速排序
公众号【编程珠玑】:专注但不限于分享计算机编程基础,Linux,C语言,C++,Python,数据库等编程相关[原创]技术文章,号内包含大量经典电子书和视频学习资源。欢迎一起交流学习,一起修炼计算机“内功”,知其然,更知其所以然。前言输入:一个最多包含n个正整数的文件,每个数都小于n,其中n=10^7。如果在输入文件中有任何正数重复出现就是致命错误。没有其他数据与该正数相关联。输出...原创 2018-12-12 18:32:57 · 2495 阅读 · 2 评论 -
你可能不知道的printf
前言printf可能是我们在学习C语言的过程中最早接触的库函数了。其基本使用想必我们都已经非常清楚了。但是下面的这些情况你是否已经清楚地知道了呢?示例程序我们来看一个示例程序,看看你能否对下面的结果输出有非常清晰的认识。#include <stdio.h>int main(void){ int a = 4; int b = 3; int c...原创 2018-12-03 19:02:52 · 443 阅读 · 0 评论 -
你一定遇到过的C语言内存问题
前言C语言强大的原因之一在于几乎能掌控所有的细节,包括对内存的处理,什么时候使用内存,使用了多少内存,什么时候该释放内存,这都在程序员的掌控之中。而不像Java中,程序员是不需要花太多精力去处理垃圾回收的事情,因为有JVM在背后做着这一切。但是同样地,能力越大,责任越大。不恰当地操作内存,经常会引起难以定位的灾难性问题。今天我们就来看看有哪些常见的内存问题。初始化堆栈中的数据对申请...原创 2018-12-19 21:38:59 · 750 阅读 · 1 评论 -
如何从40亿整数中找到不存在的一个
原文地址:从40亿个整数中找到不存在的一个前言给定一个最多包含40亿个随机排列的32位的顺序整数的顺序文件,找出一个不在文件中的32位整数。(在文件中至少确实一个这样的数-为什么?)。在具有足够内存的情况下,如何解决该问题?如果有几个外部的“临时”文件可用,但是仅有几百字节的内存,又该如何解决该问题? 分析这仍然是《编程珠玑》中的一个问题。前面我们曾经提到过《位图法》,我...原创 2018-12-26 20:34:52 · 1328 阅读 · 0 评论 -
高级指针话题-函数指针
前言函数指针是什么?如何使用函数指针?函数指针到底有什么大用?本文将一一介绍。如何理解函数指针如果有int *类型变量,它存储的是int类型变量的地址;那么对于函数指针来说,它存储的就是函数的地址。函数也是有地址的,函数实际上由载入内存的一些指令组成,而指向函数的指针存储了函数指令的起始地址。如此看来,函数指针并没有什么特别的。我们可以查看程序中函数的地址:#incl...原创 2019-01-04 20:39:06 · 354 阅读 · 0 评论 -
leetcode题目解析
前言本文为leetcode上的题目简单分析,仅作记录,欢迎提出建议,共同学习交流。题目的源代码和测试用例可以在leetcodeWithC下载001 Two Sum题目:Given an array of integers, return indices of the two numbers such that they add up to a specific target.You may ass原创 2017-08-05 18:44:06 · 861 阅读 · 0 评论