Skip to content

Latest commit

 

History

History
277 lines (177 loc) · 17.5 KB

c.md

File metadata and controls

277 lines (177 loc) · 17.5 KB

[TOC]

目录

内容

*2016/12/15*

  1. C语言规定,标识符只能由字母(AZ, az)、数字(0~9)和下划线(_)组成,并且第一个字符必须是字母或下划线。

    以下标识符是合法的:

    a, x, x3, BOOK_1, sum5

    以下标识符是非法的:

    3s 不能以数字开头

    sT 出现非法字符

    -3x 不能以减号(-)开头

    bowy-1 出现非法字符减号(-)

  2. 在标识符中,大小写是有区别的,例如BOOK和book 是两个不同的标识符。

  3. %d称为格式控制符,它指明了以何种形式输出数据。格式控制符均以%开头,后跟其他字符。%d 表示以十进制形式输出一个整数。除了 %d,printf 支持更多的格式控制,例如:

    • %c:输出一个字符。c 是 character 的简写。

    • %s:输出一个字符串。s 是 string 的简写。

    • %f:输出一个小数。f 是 float 的简写。

  4. C语言支持单行注释和多行注释:

    • 单行注释以//开头,直到本行末尾(不能换行);

    • 多行注释以/开头,以/结尾,注释内容可以有一行或多行。

  5. 在C语言中,表达式a=a#b可以简写为a#=b,#表示 +、-、*、/、% 中的任何一种运算符。

  6. ++ 在前面叫做前自增(例如 ++a)。前自增先进行自增操作,再进行其他操作。

  7. ++ 在后面叫做后自增(例如 a++)。后自增先进行其他操作,再进行自增操作。

  8. 对于语句赋值语句a=b=c;,先执行b=c,再执行a=b,而不是反过来,这说明赋值操作符=具有右结合性。

  9. C语言的运算符众多,具有不同的优先级和结合性,我们将它们全部列了出来,方便大家对比和记忆:

    优先级 运算符 名称或含义 使用形式 结合方向 说明
    1 [] 数组下标 数组名[常量表达式] 左到右
    () 圆括号 (表达式)/函数名(形参表)
    . 成员选择(对象) 对象.成员名
    -> 成员选择(指针) 对象指针->成员名
    2 - 负号运算符 -表达式 右到左 单目运算符
    (类型) 强制类型转换 (数据类型)表达式
    ++ 自增运算符 ++变量名/变量名++ 单目运算符
    -- 自减运算符 --变量名/变量名-- 单目运算符
    * 取值运算符 *指针变量 单目运算符
    & 取地址运算符 &变量名 单目运算符
    ! 逻辑非运算符 !表达式 单目运算符
    ~ 按位取反运算符 ~表达式 单目运算符
    sizeof 长度运算符 sizeof(表达式)
    3 / 表达式/表达式 左到右 双目运算符
    * 表达式*表达式 双目运算符
    % 余数(取模) 整型表达式/整型表达式 双目运算符
    4 + 表达式+表达式 左到右 双目运算符
    - 表达式-表达式 双目运算符
    5 << 左移 变量<<表达式 左到右 双目运算符
    >> 右移 变量>>表达式 双目运算符
    6 > 大于 表达式>表达式 左到右 双目运算符
    >= 大于等于 表达式>=表达式 双目运算符
    < 小于 表达式<表达式 双目运算符
    <= 小于等于 表达式<=表达式 双目运算符
    7 == 等于 表达式==表达式 左到右 双目运算符
    != 不等于 表达式!= 表达式 双目运算符
    8 & 按位与 表达式&表达式 左到右 双目运算符
    9 ^ 按位异或 表达式^表达式 左到右 双目运算符
    10 | 按位或 表达式|表达式 左到右 双目运算符
    11 && 逻辑与 表达式&&表达式 左到右 双目运算符
    12 || 逻辑或 表达式||表达式 左到右 双目运算符
    13 ?: 条件运算符 表达式1? 表达式2: 表达式3 右到左 三目运算符
    14 = 赋值运算符 变量=表达式 右到左
    /= 除后赋值 变量/=表达式
    *= 乘后赋值 变量*=表达式
    %= 取模后赋值 变量%=表达式
    += 加后赋值 变量+=表达式
    -= 减后赋值 变量-=表达式
    <<= 左移后赋值 变量<<=表达式
    >>= 右移后赋值 变量>>=表达式
    &= 按位与后赋值 变量&=表达式
    ^= 按位异或后赋值 变量^=表达式
    |= 按位或后赋值 变量|=表达式
    15 , 逗号运算符 表达式,表达式,… 左到右 从左向右顺序运算
  10. puts() 函数在输出结束时会自动换行,而 printf() 和 putchar() 不会,需要手动添加换行符\n

  11. printf 格式控制字符的完整形式如下:[flags][width][.precision]type

  12. i f(判断条件){

    语句块1

}else{

  语句块2

}

![img](/Users/mayuan/Desktop/Hi-Story/github_blog/Blog/language/img/c_1_1.png)
  1. C语言规定,else 总是与它前面最近的 if 配对,

  2. 关系运算符的运算结果只有 0 或 1。当条件成立时结果为 1,条件不成立结果为 0。我们将运算结果 1 称为“真”,表示条件成立,将 0 称为“假”,表示条件不成立。

运算符 说明 结合性 举例
&& 与运算,双目,对应数学中的“且” 左结合 1&&0、(9>3)&&(b>a)
|| 或运算,双目,对应数学中的“或” 左结合 1||0、(9>3)||(b>a)
! 非运算,单目,对应数学中的“非” 右结合 !a、!(2<5)
  1. break 是C语言中的一个关键字,专门用于跳出 switch 语句。所谓“跳出”,是指一旦遇到 break,就不再执行 switch 中的任何语句,包括当前分支中的语句和其他分支中的语句;也就是说,整个 switch 执行结束了,接着会执行整个 switch 后面的代码。

  2. 在C语言中,共有三大常用的程序结构:

    • 顺序结构:代码从前往后执行,没有任何“拐弯抹角”;
    • 选择结构:也叫分支结构,重点要掌握 if else、switch 以及条件运算符;
    • 循环结构:重复执行同一段代码。
  3. for 循环的一般形式为: for(表达式1; 表达式2; 表达式3){ 语句块 }

    它的运行过程为:

    1. 先执行“表达式1”。

    2. 再执行“表达式2”,如果它的值为真(非0),则执行循环体,否则结束循环。

    3. 执行完循环体后再执行“表达式3”。

    4. 重复执行步骤 2) 和 3),直到“表达式2”的值为假,就结束循环。上面的步骤中,2) 和 3) 是一次循环,会重复执行,for 语句的主要作用就是不断执行步骤 2) 和 3)。

    “表达式1”仅在第一次循环时执行,以后都不会再执行,可以认为这是一个初始化语句。“表达式2”一般是一个关系表达式,决定了是否还要继续下次循环,称为“循环条件”。“表达式3”很多情况下是一个带有自增或自减操作的表达式,以使循环条件逐渐变得“不成立”。

  4. break,用它来跳出 switch 语句。当 break 关键字用于 while、for 循环时,会终止循环而执行整个循环语句后面的代码。break 关键字通常和 if 语句一起使用,即满足条件时便跳出循环。

  5. continue 语句的作用是跳过循环体中剩余的语句而强制进入下一次循环。continue语句只用在 while、for 循环中,常与 if 条件语句一起使用,判断条件是否成立。

  6. a[3][4] 表示a数组第3行第4列的元素。

  7. 二维数组的初始化可以按行分段赋值,也可按行连续赋值。

    例如对数组a[5][3],按行分段赋值可写为:

    int a[5][3]={ {80,75,92}, {61,65,71}, {59,63,70}, {85,87,90}, {76,77,85} };

    按行连续赋值可写为:

    int a[5][3]={80, 75, 92, 61, 65, 71, 59, 63, 70, 85, 87, 90, 76, 77, 85};

    这两种赋初值的结果是完全相同的。1)可以只对部分元素赋初值,未赋初值的元素自动取0值。例如:

    int a[3][3]={{1},{2},{3}};

  8. 在C语言中,输出字符串的函数有两个:

  • puts():直接输出字符串,并且只能输出字符串。
    • printf():通过格式控制符 %s 输出字符串。除了字符串,printf() 还能输出其他类型的数据。
    • 在C语言中,输入字符串的函数有两个:
      • scanf():通过格式控制符 %s 输入字符串。除了字符串,scanf() 还能输入其他类型的数据。
      • gets():直接输入字符串,并且只能输入字符串。
  1. 如果希望读取的字符串中不包含空格,那么使用 scanf() 函数;如果希望获取整行字符串,那么使用 gets() 函数,它能避免空格的截断。

  2. 返回值类型可以是C语言中的任意数据类型,例如 int、float、char 等。

  3. 函数名是标识符的一种,命名规则和标识符相同。函数名后面的括号( )不能少。

  4. 函数体是函数需要执行的代码。即使只有一个语句,也要由{ }包围。

  5. 在函数体中使用return语句返回数据。

  6. 函数定义时给出的参数称为形式参数,简称形参;函数调用时给出的参数(传递的数据)称为实际参数,简称实参。函数调用时,将实参的值传递给形参,相当于一次赋值操作。注意:实参和形参的类型、数目必须一致。

  7. 形参和实参有以下几个特点:

    1. 形参变量只有在函数被调用时才会分配内存,调用结束后,立刻释放内存,所以形参变量只有在函数内部有效,不能在函数外部使用。

    2. 实参可以是常量、变量、表达式、函数等,无论实参是何种类型的数据,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参,所以应该提前用赋值、输入等办法使实参获得确定值。

    3. 实参和形参在数量上、类型上、顺序上必须严格一致,否则会发生“类型不匹配”的错误。

    函数调用中发生的数据传送是单向的,只能把实参的值传送给形参,而不能把形参的值反向地传送给实参。 因此在函数调用过程中,形参的值发生改变,而实参中的值不会变化。

  8. 函数声明给出了函数名、返回值类型、参数列表(参数类型)等与该函数有关的信息,称为函数原型(Function Prototype)。

  9. http://www.cplusplus.com/reference/clibrary/C++学习者的福利网站

  10. 定义在函数内部的变量称为局部变量(Local Variable),它的作用域仅限于函数内部, 离开该函数后就是无效的,再使用就会报错。在所有函数外部定义的变量称为全局变量(Global Variable),它的作用域默认是整个程序,也就是所有的源文件,包括 .c 和 .h 文件。

  11. C程序的全部工作都是由各式各样的函数完成的,所以也把C语言称为函数式语言。

    标准C语言(ANSI C)共定义了15 个头文件,称为“C标准库”,所有的编译器都必须支持,如何正确并熟练的使用这些标准库,可以反映出一个程序员的水平。

    • 合格程序员:<stdio.h>、<ctype.h>、<stdlib.h>、<string.h>

      • 熟练程序员:<assert.h>、<limits.h>、<stddef.h>、<time.h>
      • 优秀程序员:<float.h>、<math.h>、<error.h>、<locale.h>、<setjmp.h>、<signal.h>、<stdarg.h>
  1. main() 函数是主函数,它可以调用其它函数,而不允许被其它函数调用。因此,C程序的执行总是从 main() 函数开始,完成对其它函数的调用后再返回到 main() 函数,最后由 main() 函数结束整个程序。

  2. 部分预处理指令:

指令 说明
# 空指令,无任何效果
#include 包含一个源代码文件
#define 定义宏
#undef 取消已定义的宏
#if 如果给定条件为真,则编译下面代码
#ifdef 如果宏已经定义,则编译下面代码
#ifndef 如果宏没有定义,则编译下面代码
#elif 如果前面的#if给定条件不为真,当前条件为真,则编译下面代码
#endif 结束一个#if……#else条件编译块
  1. 编译(Compile)会将源文件(.c文件)转换为目标文件。对于VC/VS,目标文件后缀为 .obj;对于GCC,目标文件后缀为 .o。

  2. 用尖括号 #include <>:

    • 一般用于包含标准的库头文件,编译器会去系统配置的库环境变量和者用户配置的路径去搜索,而不会在项目的当前目录去查找
  3. 用双引号 #include "":

    • 一般用于包含用户自己编写的头文件,编译器会先在项目的当前目录查找,找不到后才会去系统配置的库环境变量和用户配置的路径去搜索
  4. 宏定义的一般形式为:

    #define 宏名 字符串

  5. 对宏定义的几点说明 1) 宏定义是用宏名来表示一个字符串,在宏展开时又以该字符串取代宏名,这只是一种简单的替换。字符串中可以含任何字符,可以是常数,也可以是表达式,预处理程序对它不作任何检查,如有错误,只能在编译已被宏展开后的源程序时发现。

    1. 宏定义不是说明或语句,在行末不必加分号,如加上分号则连分号也一起替换。

    2. 宏定义必须写在函数之外,其作用域为宏定义命令起到源程序结束。如要终止其作用域可使用#undef命令。

  6. 带参数的宏,在调用中,不仅要宏展开,而且要用实参去代换形参。

  7. 对于带参宏定义不仅要在参数两侧加括号,还应该在整个字符串外加括号。

  8. CPU 访问内存时需要的是地址,而不是变量名和函数名!变量名和函数名只是地址的一种助记符,当源文件被编译和链接成可执行程序后,它们都会被替换成地址。编译和链接过程的一项重要任务就是找到这些名称所对应的地址。

  9. 对星号*****的总结

    • 表示乘法,例如int a = 3, b = 5, c; c = a * b;,这是最容易理解的。
    • 表示定义一个指针变量,以和普通变量区分开,例如int a = 100; int *p = &a;。
    • 表示获取指针指向的数据,是一种间接操作,例如int a, b, *p = &a; *p = 100; b = *p;。