How to build bootable USB key
ACPI 体系中的重要名词
ACPI 体系中的重要名词
DSDT: DSDT 称做 Differentiated Definition Block,存在于 BIOS 中并与当前的硬件平台兼容的,提供了系统的硬件特性(例如某些设备的内部寄存器和存储器)的应用策略和配置,在系统初始化的时候,DSDT 被当前系统启动时初始化到名字空间中。
FADT:FADT 中包含了 ACPI 的硬件寄存器组(GPE)的应用和配置(包含它们的硬件地址)也包括DSDT表的硬件地址。
ACPI Namespace: 对于ACPI层来说,内存维持了一个目录形式的指向每个设备,以及 GPE 的名字空间,这个名字树是通过初始化的时候由 DSDT 创建的,名字树可以通过 loadtable 方法从 BIOS 中载入 DSDT 改变,而每个设备在 ACPI 层中都被描述成一个对象,包含有对这个设备特性和操作策略的描述列表,系统所有类型设备都是保存在同一个名字树下。在 ACPI OS 层上调用 _ADR 来获得 Namesapce 的设备名,Namespace 的例子见例 1-1:
OSPM(OS-directed Power Management):OSPM 操作系统支持 ACPI 的一个部分,操作系统 (OS)可以从操作系统下驱动程序的角度控制 ACPI 子模块,同时支持 ACPI 包括 SCI 中断,设备事件,系统事件模式,这些事件模式可以充分支持 Hot-plug 方式。
SCI 中断:(System Control Interrupt) 系统控制中断,SCI 中断是一种源自 ACPI 兼容芯片系统中断,系统映射不同的 ACPI 事件中断向量以便共享此中断,当底层硬件产生 SCI 中断的时候(例如设备插入事件引发中断),根据通知 OSPM 层处理相对应的 ACPI 事件,OSPM 层会调用预先安装的中断句柄。
GPE Block Device 和 GPE 事件:GPE Block Device 是平台设计者可按照 FADT(Fixed ACPI Descriptor Table) 描述表中响应 GPE 的寄存器组,GPE 的输入脚。作为 GPE 设备描述块中的地址存在于 FADT 中,每个 GPE Block Device 可以容纳 128 个 GPE 事件,ACPI 层上提供两个通用目标寄存器组–GPE0_BLK 和 GPE1_BLK,(也就是说可以响应 256 个 GPE 事件)每个寄存器组中包含两个等长度的寄存器 GPEx_STS,GPEx_EN,他们的系统地址(硬件地址)都保存在 FADT 中,作为 GPE Blocks 的行为(或者是操作)描述部分存在于 ACPI 名字空间中;用于指示当前的设备的事件,例如设备插入/拔除事件发生的时候,相关的状态位(GPEx_STS中的位,这个是在硬件设计的时候相关设备的事 件信号会连接到这些状态位)会被外部的事件所置位,生成 SCI,让 OSPM 层运行相关的控制程方法通知 ACPI 层;GPEx_EN 表示每个事件的使能位,一般说来在南桥(ICH4)中有这几个寄存器,它们的硬件地址保存在 FADT 中。
GPE 事件就是通过 GPE 寄存器组引发 SCI 中断后,通告 OSPM 层有关设备的事件,例如下面介绍 Hot-Plug 的时候会详细或者简略地介绍到总线枚举,设备检查,设备唤醒,设备弹出几个事件。
ACPI” Source Language(ASL):ASL 语言是 ACPI 层用于描述特定的 ACPI 对象的 ACPI 专用语言,并且包括了 ACPI 对象的控制方法(Control method),OEM 厂商和 BIOS 设计者在 BIOS 中使用 ASL 定义所有的设备为 ACPI 对象,并且可以生成 ASL 格式的专门的控制方法,1-1 例就是关于 ASL 的例子:
ASL 的语法规参看 ACPI Specification Revision 2.0
AML 和 AML 分析器:AML 是 ACPI 控制方法的虚拟机器语言,AML 执行过程也就是 ACPI 核心驱动层,ACPI 控制方法使用 AML 来进行编写,但是通常而言对编写者来说是写成 ASL 的方式,通过 AML 翻译器进行翻译,AML 翻译器不但具备 ASL 的翻译的功能,而且可以执行 AML 方法,当用 ASL 编写的 DSDT 表被载入到名字空间的时候,将会被 AML 翻译器翻译成执行时候可以辨别的机器码,例如关键字 SCOPE 在进入 AML 编译器之前中是以一个 ACSII 编码保存在 DSDT 中,但 DSDT 被载入名字空间之后将变成 0×10 的单字节数值(AML 操作值为 ScopeOP)。对 AML 的编译过程和转换方式,ASL 中的关键字可以参看 ACPI Specification Revision 2.0 中 section 17 。
How to remove inital message in kernel at booting procedure ?
簡易製作 iPhone 鈴聲
★iTunes
★線上編輯
===============================
iTunes
下方即出現編輯畫面,iTunes目前提供30秒長度的鈴聲。(注意:音樂來源必須從iTunes取得)
Step1
點選步驟一的"Upload"
跳出選單,選取自己欲製作的MP3檔案
Step2
調整自己想要的區段,這邊可以編輯達40秒的長度
Step3
輸入鈴聲資訊。(注意:這邊輸入正確資訊,可以幫助其尋找適合的專輯插圖等資訊)
完成。下方選項二即iPhone鈴聲,把他放進去iTunes就可以同步到iPhone。
趕快去試吧!
[轉載] Linux Suspend 之記憶體機制
Linux Suspend 之記憶體機制
休眠(Suspend)現在已經是 Laptop 必備的電源管理機制之一,而 Suspend 又分為 s2ram(Suspen to RAM)和 s2disk(Suspend to Disk) 兩種模式。若是啟動 Suspend 的機制,可以看到 Operating System 神奇的被暫停,然後 Resume 叫醒回到之前的工作狀態。如果說想深入瞭解這樣一個機制,可以從 Linux 的休眠實作來著手,swsusp 就提供了這樣一個 User-space 的實作,我們可以研究它的sourcecode。
大體上來說,Suspend 機制不過就是儲存當時系統 Memory 狀態,然後再啟動時還原回去,在實作時,必需先鎖定當時系統下所有的記憶體空間,以確保記憶體內容不再變動,可以分別用 mlockall() 和 munlockall() 來達成這樣的任務。
#include <sys/mman.h>
int mlockall(int flags);
int munlockall(void);
flags 又分成:
- MCL_CURRENT
- 鎖定全部現有的記憶體分頁
- MCL_FUTURE
- 鎖定未來將被新增的記憶體分頁
- SNAPSHOT_FREEZE
- 鎖定使 User Space Processes 靜止
- 鎖定使 User Space Processes 靜止
- SNAPSHOT_UNFREEZE
- 解除 User Space Processes 的鎖定
- 解除 User Space Processes 的鎖定
- SNAPSHOT_ATOMIC_SNAPSHOT
- 建立一個系統的記憶體快照映像檔
- 建立一個系統的記憶體快照映像檔
- SNAPSHOT_ATOMIC_RESTORE
- 還原系統記憶體狀態
- 還原系統記憶體狀態
- SNAPSHOT_FREE
- 釋放快照映像檔的記憶體
- 釋放快照映像檔的記憶體
- SNAPSHOT_SET_IMAGE_SIZE
- 設定映像檔最大 Size,如果無法達到指定的 Size,kernel 會盡可能建立最小的 image
- SNAPSHOT_AVAIL_SWAP
- 取得可用的 Swap 大小
- 取得可用的 Swap 大小
- SNAPSHOT_GET_SWAP_PAGE
- 建立一個 Swap 頁
- 建立一個 Swap 頁
- SNAPSHOT_FREE_SWAP_PAGES
- 釋放所有 SNAPSHOT_GET_SWAP_PAGE 產生的 Swap 頁
- 釋放所有 SNAPSHOT_GET_SWAP_PAGE 產生的 Swap 頁
- SNAPSHOT_SET_SWAP_FILE
- 設定 Swap 的儲存位置
[轉載] Suspend/Resume to Ram&Disk in Linux
先察看您的系統是否已經支援休眠模式了。
- 代碼: 選擇全部
#cat /sys/power/state
mem disk standby
(如果有 『mem』『disk』... 等值,表示您的系統已支援休眠模式。)
可以簡單的測試一下休眠是否成功
- 代碼: 選擇全部
#echo -n mem > /sys/power/state 或
#echo -n disk > /sys/power/state
如果上面的測試後,系統可以順利休眠與甦醒,那麼您這時即可使用 Klaptop 或 Kpowersave
(如果您是使用 KDE 環境),來詳細設定 Notebook 的相關休眠動作。
PS:
如果『(一)測試』 的部份,cat /sys/power/state 的值 mem 與 disk 均有,但 Suspend to DISK 是失敗的,
可以檢查一下,您的 menu.lst (如果是GRUB的話),是否有帶入 resume=XXX 的值給 kernel。
而 resume=XXX 的值,即是 resume partition (save the suspended image)。
- 代碼: 選擇全部
e.g: resume=/dev/hda7
resume=/dev/...
- 代碼: 選擇全部
//-- 不建議 Linux 新手或不熟的朋友重新編譯,避免發生不可預期的後果。--//
//-- 請在編譯核心之時,確保您知道自己在做什麼。--//
如果系統預設不支援休眠該怎麼辦?一種可能是相關的 ACPI 模組沒有被掛載上來,
另外也許是 kernel 並沒有把相關功能編入進去。
如果您曉得模組的相關名稱為何的話,可以使用 modprobe 將相關模組掛載上來,
並按照(一測試)的部份試看看休眠模式是否順利開啟。
這裡小弟的使用方法,則是 re-build 一份 kernel,直接將相關的 ACPI/APM 模組編入核心,
小弟使用的 kernel 為:
- 代碼: 選擇全部
linux-source-2.6.15 (2.6.15-3)
首先 reload 先前的 .config 檔,接著將以下相關的選項打 * ,編入核心:
- 代碼: 選擇全部
Code maturity level options ---> (注意 !!! EXPERIMENTAL!!! )
[*] Prompt for development and/or incomplete code/drivers
[*] Select only drivers expected to compile cleanly
Power management options (ACPI, APM) --->
[*] Software Suspend
(/dev/hda7) Default resume partition (這裡可設定您的 Resume partition)
[*] Encrypt suspend image
ACPI (Advanced Configuration and Power Interface) Support --->
[*] ACPI Support
[*] Sleep States
[*] /proc/acpi/sleep (deprecated)
編譯完成後,依照您的系統建立 initrd (mkinitrd)...修改 menu.lst... 等,接著 reboot 以新的核心啟動系統...
新核心啟動完畢後,可繼續 『(一)測試』 的步驟,來測試自己的系統是否已經支援休眠模式,
若您在 re-build kernel 後,可以順利支援 Suspend to RAM & DISK,那麼真的恭喜您了!
倘若還是不行,那麼可能就要朝多方向去 Debug 了 (已不在本文的範疇中了 )
不過,不妨參考本文後面的 Reference,或許可幫助您更順利解決問題。
(三)後記:
以上簡單描述小弟在 Linux 下啟用 Suspend to RAM & DISK 的過程(例子),
提供大家參考,如果大家有相關資料或文獻要補充那真的太感謝了!
- 代碼: 選擇全部
那麼預祝各位使用愉快!
小弟的測試環境:
- 代碼: 選擇全部
測試機器: IBM X40
測試版本: Debian (with kernel 2.6.15-3)
更多資源:
- 代碼: 選擇全部
http://moto.debian.org.tw/viewtopic.php?t=3149
http://moto.debian.org.tw/viewtopic.php?t=8304
http://moto.debian.org.tw/viewtopic.php?t=4286
http://www.suspend2.net/
「轉載」3D 驅動程式
驅動程式 |
* iZ3D 1.10 驅動程式 (1.10.0000) - 正式支援新眼鏡,改進色偏與鬼影問題 * iZ3D 1.09 驅動程式 (1.09.0000) - 立體顯示可提供更高的禎數(FPS) * iZ3D 1.08 驅動程式 (1.08.0000) - 新增自動對焦功能(Auto Focus) * iZ3D 1.07 驅動程式 (1.07.0000) - 支援Winodws XP與Windows Vista 32位元作業系統 * iZ3D 附屬立體秀圖程式sview (0.4) - 透過iZ3D立體螢幕觀賞立體相片,並允許使用者微調立體效果 |
安裝iZ3D立體驅動程式 當您進入立體世界之前,請您先安裝iZ3D官方所提供的驅動程式。
注意事項: 接著,系統會詢問您是否「移除遊戲設定」,由於您所執行過的遊戲的立體設定,都會保留在系統內,因此建議您選擇「否」,讓驅動程式沿用之前的遊戲設定。
|
「轉載」立體影片/照片播放程式(iZ3D Media Player Classic)
立體影片/照片播放程式(iZ3D Media Player Classic) |
* 可播放立體DVD(交錯格式)、左右格式、上下格式之立體影片與相片 立即下載 (版本:1.04 檔案大小:1.38MB) |
「轉載」再谈立体成像原理
最初要想制作出一幅完美的立体图方法是:用多镜头相机或单镜头相机加滑轨依次拍照出近似的多幅图象,再进行图象合成冲印和光栅处理,冲印装裱 即成。这种方法制作工艺复杂,制作的图片价格昂贵,因此不易推广。目前,人们利用先进的数码合成技术制作立体图像,只需选择清晰的照片或底片将其扫描到电 脑里,直接在电脑里利用专业的制图软件进行配图和数字处理,用高精度彩喷机打印出来,再用冷裱机装裱即可。
立体成像技术可分为三大类:
1)双眼体视成像技术,立体图像由两幅具有视差的图像构成,观众需要戴上辅助装置观看,如双眼观片器、红绿(或红蓝)眼镜、偏振片眼镜、液晶光阀眼镜、立体头盔显示器等;
2)光栅立体影像技术,立体图像由2幅以上的具有水平视差的图像合成,观众不需配戴眼镜即可观看立体画面,广泛应用在多媒体显示、广告展示、家庭装饰、婚纱摄影、立体印刷等行业;
3)激光全息技术,记录图像需要用相干光,在全息防伪商标、卡片、包装材料上具有广泛的应用。此外,还有变焦距反光镜技术、凹面镜(或凸透镜)立体投影技 术、发光晶体成像、烟雾和水幕成像等非主流立体显示技术。
光栅立体图片主要由光栅板和抽样图粘接而成。抽样图是由两幅以上的视差图象按一定规则抽样合成的特殊图象,光栅板具有分光作用,可使视差图象分离,分别进 入人的左右眼,通过大脑的综合作用形成立体影像。用光栅板代替眼镜片,免去了观众配戴眼镜的累赘,是一种自动体视立体技术。
立体图像的特点:
一幅完美的立体图是由两个或多个图层组成,视觉上层次分明色彩鲜艳,具有很强的视觉冲击力,让观看的人驻景时间长,留下深刻的印象。立体图给人以真实、栩 栩如生,人物呼之欲出,有身临其境的感觉,有很高的艺术欣赏价值。利用立体图像包装企业,使企业形象更加鲜明,突出企业实力和档次。增加影响力!更能突出 产品的高品质和高档次。也可以做出色彩艳丽、层次分明的立体婚纱、照片,是当前影像业最新的卖点之一。
「轉載」3D立體成像原理 - 普及篇
常用立体技术说明及对比(原创普及篇)
近来经常有朋友说如何看立体,立体眼镜如何看,个人觉得还是有必要把立体的技术再做一次通俗点的普及,根据我个人的经验,力争用最简单的语言把立体技术说清楚:
首先要搞懂什么是立体,立体对个体来说是一种感觉,这种感觉可以促使你分辨物体之间的差距,也就是空间感,而立体视像简单点说就是带有空间感的图片或者视 频,空间感的产生,是因为人的双眼每一只眼睛看到的影像是不一样的(专业用语:视觉差),(大家可以看看下图:红色部分右眼看不到,蓝色部分左眼看不到, 如下这个美女图红线内的还是有比较明显的区别,
以上只是做一个比方,实际我们双眼看到的影像是在每个像素上都有不同,这也是平转立需要一定技术的原因。)不同的影像通过肌体传输到大脑,经大脑计算分析即可形成(医学问题不做解释),所以只有一只眼睛的人是永远感觉不到立体的。
因此,立体技术就是实现左右眼看到不同影像的技术。目前比较常用的有三种:
1、分色技术
通过不同颜色的过滤来实现,下面这幅实际上是由二张不同的图组成,分别做了红蓝渲染,当你带上红蓝眼镜时,红色镜片过滤掉渲染了红色的图片,蓝色镜片过滤 掉渲染了蓝色的图片,即可实现双眼看到不同影像。还有些红黄、红绿等等原理都是一样的。
2、分光技术
通过光的特性和折射来实现,常说的偏振观看、观屏镜观看都属于用分光技术。
偏振:利用光的特性,光是一种电磁波,是由与传播方向垂直的电场和磁场交替转换的振动形成的。自然光的震动方向是杂乱无章的,各个方向的都有,而偏振片都 可以使通过它的自然光只沿着偏振片的偏振方向振动,两个同步投影机分别将两幅不同偏振态的图像放映到银幕上再用不同偏振态的镜片分别过滤掉其中一幅图像就 可以实现立体原理。
观屏镜观看利用的是光的折射,这里不是大家很常用的就不介绍了。
3、分时技术
利用人的双眼感知特性来实现,人的眼睛是光接受器,对多少帧数的光都很敏感,但视觉神经存在暂留现象对于10帧以下的显示画面反映就看起来会拖,20帧以 上就会比较连续,60帧就不会有闪烁(为什么3D显示和投影设备都在120帧或以上的原因)在一种系统中,电视屏幕或投影交替显示两幅图片,利用专用的 LCD(液晶) 眼镜以很快的速度交替遮挡两只眼睛的视线,目前市场上三星、优派等品牌所示的3D的显示器、投影机所使用的就是以上技术,用的眼镜基本为NVIDIA。
以上三种为目前比较常用和实用的立体技术,下面再简单地谈谈其它:
最原始的技术:对眼法
这种方式就需要大家练连眼力了,俗称“对眼”,不需要任何设备,主要用于看左右格式的图片。汇聚你的视力,看中间那副图片就是立体的(有点难度)。
正在发展的技术:裸眼显示法
简单点就是把立体眼镜做到屏幕上去(注意:投影目前是没法实现的),采用的都是光栅技术,其中有包含二种1、狭缝光栅:与儿时玩的变幻画原理相同,把二幅 不同的画用技术手段显示在光栅的二边,分别投入左右眼即可;2柱镜技术:这个解释起来有些复杂,个人认为未来不会成为主流就偷懒不介绍了;
未来的技术:全真立体
看过(星球大战)电影的那种一按键人就显现出来的通讯方式,基本会跟那个相同,目前有日本和以色列实现了简单的图像立体,也就能显示些三角形、四方形的立体图,没有太大的实用价值,估计真要实现电影里的那种,怎么也要十年八年的吧。
最后给大家汇总一下:
常用立体技术对比表
这里再补充一点:由于产生立体的原因是由人体机能所导致的,因此立体影像一定是二幅或二幅以上画面组成的
常用立体格式对比表(二幅画面)
Reference:http://www.china3-d.com/Classroom/Tutorial/2009-12-28/759.html
求線段交點
#include <stdio.h>
typedef struct Point
{
double x;
double y;
}Point;
typedef struct Vector
{
struct Point begin;
struct Point end;
}Vector;
double VectorMul(Vector AB,Vector CD)/*求向量的叉积(以向量作参数)*/
{
return ((AB.end.x-AB.begin.x)*(CD.end.y-CD.begin.y) - (AB.end.y-AB.begin.y)*(CD.end.x-CD.begin.x));
}
double mul(Point A,Point B,Point C)/*向量叉积(以点做参数):求AB与AC的叉积*/
{
Point AB,AC;
AB.x=B.x-A.x;
AB.y=B.y-A.y;
AC.x=C.x-A.x;
AC.y=C.y-A.y;
return (AB.x*AC.y - AB.y * AC.x);
}
double Max(double a,double b)
{
return a > b ? a : b ;
}
double Min(double a,double b)
{
return a < b ? a : b ;
}
int Across(Vector AB,Vector CD)
/*判断线段是否相交(快速排斥试验和跨立试验)*/
{
if( /*X方向的排斥试验*/
( Max(AB.begin.x,AB.end.x) >= Min(CD.begin.x,CD.end.x) )
&&( Max(CD.begin.x,CD.end.x) >= Min(AB.begin.x,AB.end.x) )
/*Y方向的排斥试验*/
&&( Max(AB.begin.y,AB.end.y) >= Min(CD.begin.y,CD.end.y) )
&&( Max(CD.begin.y,CD.end.y) >= Min(AB.begin.y,AB.end.y) )
&&( mul(CD.begin,AB.begin,CD.end) * mul(CD.begin,AB.end,CD.end) <= 0 )/*A、B跨立CD的测试*/
&&( mul(AB.begin,CD.begin,AB.end) * mul(AB.begin,CD.end,AB.end) <= 0 )/*C、D跨立AB的测试*/
)
{
return 1;
}
return 0;
}
Point CrossPoint(Vector AB,Vector CD)
/*
求AB与CD的交点,前提:AB与CD相交
*/
{
Vector AD,AC;
Point result;
double k;
AD.begin = AB.begin;
AD.end = CD.end;
AC.begin = AB.begin;
AC.end = CD.begin;
k=(VectorMul(AB,AD))/(VectorMul(AB,AC) * 1.0);
k=k>0?k:(-k);/*这句话很重要*/
result.x = ( k * CD.begin.x + CD.end.x )/((1+k)*1.0) ;
result.y = ( k * CD.begin.y + CD.end.y )/((1+k)*1.0) ;
return result;
}
//以下是测试代码,仅供参考
int main()
{
Vector AB,CD;
Point result;
printf("Please input A:\t");
scanf("%lf%lf",&AB.begin.x,&AB.begin.y);
printf("Please input B:\t");
scanf("%lf%lf",&AB.end.x,&AB.end.y);
printf("Please input C:\t");
scanf("%lf%lf",&CD.begin.x,&CD.begin.y);
printf("Please input D:\t");
scanf("%lf%lf",&CD.end.x,&CD.end.y);
if( Across(AB,CD) )
{
result = CrossPoint(AB,CD);
printf("The Cross Point:\t");
printf("(%.2lf,%.2lf)\n",result.x,result.y);
}
else
{
printf("The segments have no cross point!\n ");
}
getchar();
getchar();
return 0;
}
C++ Reference - sort
sort
Syntax:
#include <algorithm>
void sort( random_iterator start, random_iterator end );
void sort( random_iterator start, random_iterator end, StrictWeakOrdering cmp );
The sort() algorithm sorts the elements in the range [start,end)
into ascending
order. If two elements are equal, there is no guarantee what order they will be
in.
If the strict weak ordering function object cmp
is given, then it will be used
to compare two objects instead of the <
operator.
The algorithm behind sort() is the introsort algorithm. sort() runs in O(N log
(N)) time (average and worst case) which is faster than polynomial time but
slower than linear time.
Note that sort() will only work with random access iterators. So you cannot use
sort() on the iterators of a “list” (linked list). Instead, you should use list's
own sort method to sort it instead.
For example, the following code sorts a vector of integers into ascending
order:
vector<int> v;
v.push_back( 23 );
v.push_back( -1 );
v.push_back( 9999 );
v.push_back( 0 );
v.push_back( 4 );
cout << "Before sorting: ";
for( unsigned int i = 0; i < v.size(); i++ ) {
cout << v[i] << " ";
}
cout << endl;
sort( v.begin(), v.end() );
cout << "After sorting: ";
for( unsigned int i = 0; i < v.size(); i++ ) {
cout << v[i] << " ";
}
cout << endl;
When run, the above code displays this output:
Before sorting: 23 -1 9999 0 4
After sorting: -1 0 4 23 9999
Alternatively, the following code uses the sort() function to sort a normal
array of integers, and displays the same output as the previous example:
int array[] = { 23, -1, 9999, 0, 4 };
unsigned int array_size = 5;
cout << "Before sorting: ";
for( unsigned int i = 0; i < array_size; i++ ) {
cout << array[i] << " ";
}
cout << endl;
sort( array, array + array_size );
cout << "After sorting: ";
for( unsigned int i = 0; i < array_size; i++ ) {
cout << array[i] << " ";
}
cout << endl;
This next example shows how to use sort() with a user-specified comparison
function. The function cmp
is defined to do the opposite of the <
operator.
When sort() is called with cmp
used as the comparison function, the result is a
list sorted in descending, rather than ascending, order:
bool cmp( int a, int b ) {
return a > b;
}
...
vector<int> v;
for( int i = 0; i < 10; i++ ) {
v.push_back(i);
}
cout << "Before: ";
for( int i = 0; i < 10; i++ ) {
cout << v[i] << " ";
}
cout << endl;
sort( v.begin(), v.end(), cmp );
cout << "After: ";
for( int i = 0; i < 10; i++ ) {
cout << v[i] << " ";
}
cout << endl;