这个xcode怎么写c语言,用c语言,刚学,不要写一些不知道的语句

8,023被浏览1,230,199分享邀请回答28137 条评论分享收藏感谢收起48945 条评论分享收藏感谢收起主题信息(必填)
主题描述(最多限制在50个字符)
申请人信息(必填)
申请信息已提交审核,请注意查收邮件,我们会尽快给您反馈。
如有疑问,请联系
CSDN &《程序员》研发主编,投稿&纠错等事宜请致邮
你只管努力,剩下的交给时光!
如今的编程是一场程序员和上帝的竞赛,程序员要开发出更大更好、傻瓜都会用到软件。而上帝在努力创造出更大更傻的傻瓜。目前为止,上帝是赢的。个人网站:www.xttblog.com。个人QQ群:、
个人大数据技术博客:http://www.iteblog.com
导语:你的C语言知识可能该更新了。每个人在学习C语言之后,知识往往停滞不前,从开始学习它的那年起积攒起不同观点。本文将告诉你现代C语言该怎么写。C语言的首要原则是——能不写C语言就不写。如果一定要写,请遵守现代规则。C语言诞生于20世纪70年代初。人们在其发展的各个阶段都在“学习C语言”,但在学习C语言之后,知识往往停滞不前,从开始学习它的那年起积攒起不同观点。很重要的一点是,用C语言开发,不要再继续认为“那是我在八零或者九零年代学习的东西”。本文首先假定处于符合现代设计标准的平台上,并且不存在需要兼容过多遗留约束。我们当然不该仅因为某些公司拒绝更新其二十年前的老系统就完全遵守陈旧的标准。准备C99标准(C99和C11分别是指1999年和2011年诞生的C语言标准,显然C11标准比较新)。clang(一种C语言编译器),默认情况
clang使用C11的一种扩展版本(GNU C11模式),所以不需要多余的配置就可以适应现代特性。
如果你想使用标准的C11,需要指定-std=c11;如果你想使用标准C99,则指定-std=c99。
与gcc相比,clang编译文件速度更快。
gcc需要指定-std=c99或-std=c11
gcc构建源文件的速度一般慢于clang,但某些时候却能保证编码速度更快。性能比较和回归测试也非常重要。
gcc-5默认使GNU C11模型(与clang相同),但如果你确切地需要C11或C99,仍应指定-std=c11或-std=c99。
优化-O2,-O3
通常想使用-O2,但有时也使用-O3。在两个级别下(通过编译器)分别进行测试并且保持最佳性能。
-Os如果你关注缓存效率(本该如此),这个选项能帮上你。
警告-wall -Wextra -pedantic
最新版本的编译器支持-Wpedantic,但为了向后兼容其也接受古老的-pedantic。
在测试过程中,应该在所有的平台上都添加-Werror和-Wshadow。
因为不同的平台、编译器和库会发出不同警告,通过使用-Werror可更有针对性地部署生产资源。你或许并不想仅因为某个平台上从未见过的GCC版本在新的运行方式下时报错就毁掉用户的全部构建。
额外选择包括-Wstrict-overflow -fno-strict-aliasing。
要么指定-fno-strict-aliasing,要么就确保只以对象创建时的类型对其进行访问。因为许多C语言代码拥有跨类型的别名,当不能控制整个底层源代码树时,使用-fno-strict-aliasing是个不错的选择。
到目前为止,clang有时会对一些有效语法发出警告,所以需要添加-Wno-
missing-field-initializers。GCC在4.7.0版本后修正了这些不必要的警告。
构建编译单元
构建C程序项目的最常见方式是将每个C源文件分解成目标文件,最后将所有目标文件链接到一起。这个过程在增量开发中表现很好,但从性能和优化角度看,并非最优。因为在这种方式下编译器不能检测出跨文件的潜在优化之处。
LTO——链接时优化
LTO通过使用中间表示方式对目标文件进行处理,因此解决了“跨编译单元源文件分析和优化问题”,所以source-aware优化可在链接时跨编译单元实现。
LTO明显减缓了链接过程,但make-j会有所帮助。
clang LTO ()
gcc LTO ()
到2016年为止,clang和gcc都可通过在目标文件编译和最后库/程序链接时,向命令行选项中添加-flto来支持LTO。
不过LTO仍需监管。有时,程序中一些代码没有被直接使用,而是被附加的库使用了。因为LTO会在全局性链接时检测出没有使用或者不可访问的代码,也可能将其删除,所以这些代码将不会包含到最后的链接结果中。
架构-march = native
允许编译器使用CPU完整的特性集。
再一次,性能测试和回归测试都非常重要(之后在多个编译器以及多个版本中对结果进行比较)以确保任何启用的优化都不会产生副作用。
如果你使用not-your-build-machine特性,-msse2和-msse4.2可能起到作用。编写代码类型如果你将char、int、short、long或unsigned类型写入新代码中,就把错了。对于现代程序,应该先输入#include,之后再使用标准类型。更多细节,参见“stdint.h规范”()。常见的标准类型有:
int8_t,int16_t,int32_t,int64_t——符号数
uint8_t,uint16_t,uint32_t,uint64_t——无符号数
float——标准32位浮点数
double——标准64位浮点数
到底用不用int一些读者说他们真的非常喜爱int类型,但我们不得不把它从他们僵硬的手指中撬出来。在技术层面我想指出的是,如果在你的控制下类型的位数发生了改变,这时还希望程序正确运行是不可能的。当然你也可以找出inttypes.h文件中的RATIONALE()来看看为何使用长度不固定的类型是不安全的。如果你够聪明到可以在平台上对整个开发过程中的int类型统一定为16或32位,并且也在每个使用了它的地方测试所有16位和32位边界情况,那就可以随意使用int类型了。对于我们中不能在编程时将多层决策树规范层次清晰地记住的人,可以使用固定位数的类型,这样在编程时就可以不必忧心那些麻烦的概念和测试开销。或者,规范中更加简洁地指出:“ISO C语言标准中整数扩展规则将会造成意外改变。”所以当使用int时,祝你好运!使用char的例外情况到2016年,char类型唯一的用处就是旧API中需要(比如strncat,printf中)。或者初始化一个只读字符串(比如const char * hello = “hello”;),这是因为C语言字符串类型字面值(”hello”)是char []。同样,在C11中,我们也有原生的unicode支持,并且UTF-8的字符串类型仍然是char [],甚至是像const char * abcgrr =u8”abc “; 这样的多字节序列也一样。使用int、long等的例外情况如果你正在使用带有原生返回类型或原生参数的函数,那么请使用函数原型或者API规范中描述的类型。符号无论何时都不应该将unsigned这个词写进代码。丑陋的C语言规定往往会因多字类型而损坏了程序可读性和使用性,而现在我们编写的代码不再需要遵守那些规定了。当能够输入uint64_t时又有谁想用unsigned long long int呢?中的类型更加明确,含义更加确切,也能够更好地表达意义,并且具有更好的排版,提高了程序的使用性和可读性。指针作为整型但你可能会说“当遇到麻烦的指针数学时,我不得不将指针转换为long!”。这是错误的。正确的指针数学类型是使用中定义的unitptr_t,当然同样非常有用的ptrdiff_t也定义在stddef.h中。而并非:long diff = (long)ptrOld - (long)ptrN你可以使用:ptrdiff_t diff = (uintptr_t)ptrOld - (uintptr_t)ptrN也可以用:printf("%p is unaligned by %" PRIuPTR " bytes.\n", (void *)p, ((uintptr_t)somePtr & (sizeof(void *) - 1)));系统依赖的类型你继续争辩:“在32位平台上我想要32位字长,而在64位平台上我要64位字长。”这时思路将故意引入使用平台依赖的两种不同字长,会对编程造成困难。但是如果跳过这个问题,你仍然不想使用依赖系统的类型。在此情况下,该使用intptr_t——当前平台定义为字长的整型。在32位平台上,intptr_t = int32_t;64位平台上,intptr_t = int64_t。intptr_t也有uintptr_t的形式。对管理指针的偏移来说,我们还有ptrdiff_t,该类型适于存储指针减少的数值。最大值容器你需要一种能承载系统中所有可能的整数的类型吗?在这种情况下,人们倾向于使用已知的最大类型,比如将较小的无符号类型转换成uint64_t。从实际技术上讲,有一种更正确的方式来保证可以装载任何值。对于所有整数来说,最安全的容器是intmax_t(或者uintmax_t)。可以无精度损失地将任何符号整数(或无符号整数)赋值或者转换为这种形式。其他类型被广泛使用的系统依赖类型是stdded.h中提供的size_t。它在程序中非常基础,因为它是“能够容纳最大的数组索引的整数”,这也意味着它能容纳最大的内存偏移。在实际应用中,size_t是运算符sizeof的返回类型。size_t实际上与uintptr_t一样都是定义在所有现代平台上的。所以在32位的平台上,size_t = uint32_t,而在64位平台上,size_t = uint64_t。还有一个带有符号的size_t,也就是ssize_t,它用来表示在库函数出现错误时返回-1(注意,sszie_t是POSIX,不适用于Windows接口)。所以,难道你不该在自己的函数参数中使用size_t来适应任何字长的系统么?从技术上讲,它是sizeof的返回值,所以任何接受多字节数值的函数都允许表示成size_t类型。其他用途包括:size_t类型可作为malloc的参数,并且是read()和write()的返回类型(除了Windows平台上ssize_t不存在,其返回值是int类型)。输出类型你不应在输出时进行类型转换,而是永远使用inttypes.h中定义的合适的类型说明符。包括但不限于以下情况:
size_t——%zu
ssize_t——%zd
ptrdiff_t——%td
原始指针值%p(现代编译器中输出16进制数; 0 首先将指针转换为(void *))
int64_t——”%” PRId64
uint64_t——”%” PRIu64(64位类型应该只能使0 用PRI[udixXo]64风格的宏)
intptr_t——”%” PRIdPTR
uintptr_t——”%” PRIuPTR
intmax_t——”%” PRIdMAX
uintmax_t——”%” PRIuMAX
关于PRI* 格式化说明符需要注意:它们都是宏和宏在特定的平台基础上为了合适的输出而做的扩展。这意味着你不能这样:printf("Local number: %PRIdPTR\n\n", someIntPtr);并且因为它们是宏,应该:printf("Local number: %" PRIdPTR "\n\n", someIntPtr);注意应将%放进格式化字符串内,但类型指示符在格式化字符串外部,这是因为所有相邻的字符串都被预处理器连接成为最后的结合字符串。C99允许在任何地方进行变量声明所以,千万不要这样做:void test(uint8_t input) {
if (input & 3) {
}而是这样:void test(uint8_t input) {
if (input & 3) {
uint32_t b =
}警告:如果存在紧密的循环,请测试初始值的配置。有时分散的声明会造成意外减速。对于没有选择最快路径的代码(事情往往这样),最好还是尽可能清晰。而且,与初始化一起定义类型会极大提升可读性。C99允许在 for 循环中声明内联计数器所以不要这样:uint32_t i;
for (i = 0; i & 10; i++)而应该:for (uint32_t i = 0; i & 10; i++)一个例外:如果你需要在循环结束后仍保持计数器的值,那当然不要在循环域内声明计数器。现代编译器支持 #pragma once所以不要:#ifndef PROJECT_HEADERNAME
#define PROJECT_HEADERNAME
#endif /* PROJECT_HEADERNAME */而应该:#pragma once#pragma once告诉编译器只包含头文件一次,且不再需要那三行头部约束了。所有编译器和平台都支持并且推荐这样的编译方式,而不建议使用手动编写头部约束。更多细节,参见pragma once中编译器支持的列表()。C语言允许对自动分配的数组进行静态初始化所以,不要:uint32_t numbers[64];
memset(numbers, 0, sizeof(numbers));而应该:uint32_t numbers[64] = {0};C语言允许对自动分配的结构体进行静态初始化不要:struct thing {
struct thing localT
void initThing(void) {
memset(&localThing, 0, sizeof(localThing));
}而应该:struct thing {
struct thing localThing = {0};重要提示:如果结构体存在填充,{0}方法不会将额外的字节归零。例如结构体struct thing在counter(64位平台上)后需要填充4字节,并且结构体以字长度进行增量填充。如果需要将包含没有使用的填充在内的整个结构体置0,即使可寻址内容只有8+4=12字节,也需要使用memset(&localThing, 0, sizeof(localThing)) ,并且其中sizeof(localThing) == 16 字节。如果需要重新初始化已存在并且完成了分配的结构体,那么就为后面的任务声明一个全0的结构体:struct thing {
static const struct thing localThingNull = {0};
struct thing localThing = {.counter = 3};
localThing = localThingN如果你足够幸运是在C99(或者更新)的开发环境中,就可以使用复合文字而不是全0结构体,参见The New C: Compound Literals()。复合文字允许编译器自动创建临时匿名结构体,并将其值拷贝到目标中:localThing = (struct thing){0};C99添加可变长数组(C11可选)因此不要这样:uintmax_t arrayLength = strtoumax(argv[1], NULL, 10);
void *array[];
array = malloc(sizeof(*array) * arrayLength);
而该:uintmax_t arrayLength = strtoumax(argv[1], NULL, 10);
void *array[arrayLength];
/* no need to free array */重要警告:通常在栈区分配空间时,变长数组和普通数组一样。如果不想静态地创建一个含300万个元素的普通数组,那就不要试图在运行时使用这种语法来创建如此巨大的数组。这可不是灵活的Python、Ruby中自动增长的列表。如果运行时指定了一个数组的长度,而这个长度对于栈区而言过大的话,程序将会出现可怕的事情(崩溃、安全问题)。对于简单的,用途单一的情况,变长数组非常方便,但它不能支撑大规模软件开发。如果你需要3个元素的数组,而有时又需要300万个,那么千万不要使用变长数组。了解变长数组的语法的确不错,因为没准你就会遇到(或者想来一次快速测试)。但有可能因为忘记边界检查,或忘记了目标平台上没有足够的栈空间而使程序彻底崩溃,这是非常危险的反模式语法。注意:必须确定数长度是合理的值。(比如小于几KB,有时平台上的栈最大空间为4KB)。你不能在栈中分配巨大的数组(数百万条项目),但如果数组长度是有限的,使用C99的变长数组功能比通过malloc手动请求堆内存要简单得多。再次注意:如果没有对用户的输入进行检查,那么用户就能够通过分配一个巨大的变长数组轻松地杀死程序。一些人指出变长数组与模式相抵触,但是如果严格检查边界,在某些情况下,或许会表现得更好。C99允许注释非重叠的指针参数参看限制关键字 (,通常是 _restrict)参数类型如果函数能接受任意输入数据和任意长度的程序,那就不要限制参数的类型。所以,不要这样:void processAddBytesOverflow(uint8_t *bytes, uint32_t len) {
for (uint32_t i = 0; i & len; i++) {
bytes[0] += bytes[i];
}而应该:void processAddBytesOverflow(void *input, uint32_t len) {
uint8_t *bytes =
for (uint32_t i = 0; i & i++) {
bytes[0] += bytes[i];
}函数的输入类型只是描述了代码的接口,而不是带有参数的代码在做什么。上述代码接口意思是“接受一个字节数组和一个长度”,所以不并想限定函数调用者只能使用uint_8字节流。也许用户甚至想将一个老式的char*值或者其他什么意想不到的东西传递给你的函数。通过声明输入类型为void*然后重新指定或转换成为实际想在函数中使用的类型,这样就将用户从费力思考你自己的函数库文件的内部抽象中拯救出来。一些读者指出这个例子中的对齐问题,但我们访问的是输入的单字节元素,所以一切都没问题。如果不是这样的话,我们就是在将输入转换为更大的类型,这时候就需要注意对齐问题了。对于处理跨平台对齐的问题的不同写操作,参看Unaligned Memory Access部分章节(,记住:这页概述细节不是关于跨体系结构的C,所以扩展的知识和经验完全适用于任何示例。)返回参数类型C99给我们了将true定义为1,false定义为0的的权利。对于成功或失败的返回值,函数应该返回true或false,而不是手动指定1或0的int32_t返回类型(或者更糟糕1和-1;又或者0代表成功,1代表失败?或0带代表成功,-1代表失败)。如果函数将输入参数类型的范围变得更大的操作无效,那么在任何参数可能无效的地方,所有API都应强制使用双指针作为参数,而不应返回改变的指针。对于大规模应用,那样“对于某些调用,返回值使得输入无效”的程序太容易出错。所以,不要这样:void *growthOptional(void *grow, size_t currentLen, size_t newLen) {
if (newLen & currentLen) {
void *newGrow = realloc(grow, newLen);
if (newGrow) {
grow = newG
free(grow);
grow = NULL;
}而应该这样:/* Return value:
- 'true' if newLen & currentLen and attempted to grow
- 'true' does not signify success here, the success is still in '*_grow'
- 'false' if newLen &= currentLen */
bool growthOptional(void **_grow, size_t currentLen, size_t newLen) {
void *grow = *_
if (newLen & currentLen) {
void *newGrow = realloc(grow, newLen);
if (newGrow) {
/* resize success */
*_grow = newG
return true;
/* resize failure */
free(grow);
*_grow = NULL;
/* for this function,
* 'true' doesn't mean success, it means 'attempted grow' */
}如果这样的话就更好了:typedef enum growthResult {
GROWTH_RESULT_SUCCESS = 1,
GROWTH_RESULT_FAILURE_GROW_NOT_NECESSARY,
GROWTH_RESULT_FAILURE_ALLOCATION_FAILED
growthResult growthOptional(void **_grow, size_t currentLen, size_t newLen) {
void *grow = *_
if (newLen & currentLen) {
void *newGrow = realloc(grow, newLen);
if (newGrow) {
*_grow = newG
return GROWTH_RESULT_SUCCESS;
return GROWTH_RESULT_FAILURE_ALLOCATION_FAILED;
return GROWTH_RESULT_FAILURE_GROW_NOT_NECESSARY;
}格式化编码风格非常重要,但同时也没任何价值。如果项目有50页编码风格指南,没人会帮你。但如果你的代码没有可读性,也没人会帮你。解决方案就是永远使用自动的编码格式化。2016年,唯一可用的C格式化程序是clang-format。它拥有最好的默认C语言格式并且仍在持续改进。这是我运行clang-format的脚本:#!/usr/bin/env bash
clang-format -style="{BasedOnStyle:llvm,IndentWidth:4,AllowShortFunctionsOnASingleLine: None, KeepEmptyLinesAtTheStartOfBlocks: false}" "$@"然后调用(假设你称之为cleanup-format):@foo:o/repos/badcode% cleanup-format -i *.{,,,,,}选项-i通过覆盖已有的文件进行格式化,而不是写入新文件或者创建备份文件。如果有很多文件,可以采取并行方式递归处理整个源文件树。#!/usr/bin/env bash
# note: clang-tidy only accepts one file at a time, but we can run it
parallel against disjoint collections at once.
find . \( -name \*.c -or -name \*.cpp -or -name \*.cc \) |xargs -n1 -P4 cleanup-tidy
# clang-format accepts multiple files during one run, but let's limit it to 12
# here so we (hopefully) avoid excessive memory usage.
find . \( -name \*.c -or -name \*.cpp -or -name \*.cc -or -name \*.h \) |xargs -n12 -P4 cleanup-format -i如今新cleanup-tidy脚本出现了,其内容是:#!/usr/bin/env bash
clang-tidy \
-fix-errors \
-header-filter=.* \
--checks=readability-braces-around-statements,misc-macro-parentheses \
readability-braces-around-statements——要求所有if/while/for的申明语句全部包含在大括号内。C语言允许在循环和条件语句后面的单条语句的“大括号可选”存在历史原因。但在编写现代代码时不使用大括号来包含循环和条件将是不可原谅的。也许你会说“但是编译器承认它”并且这样不会影响代码的可读性、可维护性、可理解性和适用性。但你不是为了取悦编译器而编程,编程是为了取悦未来数年后不能了解你当时思维的人。
misc-macro-parentheses——自动添加宏中使用的所有参数的父类。
clang-tidy运行时非常棒,但却会因为某些复杂的代码卡住。clang-tidy不进行格式化,所以需要在排列整齐大括号和宏之后再运行clang-format。其他想法永远不使用malloc,而应该用calloc,当得到为0的内存时将不会有性能损失。如果你不喜欢函数原型calloc(object count, size per object),可以用#define mycalloc(N) calloc(1, N) 将其封装起来。能不用memset就不用当能静态初始化结构体或数组为0时,不要用memset(ptr, 0, len)。不过,如果要对包括填充字节在内的整个结构体进行置0时,memset()是你唯一的选择。写在最后对于编写大规模代码来说,想要不出现任何错误是不可能的。就算是我们不必担心那些像RAM中比特位随机翻转的问题或者设备以未知的几率出现错误的可能性,也会有多种多样的操作系统、运行状态、库文件以及硬件平台的问题需要担心。所以我们能做的最好的事情就是——编写简单又易于理解的代码。原作者在文章结尾列出了对本文提出意见和建议的读者,以及深入了解这些技术细节的在线文档,受篇幅所限,译文不再赘述。
文/Matt Stancliff
感谢Matt Stancliff授权《》翻译,原文链接。
本文未经允许不得转载,订阅2016年程序员请点击 。[原创]一些c语言的笔记,个人学习的时候写的,算是备忘录
& & & & & & & & & & & & & & & &#& 目录[TOC]&!--& TOC& --&-& [目录](#目录)-& [c语言知识点](#c语言知识点)& & & & -& [0.& 预处理](#0-预处理)& & & & -& [1.& 数据](#1-数据)& & & & -& [2.& 输入和输出](#2-输入和输出)& & & & -& [3.& 运算符和表达式](#3-运算符和表达式)& & & & -& [4.& 一维数组](#4-一维数组)& & & & -& [5.& 程序三大结构](#5-程序三大结构)& & & & -& [6.& 二维数组](#6-二维数组)& & & & -& [7.& 函数](#7-函数)& & & & -& [8.& 作用域](#8-作用域)& & & & -& [9.& 生存周期](#9-生存周期)& & & & -& [10.& 预处理](#10-预处理)& & & & -& [11.& 一级指针](#11-一级指针)& & & & -& [12.& 结构体struct](#12-结构体struct)& & & & -& [13.& 联合体union](#13-联合体union)& & & & -& [14.& 枚举enum](#14-枚举enum)& & & & -& [15.& 堆空间](#15-堆空间)& & & & -& [16.& 程序的内存空间布局](#16-程序的内存空间布局)& & & & -& [17.& 高级指针](#17-高级指针)& & & & -& [18.& 文件操作](#18-文件操作)& & & & -& [19.& 杂项](#19-杂项)& & & & -& [20.& 控制台编程](#20-控制台编程)&!--& /TOC& --&#& c语言知识点C语言课程主线& :& ##& 0.& 预处理& -& 1.预处理指令 & & & &-& 1.'#'开头的指令都被称为预处理指令& & & & -& 2.预处理的作用& & & & -& 3.查看预处理后的结果&
& & & &-& 4.#include& &&& & #include& &&##& 1.& 数据& -& 1.常量&
& & & &-& 1.字面量&
& & & & & & & &-& 1.字面量的类型& & -& 2.宏&
& & & &-& 1.宏的定义&
& & & &-& 2.宏的使用&
& & & &-& 3.宏的缺陷& -& 2.变量&
& & & &-& 1.变量类型&
& & & & & & & &-& 1.基本数据类型&
& & & & & & & &-& 2.修饰类型& static&
& & & & & & & & & & & &-& 寄存器变量& & & &
& & & & & & & &-& register& int& nN& & //正确& & & &
& & & & & & & &-& register& char& szStr[5];& //错误;超出寄存器的大小&
& & & &-& 2.变量的定义 & & & & & & & &-& 1.没有定义变量就使用时,将产生无法识别的标识符的错误.&
& & & &-& 3.变量的初始化&
& & & &-& 4.变量的赋值&
& & & & & & & &-& 1.赋值时'='两边的变量类型不匹配时将会产生错误.&
& & & &-& 5.类型转换&
& & & & & & & &-& 1.隐式转换 & & & & & & & && ```& c & & & & & & & &char-&short-&int-&long-&float-&double & & & & & & & &进行赋运算的时候,会将右值类型自动转换为左值,有可能会丢失数据。 & & & & & & & &例: & & & & & & & &int& i& =& 10; & & & & & & & &float& c& =& 2.5; & & & & & & & &i& =& i/c; & & & & & & & &注:& i/c& =& 4.000& & & & & i& 先自动转成float进行计算,结果再转换成=左侧的类型。最终i=4;&
& & & & & & & &``` & & & & & & & && -& 2.显示转换(强制转换) & & & & & & & && ```& c & & & & & & & && 强制类型转换 & & & & & & & && 通过使用转换可以将一个& 表达式强制转换成某一种类型,是一元运算符。 & & & & & & & & & & & &例: & & & & & & & & & & & &float& & b& =& 13.44; & & & & & & & & & & & &int& & a& =& (int)b; & & & & & & & &//将float类型强制转换成int型 & & & & & & & && ```##& 2.& 输入和输出& -& 2.1& printf格式化输出函数&
& & & &-& 2.1.1& printf的格式化输出控制符 & & & &``` & & & &%d& & & & 按十进制整型数据的实际长度输出 & & & &%md& & & m指定的输出字段的宽度,如果数据的位数小于m,则左端补空格,大于m,则按照实际位数输出(右对齐) & & & &%-md& 如果数据的位数小于m位,右端补空格,若大于m,则按实际位数输出(左对齐) & & & &%ld:输出长整型数据 & & & &%o:以八进制的形式输出整数 & & & &%x:以十六进制数形式输出整数 & & & &%u:用来输出无符号型数据 & & & &%c:输出char类型& ascii & & & &%s:字符串 & & & &%ms:输出的字符串占m列,如果字符串本身长度大于m,则全部输出,若小则左补空格 & & & &%-ms:若串长小于m,则在m列范围内,字符串向左靠,右补空格 & & & &%f:不指定字段宽度,由系统自动指定,使整数部分全部输出,并输出六位小数。在输出的数字中并非全部数据都是有效数字。单精度实数的有效位数一般为七位。 & & & &%m.nf:指定输出的数据共占列,其中有n位小数。如果数值长度小于m,则左端补空格。 & & & &%-m.nf:右端补空格 & & & &%p:打印输出一个地址 & & & &printf(&%*.*l&,& m,& n,& l); & & & & & & & &``` & & & &-& 2.1.2& printf的参数列表& -& 2.2& scanf格式化输入函数&
& & & &```& c & & & && & & & scanf、scanf_s&
& & & && & & & char& szCh[]& =& &hello&;& & & & & & & & scanf_s(&%s&,& szCh,& 6);& & & & & & & & scanf_s(&%d&,&a)& & & & & & & & scanf_S(&%c&,&c,& 1);& & & & & & & & char& str[]& ={&hello&};& & & & & & & & scanf_s(&%s&,&str,& 8); & & & &``` & & & &&
& & & &-& 2.2.1& scanf的格式化输入控制符&
& & & &-& 2.2.2& scanf的参数列表 & & & &&
& & & & & & & &&
& & & &备注:scanf_s函数在接收字符或字符串时需要加入长度,字符为1,字符串自定义长度。&
& & & &-& 2.2.3& 清空输入缓冲区 & & & & & & & &-& 2.2.3.1& scanf(&%*[^\n]&);scanf(&%*c&);##& 3.& 运算符和表达式& -& 3.1& 运算符种类&
& & & &运算符:http://tool.oschina.net/commons?type=6#cpp_&
& & & &-& 3.1.1& 算数运算符&
& & & &-& 3.1.2& 赋值运算符&
& & & &-& 3.1.3& 位运算符 & & & &&
& & & &-& && 按位与& 都是1为1,否则为0 & & & & & & & &-& |& 按位或& 有1为1,都是0为0 & & & & & & & &-& ^& 按位异或& & a^b& 如果a、b两个操作数的相应位同号,则结果为0,异号为1& &
& & & & & & & & & & & & & & & &&
& & & &-& x&&2 x右移2位,右部移出部分舍弃,左端高位根据符号位补0或者1,无符号或正数补0,负数补1。 & & & & & & & & & & & & & & & &-& x&&2& &  x左移2位,左端高位移出部分舍弃,右端低位补0&
& & & &-& 3.1.4& 条件运算符& &
& & & &-& 3.1.5& 逗号运算符&
& & & &-& 3.1.6& sizeof运算符& -& 3.2& 运算符优先级和结合性& &
& & & &括号优先级最高,逗号优先级最低 & & & & & & & &***& 注意:&&&&与&||&为短路运算符,&&当左值为假时,不在管右边;||当左值为真时,不在计算右边的值& *** & & & & & & & &c语言运算符优先级 ![c语言运算符优先级](/img/cyxj.png)& -& 3.3& 表达式的种类&
& & & &-& 3.3.1& 赋值表达式& &
& & & &-& 3.3.2& 算术表达式& &
& & & &-& 3.3.3& 关系表达式& &
& & & &-& 3.3.4& 逻辑表达式& &
& & & &-& 3.3.5& 函数表达式& & -& 3.4& 表达式的值&
& & & &-& 3.4.1& 表达式的求值过程.& -& 3.5& 复合表达式&
& & & &-& 3.5.1& 复合表达式的识别&
& & & &-& 3.5.1& 复合表达式中的子表达式求值顺序##& 4.& 一维数组& -& 4.1& 一维数组的定义 & & & &-& 数据类型& 数组名[数组长度]; & & & & & & & &-& 数组是有序数列的集合 & & & &-& 例:```& int& arrTem[11]& ```& & & & -& 不能用变量作为数组的长度(c++11中数组长度可以是变量)&
& & & & & & & & & & & & & & & &-& 数组的初始化& & & & & & & & & & & & & & & -& 当右边集合里的元素已经被使用完了的时候,数组中剩余的元素被默认赋值为0& & & & & & -& 不给定数组长度,根据实际数组元素个数分配& & & & & & & & & & -& ```& int& arrl[]& =& {1,& 1,& 3,& 5,& 8,& 8}```& & & & & & & & & & -& 共有6个元数,所以实际分配24个字节空间& & & & & & & & & & -& 右边大括号里不能为空,为空数组长度就为0了,c语言中不允许数组长度为0。& & & & & & & & & & & -& int& nArrray[]& =& {};& //报错& & & & & -& 要想给数组一次赋多个值,只能在数组定义的时候。之后只能一个一个元素的赋值。不能直接将一个数组赋给另一个数组。&
& & & &-& 4.1.1& 最大下标的作用& -& 4.2& -& 一维数据的初始化&
& & & &-& 4.2.1& 完全初始化 & & & && -& 整体赋值& ```& int& ary1[5]& =& {1,& 2,& 3,& 4,& 5}& ```&
& & & &-& 4.2.2& 部分初始化 & & & && -& 部分赋值& ```& int& arr1[5]& =& {1,& 2,& 3}& ```& -& 4.3& 一维数组的使用& -& 4.4& 一维数组的遍历& -& 4.5& 一维数组的内存& -& 4.5& 一维数据下标越界& -& 4.6& 字符数组&
& & & &-& 4.6.1& 字符数组的赋值 & & & &&
& & & &-& printf(&%c&,&asdfghijk&[1]);& & //打印'a' & & & &&
& & & &-& 字符数组的输入输出& & & & & & & & -& 逐个字符输入和输出。用格式符& ==%c==& 输入或输出一个字符。& & & & & & & & -& 将整个字符串一次输入或输出。用& ==%s==& 格式符,意思是对字符串的输入输出。& & & & & & & & -& ==注意:==& & & & & & & & & & & & & -& 输出字符不包括结束符& \0& &
& & & &-& 4.6.2& 字符串数组的长度 & & & &&
& & & &-& 注意:& & & & & & & & -& 对于没有给定数组长度的情况,此时字符串数组长度为字符串字符个数加1,因为要预留一个字符串结尾。& ('\0')& & & & & & & & -& 如果一个字符串数组包含一个以上'\0'时,则遇到第一个'\0'结束。 & & & & & & & & & & & &-& wchar_t与char类型的数组的区别& & & & & & & & -& wchar_t的每一个元素占两个字节,字符或字符串前加上==L==& & wchar_t中文字符串用%S&
& & & & & & & &```& c& & & & & & & & 对于wchar_t类型的常量,需要在字符前加上==L==。& L& 'A'& & & & & & & & & 在实际使用中,wchar_t类型的字符前面可以不用加&L&;& & & & & & & & 对于wchar_t类型的字符串常量,需要在字符串前加上L。 & & & & & & & &L&heello& world&& & & //一个字符占两个字节& & & & & & & & 对于wchar_t类型的字符串,处理这类字符串的函数一般都是w版的& & & & & & & &
& & & & & & & &wchar_t& szString[]& =& L&helloworld&;& & &
& & & & & & & &wprintf(L&%s&,& szString);& //中文的话用大写的S& & & & & & & & & & & & & & & & char& string[100];& & & & & & & & scanf_s(&%s&,& string,& 100);& & & & & & & & ```&
& & & &-& 4.6.3& 字符串相关函数&
& & & & & & & &-& 4.6.3.1& 字符串拷贝函数 & & & & & & & & & & & &-& 字符串拷贝strcpy& strcpy_s& wcscpy_s& & & & & & & &
& & & &```& c& & & & & & & &
& & & &char& *strcpy(char& *strDestination,& char& *strSource);& & & & & & & &
& & & &errno_t& strcpy_s(char& *strDestination,& size_t,& char& *strSource);& & & & & & & & & & & & & & & & & & & & &
& & & &char& *strcpy(wchar_t& *strDestination,& wchar_t& *strSource);& & & & & & & & & & & & & & & & & & & & &
& & & &errno_t& wcscpy_s(wchar_t& *strDestination,& size_t,& wchar_t& *strSource);&
& & & && & & &
& & & &```&
& & & & & & & &-& 4.6.3.2& 字符串连接函数 & & & & & & & & & & & &-& 字符串连接strcat& strcat_s& srncat& & & & & & & &
& & & &```& c& & & & & & & & & & & & char& *strcat(char& *strDestination,& char& *strSource);& & & & & & & & & & & & errno_t& strcat_s(char& *strDestination,& size_t,& charSource);& & & & & & & & & & & & & & & & & & & & & & & & wchar_t& *wcscat(wchar_t& *strDestination,& char& *strSource);& & & & & & & & & & & & errno_t& wcscat_s(wchar_t,& size_t,& wchar_t); & & & & & & & & & & & &char& *& strncat(char*dest,char*src,int& n); & & & & & & & & & & & &//把src所指向字符串的那前n个字符添加到dest结尾处(覆盖dest结尾处的“\0&)并添加”\0&.& & & & & & & & & & & ```&
& & & & & & & &-& 4.6.3.3& 字符串比较函数 & & & & & & & &&
& & & &-& 字符串比较strcmp& wcscmp& strcasecmp& stricmp& strncmpi& memcmp& memicmp& & & & & & & &
& & & &-& 对两个字符串& 从左向右逐个字符比较(ASCII),直到遇到不同字符或& \0& 为止 & & & & & & & & & & & &-& 若参数1中字符串和参数2中字符串相同则返回0; & & & & & & & & & & & &-& 若参数1中字符串长度大于参数2中字符串长度则返回大于0的值; & & & & & & & & & & & &-& 若参数1中字符串长度小于参数2中字符串长度则返回小于0的值。& & & &
& & & && & & & ```& c & & & & & & & & & & & &int& strcmp(char& *string1,& char& *string2);& & & &
& & & && & & & int& wcscmp(wchar_t& *string1,& wchar_t& *string2); & & & & & & & & & & & &int& strcasecmp(cons& char& *str1,& const& char& *strl2);& //& 比较时会自动忽略大小写的差异 & & & & & & & & & & & &int& stricmp(char& *str1,& char& *str2);& //以大小写不敏感方式比较两个串 & & & & & & & & & & & &int& strncmpi(char& *str1,& char& *str2,& unsigned& maxlen);& //比较字符串str1和str2的前maxlen个字符 & & & & & & & & & & & &int& memcmp(void& *buf1,& void& *buf2,& unsigned& int& count);//比较内存区域buf和buf2的前count个字节。void*是指任何类型的指针。 & & & & & & & & & & & &int& memicmp(void& *buf1,& void& *buf2,& unsigned& int& count);& //比较内存区域buf1和buf2的前count个字节,但不区分大小写。 & & & & & & & & & & & &```& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &
& & & & & & & && -& 4.6.3.4& 求字符串长度函数 & & & & & & & &&
& & & &-& 获取字符串长度strlen& wcsnlen& wcsnlen_s& & & & & & & &
& & & &-& 获取char型字符串长度& & & & & & & & & & & ```& c& & & & & & & & & & & & & #include& &string.h&& & & & & & & & & & & & & & & & & & & & & & & & size_t& strlen(char& *str);& & & & & & & & & & & & size_t& strlen_s(char& *str,& size_t& number0fElements);& //size_t& number0fElements字符串的最大长度& & & & & & & & & & & & & & & & & & & & & & & & size_t& wcsnlen(wchar_t& *str,& size_t& number0fElements);& & & & & & & & & & & & size_t& wcsnlen_s(wchar_t& *str,& size_t& numbr0fElements);& & & & & & & & & & & & ```& & & & & & & & & & & & & & & & & & & & ```& c & & & & & & & & & & & &//& 例:& & & & & & & & & & & & #include& &string.h&& & & & & & & & & & & & & & & & & & & & & & & & int& _tamin(int& argc,& _TCHAR& *argv[])& & & & & & & & & & & & {& & & & & & & & & & & & & & & & char& strChA& [100]& =& &abcdef&;& & & & & & & & & & & & & & & & strlen(strChA);& & & & & & & & & & & & & & & & strnlen_s(strChA,& 100);& & //100为数组的大小& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & wchar_t& strChAB[100]& =& L&abcdef&;& //wchar_t类型& & & & & & & & & & & & & & & & wcslen(strChAB);& & & & & & & & & & & & & & & & wcsnlen_s(strChAB,& 100);& & & & & & & & & & & & & & & & return& 0;& & & & & & & & & & & & }& & & & & & & & & & & & & & & & & & & & & & & & ```&
& & & & & & & &-& 4.6.3.5& 字符串查找函数 & & & & & & & & & & & &-& strstr& strtok & & & & & & & & & & & &```& c & & & & & & & & & & & &char*& strstr(char*& src,& char*& find); & & & & & & & & & & & &//从字符串src中寻找find第一次出现的位置(不比较结束符NULL) & & & & & & & & & & & &//返回指向第一次出现find位置的指针,如果没有找到则返回NULL & & & & & & & & & & & &char& *strtok(char& *src,& char& *delim); & & & & & & & & & & & &//分解字符串?一组标记串,src为要分解的字符串,delim为分隔字符串。 & & & & & & & & & & & &//首次调用时,src必须指向要分解的字符串,随后调用要把s设成NULL; & & & & & & & & & & & &//strtok中查找包含在delim中的字符,并用NULL('\n')来替换直到找遍整个字符串 & & & & & & & & & & & &//从s开头开始一个个被分隔的串。当没有被分隔的串时返回NULL,所有delim中包含的字符串都会被滤掉,并将被滤调的地方设为一处分隔节点。 & & & & & & & & & & & &```&
& & & & & & & &-& 4.6.3.6& 字符串转换函数&
& & & & & & & & & & & &-& 4.6.3.6.1& 小写字母转大写字母 & & & & & & & & & & & &&
& & & & & & & & & & & &&
& & & &```& c & & & & & & & & & & & & & & & &char& ch& =& toupper('a'); & & & & & & & & & & & & & & & &//转换单个字符 & & & & & & & & & & & & & & & &char& *strlwr(char*src) & & & & & & & & & & & & & & & &//函数说明:将字符串src转换成大写形式,只转换src中出现的小写字母,不改变其他字符 & & & & & & & & & & & & & & & &//返回值:返回指向src的指针 & & & & & & & & & & & & & & & &char*& strlwr(char*src) & & & & & & & & & & & & & & & &//函数说明:将字符串src转换成小写形式,只转换src中出现的大写字母,不改变其他字符 & & & & & & & & & & & & & & & &//返回值:返回指向src的指针&
& & & & & & & & & & & & & & & && ```&
& & & & & & & & & & & &-& 4.6.3.6.2& 大写字母转小写字母 & & & & & & & & & & & &&
& & & & & & & & & & & &&
& & & &```& char& chA& =& tolower('A');& ```&
& & & & & & & &-& 4.6.3.7& 字符串、整形、浮点型相互转换 & & & & & & & & & & & &-& 一、整型转字符串型 & & & & & & & & & & & & & & & &1.& int转为字符串 & & & & & & & & & & & & & & & & & & & &itoa(int& _Value,& char& *_Buffer,& int& _Radix);   & & & & & & & & & & & & & & & & & & & &需改为_itos_s(int& _Value,& char& *_Buffer,& size_t& _BufferCount,& int& _Radix); & & & & & & & & & & & & & & & & & & & &_Radix:表示进制,若十进制则Radix为10 & & & & & & & & & & & & & & & & & & & &_BufferCount:存储的大小,不可以比Buffer的长度大 & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &```& c & & & & & & & & & & & & & & & &#include& &iostream& & & & & & & & & & & & & & & & &using& namespace& & & & & & & & & & & & & & & & &void& main() & & & & & & & & & & & & & & & &{ & & & & & & & & & & & & & & & & & & & &int& num& =& 10; & & & & & & & & & & & & & & & & & & & &char& str[3];& & & & & & & & & & & & & & & & & & & & & & & & //& str的长度最少为3,因为10虽然两位,但还有一个结束符 & & & & & & & & & & & & & & & & & & & &_itoa_s(num,& str,& sizeof(str),& 10);& & & & //& int转为字符串 & & & & & & & & & & & & & & & & & & & &cout& &&& str& &&&& & & & & & & & & & & & & & & & //& 输出结果为10 & & & & & & & & & & & & & & & &} & & & & & & & & & & & & & & & &``` & & & & & & & & & & & & & & & &2.& long& int转为字符串 & & & & & & & & & & & & & & & & & & & &ltoa(long& _Value,& char& *_Buffer,& int& _Radix);   & & & & & & & & & & & & & & & & & & & &改为_ltoa_s(long& _Value,& char& *_Buffer,& size_t& _BufferCount,& int& _Radix); & & & & & & & & & & & & & & & &3.& 无符号长整型转为字符串 & & & & & & & & & & & & & & & & & & & &ultoa(unsigned& long& _Value,& char& *_Buffer,& int& _Radix);   & & & & & & & & & & & & & & & & & & & &改为_ultoa_s(unsigned& long& _Value,& char& *_Buffer,& size_t& _BufferCount,& int& _Radix); & & & & & & & & & & & & & & & &4.& int型转为宽字符串型 & & & & & & & & & & & & & & & & & & & &_itow(int& _Value,& wchar_t& *_Buffer,& int& _Radix);  & & & & & & & & & & & & & & & & & & & &改为_itow_s(int& _Value,& wchar_t& *_Buffer,& size_t& _BufferCount,& int& _Radix); & & & & & & & & & & & &-& 二、浮点型转字符串型 & & & & & & & & & & & & & & & &1.& double型转为字符串 & & & & & & & & & & & & & & & & & & & &gcvt(double& _Value,& int& _DigitCount,& char*& _DstBuf);   & & & & & & & & & & & & & & & & & & & &改为_gcvt_s(char*& _Buffer,& size_t& _BufferCount,& double& _Value,& int& _DigitCount); & & & & & & & & & & & & & & & & & & & &说明:显示正负号、小数点 & & & & & & & & & & & & & & & & & & & &_Digitcount:显示的位数,如1.25,显示两位是1.3(四舍五入),显示三位是1.25 & & & & & & & & & & & & & & & &```& c & & & & & & & & & & & & & & & &#include& &iostream& & & & & & & & & & & & & & & & &using& namespace& & & & & & & & & & & & & & & & &void& main() & & & & & & & & & & & & & & & &{ & & & & & & & & & & & & & & & & & & & &double& num& =& -1.235;& & & & & & & & & & & & & & & &
& & & & & & & & & & & & & & & & & & & &char& str[7];& & & & & & & & & & & & & & & & & & & & & & & & //& 在字符串中,正负号、小数点、结束符各占一位 & & & & & & & & & & & & & & & & & & & &_gcvt_s(str,& sizeof(str),& num,& 3);& & & & //& double转为字符串,显示三位,1.235四舍五入为1.24 & & & & & & & & & & & & & & & & & & & &cout& &&& str& &&&& & & & & & & & & & & & & & & & //& 输出结果为-1.24 & & & & & & & & & & & & & & & &} & & & & & & & & & & & & & & & &``` & & & & & & & & & & & & & & & &2.& double转换为字符串 & & & & & & & & & & & & & & & & & & & &ecvt(double& _Value,& int& _DigitCount,& int& *_PtDec,& int& *_PtSign);   & & & & & & & & & & & & & & & & & & & &改为_ecvt_s(char& *_Buffer,& size_t& _BufferCount,& double& _Value,& int& _DigitCount,& int& *_PtDec,& int& *_PtSign); & & & & & & & & & & & & & & & & & & & &说明:不显示小数点和正负号 & & & & & & & & & & & & & & & & & & & &_PtDec:表示小数点位置,若_PtDec为1,说明小数点左边有一个数 & & & & & & & & & & & & & & & & & & & &_PtSign:表示正负号,0为正数,1为负数 & & & & & & & & & & & & & & & &```& c & & & & & & & & & & & & & & & &#include& &iostream& & & & & & & & & & & & & & & & &using& namespace& & & & & & & & & & & & & & & & &void& main() & & & & & & & & & & & & & & & &{ & & & & & & & & & & & & & & & & & & & &double& num& =& -1.235; & & & & & & & & & & & & & & & & & & & &int& Dec,& S& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & //& Dec:小数点位置,Sign:正负号 & & & & & & & & & & & & & & & & & & & &char& str[5];& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & //& ?至少5位 & & & & & & & & & & & & & & & & & & & &_ecvt_s(str,& sizeof(str),& num,& 3,& &Dec,& &Sign);& & & & //& double转str,剔除正负号和小数点,显示三位,1235四舍五入为124 & & & & & & & & & & & & & & & & & & & &cout& &&& str& &&&& & & & & & & & & & & & & & & & & & & & & & & & & & & & //& 输出结果为124 & & & & & & & & & & & & & & & & & & & &cout& &&& Dec& &&&& & & & & & & & & & & & & & & & & & & & & & & & & & & & //& 输出结果为1,小数点左面有一个数 & & & & & & & & & & & & & & & & & & & &cout& &&& Sign& &&&& & & & & & & & & & & & & & & & & & & & & & & & & & & & //& 输出结果为1,是负数 & & & & & & & & & & & & & & & &} & & & & & & & & & & & & & & & &``` & & & & & & & & & & & & & & & &3.& double转换为字符串 & & & & & & & & & & & & & & & & & & & &fcvt(double& _Value,& int& _FractionalDigitCount,& int& *_PtDec,& int& *_PtSign); & & & & & & & & & & & & & & & & & & & &改为_fcvt(char& *_Buffer,& size_t& _BufferCount,& double& _Value,& int& _FractionalDigitCount,& int& *_PtDec,& int& *_PtSign); & & & & & & & & & & & & & & & & & & & &说明:转换结果中不包含小数点和正负号 & & & & & & & & & & & & & & & & & & & &_FractionalDigitCount:取小数位数,若_FractionalDigitCount为1,则取一位小数,要四舍五入 & & & & & & & & & & & & & & & &```& c & & & & & & & & & & & & & & & &#include& &iostream& & & & & & & & & & & & & & & & &using& namespace& & & & & & & & & & & & & & & & &void& main() & & & & & & & & & & & & & & & &{ & & & & & & & & & & & & & & & & & & & &double& num& =& -1.235; & & & & & & & & & & & & & & & & & & & &int& Dec,& S& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & //& Dec:小数点位置,Sign:正负号 & & & & & & & & & & & & & & & & & & & &char& str[5];& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & //& ?至少5位 & & & & & & & & & & & & & & & & & & & &_fcvt_s(str,& sizeof(str),& num,& 2,& &Dec,& &Sign);& //& double转str,剔除正负号和小数点,取两位小数,1235四舍五入为124 & & & & & & & & & & & & & & & & & & & &cout& &&& str& &&&& & & & & & & & & & & & & & & & & & & & & & & & & & & & //& 输出结果为124 & & & & & & & & & & & & & & & & & & & &cout& &&& Dec& &&&& & & & & & & & & & & & & & & & & & & & & & & & & & & & //& 输出结果为1,小数点左面有一个数 & & & & & & & & & & & & & & & & & & & &cout& &&& Sign& &&&& & & & & & & & & & & & & & & & & & & & & & & & & & & & //& 输出结果为1,是负数 & & & & & & & & & & & & & & & &} & & & & & & & & & & & & & & & &``` & & & & & & & & & & & &-& 三、字符串型转整型 & & & & & & & & & & & & & & & &1.& 将字符串转为int型 & & & & & & & & & & & & & & & & & & & &int& atoi(const& char& *_String); & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &2.& 将字符串转为long型 & & & & & & & & & & & & & & & & & & & &long& atol(const& char& *_String); & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &3.& 将字符串转为long型,并报告不能被转换的所有剩余部分 & & & & & & & & & & & & & & & & & & & &long& strtol(const& char& *_String,& char& **_EndPtr,& int& _Radix); & & & & & & & & & & & & & & & & & & & &_Radix:表示进制,范围为2~36和0 & & & & & & & & & & & & & & & & & & & &_EndPtr:指向字符串中不合法的部分 & & & & & & & & & & & & & & & & & & & &说明:若_Radix为2,则‘0’、‘1’合法,若_Radix为10,则‘0’、‘1’……‘9’合法,若_Radix为16,则‘0’,‘1’……‘f’合法 & & & & & & & & & & & & & & & &```& c & & & & & & & & & & & & & & & &#include& &iostream& & & & & & & & & & & & & & & & &using& namespace& & & & & & & & & & & & & & & & &void& main() & & & & & & & & & & & & & & & &{ & & & & & & & & & & & & & & & & & & & &long& num_2,& num_8,& num_10,& num_16; & & & & & & & & & & & & & & & & & & & &char& str[20]& =& &1079aeg&; & & & & & & & & & & & & & & & & & & & &char& *str1; & & & & & & & & & & & & & & & & & & & &num_2& =& strtol(str,& &str1,& 2);& & & & & & & & //& 二进制,10合法 & & & & & & & & & & & & & & & & & & & &cout& &&& num_2& &&&& & & & & & & & & & & & & & & & //& 输出2,二进制10在十进制中为2 & & & & & & & & & & & & & & & & & & & &cout& &&& str1& &&&& & & & & & & & & & & & & & & & //& 输出不合法的79aeg & & & & & & & & & & & & & & & & & & & &num_8& =& strtol(str,& &str1,& 8);& & & & & & & & //& 8进制,107合法 & & & & & & & & & & & & & & & & & & & &cout& &&& num_8& &&&& & & & & & & & & & & & & & & & //& 输出71,八进制107在十进制中为71 & & & & & & & & & & & & & & & & & & & &cout& &&& str1& &&&& & & & & & & & & & & & & & & & //& 输出不合法的9aeg & & & & & & & & & & & & & & & & & & & &num_10& =& strtol(str,& &str1,& 10);& & & & //& 10进制,1079合法 & & & & & & & & & & & & & & & & & & & &cout& &&& num_10& &&&& & & & & & & & & & & & & & & & //& 输出1079 & & & & & & & & & & & & & & & & & & & &cout& &&& str1& &&&& & & & & & & & & & & & & & & & //& 输出不合法的aef & & & & & & & & & & & & & & & & & & & &num_16& =& strtol(str,& &str1,& 16);& & & & //& 十六进制,1079ae合法 & & & & & & & & & & & & & & & & & & & &cout& &&& num_16& &&&& & & & & & & & & & & & & & & & //& 输出1079726,十六进制1079ae在十进制中为1079726 & & & & & & & & & & & & & & & & & & & &cout& &&& str1& &&&& & & & & & & & & & & & & & & & //& 输出不合法的g & & & & & & & & & & & & & & & &} & & & & & & & & & & & & & & & &``` & & & & & & & & & & & & & & & &4.& 将字符串转为无符号长整型值,并报告不能被转换的所有剩余部分 & & & & & & & & & & & & & & & & & & & &unsigned& long& strtoul(const& char& *_String,& char& **_EndPtr,& int& _Radix); & & & & & & & & & & & &-& 四、字符串型转浮点型 & & & & & & & & & & & & & & & &1.& 将字符串转换为双精度浮点型值 & & & & & & & & & & & & & & & & & & & &double& atof(const& char& *_String); & & & & & & & & & & & & & & & &2.& 将字符串转换为双精度浮点型值,并报告不能被转换的所有剩余数字 & & & & & & & & & & & & & & & & & & & &double& strtod(const& char& *_String,& char& **_EndPtr); & & & & & & & &-& 4.6.3.7& 字符串逆向 & & & & & & & & & & & &-& strrev & & & & & & & & & & & &```& c & & & & & & & & & & & &char*& strrev(char*src) & & & & & & & & & & & &//函数说明:把字符串str的所有字符的顺序颠倒过来(不包括NULL) & & & & & & & & & & & &//返回值:返回指向颠倒顺序后的字符串指针 & & & & & & & & & & & &```##& 5.& 程序三大结构& -& 5.1& 顺序结构&
& & & &-& 5.1.1& 顺序结构的识别&
& & & &-& 5.1.2& 顺序结构的语句的执行流程& -& 5.2& 选择结构&
& & & &-& 5.2.1& 构成选择结构的语句:& &
& & & & & & & &-& 5.2.1.1& if语句的形式&
& & & & & & & & & & & &-& 5.2.1.1.1& 单if语句形式 & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &if& (表达式)& {&
& & & & & & & &;} & & & &&
& & & & & & & & & & & &-& 5.2.1.1.2& if和else形式 & & & & & & & & & & & & & & & & & & & && if& (表达式) & & & & & & & & & & & & & & & & & & & && { & & & & & & & & & & & & & & & & & & & & & & & && ; & & & & & & & & & & & & & & & & & & & && } & & & & & & & & & & & & & & & & & & & && else{ & & & & & & & & & & & & & & & & & & & & & & & && ; & & & & & & & & & & & & & & & & & & & && }&
& & & & & & & & & & & &-& 5.2.1.1.3& if和else& if形式 & & & & & & & & & & & &&
& & & & & & & & & & & & & & & & & & & & & & & & & & & && if& (表达式) & & & & & & & & & & & & & & & & & & & && { & & & & & & & & & & & & & & & & & & & & & & & && ; & & & & & & & & & & & & & & & & & & & && }else& if(表达式) & & & & & & & & & & & & & & & & & & & && { & & & & & & & & & & & & & & & & & & & & & & & && ; & & & & & & & & & & & & & & & & & & & && }&
& & & & & & & & & & & &-& 5.2.1.1.4& if& ,& else& if和else形式 & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &if& (表达式) & & & & & & & & & & & & & & & & & & & &{ & & & & & & & & & & & & & & & & & & & & & & & &; & & & & & & & & & & & & & & & & & & & &} & & & & & & & & & & & & & & & & & & & &else& if(表达式) & & & & & & & & & & & & & & & & & & & &{ & & & & & & & & & & & & & & & & & & & & & & & &; & & & & & & & & & & & & & & & & & & & &} & & & & & & & & & & & & & & & & & & & &else & & & & & & & & & & & & & & & & & & & &{ & & & & & & & & & & & & & & & & & & & & & & & &; & & & & & & & & & & & & & & & & & & & &} & & & & & & & & & & & && &
& & & &-& 5.2.2& 构成选择结构体的语句:switch-case&
& & & & & & & &-& 5.2.2.1& switch-case的形式 & & & & & & & & & & & & & & & & & & & &switch& (表达式) & & & & & & & & & & & & & & & & & & & &{& & & &
& & & & & & & & & & & & & & & &case& 常量1:& & & & & & &
& & & & & & & & & & & & & & & & & & & &;& & & & & & & &
& & & & & & & & & & & & & & & && & & &
& & & & & & & & & & & & & & & &default:& & & & & & & &
& & & & & & & & & & & & & & & &;& & & & & & & &
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &}&
& & & & & & & &-& 5.2.2.2& break语句的作用&
& & & & & & & &-& 5.2.2.3& default语句的作用&
& & & & & & & &-& 5.2.2.4& case& 标签的作用.&
& & & & & & & &-& 5.2.2.5& switch-case语句的匹配过程 & & & &-& 5.2.3& if和switch语句的选择 & & & & & & & & & & & & & & & & & & & &```&
& & & & & & & & & & & &if语句的优缺点: & & & & & & & &使用if结构能够实现较为复杂的逻辑判断 & & & & & & & &用switch结构能够实现的结构,使用if结构都能实现 & & & & & & & &分支较少的情况使用if结构更简单 & & & & & & & &分支较多的情况下使用if结构会使程序结构变的复杂 & & & & & & & &如果使用& if嵌套层次过深,也容易使程序变得复杂 & & & & & & & &与switch结构相比if结构执行效率较低 & & & & & & & &switch语句的优缺点: & & & & & & & &没有复杂的逻辑判断,程序结构简单 & & & & & & & &对于分支很多的情况,特别适合用switch结构 & & & & & & & &执行效率比if结构高 & & & & & & & &switch结构只能基于一个整数值进行分支选择 & & & & & & & &switch只能判断是否相等,不能判断在某一区间的值 & & & & & & & &```& -& 5.3& 循环结构&
& & & &-& 5.3.1& while循环&
& & & & & & & &-& 5.3.1.1& while循环的形式 & & & & & & & & & & & & & & & && while& (表达式) & & & & & & & & & & & & & & & && { & & & & & & & & & & & & & & & & & & & && ; & & & & & & & & & & & & & & & && }&
& & & &-& 5.3.2& do-while循环&
& & & & & & & &-& 5.3.2.1& do-while循环的形式 & & & & & & & & & & & & & & & && do & & & & & & & & & & & & & & & && { & & & & & & & & & & & & & & & & & & & && ; & & & & & & & & & & & & & & & && }while(表达式);&
& & & &-& 5.3.3& for循环&
& & & & & & & &-& 5.3.3.1& for循环的形式 & & & & & & & &&
& & & & & & & & & & & & & & & & & & & & & & & && for(& ;& ;& ) & & & & & & & & & & & & & & & && { & & & & & & & & & & & & & & & & & & & && ; & & & & & & & & & & & & & & & && }&
& & & & & & & &-& 5.3.3.2& for循环的执行顺序和过程&
& & & &-& 5.3.4& 循环中break语句的作用 & & & & & & & & & & & && 退出循环体&
& & & &-& 5.3.5& 循环中continue语句 & & & & & & & & & & & && 中止本次循环,进行下一次循环&
& & & &-& 5.3.6& 嵌套循环&
& & & & & & & &-& 5.3.6.1& 嵌套循环的形式&
& & & & & & & &-& 5.3.6.2& 嵌套循环的总执行次数的计算&
& & & & & & & &-& 5.3.6.3& 嵌套循环的执行顺序&
& & & &-& 5.3.7& 死循环&
& & & & & & & &-& 5.3.7.1& 死循环的形成条件##& 6.& 二维数组& -& 6.1& 二维数组的定义 & & & &-& 数据类型& 数组名[][];& -& 6.2& 二维数组的初始化&
& & & &-& 6.2.1& 部分初始化&
& & & &-& 6.2.2& 完全初始化& -& 6.3& 二维数组的使用& -& 6.4& 二维数组的遍历& -& 6.5& 二维数组的内存& -& 6.6& 二维数据下标越界& -& 6.7& 二维字符数组##& 7.& 函数& -& 7.1& 函数的组成& &
& & & &-& 7.1.1& 函数头(就是函数的声明)&
& & & & & & & &-& 7.1.1.1& 返回值类型 & & & & & & & && & & & -& 返回值作为函数表达式的结果& & & & & & & & & & & & -& 返回值的类型必须何定义的时候一致&
& & & & & & & &-& 7.1.1.2& 函数名&
& & & & & & & &-& 7.1.1.2& 参数列表&
& & & & & & & & & & & &-& 7.1.1.2.1& 各个参数的类型(形式参数)&
& & & &-& 7.1.2& 函数体& -& 7.2& 函数的声明& -& 7.3& 函数的定义 & & & &-& 函数的格式& & & & & & & & ```& & & & & & & & & 返回值类型& 函数名& (参数类型& 形式参数1,& 参数类型& 形式参数2,& ...& )& & & & & & & & {& & & & & & & & & & & & 语句序列;& & & & & & & & & & & & return& 返回值;& & & & & & & & }& & & & & & & & //例:& & & & & & & & int& max(int& x,& int& y)& & & & & & & & {& & & & & & & & & & & & int&& & & & & & & & & & & & z& =& x& && y& ?& x& :&& & & & & & & & & & & & return&& & & & & & & & }& & & & & & & & ```& -& 7.4& 函数的调用&
& & & &-& 7.4.1& 调用位置 & & & &&
& & & &-& & ```函数名(实参)```&
& & & &-& 7.4.2& 返回位置& -& 7.5& 函数的形参 & & & &-& 7.5.0& 形参:在定义函数时,函数名后面括号中的参数&
& & & &-& 7.5.1& 形参的作用&
& & & &-& 7.5.2& 形参的类型&
& & & &-& 7.5.3& 形参的内存空间&
& & & &-& 7.5.4& 形参被赋值的时机& -& 7.6& 函数的实参 & & & &-& 7.6.0& 实参:在主调函数中调用一个函数时,函数名后面括号中的参数(可以是一个表达式)&
& & & &-& 7.6.1& 实参的作用&
& & & &-& 7.6.2& 实参的类型& -& 7.7& 函数传参时形参和实参的类型匹配问题&
& & & &-& 7.7.1& 隐式转换&
& & & &-& 7.7.2& 显示转换& -& 7.7& 库函数 & & & &-& ANSI& C定义的标准函数& & & & -& & & & & -& 第三方库函数##& 8.& 作用域& -& 8.1& 作用域的概念和种类&
& & & &-& 8.1.1& 复合语句作用域&
& & & &-& 8.1.2& 函数作用域&
& & & &-& 8.1.3& 文件作用域& -& 8.2& 变量的作用域&
& & & &-& 8.1& 全局变量&
& & & & & & & &-& 8.1.1& 本文件的全局变量&
& & & & & & & &-& 8.1.2& 外部文件的全局变量 & & & & & & & &&
& & & &-& 声明全局变量& & & & &
& & & & & & & &-& extern& int& g_nN& //可以多次声明,但定义只能有一次,不能重复定义。&
& & & &-& 8.2& 局部变量&
& & & & & & & &-& 8.2.1& 函数局部变量& &
& & & & & & & &-& 8.2.2& 复合语句局部变量& 8.3& 函数的作用域&
& & & &-8.3.1& 本文件的函数&
& & & &-8.3.2& 外部文件的函数##& 9.& 生存周期& -& 9.1& 生存周期的概念和类型&
& & & &-& 9.1.1& 短命的普通局部变量&
& & & &-& 9.1.2& 长寿的静态局部变量 & & & & & & & &-& 静态局部变量& & static& int& nStaticN&
& & & && & & & -& 改变变量的生存周期,把局部变量的生存周期给它升级为整个程序运行期间& & & &
& & & &-& 静态局部变量的特性& :& & & & & & & &
& & & &-& 生存周期变成程序运行期间& & & & & & & &
& & & &-& 初始化只被执行一次 & & & &&
& & & &-& 9.1.3& 长寿的普通全局变量 & & & & & & & &-& 在所有函数外部&
& & & &-& 9.1.4& 长寿但被限制作用域的静态局部变量 & & & & & & & &-& 将全局变量的作用域降低,只能在本文件中使用,其他文件不能使用;生存周期不变。& -& 9.2& 生存周期的影响&
& & & &-& 9.2.1& 变量的内存空间的使用有效期##& 10.& 预处理& -& 10.0& 无参宏 & & & &-& 10.0.1& 无参宏是指执行单一替换功能的宏定义 & & & & & & & &```#define& PI& 3.14```& -& 10.1& 有参&
& & & &-& 10.1.1& 有参宏的定义 & & & &&
& & & &```#define& S(a,b)& ((a)*(b)/2```&
& & & &-& 10.1.2& 有参宏的使用 & & & &&
& & & &-& 在有参宏中不要使用++& & --&
& & & &-& 10.1.3& 有参宏的缺陷 & & & & & & & &**只是简单的字符替换,会产生优先级的问题**& -& 10.2& 条件编译宏&
& & & &-& 10.2.1& 条件编译指令&
& & & & & & & &-& 10.2.1.1& #if&
& & & & & & & &-& 10.2.1.2& #else&
& & & & & & & &-& 10.2.1.3& #endif&
& & & & & & & &-& 10.2.1.4& #ifdef & & & & & & & &&
& & & &-& 判断某个宏是否有定义&
& & & & & & & &-& 10.2.1.5& #ifndef & & & & & & & && ```c & & & & & & & && //判断是否为调试方式编译&
& & & & & & & && #ifdef& _DEBUG & & & & & & & &&
& & & &printf(&This& is& Debug&); & & & & & & & && #else&
& & & & & & & &&
& & & &printf(&this& is& relece&); & & & & & & & && #endif & & & & & & & && //判断是否为x64方式编译 & & & & & & & && #ifdef& _M_AMD64 & & & & & & & &&
& & & &printf(&this& is& win64&); & & & & & & & && #else & & & & & & & &&
& & & &printf(&this& is& win32&); & & & & & & & && #endif & & & & & & & && ``` & & & & & & & && -& 10.3& 特殊的宏 & & & &-& 10.3.0&
& & & & & & & &#pragma& once & & & & & & & &```& c & & & & & & & &#ifndef& 宏的名字 & & & & & & & &#ifdef& 宏的名字& & //_大写的头文件的文件名_H & & & & & & & &...... & & & & & & & &#endif&
& & & &-& 10.3.1& DEBUG & & & && &
& & & &-& 10.3.2& _WIN64&
& & & &-& 10.3.3& __LINE__ & & & & & & & &-& __LINE__宏得到一个对应当前行号整数常量。 & & & &-& 10.3.4& __FUCTION__ & & & & & & & &-& 使用__func__标识符总是可以获得代码中表示函数体的函数名。& & & & -& void& print_the_name(void){printf(&%s& was& called.\n&,& __func__);}& &
& & & &-& 10.3.5& __FILE__ & & & &&
& & & &-& __FILE__宏把当前源文件的名称表示为一个字符串常量,一般是包含整个文件的路径的字符串常量&C:\\EE\main.c&&
& & & &-& 10.3.6& __TIME__ & & & & & & & &-& __TIME__提供包含日期值的字符串,格式为hh:mm:ss& //编译器执行的时间,不是程序运行的时间 & & & && -& 10.3.7& __DATE_ & & & &&
& & & &-& __DATE__生成日期的字符串表示法,在程序调用它时,它的格式是Mmm& dd& yyy。##& 11.& 一级指针& -& 11.0& 本质、两个运算符 & & & &-& 指针本质上只是4个字节(一个字节8位)的变量,这个变量对应的一个内存地址。(内存地址用8位16进制数表示0x位2进制数) & & & &-& &:取地址,获取一个变量的内存地址& & & & -& *:& & 解引用,取出一个内存地址上的值 & & & &-& 注意:在定义一个指针的时候& *& 号只是起一个标志的作用& & -& 11.1& 一级指针的类型 & & & &-& 确定取地址的时候取多长 & & & &-& ```n1& =& 0;``` & & & &-& ```n1& =& *((char*)pNum);& //强制类型转换把int*转化char*& 本来int*是取4个字节,现在变为char*& 仅仅取一个字节```& -& 11.2& 一级指针的定义 & & & &-& 数据类型& *指针名; & & & &-& 例:```int& *pNum& =& NULL;& //定义了一个名为pNum的int型指针变量,并初始化为空。```& -& 11.3& 一级指针的赋值 & & & &-& ```*p& =& 200;```& -& 11.4& 一级指针的使用& & & -& 11.4.1& 指针的指向& & & & & & & & -& 指向的是一段内存地址 & & & & & & & &-& 例: & & & & & & & &```& c & & & & & & & &int& a& =& 42; & & & & & & & &int*& pNum& =& &a;& //pNum是一个整型变量,a是一个int型变量 & & & & & & & &printf(&%p&,& pNum);& //打印的pNum这个int*变量上保存的int型变量a的内存地址0x; & & & & & & & &//打印出来的结果与printf(&%p&,&a);一样 & & & & & & & &```& & & -& 11.4.2& 指针指向的内容 & & & & & & & &-& 该内存地址上实际保存的值 & & & & & & & &-& 例:```*pNum& =& 42;//pNum是一个int型指针变量,把pNum指向的内存地址上的值改为42.``` & & & & & & & && -& 11.5& 函数形参和指针的配合使用& & & -& 11.5.1& 在函数内通过形参修改实参的值. & & & & & & & &```& c & & & & & & & &void& swap(int*& px,& int*& py) & & & & & & & &{ & & & & & & & & & & & &int*& temp& =& * & & & & & & & & & & & &*px& =& * & & & & & & & & & & & &*py& =& * & & & & & & & &} & & & & & & & &int& main() & & & & & & & &{ & & & & & & & & & & & &int& x& =& 1,& y& =& 2; & & & & & & & & & & & &swap(&x,& &y); & & & & & & & & & & & &return& 0; & & & & & & & &} & & & & & & & &```& & & -& 11.5.2& 使用指针传递更大的内存空间.& -& 11.6& 野指针& & & -& 11.6.1& 野指针的形成& & & -& 11.6.2& 野指针的危害& -& 11.7& 空指针& & & -& 11.7.1& 空指针的形成& & &
& & & & & & & &指向NULL的指针& & & -& 11.7.2& 空指针的危害& -& 11.8& 悬空指针& & & -& 11.8.1& 悬空指针的形成& & & -& 11.8.2& 悬空指针的危害& -& 11.9&
& & & &-& 类型的变化规律:& & & & -& 对变量取地址,得到的是地址,类型为一级指针类型& & & & -& 数组名,也是一级指针类型& & & & -& 对一级指针解引用,得到的是相应的数据类型& & & & -& 对一级指针类型使用下标运算符,得到的是相应的数据类型& & & & ```& & & & 例如:& & & & & & & & int& a[]& =& {1,2,3,4,5};& & & & & & & & int& *p& =&& & & & & & & & a+2,& &a[2],& p+2,& &p[2]表示的同一个一级指针类型的同一地址& & & & & & & & *(a+2),& *&a[2],& *(p+2),& *&p[2]表示int型,数据是a[2]; & & & &``` & & & &##& 12.& 结构体struct& -& 12.1& 结构体的定义(struct) & & & &```& c & & & &sttuct{ & & & & & & & & & & & & & & & &} & & & &struct& Mystruct{ & & & & & & & &......... & & & &} & & & & & & & &struct& MyStruct{ & & & & & & & &类型名1& & 成员名1; & & & & & & & &...... & & & & & & & &类型名n& & 成员名n; & & & &}; & & & &MyStruct& stc1;& //定义结构体变量stc1. & & & &例: & & & & & & & &struct& _PERSON{ & & & & & & & &char& name[20]; & & & & & & & &char& & & & & & & & &int& & & & & & & & &float& & & & &}; & & & &_PERSON&& //定义了一个_PERSON类型的mperson的变量 & & & &struct{ & & & & & & & & & & & &} & & & & & & & &struct& _PERSON{ & & & & & & & & & & & &} & & & &``` & & & & & & & && -& 12.2结构体的字段 & & & && & & & -& 12.2.1& 字段的类型& -& 12.3& 使用结构体定义变量& -& 12.4& 结构体变量的初始化& & & & -& 12.4.1& 部分字段的初始化 & & & & & & & &只初始化给出的值对应的字段,没有对应的值会被默认初始化为0;& & & & -& 12.4.2& 全部字段的初始化 & & & & & & & &``` & & & &c & & & & & & & &struct& _PERSON{ & & & & & & & & & & & &char& name[20]; & & & & & & & & & & & &wchar_t& & & & & & & & & & & & &int& & & & & & & & &}per[3]& =& { & & & & & & & & & & & &{'张三',男,& 23}, & & & & & & & & & & & &{'zzz',& 男,& 46}, & & & & & & & & & & & &{'aaa',& 女,& 26} & & & & & & & &}; & & & & & & & &```& -& 12.5& 使用结构体字段& & & & -& 12.5.1& `.`& 运算符 & & & && & & & -& 12.5.2& `-&`运算符 & & & & & & & & & & & &指针形式访问结构体字段需要使用-&运算符(相当与'*.')& -& 12.6& 在函数中接收结构体变量& & & & -& 12.6.1& 函数传递结构体变量实参和形参的传递方式 & & & &-& 结构体指针: & & & &-& 结构体数组 & & & & & & & &_PERSON*& pmperson& =& NULL; & & & & & & & &pmperson& =& && -& 12.7& 结构体嵌套& -& 12.8& 结构体变量的内存空间 & & & &-& 等于结构体内各字段的和。sizeof(_PERSON);& -& 12.9& 结构体内存空间计算方式& & & & -& 12.9.1& 结构体对齐 & & & & & & & & & & & && -& 12.10& 位段& & & & -& 12.10.1& 位段的定义形式& & & & -& 12.10.2& 位段的大小限制##& 13.& 联合体union& -& 13.1& 联合体的定义(union) & & & &```& c & & & &union& Ip & & & &{ & & & & & & & &struct& { & & & & & & & &unsigned& char& ip1; & & & & & & & &unsigned& char& ip2; & & & & & & & &unsigned& char& ip3; & & & & & & & &unsigned& char& ip4; & & & & & & & & & & & &}IPBIT; & & & &}ipP& -& 13.2& 联合体的字段& -& 13.3& 联合体的内存空间& -& 13.4& 联合体变量的内存空间计算方式& -& 13.5& 与结构体的异同哦 & & & & & & & &联和体与结构体在使用形式上都是一致的,唯一的区别是结构体每一个成员内存空间都是独立的,联合体所有的成员都共用一块内存空间。 & & & &由于联合体类型的成员变量使用的是共用内存空间,因此联合体变量中起作用的总是最后一次存放的成员变量的值。##& 14.& 枚举enum& -& 14.1& 枚举的作用& -& 14.2& 枚举的定义& -& 14.3& 枚举的使用##& 15.& 堆空间& -& 15.1& 堆空间的申请函数 & & & &-& 15.1.1& malloc & & & & & & & & & & & & & & & &刚刚分配的动态内存的初始值是不确定的. & & & & & & & &```& c & & & & & & & && void*& malloc(_In_& size_t& _size); & & & & & & & &例: & & & & & & & & & & & &void& *p& =& NULL; & & & & & & & & & & & &p& =& malloc(10); & & & & & & & & & & & &free(p);&
& & & & & & & &```&
& & & &-& 15.1.2& calloc & & & & & & & &根据元数个数元素字节数分配堆空间,分配后将堆空间初始化为0 & & & &-& 15.1.3& realloc & & & & & & & & & & & & & & & &```& ``` & & & & & & & &根据旧的空间分配新空间,分配后,将旧的空间内容拷贝到新空间中。& -& 15.2& 内存释放函数free & & & & & & & & & & & &***不能对同一指针(地址)连续两次进行free操作。*** & & & & & & & & & & & & & & & & & & & & & & & &***注意:***& 定义变量时坚持对其进行正确的初始化。 & & & & & & & &***在用free或delete释放内存之后,应及时将相应的指针置为NULL。***& -& 15.3& 悬空指针 & & & & & & & &一个指针变量,如果不为NULL且没有指向指向有效的内存地址,称为“悬空指针”,通过悬空指针访问其指向的内存区会使程序产生不可预知的错误。& -& 15.4& 内存操作函数 & & & &-& 15.4.1& 内存填充函数memset & & & &-& 15.4.2& 内存拷贝函数memcpy & & & &-& 15.4.3& 内存比较函数memcmp & & & &-& 15.4.4& 内存移动函数memmove& -& 15.5& 堆空间生存周期& -& 15.6& 内存泄漏 & & & & & & & &使用完一个指针后,如果没有进行释放,让其又指向了其它内存地址, & & & &这样就造成了内存泄漏##& 16.& 程序的内存空间布局& -& 16.1& 堆区 & & & &程序中动态分配的内存都存储在堆区& -& 16.2& 栈区 & & & & & & & & & & & &大部分函数的形参和局部变量& -& 16.3& 静态数据区 & & & & & & & &全局变量、用static修饰的局部变量& -& 16.4& 常量数据区 & & & &字符串常量& -& 16.5& 代码区 & & & &程序指令和大部分字面常量& -& 16.6& CPU寄存器组 & & & &一小部分函数形参和局部变量& -& 16.7& 生存周期 & & & &-& 16.7.1& 静态生存期 & & & &##& 17.& 高级指针& -& 17.0& 指针的算术运算 & & & &-& 只能进行加法或减法运算& & & & -& 两种形式:& & & & & & -& 1、指针+-整数:得到指针下移或者上移存储单元个数之后的内存地址。存储单元的大小就是该指针的数据类型所需的内存大小& & & & & & -& 2、指针-指针:指针与指针的减运算要求相减的两个指针属于同一类型,其结果是整数,表示两个指针之间的数据的个数,并非两个地址的差值。& -& 17.1& 保存变量的指针 & & & &-& 17.1.1& 基本数据类型变量的指针& & & & -& 17.1.2& 结构体/联合体变量的指针& -& 17.2& 保存数组的指针& & & & -& 17.2.1& 保存一维数组的指针 & & & & & & & &-& 数组名是数组类型的常量 & & & & & & & & & & & &-& 数组名,为数组的起始地址,可以隐式的转换成数组所存储元素的指针类型 & & & & & & & & & & & &```& c & & & & & & & & & & & &int& arr[]& =& {1,2,3,4,5}; & & & & & & & & & & & &int& *p& =&& & //可以隐式的转换成一级指针类型0 & & & & & & & & & & & &printf(&%s&,& typeid(a).name());& //查看对象类型_ & & & & & & & & & & & &//typeid& 是一个c++的关键字 & & & & & & & & & & & &```& & & & -& 17.2.2& 保存二维数组的指针 & & & & & & & &-& 二维数组指针 & & & & & & & &-& 二维数组名是一个指针类型,叫做一维数组指针类型& & & &
& & & &-& 类型名 (*变量名)[数组长度]& *例如:*& int& (*p)[4];& & &
& & & &-& 注意:对于数组指针,应该给出所指向数组的长度& & & &
& & & &```& & &
& & & & & & & &int& a[3][4];& & & &
& & & &int& (*p)[4];& & & &
& & & &p& =&& & //这里的a或p的类型是int& (*)[4]& & & &
& & & &```& & & &
& & & &-& 类型变化规律:& & & &
& & & && & & & -& 对于一维数组指针解引用会降维,变成1级指针。& & & &
& & & && & & & -& 对一维数组指针使用下标运算符也会降维,变成1级指针。& & & &
& & & && & & & -& 对于一维数组指针,会得到下一排起始地址,类型还是数组指针& & & &
& & & && & & & -& 对于一维数组名取地址,会变为二维数组指针,数值不变。**对于int& a[3];& &a的类型为int& (*)[3]**& & & &
& & & && & & & ```& C& & & & & & & & & & & &
& & & && & & & //例如: & & & & & & & & & & & &int& a[3][4]& & =& & & & &
& & & && & & & {& & &
& & & & & & & && & & & & & & & {1,2,3,4},& & & & & & & & &
& & & && & & {5,6,7,8},& & & & & & & & &
& & & && & & {9,10,11,12},& & & & & & & &
& & & &};& & & & & & & &
& & & &a[i]和*(a+i)等价,都是第i行第0列元素的地址,& & & & & & & &
& & & &那么a[i]+j& & *(a+i)+j& & &a[0][0]+4*i+j都是第i行第j列元素的地址。& & & & & & & &
& & & &``` & & & & & & & &-& 指针数组与二维数组的区别 & & & & & & & & & & & &```& C& & & &
& & & & & & & &指针数组& & & & char& *color[]& //color是一个指针,指向char& []& & & &
& & & & & & & &二维数组& & & char& color2[3][6]& //color2是一个数组,含有3个元素,每个元素都是一个char[6] & & & & & & & & & & & &```& & & &
& & & & & & & &**指针数组存储的是指针,二维数组存储的是数据** & & & && -& 17.2.3& 指针与多维数组& & & &
& & & &-& 多维数组指的是一维以上的数组,其数组名为多维数组指针类型。& & & &
& & & &-& 多维数组指针& & & &
& & & &-& 例如:& Array[2][3][4][5]& =& {1,2,3,4,5,6,7,8,9,10,11,12,13,14};& & & &
& & & &-& 转换规律:& & & & & & &
& & & & & & & &-& 对多维数组指针解引用会降维,变成降一维的数组指针,直到降成一级指针。& & & & & & & &
& & & &-& 对数组指针使用下标运算符也会降维,直到降维成一级指针。& & & & & & & &
& & & &-& 对于数组指针+1,会得到下一个数组的起始地址,类型不变。& & & & & & & &
& & & &-& 对多维数组名取地址,会变为更高维度的数组指针,数值不变。& -& 17.3& **指针数组与数组指针**& & & & -& 指针数组:& & & & & & & & -& 指针数组就是其元指针的数组& & & & & & & & -& 每一个元素都是指针变量& & & & & & & & -& 数据类型 *指针数组名[常量表达式];& & & & & & & & & -& `& int& *p[6];`& & & & &
& & & &```& c& & & & & & & & int& *p[6];& //p是指针数组,其中的元素为指针& & & & & & & & int& (*p1)[6];& //p1是数组指针,p是一个指针,它指向一个int型的数组,这个数组的含有6个int。& & & & & &
& & & &```& & & & -& 指针数组内存储的数据可以是任意指针类型。& & & & & & & & ```& C& & & & & & & & int& *p[5];& & & //一级指针数组& & & & & & & & int& **p[5];& & //二级指针数组& & & & & & & & int& (*p2[5])[10]& //数组指针数组,p2是一个数组,这个数组有10个元素,每个元素都是一个数组指针,指针指向的是一个int[5]的数组& & & & & & & & & & ```& -& 17.4& 保存指针的指针& & & & -& 17.4.1& 多级指针 & & & & & & & &-& 二级指针& & & &
& & & &-& 指针变量是用来存储地址的变量& & & &
& & & &-& 二级指针是用来存储指针的地址的变量& & & &
& & & &-& ```int& x& =& 100;& int& *p& =& &x;& int& **pp& =& &p;```& -& 17.5& 保存函数的指针& & & & -& 17.5.1& 函数指针 & & & & & & & &```& c & & & && & & & 函数指针类型,它可以使得你用一个变量存储一个函数的地址& ,并且能够执行它 & & & && & & & 函数指针是指向函数的指针变量 & & & && & & & void& test(int& n) & & & && & & & { & & & && & & & & & & & printf(&test& %d...\n&,& n); & & & && & & & } & & & && & & & void& (*f)(int);& & //这里的f就是函数指针变量 & & & && & & & f& =& && & & //等价于f& =& & & & && & & & (*f)(100);& & & //等价于f(100) & & & & & & & &//例& typedef& int& (*PFUN)(int);&
& & & && & & & ```& -& 17.6& 保存数组的指针的变种& & & & & -& 17.6.1& 指针数组的指针& & & &
& & & &-& 17.6.1.1& 保存指针的数组的指针. & & & & & & & & & & & &```int*& (*p)[5][2]``` & & & &-& int& (*pArr5[5])[3];& & //& 数组指针的数组 & & & & & & & &//int*& pArr[5][3];& 指针数组的指针& & & & & -& 17.6.2& 函数指针数组的指针& & & &
& & & &-& 17.6.2.1& 保存函数地址的数组的指针 & & & & & & & & & & & &```int& (*(*PFUN)(int))[10]```& & & & & -& 17.6.3& 数组指针数组的指针 & & & && &
& & & &-& 17.6.3.1& 保存数组的指针的数组的指针 & & & & & & & && &
& & & &```int& (*(*pArr)[10][5])```##& 18.& 文件操作& -& 18.0& FILE文件结构体类型&
& & & &-& c语言在stdio.h中定义了一个FILE文件结构体类型,包含管理和控制文件所需要的各种信息。在c程序中系统对文件进行的各种操作是通过指向文件结构体的指针变量来实现的。& & & &
& & & &```& c& & & & & & & & FILE& *指针变量名;& & & & & & & & FILE& *fpF& & & & & & & & //fpFile是可以指向一个FILE文件结构体的指针变量,文件指针变量的复制操作是由打开文件函数fopen()实现的。 & & & & & & & && ```& -& 18.1& 文件访问的基本模式 & & & &```& c & & & &fopen:& 打开文件,获得对此文件的指针、引用和句柄等,以证明可以使用此文件& & & & fread:& 读取文件。参数一般要指明读多少字节,读到把哪块内存。每次调用此功能,都是接着上次调用的结束位置。(所以是个输入流)& & & & fwrite:& 写入文件。参数一般指明把哪块内存写入文件,要写多少字节。每次调用此功能,都是接着上次调用的借宿位置写。(所以是个输入流)& & & & fclose:& 关闭文件,表明操作结束,不在使用此文件。文件使用完毕必须关闭,否则影响系统性能。& & & & fseek:& 随机控制流的当前位置,文件定位。 & & & &feof:& 检查文件指针是否到达文件的结束位置。 & & & &```& -& 18.2& 文件操作 & & & && & & & -& 18.2.1& 打开文件操作 & & & & & & & &-& FILE& *fopen(char& *filename,& char& *mode);& & & & & & & & -& FILE& *fpFile& =& fopen(&C:\\\test\\\File.txt&,& &r&); & & & & & & & && & & & -& c语言的文件打开模式一览& & & & & & & & & & & & & & & & & & & & & & & & & & mode& |& 处理方式& |& 文件不存在& |& 文件存在& & & & & & & & & & & & & & & & & -& |& -& |& -& |& -& & & & & & & & & & & & & & r& |& 读取& |& 出错& |& 打开文件& & & & & & & & & & & & & & & & w& |& 写入& |& 建立新文件& |& 覆盖原文件& & & & & & & & & & & & & & & a& |& 追加& |& 建立新文件& |& 在原文件后追加& & & & & & & & & & & & & & & r+& |& 读取/写入& |& 出错& |& 打开文件& & & & & & & & & & & & & & & w+& |& 写入/读取& |& 建立新文件& |& 覆盖原文件& & & & & & & & & & & & & & a+& |& 读取/写入& |& 建立新文件& |& 在

我要回帖

更多关于 vs怎么写c语言 的文章

 

随机推荐