C
c

C语言笔记

表达式

表达式是运算符及其运算数的序列,它指定一个运算。
表达式求值可以产生结果(例如求值 2+2 产生结果 4 ,可能产生副效应(例如求值 printf(“%d”,4) 会将字符 ‘4’ 送到标准输出流),并可以指代对象或函数。

综述

  • 值类别(左值、非左值对象、函数指代器)将表达式以其值分类
  • 参数和子表达式的求值顺序指定会得到何种中间结果

声明

声明是一个引入一个或多个标识符到程序中,并指定其含义及属性的 C 语言构造。
声明可以出现在任何作用域中。每个声明以分号结束(类似语句),并由两个独立部分组成: specifiers-and-qualifiers declarators-and-initializers ;

specifiers-and-qualifiers 任意顺序的下列内容的空白符分隔列表
  • 类型指定符:
declarators-and-initializers declarators 的逗号分隔列表(每个声明器提供附加类型信息及/或要声明的标识符)。 声明器可伴随初始化器enumstructunion 声明可忽略 declarators ,这种情况下它们仅引入枚举常量和/或标签。


例如:

int a, *b=NULL; // “ int ”是类型指定符,
                // “ a ”是声明器
                // “ *b ”是声明器
		//而 NULL 是初始化器
const int *f(void); // “ int ”是类型指定符
                    // “ const ”是类型限定符
                    // “ *f(void) ”是声明器
enum COLOR {RED, GREEN, BLUE} c; // “ enum COLOR {RED, GREEN, BLUE} ”是类型指定符
                                 // “ c ”是声明器

一个声明引入的每个标识符类型是通过 type specifier 所指定的类型及其 declarator 所应用的类型修饰决定的。

声明器

identifier 此声明器引入的标识符。
( declarator ) 任何可以放入括号中的声明器;引入指向数组或指向函数指针时要求这么做。
* qualifiers(可选) declarator 指针声明器:声明 S * cvr D 声明 D 为 cvr 限定指针,指向 S 所确定的类型。
noptr-declarator [ static(可选) qualifiers(可选) expression ]

noptr-declarator [ qualifiers(可选) * ]

数组声明器:声明 S D[N] 声明 D 为有 NS 所确定类型对象的数组。 noptr-declarator 是无括号指针声明器以外的其他任何声明器。
noptr-declarator ( parameters-or-identifiers ) 函数声明器:声明 S D(params) 声明 D 为接收参数 params 并返回 S 的函数。 noptr-declarator 是无括号指针声明器以外的其他任何声明器。
struct C {
    int member; // “ int ”是类型指定符
                // “ member ”是声明器
} obj, *pObj = &obj;
// “ struct C { int member; } ”是类型指定符
// 声明器“ obj ”定义 struct C 类型的对象
// 声明器“ *pObj ”声明指向 struct C 的指针,
// 初始化器“ = &obj ”提供该指针的初值
 
int a = 1, *p = NULL, f(void), (*pf)(double);
// 类型指定符是“ int ”
// 声明器“ a ”定义一个 int 类型对象
//   初始化器“=1”提供其初值
// 声明器“ *p ”定义一个指向 int 指针类型的对象
//   初始化器“ =NULL ”提供其初值
// 声明器“ f(void) ”声明接受 void 并返回 int 的函数
// 声明器“ (*pf)(double) ”定义一个指向
//   接受 double 并返回 int 的函数的指针类型对象
 
int (*(*foo)(double))[3] = NULL;
// 类型指定符是“int”
// 1. 声明器“ (*(*foo)(double))[3] ”是数组声明器:
//    所声明类型是“ 3 个 int 的数组的 /嵌套声明器/ ”
// 2. 嵌套声明器是“ *(*foo)(double)) ”,是指针声明器
//    所声明类型是“ /嵌套声明器/ 指向 3 个 int 的数组的指针”
// 3. 嵌套声明器是“ (*foo)(double) ”,是一个函数声明器
//    所声明类型是“ /嵌套声明器/ 接受 double 并返回指向 3 个 int 的数组的指针的函数”
// 4. 嵌套声明器是“ (*foo) ”,是一个(有括号,函数声明器所要求)指针声明器。
//    所声明类型是“ /嵌套声明器/ 指向接受 double 并返回指向 3 个 int 的数组的指针的函数的指针”
// 5. 嵌套声明器是“ foo ”,是一个标识符。
// 该声明引入一个标识符“ foo ”,以指代一个对象,其类型为
// “指向接受 double 并返回指向 3 个 int 的数组的指针的函数的指针”
// 初始化器“ = NULL ”提供此指针的初值。
 
// 若在用于声明符形式的表达式使用“foo”,则表达式类型将是int。
int x = (*(*foo)(1.2))[0];

每个不属于其他声明器一部分的声明器结尾是一个顺序点。

定义

定义是一个提供所有关于其所声明标识符信息的声明。

每个 enum 或 typedef 声明都是定义。

对于函数,包含函数体的声明即是函数定义:

int foo(double); // 声明
int foo(double x){ return x; } // 定义

对于对象,分配其存储的声明(自动或静态,但、非 extern )即是定义,而一个不分配存储的声明(外部声明)不是。

extern int n; // 声明
int n = 10; // 定义

对于结构体和联合体,指定其成员列表的声明是定义:

struct X; // 声明
struct X { int n; }; // 定义

初始化

对象声明可以通过名为初始化的步骤提供其初始值。

示例

#include <stdlib.h>
int a[2]; //初始化a为{0, 0}
int main(void)
{
    int i;          // 初始化 i 为不确定值
    static int j;   // 初始化 j 为 0
    int k = 1;      // 初始化 k 为 1
 
    // 初始化 int x[3] 为 1,3,5
    // 初始化 int* p 为 &x[0]
    int x[] = { 1, 3, 5 }, *p = x;
 
    // 初始化 w (二个结构体的数组)为
    // { { {1,0,0}, 0}, { {2,0,0}, 0} }
    struct {int a[3], b;} w[] = {[0].a = {1}, [1].a[0] = 2};
 
    // 函数调用表达式可用于局部变量初始化
    char* ptr = malloc(10);
    free(ptr);
 
//  错误:拥有静态存储期的对象要求常量初始化器
//  static char* ptr = malloc(10);
 
//  错误:不能初始化 VLA
//  int vla[n] = {0};
}

函数

函数是将一个标识符(函数名)关联到一条复合语句(函数体)的 C 语言构造。每个 C 程序都从 main 函数开始执行,也从它或者调用其他用户定义函数或库函数终止。

// 函数定义。
// 定义一个名为“ sum ”并拥有函数体“ { return x+y; } ”的函数
int sum(int x, int y) 
{
    return x + y;
}

函数可以拥有零或更多个形参,它们为函数调用运算符的实参所初始化,并且以通过其 return 语句向其调用者返回一个值。

int n = sum(1, 2); // 参数 x 和 y 为实参 1 和 2 所初始化

函数体在函数定义中提供。每个函数必需且只需在程序中定义一次,除非该函数为 inline 。

不可以有嵌套函数(除了一些通过非标准的编译器扩展):每个函数定义必须出现在文件作用域,而且函数无法访问其来自其调用方的局部变量:

int main(void) // main函数定义
{
    int sum(int, int); // 函数声明(可以出现于任何作用域)
    int x = 1;  // main 的局部变量
    sum(1, 2); // 函数调用
 
//    int sum(int a, int b) // 错误:不允许嵌套函数
//    {
//        return  a + b; 
//    }
}
int sum(int a, int b) // 函数定义
{
//    return x + a + b; //  错误:不能在 sum 中访问 main 的 x
    return a + b;
}

语句

语句是带顺序执行的 C 程序段。任何函数体都是一条复合语句,继而为语句或声明的序列:

int main(void)
{ // 复合语句的开始
    int n = 1; // 声明(非语句)
    n = n+1; // 表达式语句
    printf("n = %d\n", n); // 表达式语句
    return 0; // 返回语句
} // 复合语句之结尾,函数体之结尾

语句有五种类型:

  1. 复合语句
  2. 表达式语句
  3. 选择语句
  4. 迭代语句
  5. 跳转语句

标号

任何语句都能有标号,通过在语句自身前提供一个跟随冒号的名称。

标识符 : 语句 goto 语句的目标。
case 常量表达式 : 语句 switch 语句的 case 标号。
default : 语句 switch 语句的默认标号。

任何语句(但非声明)可以前附任意数量的标号,每个都声明一个 标识符 为标号名,标号名必须在闭合的函数中唯一(换言之,标号名拥有 函数作用域)。

标号声明自身没有效果,不会以任何方式变更控制流,或修改跟随其后的语句的行为。

复合语句

复合语句,或称块,是花括号所包围的语句与声明的序列。

{ 语句 | 声明(可选) }

复合语句允许将一组声明和语句组合入一个单元,并将其任何在期待单个语句的场所使用(例如在 if 语句或迭代语句中):

if (expr) // if 语句的开始
{ // 开始块
  int n = 1; // 声明
  printf("%d\n", n); // 表达式语句
} // 块结尾, if 语句结尾

每个复合语句引入其自身的块作用域。

拥有静态存储期的变量的初始化器,及 VLA 声明符在每次控制流经过这些声明时按顺序执行,就像它们是语句一样:

int main(void)
{ // 块的开始
  { // 块的开始
       puts("hello"); // 表达式语句
       int n = printf("abc\n"); // 声明,打印 "abc\n" ,将 4 存入 n
       int a[n*printf("1\n")]; // 声明,打印 "1\n" ,分配 8*sizeof(int)
       printf("%zu\n", sizeof(a)); // 表达式语句
  } // 块结束, n 与 a 的作用域结束
  int n = 7; // n 可以重新使用
}

表达式语句

跟随分号的表达式是一条语句。

表达式(可选) ;

典型的 C 程序中大多数语句是表达式语句,例如赋值或函数调用。

无表达式的表达式语句被称作空语句。它通常用于提供空循环体给 for 或 while 循环。它亦能用于在复合语句尾部或声明之前携带一个标号:

puts("hello"); // 表达式语句
char *s;
while (*s++ != '\0')
    ; // 空语句

选择语句

选择语句根据表达式的值,选择数条语句之一执行。

if ( 表达式 ) 语句 if 语句
if ( 表达式 ) 语句 else 语句 if 语句带 else 子句
switch ( 表达式 ) 语句 switch 语句

迭代语句

迭代语句重复执行一条语句。

while ( 表达式 ) 语句 while 循环
do 语句 while ( 表达式 ) ; do-while 循环
for ( 初始化子句 ; 表达式(可选) ; 表达式(可选) ) 语句 for 循环

跳转语句

跳转语句无条件地转移控制流。

break ; break 语句
continue ; continue 语句
return 表达式(可选) ; return 语句带可选的表达式
goto 标识符 ; goto 语句
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇