文档库 最新最全的文档下载
当前位置:文档库 › Android C编译

Android C编译

Android.mk文件语法规范及使用模板

Android.mk文件语法规范

根据eoeandroid上的的连载,进行一些更新、修改和加亮。

今天翻译ANDROID-MK.TXT文件(英文原文件在

/development/Ndk/Docs/android-mk.txt)

Android.mk文件语法规范

Introduction:

Android.mk编译文件是用来向Android NDK描述你的C,C++源代码文件的,这篇文档描述了它的语法。在阅读下面的内容之前,假定你已经阅读了

docs/OVERVIEW.TXT文件,了解了它们的脚色和用途。

概述:

一个Android.mk file用来向编译系统描述你的源代码。具体来说:-该文件是GNU Makefile的一小部分,会被编译系统解析一次或更多次的build系统。因此,您应尽量减少您声明的变量,不要认为某些变量在解析过程中不会被定义。-这个文件的语法允许把你的源代码组织成模块,一个模块属下列类型之一:

静态库

共享库

只有共享库将被安装/复制到您的应用软件包。虽然静态库能被用于生成共享库。你可以在每一个Android.mk file中定义一个或多个模块,你也可以在几个模块中使用同一个源代码文件。

/******************************************************************** *********/

-编译系统为你处理许多细节问题。例如,你不需要在你的Android.mk中列出头文件和依赖文件。NDK编译系统将会为你自动处理这些问题。这也意味着,在升级NDK后,你应该得到新的toolchain/platform支持,而且不需要改变你的Android.mk文件。

注意,这个语法同公开发布的Android平台的开源代码很接近,然而编译系统实现他们的方式却是不同的,这是故意这样设计的,可以让程序开发人员重用外部库的源代码更容易。

简单的例子:

---------------

在描述语法细节之前,咱们来看一个简单的"hello world"的例子,比如,下面的文件:

sources/helloworld/helloworld.c

sources/helloworld/Android.mk

'helloworld.c'是一个JNI共享库,实现返回"hello world"字符串的原生方法。

相应的Android.mk文件会象下面这样:

---------- cut here ------------------

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE:= helloworld

LOCAL_SRC_FILES := helloworld.c

include $(BUILD_SHARED_LIBRARY)

---------- cut here ------------------

好,我们来解释一下这几行代码:

LOCAL_PATH := $(call my-dir)

一个Android.mk file首先必须定义好LOCAL_PATH变量。它用于在开发树中查找源文件。在这个例子中,宏函数’my-dir’, 由编译系统提供,用于返回当前路径(即包含Android.mk file文件的目录)。

include $( CLEAR_VARS)

CLEAR_VARS由编译系统提供,指定让GNU MAKEFILE为你清除许多LOCAL_XXX变量(例如LOCAL_MODULE, LOCAL_SRC_FILES,

LOCAL_STATIC_LIBRARIES, 等等...),

除LOCAL_PATH 。这是必要的,因为所有的编译控制文件都在同一个GNU MAKE执行环境中,所有的变量都是全局的。

LOCAL_MODULE := helloworld

LOCAL_MODULE变量必须定义,以标识你在Android.mk文件中描述的每个模块。名称必须是唯一的,而且不包含任何空格。注意编译系统会自动产生合适的前缀和后缀,换句话说,一个被命名为'foo'的共享库模块,将会生成'libfoo.so'文件。

重要注意事项

如果你把库命名为‘libhelloworld’,编译系统将不会添加任何的lib前缀,也会生成libhelloworld.so,这是为了支持来源于Android平台的源代码的Android.mk 文件,如果你确实需要这么做的话。

LOCAL_SRC_FILES := helloworld.c

LOCAL_SRC_FILES变量必须包含将要编译打包进模块中的C或C++源代码文件。注意,你不用在这里列出头文件和包含文件,因为编译系统将会自动为你找出依赖型的文件;仅仅列出直接传递给编译器的源代码文件就好。【注意,默认的C++源码文件的扩展名是’.cpp’. 指定一个不同的扩展名也是可能的,只要定义LOCAL_DEFAULT_CPP_EXTENSION变量,不要忘记开始的小圆点(也就是定义为‘.cxx’,而不是‘cxx’)(当然这一步我们一般不会去改它)】include $(BUILD_SHARED_LIBRARY)

BUILD_SHARED_LIBRARY是编译系统提供的变量,指向一个GNU Makefile 脚本(应该就是在build/core目录下的shared_library.mk),负责收集自从上次调用'include $(CLEAR_VARS)'以来,定义在LOCAL_XXX变量中的所有信息,并且决定编译什么,如何正确地去做。并根据其规则生成静态库。同理对于静态库。

/******************************************************************** ********/

在sources/samples目录下有更复杂一点的例子,写有注释的Android.mk文件,你可以看看。

参考:

这是一份你应该在Android.mk中依赖或定义的变量列表,您可以定义其他变量为自己使用,

但是NDK编译系统保留下列变量名:

-以LOCAL_开头的名字(例如LOCAL_MODULE)

-以PRIVATE_, NDK_ or APP_开头的名字(内部使用)

-小写名字(内部使用,例如’my-dir’)

如果您为了方便在Android.mk中定义自己的变量,我们建议使用MY_前缀,一个小例子:

---------- cut here ------------------

MY_SOURCES := foo.c

ifneq ($(MY_CONFIG_BAR),)

MY_SOURCES += bar.c

endif

LOCAL_SRC_FILES += $(MY_SOURCES)

---------- cut here ------------------

- - - - - - - - - - -

这些GNU Make 变量在你的Android.mk文件解析之前,就由编译系统定义好了。注意在某些情况下,NDK可能分析Android.mk几次,每一次某些变量的定义会有不同。

CLEAR_VARS

指向一个编译脚本,几乎所有未定义的LOCAL_XXX变量都在

"Module-description"节中列出。

你必须在开始一个新模块之前包含这个脚本。include $(CLEAR_VARS)

BUILD_SHARED_LIBRARY

指向编译脚本,收集所有的你在LOCAL_XXX变量中提供的信息,并且决定如何把你列出的源代码文件编译成一个共享库。注意,你必须至少在包含这个文件之前定义LOCAL_MODULE和LOCAL_SRC_FILES,使用例子:

include $(BUILD_SHARED_LIBRARY)

注意这将生成一个名为lib$(LOCAL_MODULE).so的文件。

BUILD_STATIC_LIBRARY

一个BUILD_SHARED_LIBRARY变量用于编译一个静态库。静态库不会复制到你的project/packages中,诞生能够用于编译共享库,(看下面描述的

LOCAL_STATIC_LIBRARIES and LOCAL_STATIC_WHOLE_LIBRARIES)

使用例子:

include $(BUILD_STATIC_LIBRARY)

注意,这将会生成一个名为lib$(LOCAL_MODULE).a的文件。

TARGET_ARCH

目标CPU平台的名字,如同在android开放源码中指定的那样。如果是’arm’,表示要生成ARM兼容的指令,与CPU架构的修订版无关。

TARGET_PLATFORM

Android.mk解析的时候,目标Android平台的名字.详情可参考

/development/ndk/docs/stable-apis.txt.

android-3 -> Official Android 1.5 system images

android-4 -> Official Android 1.6 system images

android-5 -> Official Android 2.0 system images

TARGET_ARCH_ABI

暂时只支持两个value,armeabi和armeabi-v7a。在现在的版本中一般把这两个值简单的定义为arm,通过android 平台内部对它重定义来获得更好的匹配。

其他的ABI将在以后的NDK版本中介绍,它们会有不同的名字。注意所有基于ARM的ABI都会把'TARGET_ARCH'定义成‘arm’,但是会有不同的‘TARGET_ARCH_ABI’

TARGET_ABI

目标平台和ABI的组合,它事实上被定义成

$(TARGET_PLATFORM)-$(TARGET_ARCH_ABI) 在你想要在真实的设备中针对一个特别的目标系统进行测试时,会有用。在默认的情况下,它会是

'android-3-arm'。

/******************************************************************** *********/

下面是GNU Make‘功能’宏,必须通过使用'$(call )'来求值,他们返回文本化的信息。

my-dir

返回当前Android.mk所在的目录路径,相对于NDK编译系统的顶层。这是有用的,在Android.mk文件的开头如此定义:

LOCAL_PATH := $(call my-dir)

all-subdir-makefiles

返回一个位于当前'my-dir'路径的子目录列表。例如,看下面的目录层次:sources/foo/Android.mk

sources/foo/lib1/Android.mk

sources/foo/lib2/Android.mk

如果sources/foo/Android.mk包含一行:

include $(call all-subdir-makefiles)

那么它就会自动包含sources/foo/lib1/Android.mk 和sources/foo/lib2/Android.mk 这项功能用于向编译系统提供深层次嵌套的代码目录层次。注意,在默认情况下,NDK将会只搜索在sources/*/Android.mk中的文件。

this-makefile

返回当前Makefile的路径(即这个函数调用的地方)

parent-makefile

返回调用树中父Makefile路径。即包含当前Makefile的Makefile路径。

grand-parent-makefile

猜猜看...

/******************************************************************** *********/

模块描述变量:

下面的变量用于向编译系统描述你的模块。你应该定义在'include

$(CLEAR_VARS)'和'include $(BUILD_XXXXX)'之间定义。正如前面描写的那样,$(CLEAR_VARS是一个脚本,清除所有这些变量,除非在描述中显式注明。

LOCAL_PATH

这个变量用于给出当前文件的路径。你必须在Android.mk的开头定义,可以这样使用:

LOCAL_PATH := $(call my-dir)

这个变量不会被$(CLEAR_VARS)清除,因此每个Android.mk只需要定义一次(即使你在一个文件中定义了几个模块的情况下)。

LOCAL_MODULE

这是你模块的名字,它必须是唯一的,而且不能包含空格。你必须在包含任一的$(BUILD_XXXX)脚本之前定义它。模块的名字决定了生成文件的名字,例如,如果一个一个共享库模块的名字是,那么生成文件的名字就是lib.so。但是,在你的NDK生成文件中(或者Android.mk或者Application.mk),你应该只涉及(引用)有正常名字的其他模块。

LOCAL_SRC_FILES

这是要编译的源代码文件列表。只要列出要传递给编译器的文件,因为编译系统自动为你计算依赖。

注意源代码文件名称都是相对于LOCAL_PATH的,你可以使用路径部分,例如:LOCAL_SRC_FILES := foo.c \

toto/bar.c

注意:在生成文件中都要使用UNIX风格的斜杠(/).windows风格的反斜杠不会被正确的处理。

LOCAL_CPP_EXTENSION

这是一个可选变量,用来指定C++代码文件的扩展名,默认是'.cpp',但是你可以改变它,比如:

LOCAL_CPP_EXTENSION := .cxx

LOCAL_C_INCLUDES

路径的可选配置,是从根目录开始的,

all sources (C, C++ and Assembly). For example:

LOCAL_C_INCLUDES := sources/foo

Or even:

LOCAL_C_INCLUDES := $(LOCAL_PATH)/../foo

需要在任何包含LOCAL_CFLAGS / LOCAL_CPPFLAGS标志之前。

LOCAL_CFLAGS

可选的编译器选项,在编译C代码文件的时候使用。

这可能是有用的,指定一个附加的包含路径(相对于NDK的顶层目录),宏定义,或者编译选项。

重要信息:不要在Android.mk中改变optimization/debugging级别,只要在Application.mk中指定合适的信息,就会自动地为你处理这个问题,在调试期间,会让NDK自动生成有用的数据文件。

LOCAL_CXXFLAGS

Same as LOCAL_CFLAGS for C++ source files

LOCAL_CPPFLAGS

与LOCAL_CFLAGS相同,但是对C 和C++ source files都适用。

LOCAL_STATIC_LIBRARIES

应该链接到这个模块的静态库列表(使用BUILD_STATIC_LIBRARY生成),这仅仅对共享库模块才有意义。

LOCAL_SHARED_LIBRARIES

这个模块在运行时要依赖的共享库模块列表,在链接时需要,在生成文件时嵌入的相应的信息。注意:这不会附加列出的模块到编译图,也就是,你仍然需要在Application.mk中把它们添加到程序要求的模块中。

LOCAL_LDLIBS

编译你的模块要使用的附加的链接器选项。这对于使用”-l”前缀传递指定库的名字是有用的。例如,下面将告诉链接器生成的模块要在加载时刻链接到

/system/lib/libz.so

LOCAL_LDLIBS := -lz

看docs/STABLE-APIS.TXT获取你使用NDK发行版能链接到的开放的系统库列表。

LOCAL_ALLOW_UNDEFINED_SYMBOLS

默认情况下,在试图编译一个共享库时,任何未定义的引用将导致一个“未定义的符号”错误。这对于在你的源代码文件中捕捉错误会有很大的帮助。

然而,如果你因为某些原因,需要不启动这项检查,把这个变量设为‘true’。注意相应的共享库可能在运行时加载失败。(这个一般尽量不要去设为true)

LOCAL_ARM_MODE

默认情况下,arm目标二进制会以thumb的形式生成(16位),你可以通过设置这个变量为arm如果你希望你的module是以32位指令的形式。

'arm' (32-bit instructions) mode. E.g.:

LOCAL_ARM_MODE := arm

注意你同样可以在编译的时候告诉系统编译特定的类型,比如

LOCAL_SRC_FILES := foo.c bar.c.arm

这样就告诉系统总是将bar.c以arm的模式编译,

Android.mk使用模板

在一个Android.mk中可以生成多个可执行程序、动态库和静态库。

1,编译应用程序的模板:

#Test Exe

LOCAL_PATH := $(call my-dir)

#include $(CLEAR_VARS)

LOCAL_SRC_FILES:= main.c

LOCAL_MODULE:= test_exe

#LOCAL_C_INCLUDES :=

#LOCAL_STATIC_LIBRARIES :=

#LOCAL_SHARED_LIBRARIES :=

include $(BUILD_EXECUTABLE)

(菜鸟级别解释::=是赋值的意思,$是引用某变量的值)LOCAL_SRC_FILES 中加入源文件路径,LOCAL_C_INCLUDES 中加入所需要包含的头文件路径,LOCAL_STATIC_LIBRARIES加入所需要链接的静态库(*.a)的名称,LOCAL_SHARED_LIBRARIES中加入所需要链接的动态库(*.so)的名称,LOCAL_MODULE表示模块最终的名称,BUILD_EXECUTABLE表示以一个可执行程序的方式进行编译。

2,编译静态库的模板:

#Test Static Lib

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_SRC_FILES:= \

helloworld.c

LOCAL_MODULE:= libtest_static

#LOCAL_C_INCLUDES :=

#LOCAL_STATIC_LIBRARIES :=

#LOCAL_SHARED_LIBRARIES :=

include $(BUILD_STATIC_LIBRARY)

一般的和上面相似,BUILD_STATIC_LIBRARY表示编译一个静态库。

3,编译动态库的模板:

#Test Shared Lib

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_SRC_FILES:= \

helloworld.c

LOCAL_MODULE:= libtest_shared

TARGET_PRELINK_MODULES := false

#LOCAL_C_INCLUDES :=

#LOCAL_STATIC_LIBRARIES :=

#LOCAL_SHARED_LIBRARIES :=

include $(BUILD_SHARED_LIBRARY)

一般的和上面相似,BUILD_SHARED_LIBRARY表示编译一个共享库。

以上三者的生成结果分别在如下,generic依具体target会变:

out/target/product/generic/obj/EXECUTABLE

out/target/product/generic/obj/STATIC_LIBRARY

out/target/product/generic/obj/SHARED_LIBRARY

每个模块的目标文件夹分别为:

可执行程序:XXX_intermediates

静态库: XXX_static_intermediates

动态库: XXX_shared_intermediates

另外,在Android.mk文件中,还可以指定最后的目标安装路径,用LOCAL_MODULE_PATH和LOCAL_UNSTRIPPED_PATH来指定。不同的文件系统路径用以下的宏进行选择:

TARGET_ROOT_OUT:表示根文件系统。

TARGET_OUT:表示system文件系统。

TARGET_OUT_DATA:表示data文件系统。

用法如:

LOCAL_MODULE_PATH:=$(TARGET_ROOT_OUT)

Ubuntu下Android源码修改、编译及运行、launcher定制

环境 Linux 版本:Ubuntu 11.04 (可由10.10的版本进行升级)64位系统 GCC版本:gcc version 4.5.2 Java版本:java version "1.6.0_26" 下载android源码前注意: 1、保证Ubuntu系统中的容量在80G左右,以保证足够的空间来存放android源码以及编译后的相关文件。 2、保证Ubuntu系统进行Internet访问。 联网方法:采用拨号进行连接。相关操作步骤如下所示: 1、虚拟机→设置→硬件→网络适配器→网络连接→桥接 2、启动Ubuntu系统,打开终端(在普通用户下),输入相关命令如下: $ pppoeconf //打开后输入上网账号跟密码,确认保存 $ sudo pon dsl-provider //上网连接命令 经过这两个步骤后就可以进行上网了。 Android源码编译所依赖的tools 01.$ sudo apt-get update 02.$ sudo apt-get -y install git-core 03.$ sudo apt-get -y install gnupg 04.$ sudo apt-get -y install sun-java6-jdk flex 05.$ sudo apt-get -y install bison 06.$ sudo apt-get -y install gperf 07.$ sudo apt-get -y install libsdl-dev 08.$ sudo apt-get -y install libesd0-dev 09.$ sudo apt-get -y install libwxgtk2.6-dev 10.$ sudo apt-get -y install build-essential 11.$ sudo apt-get -y install zip 12.$ sudo apt-get -y install curl 13.$ sudo apt-get -y install libncurses5-dev 14.$ sudo apt-get -y install zlib1g-dev 15.$ sudo apt-get -y install valgrind 注意:(如果是32bit的系统的话,则要更改几个Android.mk文件) 01./external/clearsilver/cgi/Android.mk 02./external/clearsilver/java-jni/Android.mk 03./external/clearsilver/util/Android.mk 04./external/clearsilver/cs/Android.mk 用gedit打开,修改m64为m32即可 另外 将build/core/main.mk中的ifneq (64,$(findstring 64,$(build_arch)))修改为: ifneq (i686,$(findstring i686,$(build_arch)))

C语言习题集(预处理命令篇)

第六章预处理命令 6.1 选择题 1.下面叙述中正确的是()。 A. 带参数的宏定义中参数是没有类型的 B. 宏展开将占用程序的运行时间 C. 宏定义命令是C语言中的一种特殊语句 D. 使用#include命令包含的头文件必须以“.h”为后缀 2.下面叙述中正确的是()。 A. 宏定义是C语句,所以要在行末加分号 B. 可以使用#undef命令来终止宏定义的作用域 C. 在进行宏定义时,宏定义不能层层嵌套 D. 对程序中用双引号括起来的字符串内的字符,与宏名相同的要进行置换 3.在“文件包含”预处理语句中,当#include后面的文件名用双引号括起时,寻找被包含文件的方式为()。 A. 直接按系统设定的标准方式搜索目录 B. 先在源程序所在目录搜索,若找不到,再按系统设定的标准方式搜索 C. 仅仅搜索源程序所在目录 D. 仅仅搜索当前目录 4.下面叙述中不正确的是()。 A. 函数调用时,先求出实参表达式,然后带入形参。而使用带参的宏只是进行简单的 字符替换 B. 函数调用是在程序运行时处理的,分配临时的内存单元。而宏展开则是在编译时进 行的,在展开时也要分配内存单元,进行值传递 C. 对于函数中的实参和形参都要定义类型,二者的类型要求一致,而宏不存在类型问 题,宏没有类型 D. 调用函数只可得到一个返回值,而用宏可以设法得到几个结果 5.下面叙述中不正确的是()。 A. 使用宏的次数较多时,宏展开后源程序长度增长。而函数调用不会使源程序变长 B. 函数调用是在程序运行时处理的,分配临时的内存单元。而宏展开则是在编译时进 行的,在展开时不分配内存单元,不进行值传递 C. 宏替换占用编译时间 D. 函数调用占用编译时间 6.下面叙述中正确的是( )。 A. 可以把define和if定义为用户标识符 B. 可以把define定义为用户标识符,但不能把if定义为用户标识符 C. 可以把if定义为用户标识符,但不能把define定义为用户标识符 D. define和if都不能定义为用户标识符 7.下面叙述中正确的是()。 A.#define和printf都是C语句 B.#define是C语句,而printf不是 C.printf是C语句,但#define不是 D.#define和printf都不是C语句

Rockchip Android编译说明

v1.2.9 Android编译说明 1. 编译前预处理 (1) 1.1. 指定编译的产品名 (1) 1.2. 执行编译的预处理 (2) 1.3. 注意事项 (2) 2. 编译Android代码 (2) 3. 编译后处理 (3) 3.1. 生成FLASH烧写用的IMG (3) 3.2. 生成NFS用的文件目录 (3) 4. 在vendor下创建一个产品名 (4) 4.1. 新建产品目录 (4) 4.2. 功能裁剪 (4) 4.3. 注意事项 (5) 由于Android目录下可以包含多个产品的编译规则,所以编译源码要经过以下几个步骤:l编译前预处理(make prebuild) l编译Android代码(make) l编译后处理(make firmware) 1.编译前预处理 1.1. 指定编译的产品名 注意: 1.发布的Android SDK软件包已经做好以下配置,默认为sdkDemo产品,可以直接 跳到1.2的步骤。 2.如果要新建一个产品需要执行本小节1.1的操作。 3.新建产品请参见章节:在vendor下创建一个产品名 需要确认根目录下是否有buildspec.mk文件,如果有确认该文件内配置的产品名是否正确,例如sdkDemo的产品,则该文件内配置为如下值: 如果没有则拷($android)/build/buildspec.mk.default文件至根目录下,重复以上步骤。

1.2. 执行编译的预处理 在根目录下敲入make prebuild 该命令将执行一些产品相关功能的资源文件拷贝等操作。 1.3. 注意事项 l此部分步骤在只需要执行一次,后续编译不用再执行此命令。 l如何确认当前配置的产品名? 敲入make会立即弹出以下信息,确认下面的TARGET_PRODUCT字段值 l当前目录有多少的产品名? Android代码中,用户自定义扩展的产品名都存放在vendor目录下 2.编译Android代码 在根目录下敲入make

Android系统编译过程中常见问题汇总(2)

android源码编译常见问题 分类:android中级2013-03-09 16:20 397人阅读评论(2) 收藏举报编译过程: (在Ubuntu 11.04 64位机器上编译) 1. source build/envsetup.sh //初始化与环境envsetup.sh脚本 初始化完成,显示如下 including device/samsung/maguro/vendorsetup.sh including device/samsung/tuna/vendorsetup.sh including device/ti/panda/vendorsetup.sh including sdk/bash_completion/adb.bash 2. lunch full-eng //选择的目标 ============================================ PLATFORM_VERSION_CODENAME=REL PLATFORM_VERSION=4.0.1 TARGET_PRODUCT=full TARGET_BUILD_VARIANT=eng TARGET_BUILD_TYPE=release TARGET_BUILD_APPS= TARGET_ARCH=arm TARGET_ARCH_VARIANT=armv7-a HOST_ARCH=x86 HOST_OS=linux HOST_BUILD_TYPE=release BUILD_ID=ITL41D ============================================ //建立与一切使。GNU的make -JN参数可以并行处理任务,它是共同使用的任务数, //N的1倍和2倍之间是被用于建立计算机硬件线程数量。例如在E5520双机(2个CPU, //每个CPU 4核,每核心2线程),最快的构建与命令之间的J16和 -J32。 3. make -j4 编译完成

编译预处理

第九章编译预处理 9.1 选择题 【题9.1】以下叙述中不正确的是。 A)预处理命令行都必须以#号开始 B)在程序中凡是以#号开始的语句行都是预处理命令行 C)C程序在执行过程中对预处理命令行进行处理 D)以下是正确的宏定义 #define IBM_PC 【题9.2】以下叙述中正确的是。 A)在程序的一行上可以出现多个有效的预处理命令行 B)使用带参的宏时,参数的类型应与宏定义时的一致 C)宏替换不占用运行时间,只占编译时间 D)在以下定义中C R是称为“宏名”的标识符 #define C R 045 【题9.3】请读程序: #define ADD(x) x+x main() { int m=1,n=2,k=3; int sum=ADD(m+n)*k; printf(“sum=%d”,sum); } 上面程序的运行结果是。 A)sum=9 B)sum=10 C)sum=12 D)sum=18 【题9.4】以下程序的运行结果是。 #define MIN(x,y) (x)<(y)?(x):(y) main() { int i=10,j=15,k; k=10*MIN(i,j); printf(“%d\n”,k); } A)10 B)15 C)100 D)150 【题9.5】在宏定义#define PI 3.14159中,用宏名PI代替一个。 A)常量B)单精度数C)双精度数D)字符串

【题9.6】以下程序的运行结果是。 #include #define FUDGE(y) 2.84+y #define PR(a) printf(“%d”,(int)(a)) #define PRINT1(a) PR(a); putchar(‘\n’) main() { int x=2; PRINT1(FUDGE(5)*x); } A)11 B)12 C)13 D)15 【题9.7】以下有关宏替换的叙述不正确的是。 A)宏替换不占用运行时间B)宏名无类型 C)宏替换只是字符替换D)宏名必须用大写字母表示 【题9.8】C语言的编译系统对宏命令的处理是。 A)在程序运行时进行的 B)在程序连接时进行的 C)和C程序中的其它语句同时进行编译的 D)在对源程序中其它成份正式编译之前进行的 【题9.9】若有宏定义如下: #define X 5 #define Y X+1 #define Z Y*X/2 则执行以下printf语句后,输出结果是。 int a; a=Y; printf(“%d\n”,Z); printf(“%d\n”,--a); A)7 B)12 C)12 D)7 6 6 5 5 【题9.10】若有以下宏定义如下: #define N 2 #define Y(n) ((N+1)*n) 则执行语句z=2*(N+Y(5));后的结果是。 A)语句有错误B)z=34 C)z=70 D)z无定值 【题9.11】若有宏定义:#define MOD(x,y) x%y 则执行以下语句后的输出为。 int z,a=15,b=100; z=MOD(b,a); printf(“%d\n”,z++);

在Ubuntu上编译android

在Ubuntu7.10上编译android 1 概述 上个星期看到android开放源代码的消息,虽然觉得Google的这个动作会对业界产生很大影响,但没有时间仔细看,只浏览了Project layout。今天上午一个网友在mail中说已经编译、运行过android。我趁着中午休息时间,在一个Ubuntu7.10的虚拟机上编译、运行了一下。 我在这个虚拟机上编译过openmoko、poky。相对于这两个使用OpenEmbedded的平台,android的编译要简单一些,快一些。我在编译openmoko和poky时,将所有下载包都保存在一个目录中,将编译目录的sources子目录指向这个目录。这样做,一方面即使以后有些链接失效,也还可以编起来(其实编译时都不需要连接外网);另一方面在重新编译时,不用重新下载,可以加快编译速度。即使这样,完全编译一次poky也要一个晚上。编译android时,下载用了1个小时,编译也只需要1个小时。 2 编译中的两个小问题 2.1 python和JDK Google网站对编译过程的介绍还是很清晰的。不过在介绍其它软件包时,都给出了apt-get命令,却单独给出了python和JDK的链接地址,容易对读者产生误导,以为要手工安装这两个软件。其实这两个软件也应该通过apt-get安装。特别是python,如果从源代码安装,可能因为依赖其它软件,导致一些组件编译失败,影响android的编译。而且python 2.6的源代码包没有提供make uninstall,卸载也比较麻烦。其实我们只需要一个apt-get命令,就可以安装所有依赖的软件。 2.2 "fatal: git 1.5.4 or later required" 在Ubuntu7.10上执行repo init时,会出现"fatal: git 1.5.4 or later required"的错误提示。在Ubuntu8.04上编译没有这个问题。下面的流程里会介绍怎样解决这个问题。 3 在Ubuntu7.10上的编译流程

c语言中预编译指令的应用

#if #ifdef和#ifndef的用法和区别 #if #ifdef和#ifndef用法 移位运算符的优先级高于条件运算符,重载是不能改变运算符优先级的,这点要注意,所以代码应当像下面这样调整,写宏的时候一定要注意优先级,尽量用括号来屏蔽运算符优先级。#define MAXIMUM(x,y) ((x)>(y)?(x):(y)) #define MINIMUM.... #include #define MAX #define MAXIMUM(x,y) x>y?x:y #define MINIMUM(x,y) x

Android源码编译

Android源码编译 开发工具:Ubuntu10.04 在Ubuntu下使用root用户登录,注意root一开始是锁定的,使用如下命令解锁:sudopasswd root 按回车铵,提示输入当前密码,在提示输入二次密码。输入完成切换用户使用root用户登录。 Android源码结构 Makefile (全局的Makefile) bionic (Bionic含义为仿生,这里面是一些基础的库的源代码) bootloader(引导加载器) build (build目录中的内容不是目标所用的代码,而是编译和配置所需要的脚本和工具) dalvik (JAVA虚拟机) development(程序开发所需要的模板和工具) external (目标机器使用的一些库) frameworks (应用程序的框架层) hardware (与硬件相关的库) kernel (Linux2.6的源代码) packages (Android的各种应用程序) prebuil (Android在各种平台下编译的预置脚本) recovery (与目标的恢复功能相关) system (Android的底层的一些库) Out (编译好的文件) 编译Android源码必需的安装的软件包 g++库文件有可能Ubuntu自带,使用g++ -v命令查找是否安装,如果没有自带请手动安装,使用如下命令,sudo apt-get-install g++-4.4. 注意:g++分很多版本,如果使用了最新版本4.6将没办法编译,建议安装4.4版本 Gcc库文件有可能Ubuntu自带,使用gcc–v命令查找是否安装,如果没有自带使用如下命令手动安装,sudo apt-get-install gcc-4.4. 注意:gcc分很多版本,如果使用了最新版本4.6将没办法编译,建议安装4.4版本 不过还有一些应该是linux系统自带的,如果缺少就按照提示install一下sudo apt-get install build-essential sudo apt-get install make sudo apt-get install libc6-dev sudo apt-get install patch sudo apt-get install texinfo sudo apt-get install libncurses-dev

android4.1编译

Android 4.1.4 编译 1、下载源码: 我是在ics版本的基础上通过repo sync更新,发现有了an droid 4_1_r1的分支,等待更新完,repobranch切换分支,然后.Build/envsetup.she然后lunchi选择full-eng最后make,过一会报错。提示: build/core/product_config.mk:193:***_nic.PRODUCTS.[[build/target/product/v box_x 86.mk]]: "frameworks/native/build/phone-xhdpi-1024-dalvik-heap.mk" does not exist. Stop.** Don't have a product spec for: 'full' ** Do you have the right repo manifest? Google baidu bing 了大半天终于在an droid的bug单中找到了这条bug,解答是源码不全。愁了半天,repo sync都是最新的,愁了半天,最后再ics的repo 中重新下了个android 4.1.4的分支。 repoinit-uhttps: 4.1.1_r4 repo sync 下载3个小时,终于下载完成,本来下载源码需要很长时间5?10个小 时,由于再ics的基础上下载,只需要把patch下载就行了(repo会自动完成)。兴奋啊,赶紧. Build/envsetup.sh lunch 1 full-eng

/bin/bash: prebuilts/gcc/linux-x86/arm/arm-linux-androideabi- 4.6/bin/arm-linux- androideabi-gcc: 无法执行二进制文件 /bin/bash: prebuilts/gcc/linux-x86/arm/arm-linux-androideabi- 4.6/bin/arm-linux- androideabi-gcc: 无法执行二进制文件 /bin/bash: prebuilts/gcc/linux-x86/arm/arm-linux-androideabi- 4.6/bin/arm-linux- androideabi-gcc: 无法执行二进制文件 先没管它,继续机制行 make clean make -j8 过了几分钟提示错误:hostStaticLib: libhost(out/host/linux- x86/obj/STATIC_LIBRARIES/libhost_intermediates/libhost.a) ERROR: prebuilts/tools/gcc-sdk/../../gcc/linux-x86/host/x86_64-linux-glibc 2.7- 4.6/bin/x86_64-linux-ar only run on 64-bit linux make: ***[out/host/linux-x86/obj/STATIC_LIBRARIES/libhost_intermediates/libhost.a] 错误 1 host C: emulator-target-i386 <= external/qemu/cpus.c host C: emulator-target-i386 <= external/qemu/arch_init.c host C: emulator-target-i386 <= external/qemu/os-posix.c host C:

android源代码下载和编译教程

Android源代码由两部分组成,其一是Android系统应用部分的代码,其次是Android 所使用的内核代码,如果针对Google Nexus S来开发ROM,就需要下载三星的内核代码Android 系统应用代码: https://https://www.wendangku.net/doc/042669215.html,/platform/manifest Android内核代码: https://https://www.wendangku.net/doc/042669215.html,/kernel/samsung.git 准备阶段:设置Linux编译环境(本人是Ubuntu 11.10 ,32位系统),一般你需要以下配置: Python 2.5 -- 2.7. GNU Make 3.81 -- 3.82,, JDK 6 (for Gingerbread or newer); JDK 5( for Froyo or older). Git 1.7 or newer. 1、安装一些必备的包。 Git是Linux Torvalds为了帮助管理Linux内核而开发的一个开放源码的分布式版本控制系统软件,它不同于SVN,CVS这样集中式的版本控制系统。在集中式版本控制系统中只有一个仓库(repository),许多个工作目录,而git这样的分布式控制系统中,每一个工作目录都包含一个完整仓库,它们支持离线工作,本地提交可以稍后提交到服务器上。分布式系统理论上也比集中式的单服务器系统更健壮,单服务器系统一旦服务器出现问题整个系统就不能运行了,分布式系统通常不会因为一两个节点而收到影响? 因为Android是由kernel,Dalvik,Bionic,prebuild,build等多个Git项目组成, 所以Android项目编写了一个名为repo的python的脚本来统一管理这些项目的仓库,使得Git的使用更加简单。 $ sudo apt-get install git-core gnupg flex bison gperf build-essential \ zip curl zlib1g-dev libc6-dev lib32ncurses5-dev ia32-libs \ x11proto-core-dev libx11-dev lib32readline5-dev lib32z-dev \ libgl1-mesa-dev g++-multilib mingw32 tofrodos python-markdown \ libxml2-utils xsltproc $ sudo apt-get install libx11-dev:i386 2、创建源代码目录 首先确保在当前用户的主目录下创建一个/bin目录(如果没有的话),然后把它加到PATH 环境变量中: $ mkdir ~/bin $ PATH=~/bin:$PATH 或者$export PATH=$PATH:~/bin 3、用curl下载repo脚本,并保存在~/bin/repo文件中: $ curl https://https://www.wendangku.net/doc/042669215.html,/dl/googlesource/git-repo/repo > ~/bin/repo 为repo加上执行权限 $ chmod a+x ~/bin/repo 4、初始化版本库 首先建立一个目录,用来存放下载下来的东西 $mkdir MyAndroid $cd MyAndroid 以后,执行如下命令 $ repo init -u https://https://www.wendangku.net/doc/042669215.html,/platform/manifest -b android-2.3.7_r1 我这里下载的是android2.3.7版本的,所用的参数是android-2.3.7_r1。由于最新的是android-4.0.3_r1,所以使用上面即可下载2.3.7的源代码 注意:如果要是把所有的版本都下载下来,那时间是需要很久很久的,需要耐心等待,但是如果仅仅是下载某一个版本的话,还是很快就可以了。 最后,如果看到repo initialized in /MyAnroid的提示,说明本地的版本库已经初始化成功了(期间需要你填写姓名和Gmail地址)。

c语言预处理命令之条件编译(ifdefelseendifif等)

C语言预处理命令之条件编译(#ifdef,#else,#endif,#if等) 预处理过程扫描源代码,对其进行初步的转换,产生新的源代码提供给编译器。可见预处理过程先于编译器对源代码进行处理。 在C语言中,并没有任何内在的机制来完成如下一些功能:在编译时包含其他源文件、定义宏、根据条件决定编译时是否包含某些代码。要完成这些工作,就需要使用预处理程序。尽管在目前绝大多数编译器都包含了预处理程序,但通常认为它们是独立于编译器的。预处理过程读入源代码,检查包含预处理指令的语句和宏定义,并对源代码进行响应的转换。预处理过程还会删除程序中的注释和多余的空白字符。 预处理指令是以#号开头的代码行。#号必须是该行除了任何空白字符外的第一个字符。#后是指令关键字,在关键字和#号之间允许存在任意个数的空白字符。整行语句构成了一条预处理指令,该指令将在编译器进行编译之前对源代码做某些转换。下面是部分预处理指令: 指令用途 #空指令,无任何效果 #include包含一个源代码文件 #define定义宏 #undef取消已定义的宏 #if如果给定条件为真,则编译下面代码 #ifdef如果宏已经定义,则编译下面代码 #ifndef如果宏没有定义,则编译下面代码 #elif如果前面的#if给定条件不为真,当前条件为真,则编译下面代码 #endif结束一个#if……#else条件编译块 #error停止编译并显示错误信息 一、文件包含 #include预处理指令的作用是在指令处展开被包含的文件。包含可以是多重的,也就是说一个被包含的文件中还可以包含其他文件。标准C编译器至少支持八重嵌套包含。

预处理过程不检查在转换单元中是否已经包含了某个文件并阻止对它的多次包含。这样就可以在多次包含同一个头文件时,通过给定编译时的条件来达到不同的效果。例如: #defineAAA #include"t.c" #undefAAA #include"t.c" 为了避免那些只能包含一次的头文件被多次包含,可以在头文件中用编译时条件来进行控制。例如: /*my.h*/ #ifndefMY_H #defineMY_H …… #endif 在程序中包含头文件有两种格式: #include #include"my.h" 第一种方法是用尖括号把头文件括起来。这种格式告诉预处理程序在编译器自带的或外部库的头文件中搜索被包含的头文件。第二种方法是用双引号把头文件括起来。这种格式告诉预处理程序在当前被编译的应用程序的源代码文件中搜索被包含的头文件,如果找不到,再搜索编译器自带的头文件。 采用两种不同包含格式的理由在于,编译器是安装在公共子目录下的,而被编译的应用程序是在它们自己的私有子目录下的。一个应用程序既包含编译器提供的公共头文件,也包含自定义的私有头文件。采用两种不同的包含格式使得编译器能够在很多头文件中区别出一组公共的头文件。

C中的预处理命令

C中的预处理命令是由ANSIC统一规定的,但它不是C语言的本身组成部分,不能直接对它们进行编译,因为编译程序无法识别它们。必须对程序进行通常的编译(包括词法和语法分析,代码生成,优化等)之前,先对程序中这些特殊的命令进行“预处理”,例如:如果程序中用#include命令包含一个文件“stdio.h”,则在预处理时,将stdio.h文件中的实际内容代替该命令。经过预处理后的程序就像没有使用预处理的程序一样干净了,然后再由编译程序对它进行编译处理,得到可供执行的目标代码。现在的编译系统都包括了预处理,编译和连接部分,在进行编译时一气呵成。我们要记住的是预处理命令不是C语言的一部分,它是在程序编译前由预处理程序完成的。 C提供的预处理功能主要有三种:宏定义,文件包含,条件编译。它们的命令都以“#”开头。 一,宏定义:用一个指定的标识符来代表一个字符串,它的一般形式为: #define 标识符字符串 #define PI 3.1415926 我们把标识符称为“宏名”,在预编译时将宏名替换成字符串的过程称为“宏展开”,而#define 是宏定义命令。 几个应该注意的问题: 1,是用宏名代替一个字符串,也就是做简单的置换,不做正确性检查,如把上面例子中的1写为小写字母l,预编译程序是不会报错的,只有在正式编译是才显示出来。 2,宏定义不是C语句,不必在行未加分号,如果加了分号则会连分号一起置换。 3,#define语句出现在程序中函数的外面,宏名的有效范围为定义命令之后到本源文件结束,通常#define命令写在文件开头,函数之前,作为文件的一部分,在此文件范围内有效。4,可以用#undef命令终止宏定义的作用域。如: #define PI 3.1415926 main(){ } #undef PI mysub(){ } 则在mysub中PI 不代表3.1415926。 5,在进行宏定义时,可以引用已定义的宏名,可以层层置换。 6,对程序中用双撇号括起来的字符串内的字符,即使与宏名相同,也不进行置换。 7,宏定义是专门用于预处理命令的一个专有名词,它与定义变量的含义不同,只做字符替换不做内存分配。 带参数的宏定义,不只进行简单的字符串替换,还进行参数替换。定义的一般形式为:#define 宏名(参数表)字符串 如:#define S(a,b) a*b,具体使用的时候是int area; area=(2,3); 对带参数的宏定义是这样展开置换的:在程序中如果有带参数的宏(如area=(2,3)),则按#define命令行中指定的字符串从左到右进行置换。如果串中包含宏中的形参(如a,b),则将程序语句中的相关参数(可以是常量,变量,或表达式)代替形参。如果宏定义中的字符串中的字符不是参数字符(如上*),则保留,这样就形成了置换的字符串。 带参数的宏与函数有许多相似之处,在调用函数时也是在函数名后的括号内写实参,也要求实参与形参的数目相等,但它们之间还有很大的不同,主要有: 1,函数调用时,先求出实参表达式的值,然后代入形参,而使用带参的宏只是进行简单的字符替换。

Ubuntu下编译Android源码全过程

Ubuntu下编译Android源码全过程(转) 源码, 编译, Ubuntu, Android 一、获取Android源代码 Git是LinuxTorvalds(Linux之父)为了帮助管理Linux内核开发而开发的一个开放源码的分布式版本控制软件,它不同于Subversion、CVS这样的集中式版本控制系统。在集中式版本控制系统中只有一个仓库(Repository),许多个工作目录(WorkingCopy),而在Git这样的分布式版本控制系统中(其他主要的分布式版本控制系统还有BitKeeper、Mercurial、GNUArch、Bazaar、Darcs、SVK、Monotone等),每一个工作目录都包含一个完整仓库,它们支持离线工作,本地提交可以稍后提交到服务器上。 因为Android是由Kernel、Dalvik、Bionic、Prebuilt、build等多个项目组成,如果我们分别使用Git来逐个获取显得很麻烦,所以Android项目编写了一个名为Repo的Python 的脚本来统一管理这些项目的仓库,使得项目的获取更加简单。 在Ubuntu 8.04上安装Git只需要设定正确的更新源,然后使用apt-get就可以了,apt-get 是一条Linux命令,主要用于自动从互联网的软件仓库中搜索、安装、升级、卸载软件或 操作系统。 apt-get命令一般需要root权限执行,所以一般跟着sudo命令。 sudo apt-get install git-core curl 这条命令会从互联网的软件仓库中安装git-core和curl。 其中curl是一个利用URL语法在命令行方式下工作的文件传输工具,它支持很多协议,包括FTP、FTPS、HTTP、HTTPS、TELENT等,我们需要安装它从网络上获取Repo脚本文件。 curl https://www.wendangku.net/doc/042669215.html,/repo >~/bin/repo 这句命令会下载repo脚本文件到当前主目录的/bin目录下,并保存在文件repo中。 最后我们需要给repo文件可执行权限

第9章 预处理命令

第9章预处理命令 宏定义不是C语句,所以不能在行尾加分号。如果加了分号则会连分号一起进行臵换。 可以用#undef命令终止宏定义的作用域。 对程序中用“”括起来的内容(即字符串内的字符),即使与宏名相同,也不进行臵换。宏定义只做字符替换,不分配内存空间。 宏名不是变量,不分配存储空间,也不能对其进行赋值。 在宏展开时,预处理程序仅对宏名作简单的字符串替换,不作任何检查。 在进行宏定义时,可以引用已定义的宏名 无参宏定义的一般格式: #define 标识符字符串 将这个标识符(名字)称为“宏名”,在用预编译时将宏名替换成字符串的过程称为“宏展开”。#define是宏定义命令。 带参宏定义的一般格式: #define 宏名(形参表)字符串 带参宏的调用和宏展开: 调用格式:宏名(实参表); 宏展开(又称为宏替换)的方法:用宏调用提供的实参直接臵换宏定义中相应的形参,非形参字符保持不变。 定义有参宏时,宏名与左圆括号之间不能留有空格。否则,C编译系统会将空格以后的所有字符均作为替代字符串,而将该宏视为无参宏。 有参宏的展开,只是将实参作为字符串,简单地臵换形参字符串,而不做任何语法检查。 为了避免出错,可以在所有形参外,甚至整个字符串外,均加上一对圆括号。 如: #define S(r) 3.14*(r)*(r) 则:area=S(a+b); 展开后为: area=3.14*(a+b)*(a+b); 调用有参函数时,是先求出实参的值,然后再复制一份给形参。而展开有参宏时,只是将实参简单地臵换形参。函数调用是在程序运行时处理的,为形参分配临时的内存单元;而宏展开则是在编译前进行的,在展开时不分配内存单元,不进行值的传递,也没有“返回值”的概念。调用函数只可得到一个返回值,而用宏可以设法得到几个结果。 在有参函数中,形参都是有类型的,所以要求实参的类型与其一致;而在有参宏中,形参和宏名都没有类型,只是一个简单的符号代表,因此,宏定义时,字符串可以是任何类型的数据。 使用宏次数多时,宏展开后源程序变长,因为每展开一次都是程序增长,而函数调用不会使源程序变长。 宏替换不占用运行时间,只占编译时间。而函数调用则占用运行时间(分配单元、保留现场、值传递、返回)。 在程序中如果有带实参的宏,则按#define命令行中指定的字符串从左到右进行臵换。如果字符串中包含宏中的形参,则将程序语句中相应的实参(可以是常量、变量或表达式)代替形参。如果宏定义中的字符串中的字符不是参数字符,则保留。

Android ninja 编译启动过程分析

Android ninja编译启动过程分析 ---make是如何转换到到ninja编译的 1.首先你的得对make的工作机制有个大概的了解: 运行的命令在要编译的目录下运行make,或者make target_name a.分析处理保存阶段(没有实际编译动作):它首先对当前目录下的Makefile文件的做一次扫描,语法分析,还有处理,主要是变量的保存,目标依赖列表生成,目标下的action列表的生成,然后记住 b.然后按记住的目标执行action列表动作(有实际编译动作). 编译启动的入口方式还是运行make: 2开始make-jxxx方式进入.....(xxx是本机cpu的数量) make开始做进行第一次扫描.... 目前USE_NINJA还是没有定义,估计以后很久很久才能启用的了! BUILDING_WITH_NINJA开始也是没定义的 看make扫描入口文件: Makefile: include build/core/main.mk 在build/core/main.mk: 在ninia之前都有include help.mk和config.mk 97include$(BUILD_SYSTEM)/help.mk 98 99#Set up various standard variables based on configuration 100#and host information. 101include$(BUILD_SYSTEM)/config.mk 说明make help//显示make帮助make config//当前显示配置 103relaunch_with_ninja:= 104ifneq($(USE_NINJA),false) 105ifndef BUILDING_WITH_NINJA<==第二次扫描不会到这里了 106relaunch_with_ninja:=true 107endif 108endif 116ifeq($(relaunch_with_ninja),true)<===第一次扫描入这里了 117#Mark this is a ninja build. 118$(shell mkdir-p$(OUT_DIR)&&touch$(OUT_DIR)/ninja_build) 119include build/core/ninja.mk//---进入ninja.mk 第一次扫描到此为止就结束掉了,因为在当前ifeq else endif后面没有代码了 120else#///!relaunch_with_ninja<===第二次扫描入这里了

变量的存储类型与预编译命令

实验十二变量的存储类型与与编译命令(上机练习)1、输入下面的程序并运行,分析为什么会得到此结果。 #include #define PI 3.1415926 #define S(r) PI*r*r float S1(int r) { return(PI*r*r); } void main() { printf("%f\n",S(2)); printf("%f\n",S(1+1)); printf("%f\n",S1(2)); printf("%f\n",S(1+1)); } 具体要求: ①分析程序的运行结果。 ②认真比较函数和宏定义的不同之处。 2.以下程序的输出结果是()。 A.15 B.100 C.10 D.150 #include #define MIN(x,y) (x)<(y)?(x):(y) main() { int i,j,k;i=10;j=15;k=10*MIN(i,j); printf("%d\n",k);} 3.以下程序中的for循环执行的次数是()。 A.5 B.6 C.8 D.9 #define N 2 #define M N+1 #define NUM (M+1)*M/2 main() { int i;for(i=1;i<=NUM;i++); printf(“%d\n”,i);} 4.以下程序的输出结果是()。

A.11 B.12 C.13 D.15 #include “stdio.h” #define FUDGF(y) 2.84+y #define PR(a) printf(“%d”,(int)(a)) #define PRINT1(a) PR(a);putchar(‘\n’) main() { int x=2;PRINT1(FUDGF(5)*x); } 5.以下叙述正确的是()。 A.用#include包含的头文件的后缀不可以是“.a” B.若一些源程序中包含某个头文件;当该头文件有错时,只需对该头文件进行修改,包含此头文件所有源程序不必重新进行编译 C.宏命令可以看做是一行C语句 D.C编译中的预处理是在编译之前进行的。 6.以下有关宏替换的叙述不正确的是()。 A.宏替换不占用运行时间 B.宏名无类型 C.宏替换只是字符替换 D.宏名必须用大写字母表示7.宏定义#define G 9.8中的宏名G代替() A.一个单精度实数 B.一个双精度实数C.一个字符串 D.不确定类型的数8.若有宏定义: #define MOD(x,y) x%y 则执行以下程序段的输出为() int z,a=15,b=100; z=MOD(b,a); printf(“%d\n”,z++); A.11 B.10 C.6 D.宏定义不合法 9.以下程序的运行结果是()。 #define DOUBLE(r) r*r main( ) { int y1=1,y2=2,t; t=DOUBLE(y1+y2); printf(“%d\n”,t);} A.11 B.10 C.5 D.9 10.下列程序段的输出结果是()

相关文档