Blog Archive

Thursday, October 12, 2017

Shared libraries with GCC on Linux

Link: Shared libraries with GCC on Linux - Cprogramming.com
By anduril462
Libraries are an indispensable tool for any programmer. They are pre-existing code that is compiled and ready for you to use. They often provide generic functionality, like linked lists or binary trees that can hold any data, or specific functionality like an interface to a database server such as MySQL.
Most larger software projects will contain several components, some of which you may find use for later on in some other project, or that you just want to separate out for organizational purposes. When you have a reusable or logically distinct set of functions, it is helpful to build a library from it so that you don’t have to copy the source code into your current project and recompile it all the time and so you can keep different modules of your program disjoint and change one without affecting others. Once it’s been written and tested, you can safely reuse it over and over again, saving the time and hassle of building it into your project every time.
Building static libraries is fairly simple, and since we rarely get questions on them, I won’t cover them. 
I’ll stick with shared libraries, which seem to be more confusing for most people.
Before we get started, it might help to get a quick rundown of everything that happens from source code to running program:
1.    C Preprocessor: This stage processes all the preprocessor directives. Basically, any line that starts with a #, such as #define and #include.
2.    Compilation Proper: Once the source file has been preprocessed, the result is then compiled. Since many people refer to the entire build process as compilation, this stage is often referred to as ‘compilation proper.’ This stage turns a .c file into an .o (object) file.
3.    Linking: Here is where all of the object files and any libraries are linked together to make your final program. Note that for static libraries, the actual library is placed in your final program, while for shared libraries, only a reference to the library is placed inside. Now you have a complete program that is ready to run. You launch it from the shell, and the program is handed off to the loader.
4.    Loading: This stage happens when your program starts up. Your program is scanned for references to shared libraries. Any references found are resolved and the libraries are mapped into your program.
Steps 3 and 4 are where the magic (and confusion) happens with shared libraries.
Now, on to our (very simple) example.
foo.h:
1
2
3
4
5
6
#ifndef foo_h__
#define foo_h__

extern void foo(void);

#endif  // foo_h__
##foo.c:
1
2
3
4
5
6
7
#include <stdio.h>


void foo(void)
{
    puts("Hello, I'm a shared library");
}
##main.c:
1
2
3
4
5
6
7
8
9
#include <stdio.h>
#include "foo.h"

int main(void)
{
    puts("This is a shared library test...");
    foo();
    return 0;
}
foo.h defines the interface to our library, a single function, foo(). 
foo.c contains the implementation of that function, and 
main.c is a driver program that uses our library.
For the purposes of this example, everything will happen in /home/username/foo
Step 1: Compiling with Position Independent Code
We need to compile our library source code into position-independent code (PIC):1
$ gcc -c -Wall -Werror -fpic foo.c
Step 2: Creating a shared library from an object file
Now we need to actually turn this object file into a shared library. We’ll call it libfoo.so:
gcc -shared -o libfoo.so foo.o
Step 3: Linking with a shared library
As you can see, that was actually pretty easy. We have a shared library. Let’s compile our main.c and link it with libfoo. We’ll call our final program ‘test.’ 
Note that the -lfoo option is not looking for foo.o, but libfoo.so. 
GCC assumes that all libraries start with ‘lib’ and end with .so or .a (.so is for shared object or shared libraries, and .a is for archive, or statically linked libraries).
$ gcc -Wall -o test main.c -lfoo
/usr/bin/ld: cannot find -lfoo
collect2: ld returned 1 exit status
Telling GCC where to find the shared library
Uh-oh! The linker doesn’t know where to find libfoo. GCC has a list of places it looks by default, but our directory is not in that list.2We need to tell GCC where to find libfoo.so. We will do that with the -L option. In this example, we will use the current directory, /home/username/foo:
$ gcc -L/home/username/foo -Wall -o test main.c -lfoo
Step 4: Making the library available at runtime
Good, no errors. Now let’s run our program:
$ ./test
./test: error while loading shared libraries: libfoo.so: cannot open shared object file: No such file or directory
Oh no! The loader can’t find the shared library.3 We didn’t install it in a standard location, so we need to give the loader a little help. We have a couple of options: we can use the environment variable LD_LIBRARY_PATH for this, or rpath. Let’s take a look first at LD_LIBRARY_PATH:
Using LD_LIBRARY_PATH
$ echo $LD_LIBRARY_PATH
There’s nothing in there. Let’s fix that by prepending our working directory to the existing LD_LIBRARY_PATH:
$ LD_LIBRARY_PATH=/home/username/foo:$LD_LIBRARY_PATH
$ ./test
./test: error while loading shared libraries: libfoo.so: cannot open shared object file: No such file or directory
What happened? Our directory is in LD_LIBRARY_PATH, but we didn’t export it. In Linux, if you don’t export the changes to an environment variable, they won’t be inherited by the child processes. The loader and our test program didn’t inherit the changes we made. Thankfully, the fix is easy:
$ export LD_LIBRARY_PATH=/home/username/foo:$LD_LIBRARY_PATH
$ ./test
This is a shared library test...
Hello, I'm a shared library
Good, it worked! 
LD_LIBRARY_PATH is great for quick tests and for systems on which you don’t have admin privileges. 
As a downside, however, exporting the LD_LIBRARY_PATH variable means it may cause problems with other programs you run that also rely on LD_LIBRARY_PATH if you don’t reset it to its previous state when you’re done.

Using rpath
Now let’s try rpath (first we’ll clear LD_LIBRARY_PATH to ensure it’s rpath that’s finding our library). Rpath, or the run path, is a way of embedding the location of shared libraries in the executable itself, instead of relying on default locations or environment variables. We do this during the linking stage. Notice the lengthy ‘-Wl,-rpath=/home/username/foo’ option. The -Wl portion sends comma-separated options to the linker, so we tell it to send the -rpath option to the linker with our working directory.
$ unset LD_LIBRARY_PATH
$ gcc -L/home/username/foo -Wl,-rpath=/home/username/foo -Wall -o test main.c -lfoo
$ ./test
This is a shared library test...
Hello, I'm a shared library
Excellent, it worked. The rpath method is great because each program gets to list its shared library locations independently, so there are no issues with different programs looking in the wrong paths like there were for LD_LIBRARY_PATH.

rpath vs. LD_LIBRARY_PATH
There are a few downsides to rpath, however. 

  • First, it requires that shared libraries be installed in a fixed location so that all users of your program will have access to those libraries in those locations. That means less flexibility in system configuration. 
  • Second, if that library refers to a NFS mount or other network drive, you may experience undesirable delays or worse on program startup.

Using ldconfig to modify ld.so
What if we want to install our library so everybody on the system can use it? For that, you will need admin privileges. You will need this for two reasons: first, to put the library in a standard location, probably /usr/lib or /usr/local/lib, which normal users don’t have write access to. Second, you will need to modify the ld.so config file and cache. As root, do the following:
$ cp /home/username/foo/libfoo.so /usr/lib
$ chmod 0755 /usr/lib/libfoo.so
Now the file is in a standard location, with correct permissions, readable by everybody. We need to tell the loader it’s available for use, so let’s update the cache:
$ ldconfig
That should create a link to our shared library and update the cache so it’s available for immediate use. Let’s double check:
$ ldconfig -p | grep foo
libfoo.so (libc6) => /usr/lib/libfoo.so
Now our library is installed. Before we test it, we have to clean up a few things:
Clear our LD_LIBRARY_PATH once more, just in case:
$ unset LD_LIBRARY_PATH
Re-link our executable. Notice we don’t need the -L option since our library is stored in a default location and we aren’t using the rpath option:
$ gcc -Wall -o test main.c -lfoo
Let’s make sure we’re using the /usr/lib instance of our library using ldd:
$ ldd test | grep foo
libfoo.so => /usr/lib/libfoo.so (0x00a42000)
Good, now let’s run it:
$ ./test
This is a shared library test...
Hello, I'm a shared library
That about wraps it up. We’ve covered how to build a shared library, how to link with it, and how to resolve the most common loader issues with shared libraries, as well as the positives and negatives of different approaches.

1.    What is position independent code? PIC is code that works no matter where in memory it is placed. Because several different programs can all use one instance of your shared library, the library cannot store things at fixed addresses, since the location of that library in memory will vary from program to program. 
2.    GCC first searches for libraries in /usr/local/lib, then in /usr/lib. Following that, it searches for libraries in the directories specified by the -L parameter, in the order specified on the command line. 
3.    The default GNU loader, ld.so, looks for libraries in the following order: 
1.    It looks in the DT_RPATH section of the executable, unless there is a DT_RUNPATH section.
2.    It looks in LD_LIBRARY_PATH. This is skipped if the executable is setuid/setgid for security reasons.
3.    It looks in the DT_RUNPATH section of the executable unless the setuid/setgid bits are set (for security reasons).
4.    It looks in the cache file /etc/ld/so/cache (disabled with the ‘ -z nodeflib’ linker option).

5.    It looks in the default directories /lib then /usr/lib (disabled with the ‘ -z nodeflib’ linker option).


Wednesday, October 11, 2017

What if you linked external hard drive and can not access it?

usb - Detect and mount devices - Ask Ubuntu:


How to check disks tree structure and locate target disk:
lsblk


How do I find out my motherboard model?

lspci

How to mount

Manually Mount a USB Drive

A USB storage device plugged into the system usually mounts automatically, but if for some reasons it doesn't automount, it's possible to manually mount it with these steps.
  1. Press Ctrl+Alt+T to run Terminal.
  2. Enter sudo mkdir /media/usb to create a mount point called usb.
  3. Enter sudo fdisk -l to look for the USB drive already plugged in, let's say the drive you want to mount is /dev/sdb1.
  4. To mount a USB drive formatted with FAT16 or FAT32 system, enter:
    sudo mount -t vfat /dev/sdb1 /media/usb -o uid=1000,gid=100,utf8,dmask=027,fmask=137
    
    OR, To mount a USB drive formatted with NTFS system, enter:
    sudo mount -t ntfs-3g /dev/sdb1 /media/usb


'via Blog this'

Tuesday, October 10, 2017

New tools & data for soundscape synthesis and online audio annotation

New tools & data for soundscape synthesis and online audio annotation

We're glad to announce the release of two open-source tools and a new dataset developed as part of the SONYC project we hope will be of use to the community: 

Scaper: a library for soundscape synthesis and augmentation
- Automatically synthesize soundscapes with corresponding ground truth annotations 
- Useful for running controlled ML experiments (ASR, sound event detection, bioacoustic species recognition, etc.)
- Useful for running controlled experiments to assess human annotation performance
- Potentially useful for generating data for source separation experiments (might require some extra code)
- Potentially useful for generating ambisonic soundscapes (definitely requires some extra code)

AudioAnnotator: a javascript web interface for annotating audio data
- Developed in collaboration with Edith Law and her students at the University of Waterloo's HCI Lab
- A web interface that allows users to annotate audio recordings
- Supports 3 types of visualization (waveform, spectrogram, invisible)
- Useful for crowdsourcing audio labels
- Useful for running controlled experiments on crowdsourcing audio labels
- Supports feedback mechanisms for providing real-time feedback to the user based on their annotations

URBAN-SED dataseta new dataset for sound event detection
- Includes 10,000 soundscapes with strongly labeled sound events generated using scaper
- Totals almost 30 hours and includes close to 50,000 annotated sound events
- Baseline convnet results on URBAN-SED are included in the scaper-paper.

Further information about scaper, the AudioAnnotator and the URBAN-SED dataset, including controlled experiments on the quality of crowdsourced human annotations as a function of visualization and soundscape complexity, are provided in the following papers:

M. Cartwright, A. Seals, J. Salamon, A. Williams, S. Mikloska, D. MacConnell, E. Law, J. Bello, and O. Nov.
Proceedings of the ACM on Human-Computer Interaction, 1(2), 2017.

J. Salamon, D. MacConnell, M. Cartwright, P. Li, and J. P. Bello.
In IEEE Workshop on Applications of Signal Processing to Audio and Acoustics (WASPAA), New Paltz, NY, USA, Oct. 2017.

We hope you find these tools and data useful and look forward to receiving your feedback (and pull requests!).

14.04 - How to install Anaconda on Ubuntu? - Ask Ubuntu

14.04 - How to install Anaconda on Ubuntu? - Ask Ubuntu: "bash Anaconda-2.3.0-Linux-x86_64.sh"



'via Blog this'

Monday, October 2, 2017

美股新手必备利器 (app & 网站)


美股新手必备利器 (app & 网站) 

0,快速尝试,免手续费:Robinhood app
业余业余炒股新手买股票、注册账户,最简单的就是:
http://share.robinhood.com/gangl
(上面是一个邀请码,注册就可以获得免费1支赠送的股票)


1、券商:

Firstrade.com(第一理财):总部位于纽约的美国本土券商,老板是华人,所以中文服务做得不错,适合英文不太好的国内美股投资者。https://www.firstrade.com/

InteractiveBrokers.com:美国盈透证券,适合投资经验比较丰富的美股投资者,相对来说不太适合新手。http://interactivebrokers.com/

Guoking.com.hk:国京证券,香港券商,开美股账户的同时也可以炒港股。全中文服务大陆设有办事处,适合国内投资者。http://www.guoking.com.hk/

2、免费美股实时行情及股票筛选器:

NASDAQ Real TimeQuotes:纳斯达克官方网站提供的实时报价页面,能同时查询最多25只美股的实时股价,其优点是无延时(很多财经网站上的美股行情普遍都有15~20分钟的延时)。http://www.nasdaq.com/quotes/real-time.aspx

freestockcharts.com:google finance https://www.google.com/finance又上不去了?觉得雅虎财经不好用?那就试试这个网站吧,该网站能免费看美股实时行情,优点是可看K线图以及在图形中可加入各种技术分析指标,并且比较实时等;缺点是界面为英文,页面加载较慢等。freestockchart基本上就是国外口碑最好的行情平台ThinkorSwim(需要付费才能使用,美股券商TD Ameritrade的客户可免费使用ThinkorSwim,但TD Ameritrade已经不支持美国本土以外人士注册开户)的简化版。http://www.freestockcharts.com/

finviz.com:Finviz和FreeStockCharts是国内投资者经常关注美盘的两个网站,以前我一直主要参考雅虎财经英文版:finance.yahoo.com 觉得雅虎的数据是最全面的,现在发现这个finviz.com似乎更强大,应该可算作数据信息最全的美股网站了;另外该网站还提供选股页面:finviz.com/screener.ashx,交易的第一不就是要找到自己想要的股票,除了一些人人都知道的大股票像是AAPL, AMZN, CMG, COST, KO….等等, 要如何有效率的找到符合自己条件的股票呢? 在这个网站中, 你可以设定你要的条件, 像是价位, 市值, 交易量, P/E, 甚至是财报日, 他都会自动帮你列出来, 你还可以下载成csv档, 相当好用, 大家不防去试试吧! http://www.finviz.com/

StockFetcher.com:是很不错的技术分析选股器。http://www.stockfetcher.com/

stockcharts.com:该网站是一个专门为用户提供金融图标制作工具的网站。有没有人觉得制作一张金融图标是一件轻而易举的事情?该网站提供制图工具,教育信息,专家建议和支持,帮助您在市场竞争中如鱼得水,财源滚滚。这个网站好就好在有一个数据处理功能,比如可以做出诸如上证指数除以美元指数这样的图。技术图表功能强大,操作界面直观,有免费服务和会员收费服务;该站每天根据多种技术指标自动搜索美国和加拿大的股票和公共基金。http://stockcharts.com/

tradingview.com:这个网站的图表做的还是不错的,各种分析工具很全,支持鼠标直接拖拽和缩放,速度也很好。种类多,包括股票,各种股指,期货,以及外汇。平时可以用来当做stockcharts.com的补充。https://www.tradingview.com/

BigCharts(有一些独特的技术图形指标和MarketWatch提供的企业研究报告,免费服务;行业分类列表,不同时间段的行业和类股强弱排序)http://bigcharts.marketwatch.com/

cn.advfn.com:来自英国的网站,有中文版,能查上市公司财务数据;公司财务数据之齐全、整理和查询方便,无出其右者。有些内容需要注册和缴纳费用才能浏览。http://cn.advfn.com/

Yahoo StockScreener:非常强大的选股工具,有java版和普通html版,可以根据很多设定的条件来筛选股票。http://screener.finance.yahoo.com/newscreener.html

Google Stockscreener:html界面,功能强大,可选参数很多。https://www.google.com/finance/stockscreener

marketwatch.com提供的选股器:MarketWatch是DowJones & Co公司旗下的网站,主要追溯市场动态,为投资者和每个月1600万的访问者提供与市场和财经相关的最新报道。http://www.marketwatch.com/tools/stockresearch/screener/

根据与纳斯达克达成的协议,新浪将向广大用户免费提供所有在美国上市证券的实时报价和交易数据,新浪用户将前所未有地获得权威的美股完备行情。PC版:http://t.cn/zO32x74 手机版:http://t.cn/zHLjPWm,具体介绍可以参考这篇文章:新浪正式推出毫秒级极速版美股实时行情http://finance.sina.com.cn/stock/usstock/c/20130826/213316567078.shtml

3、美股投资社交网站:

stocktwits.com:从其域名就可以看出,该网站是一个专门讨论股票的twitter,有蛮多炒美股的老外在上面分享实时买入或做空记录。http://stocktwits.com/

xueqiu.com:雪球网,算是国内做得比较好的投资社区了,以前主要讨论美股,现在A股和港股也都有讨论。为什么很多国内做美股的喜欢逛雪球网:【这里的同学们都是玩美股的中国同胞,来这里发发帖子,看看帖子,用的是自己的母语,感觉比较亲切;同时,平时在身边的同事朋友,要说起A股,满地都是,但是玩美股的,还真没几个,有点孤独感,在这里可以找到一种“同道中人”的群体感。】http://xueqiu.com/

wikinvest.com:该网站是一家新兴的投资网站,它试图以其更多的交互信息和更丰富的数据来挑战像雅虎财经这样已经建制完备的网站,被称为证券版的mint.com(美国在线记账网站,是一家免费的个人财务管理网站),亮点依然是管理你的所有真实的证券账户,各个账户的收益,个股的走势一目了然。当你持有的个股发生重大新闻或价格波动时网站可以通过页面、iphone、ipad随时通知你。https://www.wikinvest.com/account/portfolio/regx/start

4、美股模拟:

很多网友都在找美股模拟交易平台,想在真正投资美股前体验一番,下面我们就整理了一些提供美股模拟交易的网站:

SureTrader:是少数支持信用卡入金的美股券商(因为其总部位于避税天堂巴哈马,所以很多监管措施不像美国本土那样严格,这个特点可以说是有利也有弊),同时也提供模拟炒美股功能,只需在其首页提交email即可获得模拟账户(有网友反映提交email时容易报错,需要多试几次才会成功)。http://www.suretrader.com/

Lightspeed:美国相当知名的一家券商(交易成本低,仅次于IB盈透证券;交易平台也比较成熟),很多美股日内交易者(Day Trader)使用该券商的交易平台。Lightspeed有提供模拟账户供客户试用,在其官网上提交申请即可获得试用账号。Lightspeed的缺点是不提供中文服务,所以如果是开实盘账户,建议还是找有中文服务的美国券商比较好。http://www.lightspeed.com/

IB盈透证券:TWS模拟演示平台除了市场数据是用于前一周代码的模拟数据及不会执行和结算定单外,从形式到功能都反映了实际运行的版本情况。http://interactivebrokers.com/

thinkorswim:虽然TD Ameritrade这家券商不支持非美国人开户,但这并不妨碍我们试用其旗下的thinkorswim平台,有兴趣的朋友可以试用下传说中最好用的美股交易平台thinkorswim。https://www.thinkorswim.com/

optionsxpress提供的模拟交易:optionsxpress这家券商目前也无法接受中国人开户,但其提供的模拟交易国人还是能用的。http://www.optionsxpress.com/

investopedia:国外非常流行的一个模拟炒股网站,优点是可以同时做美股期权,同时模拟出色的交易员可以有机会被邀请参加私人games;注册需要美国人信息。初次投资金额为一百万,但是这游戏有个不好的规则就是不能将总投资额的25%投资在同一个股票上,因此害我不能集中投资咯。http://www.investopedia.com/

wallstreetsurvivor.com:国外做得比较好的模拟炒股网站,需翻墙才能使用。http://www.wallstreetsurvivor.com/

sterlingtrader.com:日内交易员(daytrader)使用的交易平台,不适合普通美股投资者,可申请免费模拟操作,去里边下载个sterling,再注册个账号就行了。https://www.sterlingtrader.com/

5、手机APP

现在很多人习惯在手机上看股票了,下面是几款能在手机上应用的美股行情软件:

Firstrade(第一理财)iPhone交易App:已经在Firstrade(第一理财)开户的朋友可下载其App,然后就能实现在iPhone上直接查看行情和下单交易了。https://www2.firstrade.com/content/zh-cn/trading/mobile

Stocks – Realtime Stock Quotes(安卓版):在北美的华人可能同时有美国,加拿大或中国的股票,手机上装个股软是为了及时看行情以及看到自己的收益。我试用多个免费软件,发现最好名叫“Stocks – Realtime Stock Quotes”。这个软件支持查看全球股市,同时你可以录入你的交易记录,它可以为你自动计算收益(包括自动除权除息等) 。这个软件最大的妙处的是后台和Google Finance同步,通过个人Google账户可以网上管理,强烈推荐。https://play.google.com/store/apps/details?id=org.dayup.stocks&hl=zh_cn

腾讯自选股(安卓、iOS版均有):腾讯自选股提供美股全市场报价,并在开盘期间提供BATS实时行情报价信息。http://finance.qq.com/products/portfolio/index.htm

新浪财经客户端(安卓、iOS版均有):提供沪深、美股、港股、全球股指、环球商品、外汇等众多市场实时行情,轻松实现手机看行情。http://finance.sina.com.cn/mobile/comfinanceweb.shtml

国京闪电交易软件(安卓、iOS版均有):提供香港市场多种K线图查阅,有熟悉的F10资讯功能,主面板查看自选股,可随意排序,满足普通用户需求,行情面板左侧边可展开自选股列表,单窗口查看自选股更方便。更有条件交易功能,专业用户的最爱。http://www.guoking.com.hk/n/soft/index.html

6、美股新闻:

华尔街见闻:提供及时的中文财经新闻。http://wallstreetcn.com/

A Simple Makefile Tutorial

Ref:  http://www.cs.colby.edu/maxwell/courses/tutorials/maketutor/



A Simple Makefile Tutorial

Makefiles are a simple way to organize code compilation. This tutorial does not even scratch the surface of what is possible using make, but is intended as a starters guide so that you can quickly and easily create your own makefiles for small to medium-sized projects.

A Simple Example

Let's start off with the following three files, hellomake.c, hellofunc.c, and hellomake.h, which would represent a typical main program, some functional code in a separate file, and an include file, respectively.

hellomake.chellofunc.chellomake.h
#include <hellomake.h>

int main() {
  // call a function in another file
  myPrintHelloMake();

  return(0);
}
#include <stdio.h>
#include <hellomake.h>

void myPrintHelloMake(void) {

  printf("Hello makefiles!\n");

  return;
}
/*
example include file
*/

void myPrintHelloMake(void);
Normally, you would compile this collection of code by executing the following command:

gcc -o hellomake hellomake.c hellofunc.c -I.

This compiles the two .c files and names the executable hellomake. The -I. is included so that gcc will look in the current directory (.) for the include file hellomake.h. Without a makefile, the typical approach to the test/modify/debug cycle is to use the up arrow in a terminal to go back to your last compile command so you don't have to type it each time, especially once you've added a few more .c files to the mix.

Unfortunately, this approach to compilation has two downfalls. First, if you lose the compile command or switch computers you have to retype it from scratch, which is inefficient at best. Second, if you are only making changes to one .c file, recompiling all of them every time is also time-consuming and inefficient. So, it's time to see what we can do with a makefile.

The simplest makefile you could create would look something like:

Makefile 1

hellomake: hellomake.c hellofunc.c
     gcc -o hellomake hellomake.c hellofunc.c -I.
If you put this rule into a file called Makefile or makefile and then type make on the command line it will execute the compile command as you have written it in the makefile. Note that make with no arguments executes the first rule in the file. Furthermore, by putting the list of files on which the command depends on the first line after the :, make knows that the rule hellomake needs to be executed if any of those files change. Immediately, you have solved problem #1 and can avoid using the up arrow repeatedly, looking for your last compile command. However, the system is still not being efficient in terms of compiling only the latest changes.

One very important thing to note is that there is a tab before the gcc command in the makefile. There must be a tab at the beginning of any command, and makewill not be happy if it's not there.

In order to be a bit more efficient, let's try the following:

Makefile 2

CC=gcc
CFLAGS=-I.

hellomake: hellomake.o hellofunc.o
     $(CC) -o hellomake hellomake.o hellofunc.o -I.

So now we've defined some constants CC and CFLAGS. It turns out these are special constants that communicate to make how we want to compile the files hellomake.c and hellofunc.c. In particular, the macro CC is the C compiler to use, and CFLAGS is the list of flags to pass to the compilation command. By putting the object files--hellomake.o and hellofunc.o--in the dependency list and in the rule, make knows it must first compile the .c versions individually, and then build the executable hellomake.

Using this form of makefile is sufficient for most small scale projects. However, there is one thing missing: dependency on the include files. If you were to make a change to hellomake.h, for example, make would not recompile the .c files, even though they needed to be. In order to fix this, we need to tell make that all .c files depend on certain .h files. We can do this by writing a simple rule and adding it to the makefile.

Makefile 3

CC=gcc
CFLAGS=-I.
DEPS = hellomake.h

%.o: %.c $(DEPS)
 $(CC) -c -o $@ $< $(CFLAGS)

hellomake: hellomake.o hellofunc.o 
 gcc -o hellomake hellomake.o hellofunc.o -I.
This addition first creates the macro DEPS, which is the set of .h files on which the .c files depend. Then we define a rule that applies to all files ending in the .o suffix. The rule says that the .o file depends upon the .c version of the file and the .h files included in the DEPS macro. The rule then says that to generate the .o file, make needs to compile the .c file using the compiler defined in the CC macro. The -c flag says to generate the object file, the -o $@ says to put the output of the compilation in the file named on the left side of the :, the $< is the first item in the dependencies list, and the CFLAGS macro is defined as above.

As a final simplification, let's use the special macros $@ and $^, which are the left and right sides of the :, respectively, to make the overall compilation rule more general. In the example below, all of the include files should be listed as part of the macro DEPS, and all of the object files should be listed as part of the macro OBJ.

Makefile 4

CC=gcc
CFLAGS=-I.
DEPS = hellomake.h
OBJ = hellomake.o hellofunc.o 

%.o: %.c $(DEPS)
 $(CC) -c -o $@ $< $(CFLAGS)

hellomake: $(OBJ)
 gcc -o $@ $^ $(CFLAGS)
So what if we want to start putting our .h files in an include directory, our source code in a src directory, and some local libraries in a lib directory? Also, can we somehow hide those annoying .o files that hang around all over the place? The answer, of course, is yes. The following makefile defines paths to the include and lib directories, and places the object files in an obj subdirectory within the src directory. It also has a macro defined for any libraries you want to include, such as the math library -lm. This makefile should be located in the src directory. Note that it also includes a rule for cleaning up your source and object directories if you type make clean. The .PHONY rule keeps make from doing something with a file named clean.

Makefile 5

IDIR =../include
CC=gcc
CFLAGS=-I$(IDIR)

ODIR=obj
LDIR =../lib

LIBS=-lm

_DEPS = hellomake.h
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))

_OBJ = hellomake.o hellofunc.o 
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))


$(ODIR)/%.o: %.c $(DEPS)
 $(CC) -c -o $@ $< $(CFLAGS)

hellomake: $(OBJ)
 gcc -o $@ $^ $(CFLAGS) $(LIBS)

.PHONY: clean

clean:
 rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~ 
So now you have a perfectly good makefile that you can modify to manage small and medium-sized software projects. You can add multiple rules to a makefile; you can even create rules that call other rules. For more information on makefiles and the make function, check out the GNU Make Manual, which will tell you more than you ever wanted to know (really).

'via Blog this'

C++ Primer_Ed4 习题答案


Reference:
http://www.cnblogs.com/miki-52/p/5806946.html

C++ Primer Answers


Part 1 基本语言

Part 2 容器和算法

Part 3 类和数据抽象

Part 4 面向对象编程与泛型编程

 

Part 5 高级主题

附录:操作符优先级

Part 1 基本语言

Chapter 3

Exercise 3.1: 用适当的 using声明,而不用 std::,访问标准库中名字的方法,重新编写第 2.3 节的程序,计算一给定数的给定次幂的结果。

    #include <iostream>
    using  std::cin;
    using std::cout;
    using std::endl;
    int main()
    {
        int base,exponent;
        long result=1;
        cout<<"Enter base and exponent:"<<endl;
        cin>>base>>exponent;
        if(exponent<0)
        {
            cout<<"Exponent can't be smaller than 0"<<endl;
            return -1;
        }
        else
        {
            for(int cnt=1;cnt<=exponent;++cnt)
            {
                result*=base;
            }
        }
        cout<<base<<" raised to the power of "<<exponent<<":"<<result<<endl;
        //cout << "Hello world!" << endl;
        return 0;
    }