从sublime 执行composer打开的powershell不能调用composer

4619人阅读
php网站(48)
详细设置 && 20+插件
本文章会在本人有插件或者设置更新时,进行不定时更新
更新:NO. 21 侧边栏同步编辑窗口底色插件。
更新:代码片段:better-completions;主题:Material,Seti_UI;代码格式化:HTML-CSS-JS
Prettify;vue语法高亮:Vue Syntax Highlight;Terminal与MarkdownEditing个性化定制
为什么要选择Sublime Text3?
Sublime Text3 自动保存,打开图片跨平台启动快!!!!多行游标,太好用。插件,简直选不过来。代码片段VIM兼容模式
菜单栏基础功能介绍
File:文档相关,新建文件,打开文件或文件夹等。Edit:文件编辑相关,复制,剪切等(CVS大法好)。除此之外还有一些强大的功能。Selection:选择相关,帮助选择代码。Find:查找替换相关。这个和其它编辑器区别好像不大。
Ctrl+F查找、Ctrl+H替换等。
View:对Sublime_Text编辑器本身的一些配置。
SideBar:开启侧边栏Ctrl+k,bShow console:打开控制台窗口,安装package control需要使用.
Goto:快捷导航:下面介绍。Goto Anythingtools:工具,一些命令。
new Snippet:自定义代码片段,保存到user下
Project: 项目相关,用的少。Preferences:对于sublime_text进行一些个性化定值。Help:如同名字。注册在这里
line相关:
Ctrl+Shift+D:复制当前行Ctrl+Shift+K:删除当前行Ctrl+j&合并一行Ctrl+Enter:在当前行下添加新行。AfterCtrl+Shift+Enter:在当前行上添加新行。BeforeCtrl+Shift+上、下:移动当前行
Comment注释:
Ctrl+/:行注释。Ctrl+Shift+/:块注释
Ctrl+Shift+P:调用命令面板,快速查找,例如:改变语法模式等。
模糊匹配,可以减少对快捷键的记忆。
Shift+Alt+1,2,3,4,5:开启对应数字的多栏编辑
Ctrl+P:Goto Anything
Ctrl+P: 查找项目中的文件:
直接输入名称:在不同文件中切换,支持级联的目录模式::+ 行号:Ctrl+G&定位到具体的行。@:+ 符号:Ctrl+R定位到具体的符号,例如:JS函数名,CSS选择器名。#:+ 关键字:Ctrl+;匹配到具体的匹配的关键字。主要是模糊匹配。
Ctrl+D:选中当前光标所在位置的单词。连续使用时,进行多光标选择,选中下一个同名单词。Ctrl+K:配合Ctrl+D可以跳过下一个同名单词。Ctrl+L:选择当前光标所在位置的行。连续使用时,继续选中下一行。Ctrl+Shift+L:在多行选中后,在所有选中的行后产生游标。Alt+F3:选中文档中所有的同名单词。Shift+鼠标右键:向下拖动,产生多个光标。
使用&View–&Show
console,快捷键: Ctrl+` 调出console面板输入sublime.log_commands(True),可以得到当前使用的命令面板进行设置的值。方便进行快捷键的绑定。
下面这些都可以通过命令面板快捷查找
Settings-User:个人对于sublime_text的定制。使用JSON格式,会直接覆盖掉Settings-Default默认设置中的内容。
&color_scheme&: &Packages/Material Theme/schemes/Material-Theme-Darker.tmTheme&,
&theme&: &Material-Theme-Darker.sublime-theme&,
&draw_minimap_border&: true,
&font_face&: &Monaco&,
&font_size&: 10,
&highlight_line&: true,
&save_on_focus_lost&: true,
&theme&: &Spacegray Eighties.sublime-theme&,
&word_separators&: &./\\()\&':,.;&&~!@#$%^&*|+=[]{}`~?&,
&word_wrap&: true,
&trim_trailing_white_space_on_save&: true,
&ensure_newline_at_eof_on_save&: true,
&disable_tab_abbreviations&: true,
&translate_tabs_to_spaces&: true,
&tab_size&: 4,
&fade_fold_buttons&: false,
&bold_folder_labels&: true,
&auto_find_in_selection&: true
key - Bindings-User:个人对于快捷键的设置。同样会覆盖默认的设置。例如:
&keys&: [&shift+tab&], &command&: &reindent&,&args&:{&single_line&:false}
构建系统实现快捷调用浏览器
构建系统可以让您通过外部程序来运行文件,并可以在Sublime Text查看输出。
tools:工具下的Build
System选择新建一个选项后(Build System–&New
Build System),进行如下设置(注意后缀),保存到user目录下:
&cmd& :[&C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe&,&$file&],
&selector&:[&text.html&]
之后再进入刚刚的的地方,选择第一个Automatic,修改内容后按Ctrl+B,可以看到自动调用chrome并且是修改后的内容。在sublime
Text的console中可以看到输出的信息。更多功能请查看
上面是一些基础功能的介绍
插件的安装与使用
安装package control。
这里我使用的是sublimeText 3,2 的话上官网查询代码。
首先打开package control的。
复制下面这一段代码:
import urllib.request,os, h = 'e5ee549c' + '8bc59f460fa163dafc88'; pf = 'Package Control.sublime-package'; ipp = sublime.installed_packages_path(); urllib.request.install_opener( urllib.request.build_opener( urllib.request.ProxyHandler()) ); by = urllib.request.urlopen( 'http://packagecontrol.io/' + pf.replace(' ', '%20')).read(); dh = hashlib.sha256(by).hexdigest(); print('Error validating download (got %s instead of %s), please try manual install' % (dh, h)) if dh != h else open(os.path.join( ipp, pf), 'wb' ).write(by)
在上面说的View–&Show
console,快捷键: Ctrl+` 打开控制台窗口,粘贴上面的代码,回车,然后就是等待安装了,需要一定的时间。安装完成后重启 。
使用Ctrl+Shift+P,打开控制面板,输入PC,效果如下:说明安装成功了。
按照上面的步骤,打开图片中的安装插件就行了,其实默认配色真的挺好看的推荐在安装前,先去。的样式,以及设置方法,说明文档。一般安装成功后,会自动弹出。以Theme - Spacegray为例:
先使用Ctrl+Shift+P&输入PCI,回车选择&Install
Package&。需要等待一会加载时间,输入Theme-Spacegray。其实不输入完也会模糊匹配出来的。
回车等待安装就好,成功后会弹出一个使用设置的页面,把其中的如下代码拷贝到Settings-User,保存,你会发现,默认的主题已经变成了刚刚我们查看过的主题了。
&color_scheme&: &Packages/Theme - Spacegray/base16-eighties.dark.tmTheme&,
&theme&: &Spacegray Eighties.sublime-theme&
当然,你也可以通过菜单栏,进行主题的选择。会有相同的效果。它会自动在Settings-User进行设置。
安利两款主题:
两款主题都有侧边栏图标显示:我在这里说不清到底谁好谁差,全凭个人的喜好吧!
Material:
安装方法还是和上面一样,最好是根据它的README描述来进行设置。
个人常用插件及使用方法:
NO.1&AdvancedNewFile:快速新建文件。
假设有文件夹file。我们正在输入代码,又想在新的子目录下新建html文件的话用传统方式得很多步,新建目录,新建文件,保存等等等。但是有了该插件之后,事情就变得简单了许多,只需要按下Ctrl+Shift+N,输入文件夹以及文件名,你就会看到如下效果:(回车,你会发现已经子目录下的文件已经新建完成了!)
NO.2&Nettuts+ Fetch:管理类库。
安装成功后输入Ctrl+Shift+P打开命令面板,输入Fetch,可以看到以下:
选择file可以看到设置的文件。选择下载
配合刚刚上面的插件使用,简直完美..
必装插件,无比强大,就不过多介绍了。可以在浏览器中打开,还可以配置不同文件的打开方式。
单单下面这一个功能就必须安装了!快捷在不同浏览器打开:
配置设置:
&keys&: [&f1&],
&command&: &side_bar_files_open_with&,
&paths&: [],
&application&: &C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe&,
&extensions&: &.*&
&keys&: [&f2&],
&command&: &side_bar_files_open_with&,
&paths&: [],
&application&: &D:\\浏览器\\火狐\\firefox.exe&,
&extensions&: &.*&
&keys&: [&f3&],
&command&: &side_bar_files_open_with&,
&paths&: [],
&application&: &C:\\Program Files\\Internet Explorer\\iexplore.exe&,
&extensions&: &.*&
可选SyncedSideBar:每次打开文件,侧边栏都会同步显示该文件所在目录树中的位置
NO.4&DocBlockr:代码块注释。
可以快速的对函数进行注释。保持代码规范。支持多种语言。(个人觉得brackets的这个插件比Sublime
Text做得好多了。)
/*:回车创建一个代码块注释/**:回车在自动查找函数中的形参等等。
它会生成&JSDoc&格式的注释。如果你从没有使用过类似的工具,DocBlockr&会让你觉得以前没有它是如何写代码的。帮助你创造你的代码注释,通过解析功能,参数,变量,并且自动添加基本项目。
NO.5&SublimeLinter-jshint:语法校验
需先安装SublimeLinter。需先安装Node.JS及npm。在cmd输入&npm install -g jshint,等待安装成功就好了。
安装成功后,重启就可以测试代码的风格了。
当然还可以自定义校验规则,在该目录下使用Ctrl+Shift+N创建文件.jshintrc,在其中使用JSON格式配置校验风格。
&eqeqeq&:true
并且在左下角会有错误提示。需要注意的是内容有更改时,才会立即生效。
详细自定义规则:
NO.6&Git&:版本控制
可视化的操作:帮助你与你的Git repo协议进行交互。它支持很多命令像init,push,&pull,&branch,&stash,等等。了解更多关于你在Sublime
Text里面究竟能使用哪些Git功能,以提高您的工作流程。
GitGutter:
Sublime Text 有了 Git 插件之后,GitGutter 更好的帮助开发者查看文件之前的改动和差异,提升开发效率。(其实我是冲着这个来的)
NO.7&Emmet:不解释。
中文文档:
NO.8&JsFormat:代码格式化&使用&HTML-CSS-JS Prettify,下面介绍:
JsFormat 基于&JS Beautifier,可以帮助你自动格式化JavaScript和
JSON。这对于阅读代码是非常有用的。快捷键:Ctrl + Alt + f&或者,你也可以使用菜单栏。可定制喜欢的格式:在 SublimeText 3 中 Preferences -& Package Settings -& JsFormat -& Settings - Default 可以调整这些配置。
NO.10&jQuery:jQuery的API代码片段
我知道目前在很多地方&jQuery看似已经落伍了,但是如果你不是建立一个交互性很强的网站或者你只是想在已有应用上添加功能,它仍然是非常有用的。
比如,输入$.a就可以让我选择$.ajax(),然后自动扩展成以下代码:
url: '/path/to/file',
type: 'default GET (Other values: POST)',
dataType: 'default: Intelligent Guess (Other values: xml, json, script, or html)',
data: {param1: 'value1'},
.done(function() {
console.log(&success&);
.fail(function() {
console.log(&error&);
.always(function() {
console.log(&complete&);
NO.11&BracketHighlighter:符号高亮
该插件提供行数列高亮的各种配对的语法符号,显示在行号上。效果如下:
配置方法参考
NO.12&JavaScript Next:完美支持ECMAScript 6
JavaScript Next 提供了比默认JavaScript Package更好的语法高亮,而且他完美支持ECMAScript 6。建议完全使用&JavaScript Next代替JavaScript Package。
NO.13&CSS3:CSS3语法高亮
默认安装的Sublime Text对CSS3的支持让人抓狂,帧动画?别开玩笑了你只会看到一片白色的纯文本一样的代码。事实上不光CSS3,我建议用CSS3 Package完全替代原来的CSS Package来完成语法高亮。把原来的禁用了吧
NO.14&Color Highlighter&:CSS颜色高亮
这个插件我等了很久了(在使用breakets的时候发现 的,好用到爆),我最早用Sublime Text写CSS时候就在想“这堆颜色码谁知道是什么颜色”。。还是brackets的牛逼Color Highlighter这个插件会检测CSS文件中的颜色码,不论是Hex码或者RGB码都能很好的显示。Color Highlighter能够设置成用背景色或者边框提示颜色,我一般在Settings里做这样的设置:
&ha_style&: &filled&,
&icons&: false
效果如下:
NO.15Colorpicker:使用一个取色器改变颜色
使用方法:&ctrl + shift + c,快捷键有冲突,需修改。可以通过ctrl+shift+p:搜索Colorpicker调用
NO.16&Markdown Editing&和&Markdown
Preview,实现预览MD
当在 Sublime Text 中编写 markdown 文件时,在浏览器中打开全是乱码,因为还没有将 markdown 文件解析成相应的 HTML.这两个插件的功能就是可以用浏览器浏览 Sublime Text 中编写的 markdown文件。配置:
打开 Preferences-&Package Settings-&Markdown Preview-&Setting User 将下面这句话粘贴进去。
&browser& : &C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe&
&keys&: [&f6&], &command&: &markdown_preview&, &args&: {&target&: &browser&, &parser&:&markdown&}
直接按F6就可以打开浏览器预览markdown,并且它们的安装还会让编写markdown时支持一些快捷键。
不进行这些配置的话,因为我们在前面&构建系统&使用了一些操作,按ctrl+b,就会在当前文件目录下,创建一个同名的html文件。
选中该htnl文件,再次按ctrl+b可以达到同样的预览效果,不过还是F6简单不是吗?
我知道你们都忍不了那默认的白色背景,丑爆了好吗? 现在我们找到
preference–&package
Settings–&MarkdownEditing–&Markdown
GFM Settings-users,把下面这个复制进去:
&color_scheme&: &Packages/Material Theme/schemes/Material-Theme-Darker.tmTheme&,
然后你就会发现世界又回到了春天-。-(这里使用的我上面介绍的Material),更多的设置就举一反三啦!
NO.17AutoFileName:文件路径自动提示
这个直接安装就可以用了,挺方便的。
NO.18&Terminal:在Sublime Text直接打开命令行
默认快捷键&Ctrl+Shift+T。
在windows下默认会打开Windows
PowerShell,那界面简直丑到不行好吗!!
根据上面的经验同样找到preference–&package
Settings–&Terminal–&Terminal
Settings-users:进行下面的设置:
&terminal&: &C:\\WINDOWS\\system32\\cmd.exe&,
&parameters&: [&/START&, &%CWD%&]
然后人生就焕发了第二春 -。-(强烈建议大家去搜索使用被我注释掉的Cmder,这才是一个shell的样子嘛!)
NO.19&CSScomb&: CSS属性排序
NO.20&JavaScript Completions和JavaScript
& NodeJS Snippets。输入提示,代码补全
看个人喜好咯,不用代码补全,可以锻炼英语!!
有人反映说安装主题后侧边栏颜色不更改,其实有两个方法,一个在\Data\Packages\主题修改主题配置。
比较麻烦,就不说了,直接安装这个插件就好了,记得重启刷新。
NO.22&HTML-CSS-JS Prettify: HTML-CSS-JavaScript 代码格式化
其实有了这个代码格式化插件,就可以删除上面的代码格式化插件了。因为功能确实强大!
其实我把官网的配置趴下来之后就改了两个地方:
&selector_separator_newline&: false: 不需要每个CSS选择器单独占一行&allowed_file_extensions&: [&..这是老的,新增在--&&,&vue&],:将vue的组件当成html来进行格式化默认快捷键:Ctrl+Shift+H
更多的个性化定制大家自己去实现吧!
NO.23&better-completions: 涵盖了html,&jquery,javascript,Bootstrap的代码片段。
官网介绍的很详细。
这个插件要是包含的类型多,当然在每一种语言上的匹配肯定是不如上面介绍。不过为了少按几个插件,还是用了它,把上面的几个代码片段插件删了。
不过它也是支持加载自定义代码片段的,如果有需要的话,那就自己编写吧^_^。
& & & & & & & & ImagePaste&
liveReload:浏览器即时刷新!(这里有很多坑,以后填吧)IMESupport&:输入法不跟随时安装FileHeader&:自动更新保存时间,文件模板QuoteHTML&:把HTML拼接成js插入字符串CSS Format&:CSS格式化AutoPrefixer&:浏览器私有属性前缀补全 (Node.js依赖)ConvertToUTF8:GBK编码兼容Vue Syntax Highlight:vue文件的语法高亮
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:132917次
积分:2845
积分:2845
排名:第13900名
原创:147篇
转载:193篇
评论:25条
(11)(4)(1)(11)(6)(34)(22)(1)(8)(11)(51)(21)(13)(5)(31)(21)(91)(1)
(window.slotbydup = window.slotbydup || []).push({
id: '4740887',
container: s,
size: '250,250',
display: 'inlay-fix'Sublime Terminal插件Win7下更改Powershell为CMD – 君无
Sublime Terminal插件Win7下更改Powershell为CMD
为何要切换Powershell为CMD,因为Powershell启动速度有点延迟(难道因为我的机器太烂),我承认Powershell更强大,支持linux命令语法,但用不着。
找到Terminal插件安装位置,win7下为C:UsersAdministratorAppDataRoamingSublime Text 2Packagessublime_terminal,因为网络原因我是直接下载的源码解压到这里的,所以正常的文件夹名称大概是”Sublime Terminal”,修改”Terminal.py”文件:
if os.name == 'nt':
# if os.path.exists(os.environ['SYSTEMROOT'] +
'\System32\WindowsPowerShell\v1.0\powershell.exe'):
# This mimics the default powershell colors since calling
# subprocess.POpen() ends up acting like launching powershell
# from cmd.exe. Normally the size and color are inherited
# from cmd.exe, but this creates a custom mapping, and then
# the LaunchPowerShell.bat file adjusts some other settings.
key_string = 'Console\%SystemRoot%_system32_' +
'WindowsPowerShell_v1.0_powershell.exe'
key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER,
key_string)
except (WindowsError):
key = _winreg.CreateKey(_winreg.HKEY_CURRENT_USER,
key_string)
_winreg.SetValueEx(key, 'ColorTable05', 0,
_winreg.REG_DWORD, 5645313)
_winreg.SetValueEx(key, 'ColorTable06', 0,
_winreg.REG_DWORD, )
default = os.path.join(package_dir, 'PS.bat')
sublime_terminal_path = os.path.join(sublime.packages_path(), installed_dir)
# This should turn the path into an 8.3-style path, getting around unicode
# issues and spaces
buf = create_unicode_buffer(512)
if windll.kernel32.GetShortPathNameW(sublime_terminal_path, buf, len(buf)):
sublime_terminal_path = buf.value
os.putenv('sublime_terminal_path', sublime_terminal_path.replace(' ', '` '))
default = os.environ['SYSTEMROOT'] + '\System32\cmd.exe'
elif sys.platform == 'darwin':
即直接将Powershell判断注释掉,只要是Windows,就直接将Terminal路径设置为cmd路径。几年前我公司开发的一个产品。用户反馈说360会报错,有病毒。&br&我们都很纳闷,看了代码没有发现有越界的地方。为此我们还换了几款杀毒软件,都没有报毒。&br&叫用户卸载360吧,也不现实,你可以说服1个,10个用户,甚至500个用户,但是个用户呢。&br&最后没办法咨询了360,360很&b&淡定&/b&的给了我们一个“解决方案”,把我们发布的程序提交给他们“审核”,发现没问题后就会加入白名单,为此要提供一笔“审核费用”。&br&得到这个方案后我们肯定是很不情愿的,但是没办法只能妥协,真是比吃瘪还难受。&br&&br&戏剧的还在后面。。。。&br&—————————————————————————————————————&br&我们领导决定得把这笔费用赚回来,于是很没节操的在程序里添加了一个广告位。呵呵哒。
几年前我公司开发的一个产品。用户反馈说360会报错,有病毒。 我们都很纳闷,看了代码没有发现有越界的地方。为此我们还换了几款杀毒软件,都没有报毒。 叫用户卸载360吧,也不现实,你可以说服1个,10个用户,甚至500个用户,但是个用户呢。 最后…
我就是零基础学习swift语言,之前是写javascript,学了有3-4天了吧,说下我的感受,和这个东西与前端开发的关系。&br&&br&开始之前,写下这个答案我的主要观点: &b&可以跳过oc直接学习swift,一点问题没有的,只不过后期我觉得还是要学下oc,因为毕竟很多时候你用的都是oc写好的类,遇到bug了一点不会,太捉急了吧,还有不少教程都是以oc为例子的,看着也捉急&/b&~&br&&br&看我下我拿swift写的demo……毫无违和感好么。。~&br&&br&&div class=&highlight&&&pre&&code class=&language-text&&/bmiddle/62bfb217jw1ehg4havla3g208w0gctki.gif
/bmiddle/62bfb217jw1ehh5muu356g208y0dwqda.gif
/bmiddle/62bfb217jw1ehhatl90zfg208s0dynpe.gif 【代码地址下图】
/bmiddle/62bfb217jw1ehhatvusprj20or0kz78o.jpg
知乎的图片不支持gif啊- - 只有贴地址了
&/code&&/pre&&/div&&br&&br&首先看swift的基础语法,了解了最基本的控制,变量,数据体,类与结构体,继承之后,开始可以写一些简单的命令行工具,说白了就是终端工具,打印log之类的没一点问题。&br&&br&可惜,我们学习这个东西不是为了开发command line程序的,我用shell或者nodejs也挺好比这个上手还快。&br&&br&所以紧接着第二天开始直接跳过command line程序编写ios app,也就是iphone程序。&br&&br&然后我就觉得我他妈的掉进了一个深坑。&br&&br&搜了一下 现成得swift教程做app的中文几乎没有,国外有几篇讲的是开发一个todolist的教程,写的和官方的那个oc的todolist教程差不多,但是从我开始做到最后结束跑到模拟器里,我他妈也没写上超过20行得swift。。。基本都是IB实现的界面,事件,换场以及控件的创建。&br&&br&我琢磨那他妈的我用oc也是一样的,算了,ios开发莫非就只是拖拖控件?了解一下mvc的概念就ok?&br&&br&于是我去github上开始搜索开源的swift项目,比如2048,还有那个flappy,还有一个天气app的软件。&br&&br&看了几行源码我就特么的放弃了。倒不是看不懂,我发现都是基于cocoa的,什么cocoa呢?我又去搜了一下,说了我是ios开发小白一点经验没有,然后我发现又是他妈的一个深坑啊。。cocoa的api都是oc编写的啊,swift是可以直接调用没的问题,可是cocoa的功能实在太多了啊。。&br&&br&最他妈主要的是cocoa的帮助手册例子代码,api都他妈的是oc的api啊……我完全不会oc,我说了我是零基础,然后我在思考,我是否需要去学习下oc回来才能看懂那些api到底是怎么调用?那么多开源包都是些什么东西?&br&&br&卧槽,那我学会了oc,我还学swift干啥呢?&br&&br&不是说不用学oc了么……我特么的学swift就是为了不想了解oc啊。结果呢。&br&&br&你不会oc也就是写写command line程序啊……我去你大爷的啊- -。&br&&br&还有,xcode功能如此强大,我感觉如果自己写着玩,根本啥也不用学好么,鼠标拽拽一个app就出来了啊。。&br&&br&而专家级呢?我觉得大部分得oc库,类都还都是oc的,你用swift可以调用,但是如果有bug呢?你想看内部实现呢?商业项目中这种开源坑遇到太多了,难道你就只用swift搞定么?&br&&br&不太可能,也根本不可能,大家的代码都是oc的,底层是oc的,表现层也是,那么你swift到底是干什么用的呢?&br&&br&===================================================&br&&br&这是我学习了不到一周对swift和ios开发的理解,不学oc,我开发的时候就经常会陷入【这他妈是啥,这他妈又是啥的一个一个深坑】&br&&br&好了,就说这么多,最后扣下我第一句话。&br&&br&&b&swift开发和前端开发的关系就是java和javascript关系,雷锋和雷峰塔的关系。&/b&&br&&br&PS,我发现其实文档中的实例代码是有swift的例子的,不知道是不是自动更新的,记得上周还木有。刚才发现有了,也可能之前我没仔细看~木哈哈。比如下面这段:&br&&br&&img src=&/f8d2decb88c9931390fd_b.jpg& data-rawwidth=&625& data-rawheight=&248& class=&origin_image zh-lightbox-thumb& width=&625& data-original=&/f8d2decb88c9931390fd_r.jpg&&给苹果的文档 赞一个。。但是我依然不他妈的知道那个UIControlState是特么啥,我觉得,会oc开发的同学上手一定比0基础的要快很多……!
我就是零基础学习swift语言,之前是写javascript,学了有3-4天了吧,说下我的感受,和这个东西与前端开发的关系。 开始之前,写下这个答案我的主要观点: 可以跳过oc直接学习swift,一点问题没有的,只不过后期我觉得还是要学下oc,因为毕竟很多时候你用的…
Emacs 非常强大,能实现绝大部分 IDE 的功能,还有一堆 IDE 没有的功能&br&为了更好的使用 Emacs 你可以在你的 bashrc / zshrc / 其他 shell 配置里加上这么一行:&br&alias emacs='vim'&br&(逃
Emacs 非常强大,能实现绝大部分 IDE 的功能,还有一堆 IDE 没有的功能 为了更好的使用 Emacs 你可以在你的 bashrc / zshrc / 其他 shell 配置里加上这么一行: alias emacs='vim' (逃
谢邀。题主说的是才出不久的《编译系统透视:图解编译原理》一书。&br&&br&豆瓣链接:&a href=&///?target=https%3A///subject//& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&《编译系统透视:图解编译原理》&i class=&icon-external&&&/i&&/a&&br&华章图书链接:&a href=&///?target=http%3A///Books/9103.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&华章图书 - 编译系统透视:图解编译原理&i class=&icon-external&&&/i&&/a&&br&样章:&a href=&///?target=http%3A///d_.shtml& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&编译系统透视:图解编译原理 - IT168&i class=&icon-external&&&/i&&/a&&br&配套视频:&a href=&///?target=http%3A///vplus/2f8cf44cbc8be594a25ee/foldervideos/5tk5q6& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&《编译系统透视》配套视频&i class=&icon-external&&&/i&&/a&&br&配套源码:&b&即将(也就是尚未)公开链接(注意!!!)&/b&。我看到公开链接的消息的话会更新过来。&br&&br&&b&总体印象&/b&&br&&br&看到这个问题才知道新出了这么一本书,聊有兴致地看了下目录然后读了一下样章(头3章),觉得挺不错。还没取找配套的视频来看。&br&已经托人帮忙带一本过来,等拿到实体书读过之后再看看有没有什么要更新到这个回答的。&br&&br&一句话:杨福川编辑又立功了 &_&&br&&br&这是一本以&b&GCC的源码剖析&/b&为题的&b&入门书&/b&。它以GCC的源码为线索,对C语言的非优化编译的整个编译流程,包括编译后的链接以及运行时结构都有图文并茂的讲解;&b&着重讲解了GCC的语法分析部分&/b&。&br&&br&说真的还挺震撼:敢拿产品级C语言编译器为主题来做源码剖析,写作团队还是很够魄力的。&b&本书有配套的裁剪版GCC 4.x系列的源码,并且带有配套的编译和调试环境,这点是最最吸引的地方;然而目前配套的裁剪后源码尚未公开,配套的调试环境似乎只是在作者之一的杨老师授课时给学生使用了。&/b&源码剖析类的书就应该方便读者能动手调试实际运行中的程序,这点是这本书的强项。&br&&br&本书在图解方面做得确实很不错。许多细节步骤都有配图,特别是介绍语法分析的部分讲解得很详细,方便读者形象的理解每个步骤发生的变化。不过,就如书中前言所说,这些“动态”的图解恐怕以动态图片或者视频的方式来展示效果会更好,而本书的头三章也有配套视频(链接在本回答开头)。&br&&br&它不是,注意不是,一本深入讲解编译“原理”的书。它并不深入介绍词法分析或语法分析背后的理论,而是简单带过一点理论之后以若干案例配合图解,结合GCC的具体实现来讲解C编译器的情况。&br&这意味着:这本书会贴很多带注释的GCC源码;这本书也会有很多步骤分得很细的图解——对一些读者来说这些图可能过于冗长了。不喜欢这种风格的源码剖析书的同学请不要购买这本书,毕竟不是啥便宜的书orz&br&这本书的贴代码和图解风格,请参考 &a href=&/question//answer/& class=&internal&&如何评价《编译系统透视:图解编译原理》一书? - 德玛西亚的回答&/a&&br&&br&&b&购买前请一定要读读样章感受一下这是否是合适您的阅读习惯的书。&/b&样章链接在本回答顶上。&br&&br&我原本的回答似乎引起了一些对这本书不正确的期待,请参考 &a href=&/question//answer/& class=&internal&&如何评价《编译系统透视:图解编译原理》一书? - 赵跃宇的回答&/a&&br&如果您跟引用的这个回答有相同期望的话请不要购买这本书嗯。我得想想怎么组织语言才不容易引起误解。&br&&img src=&/beb38a4d2bb3dca2c9c0daf_b.png& data-rawwidth=&1616& data-rawheight=&1154& class=&origin_image zh-lightbox-thumb& width=&1616& data-original=&/beb38a4d2bb3dca2c9c0daf_r.png&&&br&&br&=======================================================&br&&br&&b&头重脚轻&/b&&br&&br&然而…嗯当然得有然而。&br&然而这本书跟许多定位在入门级别的编译原理书一样,“头重脚轻”,说得不好听有点虎头蛇尾;词法与语法分析占的篇幅实在太多,而&b&对产品级C语言编译器中真正的重头戏——编译优化——只有寥寥几笔简单带过&/b&。有选题GCC的魄力,却没有把握GCC精华的结果,相当可惜。&br&其它定位在入门级编译原理的书籍,通常搭配的是比较简单的实现,例如本回答最后提到的LCC和cbc;对于比较简单的实现把主要篇幅放在编译器前端是很合适的,因为对应的实现中的大头也是在这里。而GCC的大头都是在优化器和后端里,相信会有不少读者是期待着了解更多跟“优化”相关的话题,而这本书偏偏没有侧重于这方面。&br&当然,定位如此,倒也就是这样了。如此安排对刚接触编译器(特别是GCC)的读者来说应该是比较友好的吧,嗯。&br&&br&GCC中C语言的编译器的工作流程大致可以分为:(这里特意把前端阶段拆分开来说)&br&&div class=&highlight&&&pre&&code class=&language-text&&输入源码
-& [ 1. 预处理 libcpp ]
-& 预处理后的源码
-& [ 2. 词法分析 c-lex.c ]
-& token流
-& [ 3. 语法分析 c-parse.c ]
-& AST(GENERIC形式)
-& [ 4. 语义分析 c-typeck.c等 ]
-& AST(GENERIC形式)
-------- -& [ 5. 平台无关中间代码生成 Gimplify ] -& IL(GIMPLE形式+CFG)
-& [ 6. 平台无关优化 ]
-& IL(GIMPLE形式+CFG)
-& [ 7. 平台相关中间代码生成 ]
中端/后端 -& [ 8. 平台相关优化 ]
-& [ 9. 目标代码生成 ]
-& 汇编 / 机器码
-& [ 10. 链接 ]
-& 可执行文件 / 共享库文件
&/code&&/pre&&/div&GCC里中端/后端都是重量级的,相比之下前端的代码“轻量”得多。&br&&br&本书绝大部分篇幅都是针对上面的2、3、4和1,有少量篇幅提到5、7、9、10,而6、8都是草草带过。当然,就算不做任何优化也算是走完了整个编译流程,但如果是这样为啥要用前端代码出名的混乱的GCC为案例来分析呢?&br&&br&同样是对产品级C编译器做源码剖析,要是这本书是用Clang为题感觉或许会更好。反正这本书也没怎么介绍GCC的优化,还不如以代码结构更加干净清晰的Clang入手,把前端部分介绍好,然后简单带过一下LLVM,把LLVM IR、FastISel、Fast寄存器分配和从MachineInstr到目标代码这个最简单的流程介绍一下,书的结构还是会跟现在的保持一致,但内容上或许更易于让读者理解。&br&&br&如果这本书能做成系列书,出个“第二册”“第三册”,图解一下GCC里的各种优化,那就更好了。把High GIMPLE -& Low GIMPLE,GIMPLE的Tree SSA形式的生成算法,Memory SSA的计算,各种平台无关优化(特别是例如循环优化、指针分析),然后MD文件与BURS,到RTL,到局部和全局图着色寄存器分配,到最终的代码生成,这么一套下来都以这本书对语法分析的详细程度来写出来,那得多赞呐 ^_^&br&&br&=======================================================&br&&br&&b&一些细节&/b&&br&&br&节选样章里的一些地方吐点槽:&br&&br&第一章,第3页:&br&&blockquote&程序执行的本质就是代码区的指令不断执行,驱使动态数据区和静态数据区产生数据变化。这一过程需要 计算机的管控。下面我们着重介绍对代码区和动态数据区的管控。CPU 中有三个寄存器,分别是 eip、ebp 和 esp,情景如图 1-6 所示。&/blockquote&这段话其实挺突兀的。我在样章中根本搜不到“x86”的字样,前言、第一章等介绍背景的地方都没有提及本书是以x86平台为例子,然而这里却突然冒出了32位x86的三个寄存器的名字。至少把背景定位清楚也好。&br&&br&-----------------------------------------&br&&br&第一章,第7页&br&&img src=&/5bcd2067fb4_b.png& data-rawwidth=&1494& data-rawheight=&1358& class=&origin_image zh-lightbox-thumb& width=&1494& data-original=&/5bcd2067fb4_r.png&&代码例子:&br&&div class=&highlight&&&pre&&code class=&language-c&&&span class=&kt&&int&/span& &span class=&nf&&fun&/span&&span class=&p&&(&/span&&span class=&kt&&int&/span& &span class=&n&&a&/span&&span class=&p&&,&/span& &span class=&kt&&int&/span& &span class=&n&&b&/span&&span class=&p&&);&/span&
&span class=&kt&&int&/span& &span class=&n&&m&/span& &span class=&o&&=&/span& &span class=&mi&&10&/span&&span class=&p&&;&/span&
&span class=&kt&&int&/span& &span class=&nf&&main&/span&&span class=&p&&()&/span& &span class=&p&&{&/span&
&span class=&kt&&int&/span& &span class=&n&&i&/span& &span class=&o&&=&/span& &span class=&mi&&4&/span&&span class=&p&&;&/span&
&span class=&kt&&int&/span& &span class=&n&&j&/span& &span class=&o&&=&/span& &span class=&mi&&5&/span&&span class=&p&&;&/span&
&span class=&n&&m&/span& &span class=&o&&=&/span& &span class=&n&&fun&/span&&span class=&p&&(&/span&&span class=&n&&i&/span&&span class=&p&&,&/span& &span class=&n&&j&/span&&span class=&p&&);&/span&
&span class=&k&&return&/span& &span class=&mi&&0&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&span class=&kt&&int&/span& &span class=&nf&&fun&/span&&span class=&p&&(&/span&&span class=&kt&&int&/span& &span class=&n&&a&/span&&span class=&p&&,&/span& &span class=&kt&&int&/span& &span class=&n&&b&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&kt&&int&/span& &span class=&n&&c&/span& &span class=&o&&=&/span& &span class=&mi&&0&/span&&span class=&p&&;&/span&
&span class=&n&&c&/span& &span class=&o&&=&/span& &span class=&n&&a&/span& &span class=&o&&+&/span& &span class=&n&&b&/span&&span class=&p&&;&/span&
&span class=&k&&return&/span& &span class=&n&&c&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&br&这里以GCC为例,在32位x86上用-O0关闭所有优化来编译范例代码,得到的汇编会是:&br&&div class=&highlight&&&pre&&code class=&language-text&&m:
%esp, %ebp
$-16, %esp
$4, 28(%esp)
$5, 24(%esp)
24(%esp), %eax
%eax, 4(%esp)
28(%esp), %eax
%eax, (%esp)
fun(int, int)
fun(int, int):
%esp, %ebp
$0, -4(%ebp)
12(%ebp), %eax
8(%ebp), %edx
(%edx,%eax), %eax
%eax, -4(%ebp)
-4(%ebp), %eax
&/code&&/pre&&/div&可以看到GCC在这种配置下在进入一个函数时是一口气把整个栈帧的空间都分配好了,例如main()里的:&br&&div class=&highlight&&&pre&&code class=&language-text&&
&/code&&/pre&&/div&然后局部变量赋值时不是逐个push到栈上,而是直接在已经分配好的栈帧里赋值到对应的slot上,例如i的赋值:&br&&div class=&highlight&&&pre&&code class=&language-text&&
$4, 28(%esp)
&/code&&/pre&&/div&&br&可以理解作者只是想以一个笼统的运行时模型来介绍程序运行的大致概念。书中的这组例子也是一种&i&可能的&/i&实现方式。但既然以GCC为例,更贴合GCC的做法来讲解是不是更好呢?&br&&br&-----------------------------------------&br&&br&目录里有这么一处看着很奇怪的地方:&br&&blockquote&&ul&&li&6.7 所有案例语法树转中间结构(RTL)的过程 754&br&&/li&&ul&&li&6.7.1 基础类型数据语法树转高端gimple的过程 754&/li&&li&6.7.2 用户自定义数据语法树转高端gimple的过程 794&/li&&li&6.7.3 指针类型数据语法树转高端gimple的过程 838&/li&&li&6.7.4 作用域和生存期案例语法树转高端gimple的过程 878&/li&&li&6.7.5 复杂表达式案例的语法树转高端gimple的过程 887&/li&&/ul&&/ul&&/blockquote&章节的大标题是说从语法树生成RTL的过程,但下面的每个小章节的标题都是从语法树到High GIMPLE的过程。&br&从High GIMPLE到RTL,中间还隔着High GIMPLE -& Low GIMPLE -& CFG -& Tree SSA (可跳过) -& RTL这样的流程。没拿到书不知道这里实际内容怎样,想拜托有读到这部分的同学告知这里实际是怎样的。&br&&br&=======================================================&br&&br&&b&其它选择&/b&&br&&br&如上文所述,要覆盖一个从预处理-&词法分析-&语法分析+语义分析-&中间代码生成-&汇编-&链接这样完整的编译流程,并不需要使用GCC这么重量级的编译器为题。&br&&br&相比之下,入门用的、介绍C或类C语言编译器的书,我还是更喜欢下面两本书:&br&&ul&&li&&a href=&///?target=https%3A///subject/1610344/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&《A Retargetable C Compiler: Design and Implementation》&i class=&icon-external&&&/i&&/a&&br&&/li&&li&&a href=&///?target=http%3A///subject/4117971/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&『ふつうのコンパイラをつくろう——言語処理系をつくりながら学ぶコンパイルと実行環境の仕組み』&i class=&icon-external&&&/i&&/a&(中文翻译版&a href=&///?target=http%3A//.cn/book/1308& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&《自制编译器》&i class=&icon-external&&&/i&&/a&正在进行中,预计年内能上市)&/li&&/ul&其中第二本书我在这里有简单介绍:&a href=&/p/& class=&internal&&学习编程语言与编译优化的一个书单&/a&&br&&br&这两本书,前者介绍的是一个完整但简单得多的C语言编译器LCC,有完整的编译流程,并且讲解了一些优化;后者介绍的是一个简单的用Java实现的简化版C的编译器cbc,介绍了完整的编译+链接流程,用Java实现十分便于修改和调试。&br&前者更贴近现实,而后者更简单易懂,两者分别适合从不同角度切入编译原理的入门学习。&br&&br&评论区有同学提到这本书:&br&&a href=&///?target=http%3A///software/compiler.design.in.c.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Compiler in C - Allen Holub&i class=&icon-external&&&/i&&/a&&br&这是本老书了,作者很慷慨的把书本的电子版以及配套代码免费发布在了个人网站上(点上面的链接可以下载)。&br&这确实也是一本讲得很详细的入门书,也是图文并茂、平易近人的风格。有兴趣挖掘历史的话这本读读也是轻松有趣。&br&跟其它入门书一样,这本也是重前端轻后端的,优化部分简单略过;目标代码生成部分为了简单而实现了一个“虚拟机”,这“目标代码”其实还是C语言,可以进一步用别的C编译器来编译到机器码(嗯您没看错)——这里简化得可能有点过了,汇编/具体机器码/链接之类的话题都是略过。
谢邀。题主说的是才出不久的《编译系统透视:图解编译原理》一书。 豆瓣链接: 华章图书链接: 样章: 配套视频: 配套源…
&p&没有过时呀。有个小伙伴一直问我考勤系统脚本的代码。我在这里分享出来。&/p&&p&写这个脚本的背景是CTO和HR商量了下,整个信息中心和业务部门分开做考勤规则。&/p&&p&我们的考勤系统只是记录打卡,但不会判断迟到、漏打卡、加班等等的规则。&/p&&p&之前也是一个程序员帮HR写的程序,此次复杂度加倍。CTO问各位研发总监有木有人要开发下。&/p&&p&无人回应。&/p&&p&做数据的我,弱弱的举了小爪,说我可以帮忙写下。&/p&&p&花了半天就写好了,还设想了各种遇到的情况。HR惊叹于我的速度,说上个程序员花了两周...我汗颜。&/p&&p&HR们,如果还在为考勤烦恼,以下可以下载下来&/p&&p&百度网盘:链接:&a href=&///?target=http%3A///s/1pLuRwoj& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&/s/1pLuRwo&/span&&span class=&invisible&&j&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a& 密码:w47g&/p&&p&以下截图,我的代码都详细写好了注释。大家可以按照注释修改&/p&&img data-rawheight=&660& src=&/v2-4b366ac449a1a77a5f23d636ce70b512_b.png& data-rawwidth=&1355& class=&origin_image zh-lightbox-thumb& width=&1355& data-original=&/v2-4b366ac449a1a77a5f23d636ce70b512_r.png&&&p&&br&&/p&&img data-rawheight=&711& src=&/v2-d5e8daefd355d90e209eb6f7ff4a9e2b_b.png& data-rawwidth=&719& class=&origin_image zh-lightbox-thumb& width=&719& data-original=&/v2-d5e8daefd355d90e209eb6f7ff4a9e2b_r.png&&&p&&br&&/p&&img data-rawheight=&732& src=&/v2-67db90bc3e95ef74b74e61b365e8c904_b.png& data-rawwidth=&723& class=&origin_image zh-lightbox-thumb& width=&723& data-original=&/v2-67db90bc3e95ef74b74e61b365e8c904_r.png&&&p&代码如下:&/p&&p&Sub Organize_Attendance()&/p&&p&On Error Resume Next&/p&&p&Application.ScreenUpdating = False&/p&&p&Dim Cus_FirstDay As Date, Cus_Lastday As Date, abcd As Date, Cus_Days, St2_Row, Arr_Pointer, Arr_Pointer2&/p&&p&Dim Sht, St1, St2, St3&/p&&p&Dim Arr(0 To 31000, 1 To 14), Date1, Date2, Date3, Record, Date4, Name&/p&&p&&br&&/p&&p&'整理表页名称,用于判断是否缺失&/p&&p&txt = &&&/p&&p&a = 0&/p&&p&b = 0&/p&&p&c = 0&/p&&p&For Each Sht In Sheets&/p&&p&
If &a href=&///?target=http%3A//sht.name/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Sht.Name&i class=&icon-external&&&/i&&/a& = &控制表格& Then a = 1&/p&&p&
If &a href=&///?target=http%3A//sht.name/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Sht.Name&i class=&icon-external&&&/i&&/a& = &出勤记录& Then b = 1&/p&&p&
If &a href=&///?target=http%3A//sht.name/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Sht.Name&i class=&icon-external&&&/i&&/a& = &输出表格& Then c = 1&/p&&p&Next&/p&&p&&br&&/p&&p&'查找是否有“控制表格”和“出勤记录”两张表&/p&&p&If a && 1 And b = 1 Then&/p&&p&
txt = &没有找到控制表格表页&&/p&&p&ElseIf a = 1 And b && 1 Then&/p&&p&
txt = &没有找到出勤记录表页&&/p&&p&ElseIf a && 1 And b && 1 Then&/p&&p&
txt = &没有找到控制表格、出勤记录表页&&/p&&p&End If&/p&&p&&br&&/p&&p&If txt && && Then&/p&&p&
MsgBox (txt)&/p&&p&
Exit Sub&/p&&p&End If&/p&&p&&br&&/p&&p&'如果有输出表格,则进行清空,如果没有新建一个&/p&&p&If c = 1 Then&/p&&p&
Sheets(&输出表格&).Cells.Delete&/p&&p&Else&/p&&p&
Sheets.Add&/p&&p&&a href=&///?target=http%3A//activesheet.name/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&ActiveSheet.Name&i class=&icon-external&&&/i&&/a& = &输出表格&&/p&&p&End If&/p&&p&&br&&/p&&p&Set St1 = Sheets(&控制表格&)&/p&&p&Set St2 = Sheets(&出勤记录&)&/p&&p&Set St3 = Sheets(&输出表格&)&/p&&p&&br&&/p&&p&'定义表头内容&/p&&p&Arr(0, 1) = &工号&&/p&&p&Arr(0, 2) = &姓名&&/p&&p&Arr(0, 3) = &单位名称&&/p&&p&Arr(0, 4) = &考勤日期&&/p&&p&Arr(0, 5) = &班次&&/p&&p&Arr(0, 6) = &上班&&/p&&p&Arr(0, 7) = &下班&&/p&&p&Arr(0, 8) = &是否跨天&&/p&&p&Arr(0, 9) = &在司时间&&/p&&p&Arr(0, 10) = &是否足够9小时&&/p&&p&Arr(0, 11) = &考勤是否合理&&/p&&p&Arr(0, 12) = &是否缺勤&&/p&&p&Arr(0, 13) = &备注&&/p&&p&&br&&/p&&p&'定义节假日、倒休等特殊日期字典&/p&&p&Set Date1 = CreateObject(&Scripting.Dictionary&)&/p&&p&Set Date2 = CreateObject(&Scripting.Dictionary&)&/p&&p&Set Date3 = CreateObject(&Scripting.Dictionary&)&/p&&p&For Each Rng In St1.Range(&H2:H& & St1.Range(&H65536&).End(xlUp).Row)&/p&&p&
Date1.Add Rng.Value, Rng.Value&/p&&p&Next&/p&&p&For Each Rng In St1.Range(&I2:I& & St1.Range(&I65536&).End(xlUp).Row)&/p&&p&
Date2.Add Rng.Value, Rng.Value&/p&&p&Next&/p&&p&For Each Rng In St1.Range(&J2:J& & St1.Range(&J65536&).End(xlUp).Row)&/p&&p&
Date3.Add Rng.Value, Rng.Value&/p&&p&Next&/p&&p&&br&&/p&&p&'记录出勤记录行数&/p&&p&St2_Row = St2.Range(&A65536&).End(xlUp).Row&/p&&p&&br&&/p&&p&'定义月份第一天,当月天数&/p&&p&'Cus_FirstDay = DateSerial(St1.[b2].Value, St1.[b3].Value, 1)&/p&&p&'Cus_Lastday = DateSerial(St1.[b2].Value, St1.[b3].Value + 1, 0)&/p&&p&&br&&/p&&p&For i = 2 To St2_Row&/p&&p&
abcd = St2.Cells(i, 4).Value&/p&&p&
If Cus_FirstDay = #12:00:00 AM# Or Cus_FirstDay & abcd Then&/p&&p&
Cus_FirstDay = abcd&/p&&p&
End If&/p&&p&
If Cus_Lastday = #12:00:00 AM# Or Cus_Lastday & abcd Then&/p&&p&
Cus_Lastday = abcd&/p&&p&
End If&/p&&p&Next&/p&&p&Cus_Days = DateDiff(&d&, Cus_FirstDay, Cus_Lastday) + 1&/p&&p&&br&&/p&&p&'定义当月班次数组&/p&&p&ReDim Date4(1 To Cus_Days, 1 To 2)&/p&&p&For i = 1 To Cus_Days&/p&&p&
a = DateAdd(&d&, i - 1, Cus_FirstDay)&/p&&p&
Date4(i, 1) = a&/p&&p&
If Date1.Exists(a) Then&/p&&p&
Date4(i, 2) = &三倍节假日&&/p&&p&
ElseIf Date2.Exists(a) Then&/p&&p&
Date4(i, 2) = &周末&&/p&&p&
ElseIf Date3.Exists(a) Then&/p&&p&
Date4(i, 2) = &工作日&&/p&&p&
ElseIf WorksheetFunction.Weekday(a, 2) = 6 Then&/p&&p&
Date4(i, 2) = &周六&&/p&&p&
ElseIf WorksheetFunction.Weekday(a, 2) = 7 Then&/p&&p&
Date4(i, 2) = &周日&&/p&&p&
Else&/p&&p&
Date4(i, 2) = &工作日&&/p&&p&
End If&/p&&p&Next&/p&&p&&br&&/p&&p&'定义员工工号字典&/p&&p&Set Name = CreateObject(&Scripting.Dictionary&)&/p&&p&&br&&/p&&p&'定义当前员工第一行指针&/p&&p&Arr_Pointer = -Cus_Days&/p&&p&&br&&/p&&p&'开始按照出勤记录每行循环处理数据,记录工号、姓名、公司、班次、日期、上下班时间、是否跨天的数据&/p&&p&For i = 2 To St2_Row&/p&&p&
'将出勤记录当前行转换为数组&/p&&p&
Record = WorksheetFunction.Transpose(WorksheetFunction.Transpose(St2.Range(&A& & i & &:E& & i).Value))&/p&&p&
'检测是否是录入过该员工&/p&&p&
If Not Name.Exists(Record(1)) Then&/p&&p&
'如果是第一次录入,增加工号字典,更改第一行指针,在数组内添加该员工一整月天数的前5列数据&/p&&p&
Name.Add Record(1), Record(1)&/p&&p&
Arr_Pointer = Arr_Pointer + Cus_Days&/p&&p&
For n = 1 To Cus_Days&/p&&p&
Arr(Arr_Pointer + n, 1) = Record(1)&/p&&p&
Arr(Arr_Pointer + n, 2) = Record(2)&/p&&p&
Arr(Arr_Pointer + n, 3) = Record(3)&/p&&p&
Arr(Arr_Pointer + n, 4) = Date4(n, 1)&/p&&p&
Arr(Arr_Pointer + n, 5) = Date4(n, 2)&/p&&p&
Next&/p&&p&
End If&/p&&p&&br&&/p&&p&
'判断时间属性,填入数组&/p&&p&
Arr_Pointer2 = Arr_Pointer + Day(St2.Cells(i, 4).Value)&/p&&p&
If St2.Cells(i, 5).Value &= TimeValue(&13:00:00&) Then '如果打卡时间超过13点&/p&&p&
If Arr(Arr_Pointer2, 7) = && Then&/p&&p&
Arr(Arr_Pointer2, 7) = St2.Cells(i, 5).Value '如果数组里还没有记录,则将单元格写入数组&/p&&p&
ElseIf Arr(Arr_Pointer2, 7) & St2.Cells(i, 5).Value Then&/p&&p&
Arr(Arr_Pointer2, 7) = St2.Cells(i, 5).Value '如果数组的记录小于单元格,则将单元格写入数组(下班打卡取较大数据)&/p&&p&
End If&/p&&p&
ElseIf St2.Cells(i, 5).Value & TimeValue(&6:00:00&) Then '如果打卡时间早于6点&/p&&p&
If Day(Record(4)) = 1 Then&/p&&p&
Arr(Arr_Pointer2, 13) = &上个月末最后一天有加班&&/p&&p&
Else&/p&&p&
Arr_Pointer2 = Arr_Pointer2 - 1 '指针时间提前一天&/p&&p&
If Arr(Arr_Pointer2, 7) = && Then&/p&&p&
Arr(Arr_Pointer2, 7) = St2.Cells(i, 5).Value '如果数组里还没有记录,则将单元格写入数组&/p&&p&
ElseIf Arr(Arr_Pointer2, 7) &= TimeValue(&13:00:00&) Then&/p&&p&
Arr(Arr_Pointer2, 7) = St2.Cells(i, 5).Value '如果数组里的记录是前一天晚上的记录,则将单元格写入数组(凌晨打卡要晚于前一天晚上)&/p&&p&
ElseIf St2.Cells(i, 5).Value & Arr(Arr_Pointer2, 7) Then&/p&&p&
Arr(Arr_Pointer2, 7) = St2.Cells(i, 5).Value '如果数组里的记录是凌晨的,并且小于单元格,则将单元格写入数组(下班打卡取较大数据)&/p&&p&
End If&/p&&p&
Arr(Arr_Pointer2, 8) = &是&&/p&&p&
End If&/p&&p&
Else '如果打卡时间介于6点到13点&/p&&p&
If Arr(Arr_Pointer2, 6) = && Then&/p&&p&
Arr(Arr_Pointer2, 6) = St2.Cells(i, 5).Value '如果数组里还没有记录,则将单元格写入数组&/p&&p&
ElseIf Arr(Arr_Pointer2, 6) & St2.Cells(i, 5).Value Then&/p&&p&
Arr(Arr_Pointer2, 6) = St2.Cells(i, 5).Value '如果数组的记录大于单元格,则将单元格写入数组(上班打卡取较小数据)&/p&&p&
End If&/p&&p&
End If&/p&&p&Next&/p&&p&&br&&/p&&p&For i = 1 To Arr_Pointer + Cus_Days&/p&&p&
'备注周末or节假日&/p&&p&'
If Arr(i, 5) = &周末& Or Arr(i, 5) = &三倍节假日& Then&/p&&p&'
If Arr(i, 6) = && And Arr(i, 7) = && Then Arr(i, 13) = Arr(i, 13) & & 周末or节假日 &&/p&&p&'
End If&/p&&p&
'如果上下班都有时间,则填充在司时间&/p&&p&
If Arr(i, 6) && && And Arr(i, 7) && && Then&/p&&p&
If Arr(i, 8) = &是& Then&/p&&p&
Arr(i, 9) = Arr(i, 7) + 1 - Arr(i, 6)&/p&&p&
Else&/p&&p&
Arr(i, 9) = Arr(i, 7) - Arr(i, 6)&/p&&p&
End If&/p&&p&
Arr(i, 9) = Application.WorksheetFunction.RoundDown(Arr(i, 9) * 24, 2)&/p&&p&
If Arr(i, 9) &= 9 Then Arr(i, 10) = &是&&/p&&p&
End If&/p&&p&
'判断是否缺上下班打卡记录&/p&&p&
If Arr(i, 5) = &工作日& Then&/p&&p&
'判断总部考勤是否合理&/p&&p&
If Arr(i, 3) = &总部& Then&/p&&p&
If Arr(i, 6) = && And Arr(i, 7) = && Then&/p&&p&
Arr(i, 12) = &缺勤&&/p&&p&
ElseIf Arr(i, 6) = && Or Arr(i, 7) = && Then&/p&&p&
Arr(i, 12) = &漏打卡&&/p&&p&
ElseIf Arr(i, 6) &= TimeValue(&08:30:00&) And (Arr(i, 7) &= TimeValue(&17:30:00&) Or Arr(i, 7) &= TimeValue(&06:00:00&)) Then&/p&&p&
Arr(i, 11) = &合理&&/p&&p&
ElseIf Arr(i, 6) &= TimeValue(&09:00:00&) And (Arr(i, 7) &= TimeValue(&18:00:00&) Or Arr(i, 7) &= TimeValue(&06:00:00&)) Then&/p&&p&
Arr(i, 11) = &合理&&/p&&p&
Else&/p&&p&
Arr(i, 11) = &迟到or早退&&/p&&p&
End If&/p&&p&
End If&/p&&p&
'判断金佰达考勤是否合理&/p&&p&
If Arr(i, 3) = &金佰达& Then&/p&&p&
'如果上下班都没打卡,前一天下班时间又不是晚于凌晨两点的,是缺勤&/p&&p&
If Arr(i, 6) = && And Arr(i, 7) = && Then&/p&&p&
If Arr(i - 1, 1) = Arr(i, 1) And Arr(i - 1, 7) &= TimeValue(&06:00:00&) And Arr(i - 1, 7) &= TimeValue(&02:00:00&) Then&/p&&p&
Arr(i, 11) = &合理&&/p&&p&
Else&/p&&p&
Arr(i, 12) = &缺勤&&/p&&p&
End If&/p&&p&
'如果上下班有一次没打卡,前一天下班时间又不是晚于凌晨两点的,是漏打一次卡&/p&&p&
ElseIf Arr(i, 6) = && Or Arr(i, 7) = && Then&/p&&p&
If Arr(i - 1, 1) = Arr(i, 1) And Arr(i - 1, 7) &= TimeValue(&06:00:00&) And Arr(i - 1, 7) &= TimeValue(&02:00:00&) Then&/p&&p&
Else&/p&&p&
Arr(i, 12) = &漏打卡&&/p&&p&
End If&/p&&p&
'打卡时间早于8点半、晚于17点半是合理的&/p&&p&
ElseIf Arr(i, 6) &= TimeValue(&08:30:00&) And Arr(i, 7) &= TimeValue(&17:30:00&) Then&/p&&p&
Arr(i, 11) = &合理&&/p&&p&
'打卡时间早于8点半、并且下班跨天是合理的&/p&&p&
ElseIf Arr(i, 6) &= TimeValue(&08:30:00&) And Arr(i, 8) = &是& Then&/p&&p&
Arr(i, 11) = &合理&&/p&&p&
'打卡时间早于9点、在司时间大于9小时是合理的&/p&&p&
ElseIf Arr(i, 6) &= TimeValue(&09:00:00&) And Arr(i, 9) &= 9 Then&/p&&p&
Arr(i, 11) = &合理&&/p&&p&
'(同一个人)头一天晚上打卡时间介于2点到6点之间的是合理的&/p&&p&
ElseIf Arr(i - 1, 1) = Arr(i, 1) And Arr(i - 1, 7) &= TimeValue(&06:00:00&) And Arr(i - 1, 7) &= TimeValue(&02:00:00&) Then&/p&&p&
Arr(i, 11) = &合理&&/p&&p&
'(同一个人)头一天晚上打卡时间介于0点到2点之间,第二天早晨早于13点,晚上晚于18点是合理的&/p&&p&
ElseIf Arr(i - 1, 1) = Arr(i, 1) And Arr(i - 1, 7) && && And Arr(i - 1, 7) & TimeValue(&02:00:00&) And _&/p&&p&
Arr(i, 6) &= TimeValue(&13:00:00&) And Arr(i, 7) &= TimeValue(&18:00:00&) Then&/p&&p&
Arr(i, 11) = &合理&&/p&&p&
'(同一个人)头一天晚上打卡时间晚于20点,第二天早晨早于9点20,晚上晚于18点是合理的&/p&&p&
ElseIf Arr(i - 1, 1) = Arr(i, 1) And Arr(i - 1, 7) &= TimeValue(&20:00:00&) And _&/p&&p&
Arr(i, 6) &= TimeValue(&09:20:00&) And Arr(i, 7) &= TimeValue(&18:00:00&) Then&/p&&p&
Arr(i, 11) = &合理&&/p&&p&
'(同一个人)头一天晚上打卡时间晚于22点,第二天早晨早于10点,晚上晚于18点是合理的&/p&&p&
ElseIf Arr(i - 1, 1) = Arr(i, 1) And Arr(i - 1, 7) &= TimeValue(&22:00:00&) And _&/p&&p&
Arr(i, 6) &= TimeValue(&10:00:00&) And Arr(i, 7) &= TimeValue(&18:00:00&) Then&/p&&p&
Arr(i, 11) = &合理&&/p&&p&
Else&/p&&p&
Arr(i, 11) = &迟到or早退&&/p&&p&
End If&/p&&p&
End If&/p&&p&
End If&/p&&p&&br&&/p&&p&Next&/p&&p&&br&&/p&&p&'设置输出表的格式&/p&&p&St3.Columns(&A:A&).NumberFormatLocal = &@&&/p&&p&St3.Columns(&D:D&).NumberFormatLocal = &[$-F800]dddd, mmmm dd, yyyy&&/p&&p&St3.Columns(&F:G&).NumberFormatLocal = &[$-F400]h:mm:ss AM/PM&&/p&&p&St3.Columns(&I:I&).Style = &Comma&&/p&&p&St3.Columns(&B:M&).ColumnWidth = 12&/p&&p&&br&&/p&&p&'结果数组输出到表格内&/p&&p&St3.Range(&A1:N& & Arr_Pointer + Cus_Days) = Arr()&/p&&p&&br&&/p&&p&'清除无打卡记录的休息日行&/p&&p&'St3.Columns(&N:N&).SpecialCells(xlCellTypeConstants, 23).EntireRow.Delete&/p&&p&&br&&/p&&p&Application.ScreenUpdating = True&/p&&p&&a href=&///?target=http%3A//st3.select/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&St3.Select&i class=&icon-external&&&/i&&/a&&/p&&p&St3.Range(&a2&).Select&/p&&p&ActiveWindow.FreezePanes = True&/p&&p&&br&&/p&&p&&br&&/p&&p&End Sub&/p&
没有过时呀。有个小伙伴一直问我考勤系统脚本的代码。我在这里分享出来。写这个脚本的背景是CTO和HR商量了下,整个信息中心和业务部门分开做考勤规则。我们的考勤系统只是记录打卡,但不会判断迟到、漏打卡、加班等等的规则。之前也是一个程序员帮HR写的程…
现在的程序员啊,还是太水。当年给一把沙子,程序员都能自己造cpu
现在的程序员啊,还是太水。当年给一把沙子,程序员都能自己造cpu
&div class=&highlight&&&pre&&code class=&language-text&&void (*a)(void)
&/code&&/pre&&/div&&p&名叫 a 的函数指针,指向「接受类型为 void,返回类型也为 void 」的函数。&/p&&div class=&highlight&&&pre&&code class=&language-text&&char *(*a)(void)
&/code&&/pre&&/div&&p&名叫 a 的函数指针,指向「接受类型为 void,返回类型为 char 指针」的函数。&/p&&div class=&highlight&&&pre&&code class=&language-text&&char (*(*a)(void))[20]
&/code&&/pre&&/div&&p&名叫 a 的函数指针,指向「接受类型为 void,返回类型为指向长度 20 的 char 数组的指针」的函数。&/p&&div class=&highlight&&&pre&&code class=&language-text&&char *(*(*a)(void))[20]
&/code&&/pre&&/div&&p&名叫 a 的函数指针,指向「接受类型为 void,返回类型为指向长度 20 的 char * 数组的指针」的函数。&/p&&p&推荐阅读:&a href=&///?target=http%3A//unixwiz.net/techtips/reading-cdecl.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Reading C type declarations&i class=&icon-external&&&/i&&/a&&/p&&p&推荐安装:&/p&&div class=&highlight&&&pre&&code class=&language-text&&$& cdecl
Type `help' or `?' for help
cdecl& explain char *(*(*a)(void))[20];
declare a as pointer to function (void) returning pointer to array 20 of pointer to char
&/code&&/pre&&/div&
void (*a)(void)名叫 a 的函数指针,指向「接受类型为 void,返回类型也为 void 」的函数。char *(*a)(void)名叫 a 的函数指针,指向「接受类型为 void,返回类型为 char 指针」的函数。char (*(*a)(void))[20]名叫 a 的函数指针,指向「接受类型为 void,…
用vim的哪来那么多优越感,我来用Visual Studio教你们一些人生的道理。所有vim能做的事情,至少是你们举的例子,Visual Studio全都能轻松做到,甚至费时都不会增加很多:&br&&blockquote&删除下两行&/blockquote&Shift+下箭头,Del,比2dd慢很多?(经评论指正按两下Ctrl+X就好)&br&&blockquote&删除下一个单词&/blockquote&Shift+Ctrl+右箭头,Del。比dw慢很多?(经评论指正按Ctrl+Del就好。抱歉平时用vim,vs不太熟。)&br&&blockquote&用ide的我已经看到你们按住退格键/delete好几秒不动了 但是vim不用&/blockquote&那是你不会用IDE&br&&blockquote&把代码的连续n行注释了&br&用ide的各位说这好办,用pycharm的按了批量注释快捷键,加了一串#;写matlab的用啥啥啥批量注释快捷键,加了一串%;写java/c-family的按了啥啥啥批量注释快捷键,加了一串//&br&请问我现在上面这堆都要写,我要装几种ide?我要背几种快捷键?&br&但是用了vim就不用,ctrl+V, I就解决了。行数再多直接替换行首&br&哪有那么多时间和空间装ide玩。。装个runtime就硬盘就够满了。。&/blockquote&VS所有语言(比如C++, C#, Python, Nodejs)只需要一个快捷键,Ctrl+K/C。比Ctrl+V/I慢很多?&br&&blockquote&所有的数字后面加上单位cm&br&我已经看到用ide的各位骂了句艹,这不是写代码啊,然后关了ide打开记事本对第一个数字后面加了cm,然后复制这个cm, 然后鼠标点第二个,粘贴,点第三个,粘贴。。。&br&但是vim不用,正则匹配替换解决&/blockquote&VS也有正则匹配&br&&blockquote&下面这堆用ide的还撑得住吗?&br&只删除奇数行/偶数行&br&每行开头添加行号&br&删除所有带数字的行&br&多剪贴板&br&命令宏&/blockquote&撑得住,VS有宏有正则匹配。&br&&br&总之,觉得vim比VS之类IDE好的,不是说你vim用得好,而只是你不会用IDE而已。不过是把Shift/Ctrl和方向键换成了hjkl,正则表达式和宏之类也完全没变,哪来那么多优越感。还有说答主不会vim的够了,我的vimrc在github上有几十个star,也是蛋疼配过自动补全的苦逼。苦逼何苦为难苦逼。
用vim的哪来那么多优越感,我来用Visual Studio教你们一些人生的道理。所有vim能做的事情,至少是你们举的例子,Visual Studio全都能轻松做到,甚至费时都不会增加很多: 删除下两行Shift+下箭头,Del,比2dd慢很多?(经评论指正按两下Ctrl+X就好) 删除下…
这问题是个好坑。肯定很多人都对LLVM与JVM的关系有各种误解,包括从业人士也会有片面理解。本来看到这个问题就想马上回答的,被&a href=&/p/& class=&internal&&小叶子&/a&搅和的根本脱不开身…ToT&br&还好现在已有的回答都在靠谱的方向上,感觉题主应该已经能充分感受到正解的方向性了。我这里就写点已有答案没写的或者表述不充分的吧。&br&&br&简单说,LLVM与JVM不是同一范畴的东西,就像苹果和梨,本来不能直接对比。&br&&br&不过在出于某种特定目的去考察的时候,两者就有一定可比性,例如说同样是要实现一门编程语言,在选择代码生成器(code generator)的解决方案时,是选择LLVM、GCC等,还是JVM、.NET等,还是自己手写,这个角度就可以对它们进行特定的比较。好比想要保健身体而吃水果,是吃苹果更有益还是吃梨更有益,两者可以做特定的比较。&br&&br&而换个角度,LLVM与JVM并不是互斥的两个技术——两者可以有机的结合在一起。我现在所在的Azul Systems公司就在做基于LLVM的JVM JIT编译器,微软也有一个组在做基于LLVM的.NET JIT/AOT编译器&a href=&///?target=https%3A///dotnet/llilc& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&LLILC&i class=&icon-external&&&/i&&/a&。好比苹果树和梨树可以嫁接,在梨树上嫁接苹果树得到梨苹果(嗯不是苹果梨)。&br&正好我们对JVM和LLVM都很熟悉,回答这个问题有更多第一手信息吧。详细请跳传送门:&a href=&/question//answer/& class=&internal&&如何看待微软LLILC,一个新的基于LLVM的CoreCLR JIT/CoreRT AOT编译器? - RednaxelaFX 的回答&/a&&br&&br&================================================&br&&br&&b&一些杂谈&/b&&br&&br&JVM是一套规范,有许多不同的实现,各自取舍差异很大。不指定到非常细致的供应商、目标平台、版本信息的话,根本无法确定说的是怎样的实现。&br&不要说多个JVM了,就算一个JVM里也可能有多个编译器,要说编译器实现细节的话可得指定清楚具体是哪个了。&br&&br&LLVM则是单一的实现,虽然可以拆开来有很多花样可玩。只要指定版本和目标平台,还有指定是公版还是带有定制,大家都知道说的是什么。&br&&br&拿JVM的Java bytecode来跟LLVM IR比的话,这还可以比,因为这都还是在表面跟编译器前端打交道的“接触面”上,定义标准而抽象。但下到下面的实现就必须指定实现来比较了。&br&目前最流行的JVM实现毫无疑问是OpenJDK / Oracle JDK里的HotSpot VM,正好我也对它最熟悉,所以下面会使用它和若干其它JVM实现来跟LLVM做一下对比。&br&&br&大家提到“JVM”的时候,大都是把它当作一个黑盒子来用,而不会把它拆开来单独使用其中的一些组件。这个黑盒子包含一篮子运行时服务,典型情况不但有负责执行代码的解释器或JIT编译器,还有GC、线程支持、元数据管理(例如类加载)等功能,外加配套的Java标准库。这些全部打包在一起构成Java运行时环境(Java Runtime Environment),作为一个整体提供给用户使用。&br&生成Java bytecode就是指望让JVM来运行它,而且通常不会指望JVM把字节码编译出来的机器码吐回给用户做后续的操作——也就是说很少有人会想拿JVM当作静态编译器的后端来用(呃虽说其实这种可能性和相关实验也是存在的…毕竟奇葩)。&br&&br&而LLVM是一个编译器套件,用法就丰富的多。&br&最常规的,用它来做静态编译器后端,没问题;&br&做动态编译器后端,也能行。&br&单独拿出LLVM的一个或多个pass来做IR到IR的转换也不在话下。&br&基于LLVM来做调试器,也没问题。&br&拿LLVM IR当跨平台汇编用也很有趣。&br&还有许许多多基于LLVM做代码分析的。&br&&br&================================================&br&&br&&b&IR层面的对比&/b&&br&&br&之前回答的一个问题正好是预备知识:&a href=&/question//answer/& class=&internal&&IR和ByteCode有什么区别? - RednaxelaFX 的回答&/a&&br&JVM的Java bytecode跟LLVM IR都可以看作编译器IR。但它们的设计目的是完全不同的,因而不适合直接比较优劣。&br&&br&Java bytecode与LLVM IR都用于表述计算的模型,但两者所处的抽象层次不同。&br&Java bytecode更高层(更抽象),是一种非常高层的IR。其字节码的语义与Java语言的语法结构有非常直接的对应关系,包含大量(类Java的)面向对象语言的高层操作,例如虚方法调用、接口方法调用等。&br&它最大的“缺点”——没有暴露任何显式的指针操作,因而用于实现一些精密操作时显得拘谨。而且它遵循Java的类型系统,(到Java 9为止)不允许在对象内嵌套对象,在需要精确指定内存布局的场景上无能为力。这些“缺点”都不是一个VM的必然,跟Java字节码相似的.NET的MSIL就有这些自由度。看这个把CoreCLR的JIT编译器单独拆出来插到CPython上的例子,体会一下MSIL字节码的表达能力:&a href=&/p/& class=&internal&&Pyjion的代码质量一例 [] - 编程语言与高级语言虚拟机杂谈(仮) - 知乎专栏&/a&&br&&br&LLVM IR更低层(更接近机器),但尚未完全暴露出具体平台相关的特征,所以可以看作一种中层IR。简单的说,C语言能表述的,在LLVM IR里也可以直接表述(没有例外),而C语言所不能表述的,在LLVM IR里多半也不能直接表述(有例外)。&br&&br&(待续…什么基于栈基于虚拟寄存器之类的表皮差异也可以讨论,还有很多别的更有趣的也可以讨论,例如说用作编程语言实现的code generator时的差异。估计题主关心的也就是这个,但这个展开说可以写太多,一时来不及码字。)&br&&br&举个小例子来说明Java bytecode与LLVM IR都无法(直接)表述的语义。&br&假如我们要写一个字节码解释器,想尽可能利用平台相关的资源,特别是想要把解释器栈跟native栈混在一起的话,就会有直接在自己的代码里显式操作栈指针寄存器的需求。在这一点上,Java bytecode的抽象层次太高自然是无法(直接)表述,而LLVM IR也不可以——这就是C语言不能表述的,LLVM IR也无法表述的一种例子。&br&我们有同事尝试过用LLVM IR来实现跨平台的高性能字节码解释器(希望实现的性能特征跟HotSpot VM的template interpreter类似),但苦于不能方便的在LLVM IR里表述“栈指针寄存器”这个概念,而我们的JVM的解释器调用约定(calling convention)又有点特别,这实验就暂时放下了。中间其实做出过几个实验版是能在x86-64上跑的,但在表述RSP的时候都用了hack(例如说利用intrinsic…),离完美还很遥远。&br&&br&再举一个小例子来说明LLVM IR能表述,而C语言无法直接表述的语义。&br&LLVM IR允许对指针指定“地址空间”(address space)。默认的address space 0代表普通内存,而非0的地址空间可以由LLVM的使用者自行指定其语义,例如说显存,又例如说GC管理的内存,等等。最重要的一点是:不同地址空间之间的指针不能混用——这也就隐含了LLVM不会混合优化不同地址空间之间的指针,这是保证LLVM不乱动指针的很重要的手段。&br&&br&================================================&br&&br&&b&JVM的JIT / AOT编译器的复杂度&/b&&br&&br&一个JVM的JIT编译器可以容忍多大的复杂度呢?举个例子,前面提到,Azul Systems正在给JVM开发基于LLVM的JIT编译器。这个编译器目前是用类似Clang -O3的pass来把Java字节码编译到机器码的——是的,我们能容忍这样的复杂度,并不是稍微复杂一点的算法就不敢用的。并且它依托于我们的JVM原本就有的profiling和code cache management等基础设施,自带PGO,最终的代码管理也不依赖MCJIT。&br&&br&即便说回到现有的JIT编译器,HotSpot VM与Zing VM的Server Compiler(C2),其中也使用了许多很重的算法。&br&它目前最慢的组件是寄存器分配器,使用改进版的Chaitin-Briggs图着色(graph coloring)算法;&br&它的指令选择用的是一种BURS(bottom-up rewrite system),这个阶段的IR形式跟LLVM的SelectionDAG其实颇相似但比后者更完整一些,是对整个编译单元的;&br&它有专门做全局调度(global scheduling),当把代码确定调度到某个基本块后,会在基本块内做拓扑排序(以及其它的基于权重的排序)来实现局部调度(local scheduling)。大的全局调度只会做一次,但其实有若干小的全局调度是混在循环优化里做的。要想多加一些调度、排序代码那也是不眨眼的,只要生成的代码质量好;&br&它会创建许多现代编译器里常见的辅助数据结构,例如dominator tree、loop nesting tree之类,并且会在某些范围内维护这些数据结构的时效性。&br&&br&而另外一个例子,IBM J9的Testarossa编译器(J9 TR),虽然它最主要的应用场景是在IBM J9 JVM里充当JIT编译器用,但同一个编译器也有用于静态编译COBOL、C/C++等(Static Testarossa,sTR)。在以最高优化层次编译Java字节码时,它能容忍的算法复杂度同样非常高。&br&&br&这些JVM之所以能容忍JIT编译器使用高复杂度的算法,主要是通过多层编译(tiered compilation)来达到启动开销与顶峰性能之间的平衡。最初代码要么用解释器执行,要么用较低优化程度的编译器或者编译器的较低优化级别来编译,然后逐步把对性能影响大的代码(“热”的代码)用更高优化级别来编译。这样就可以在初期用较低开销达到较高的性能基准,同时并行的慢慢把性能推向峰值。&br&&br&当然,即便JVM的JIT编译器可以容忍高复杂度的算法,但当其要支持的目标场景的常见情况可以用更低复杂度的算法就达到一样或相似的优化效果时,JVM实现们还是会倾向使用后者的。只是,当大家都把性能推向极限时,堆高复杂度的实现也不是啥稀奇事。&br&&br&况且,JVM并不是只能有JIT编译器。做AOT编译器也是很自然的事。这些编译器自然可以像一般C/C++编译器那样容忍更高的复杂度。这里就算不展开说。先放传送门把过去回答汇总下:&a href=&/question//answer/& class=&internal&&Java中有类似于NGen的工具(AOT编译器)吗? - RednaxelaFX 的回答&/a&
这问题是个好坑。肯定很多人都对LLVM与JVM的关系有各种误解,包括从业人士也会有片面理解。本来看到这个问题就想马上回答的,被搅和的根本脱不开身…ToT 还好现在已有的回答都在靠谱的方向上,感觉题主应该已经能充分感受到正解的方向性了。我这里就…
现在都2014年了竟然还在为这种破事儿争论不休。&br&&br&IDE本来就是从代码编辑器发展而来,整个文本编辑器加一堆插件不是IDE是什么?除了可以用来装逼之外,和IDE又有神马区别呢?&br&&br&&br&对于这种问题,其实一句话可以总结。&br&&br&对于Low逼而言,&b&什么东西都可以作为他差劲的借口&/b&。对于有追求的真正的程序员而言,&b&什么东西都不能成为自己差劲的借口&/b&,因为什么东西不好用,他们就会自己发明和改造。
现在都2014年了竟然还在为这种破事儿争论不休。 IDE本来就是从代码编辑器发展而来,整个文本编辑器加一堆插件不是IDE是什么?除了可以用来装逼之外,和IDE又有神马区别呢? 对于这种问题,其实一句话可以总结。 对于Low逼而言,什么东西都可以作为他差劲的…
Eclipse是一个用Java实现的IDE。它的上层逻辑都是用Java写的,GUI库底层用了SWT有一部分native组件。&br&在Windows上跑Eclipse的话,那个eclipse.exe其实只是一个“启动程序”(launcher),通过JNI来启动Eclipse真正的Java本体。&br&&a href=&///?target=http%3A//wiki.eclipse.org/Equinox_Launcher& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Equinox Launcher&i class=&icon-external&&&/i&&/a&&br&&br&所以,当eclipse.ini通过JNI的API找到了合适的JVM,准备进入Eclipse的Java本体的时候,JVM就启动了。而在退出Eclipse的时候,这个JVM才会退出。&br&&br&eclipse.ini 配置文件就是用来配置这个运行Eclipse用的JVM实例的。&br&&br&在Eclipse JDT里写Java程序,如果实用debug或者run功能,那么Eclipse JDT会另外启动一个JVM进程来执行指定的Java程序。项目配置里debug/run里的arguments就是用来配置这个另外的JVM进程用的。
Eclipse是一个用Java实现的IDE。它的上层逻辑都是用Java写的,GUI库底层用了SWT有一部分native组件。 在Windows上跑Eclipse的话,那个eclipse.exe其实只是一个“启动程序”(launcher),通过JNI来启动Eclipse真正的Java本体。
所以,当ec…
&b&长度为0。&/b&&br&&br&楼上各位给出的代码都十分精彩,但假如就“能过编译并生成可执行文件,并且可执行文件运行时会导致崩溃的代码”这一定义来说,最短的C++代码的长度是0,即空的&.cc&文件。&br&&br&操作过程如下(以linux命令行为例):&br&&br&首先,创建空的&.cc&文件。&br&&div class=&highlight&&&pre&&code class=&language-bash&&&span class=&nv&&$ &/span&touch empty.cc
&/code&&/pre&&/div&&br&之后用g++仅进行编译与汇编,而不进行链接。&br&&div class=&highlight&&&pre&&code class=&language-bash&&&span class=&nv&&$ &/span&g++ -c empty.cc
&/code&&/pre&&/div&&br&再用ld命令手动进行链接。&br&&div class=&highlight&&&pre&&code class=&language-bash&&&span class=&nv&&$ &/span&ld empty.o
ld: warning: cannot find entry symbol _start&span class=&p&&;&/span& defaulting to 0078
&/code&&/pre&&/div&&br&最后运行可执行文件,得到Segmentation fault。&br&&div class=&highlight&&&pre&&code class=&language-bash&&&span class=&nv&&$ &/span&./a.out
Segmentation fault &span class=&o&&(&/span&core dumped&span class=&o&&)&/span&
&/code&&/pre&&/div&&br&&br&注:以上均为linux命令行,实际C++代码长度为0。
长度为0。 楼上各位给出的代码都十分精彩,但假如就“能过编译并生成可执行文件,并且可执行文件运行时会导致崩溃的代码”这一定义来说,最短的C++代码的长度是0,即空的".cc"文件。 操作过程如下(以linux命令行为例): 首先,创建空的".cc"文件。 $ touc…
如须进行与图像相关的 C/C++ 开发,墙裂推荐 &a href=&///?target=https%3A//visualstudiogallery./e682d542-7ef3-402c-b857-bbfba714f78d& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Image Watch extension&i class=&icon-external&&&/i&&/a& ~&br&&br&Image Watch 可以在 debug 时直接显示图像的像素数据,可以灵活设置图像的显示方式,譬如自动归一化、用伪色显示等等。&br&&br&Image Watch 默认支持 OpenCV 以及 Windows SDK 中的部分图像类型,如 cv::Mat, IplImage 等。甚至通过定制 .natvis 文件,我们可以任意拓展 Image Watch 的支持对象。&br&&br&譬如在我自己的项目中,能够用 Image Watch 来 Debug 自定义的图像类型:&br&&img src=&/24a5e7a0786cecff8eafca579bd077b2_b.png& data-rawwidth=&900& data-rawheight=&507& class=&origin_image zh-lightbox-thumb& width=&900& data-original=&/24a5e7a0786cecff8eafca579bd077b2_r.png&&&br&放大可以直接看像素值&img src=&/52dd61feed129cde83afeb6_b.png& data-rawwidth=&865& data-rawheight=&506& class=&origin_image zh-lightbox-thumb& width=&865& data-original=&/52dd61feed129cde83afeb6_r.png&&&img src=&/44ef6a004f63ad9adb966473ccb6d891_b.png& data-rawwidth=&860& data-rawheight=&504& class=&origin_image zh-lightbox-thumb& width=&860& data-original=&/44ef6a004f63ad9adb966473ccb6d891_r.png&&&br&用来 debug 矩阵类型也比 vs 自带的 watch 方便不少&br&&img src=&/dc4eaf68fc6ce_b.png& data-rawwidth=&635& data-rawheight=&502& class=&origin_image zh-lightbox-thumb& width=&635& data-original=&/dc4eaf68fc6ce_r.png&&&br&&br&如何写 .natvis 详见 &a href=&///?target=http%3A///en-us/um/redmond/groups/ivm/imagewatchhelp/imagewatchhelp.htm& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Image Watch Help&i class=&icon-external&&&/i&&/a&&br&这里有个坑:自定义的 .natvis 文件需要放到 C:\Users\{用户名}\Documents\Visual Studio 2015\Visualizers 下面才能被 Image Watch 识别,否则只会显示 invalid ...&br&&br&Happy Coding!
如须进行与图像相关的 C/C++ 开发,墙裂推荐
~ Image Watch 可以在 debug 时直接显示图像的像素数据,可以灵活设置图像的显示方式,譬如自动归一化、用伪色显示等等。 Image Watch 默认支持 OpenCV 以及 Windows SDK 中的部分图像类…
&p&你想创造一门V语言而且用V语言来写V编译器的话,你得按照下面的方法做:&/p&&p&1、用C++把那个编译器(A)写出来,顺便留下很多测试用例。&/p&&p&2、用V语言把那个编译器写(B)出来,用A.exe来编译B,修改直到所有测试用例都通过为止。&/p&&p&3、B.exe来编译B自己得到B2.exe,修改直到B2.exe所有测试用例都通过为止。这是为了保证,就算B本身有很多bug,至少编译自己是没有bug的,从而你就可以走到第四步。&/p&&p&4、当你觉得有信心了,用A.exe把B编译一遍,就得到了B.exe。然后A的代码和A.exe都在也不需要存在了,删掉他们。以后你就不断的用B.exe来编译下一个版本的B就好了。就自举了。&/p&
你想创造一门V语言而且用V语言来写V编译器的话,你得按照下面的方法做:1、用C++把那个编译器(A)写出来,顺便留下很多测试用例。2、用V语言把那个编译器写(B)出来,用A.exe来编译B,修改直到所有测试用例都通过为止。3、B.exe来编译B自己得到B2.exe,修…
&p&评论已关,大家爱用啥用啥,有点时间找个妹子或者学学编程吧,不要在vim或者emacs这种东西上浪费时间。&/p&&p&&br&&/p&&p&&br&&/p&&p&大型程序也是一个一个小文件组成的,编辑完全可以使用vim。不过我觉得裸的vim很难用。这个是我装的所有插件。效果图在这,你看看是不是和你印象中的vim不太一样,不逊色于IDE,而且轻量级,在服务器ssh登录照样写代码。&/p&&img src=&/v2-4c0b895619bee5434331babe_b.png& data-caption=&& data-rawwidth=&1440& data-rawheight=&900& class=&origin_image zh-lightbox-thumb& width=&1440& data-original=&/v2-4c0b895619bee5434331babe_r.png&&&p&&br&&/p&&p&&a href=&///?target=http%3A//1.z0./vim_tmux_tdd.gif& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&1.z0.&/span&&span class=&invisible&&/vim_tmux_tdd.gif&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&/p&&p&(注意中间那道丑爆的大红线是为了提醒我pep8标准不要超过80列,python-mode里可以关掉)&/p&&p&具体安装信息在这篇博客里头,感兴趣的话可以看看&/p&&p&《使用vim+tmux+zsh+autojump高效工作》&a href=&///?target=http%3A//ningning.today//tools/vim-tmux-zsh-autojump/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&使用vim+tmux+zsh+autojump高效工作&i class=&icon-external&&&/i&&/a&&/p&&p&&br&&/p&&p&&a href=&///?target=http%3A//& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Vim Awesome&i class=&icon-external&&&/i&&/a& 你可以在这个网站筛选你感兴趣的插件,按照github的star数排名的,安装方式请参考上边博客链接。另外vim也是在与时俱进的,并不是多年不变的老古董,很多github活跃用户在给vim开发插件。笔者除了撸代码外,平常写博客,写笔记(markdown),写文档(rst)等都是在vim里写的,有实时预览插件。笔者之所以花很大代价打造编辑器是因为有大量时间会花在文本编辑上,觉得一个高效率和可定制的编辑环境会节省不少时间,甚至笔者觉得vim反倒更适合写文章 。&/p&&p&如果偷懒的话已经有人帮你弄好了&a href=&///?target=http%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&The Ultimate Vim Distribution&i class=&icon-external&&&/i&&/a&&/p&&p&&br&&/p&&p&vim插件之-代码篇&/p&&ul&&li&Bundle ‘klen/python-mode’,拥有python几乎所有IDE的功能,强烈建议你打开pylint和pyflake对代码进行检测,能消除很多低级错误,提高代码质量&/li&&li&Bundle 'fatih/vim-go',Golang插件&/li&&li&Plugin ‘jmcantrell/vim-virtualenv’,虚拟环境python支持&/li&&li&Plugin ‘pangloss/vim-javascript’, js支持&/li&&li&Bundle ‘mattn/emmet-vim’, 书写html和css,前端支持&/li&&li&Bundle ‘SirVer/ultisnips’和 Plugin ‘honza/vim-snippets’, 代码片段补全&/li&&li&Bundle ‘scrooloose/syntastic’, 支持各种流行编程语言的语法检测&/li&&li&Bundle ‘majutsushi/tagbar’,支持大纲浏览&/li&&li&Plugin ‘tpope/vim-fugitive’, git支持,直接在vim中执行git命令&/li&&li&Plugin ‘Valloric/YouCompleteMe’, 支持c/c++/python/go等流行编程语言的代码补全&/li&&li&Bundle ‘scrooloose/nerdcommenter’,快速注释,支持几乎所有编程语言&/li&&/ul&&p&到此为止你就已经有了一个python全栈开发IDE了,并且这套配置用ssh登录到服务器上也可以愉快地写代码了。很多后端程序员喜欢直接 ssh 到服务器上写代码(原因可}

我要回帖

更多关于 c 调用powershell 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信