C进阶语法


  1、函数

    函数是一组一起执行一个任务的语句。

    每个 C 程序都至少有一个函数,即主函数 main() ,所有简单的程序都可以定义其他额外的函数。

    函数声明告诉编译器函数的名称、返回类型和参数。函数定义提供了函数的实际主体

    定义函数:

return_type function_name( parameter list )
{
   body of the function
}

      ①、返回类型:一个函数可以返回一个值。return_type 是函数返回的值的数据类型。有些函数执行所需的操作而不返回值,在这种情况下,return_type 是关键字 void

      ②、函数名称:这是函数的实际名称。函数名和参数列表一起构成了函数签名

      ③:参数就像是占位符。当函数被调用时,您向参数传递一个值,这个值被称为实际参数。参数列表包括函数参数的类型、顺序、数量。参数是可选的,也就是说,函数可能不包含参数

      ④:函数主体包含一组定义函数执行任务的语句

    函数声明:

      函数声明会告诉编译器函数名称及如何调用函数。函数的实际主体可以单独定义。

       当您在一个源文件中定义函数且在另一个文件中调用函数时,函数声明是必需的。在这种情况下,您应该在调用函数的文件顶部声明函数。

// 函数声明格式:
return_type function_name( parameter list );

// 函数声明示例
int max(int num1, int num2);

// 在函数声明中,参数的名称并不重要,只有参数的类型是必需的
int max(int, int);

  2、作用域规则

    任何一种编程中,作用域是程序中定义的变量所存在的区域,超过该区域变量就不能被访问

    C 语言中有三个地方可以声明变量:

      ①:在函数或块内部的局部变量

      ②:在所有函数外部的全局变量

      ③:在形式参数的函数参数定义中

    全局变量与局部变量在内存中的区别:

      ①:全局变量保存在内存的全局存储区中,占用静态的存储单元;

      ②:局部变量保存在栈中,只有在所在函数被调用时才动态地为变量分配存储单元。

    

    当局部变量被定义时,系统不会对其初始化,您必须自行对其初始化。定义全局变量时,系统会自动对其初始化,下表是常用类型的全局变量的初始化默认值:

数据类型初始化默认值
int 0
char '\0'
float 0
double 0
pointer NULL

  3、数组

    数组是可以存储一个固定大小的相同类型元素的顺序集合。

    所有的数组都是由连续的内存位置组成。最低的地址对应第一个元素,最高的地址对应最后一个元素

    数组中的特定元素可以通过索引访问,第一个索引值为 0

    声明数组:

type arrayName [ arraySize ];

// 如声明一个类型为 double 的包含 10 个元素的数组 balance, 
double balance[10];

// 声明并初始化
double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};
// 省略数组的大小,默认为初始化时元素的个数
double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0};

// 给数组某个元素赋值
balance[4] = 50.0;

// 访问数组元素
double salary = balance[9];

  4、枚举(enum)

    枚举是 C 语言中的一种基本数据类型,它可以让数据更简洁,更易读  

// 枚举语法定义格式
enum 枚举名 {枚举元素1,枚举元素2,……};

// 一个每个星期的枚举
enum DAY
{
      MON=1, TUE, WED, THU, FRI, SAT, SUN
};

    注意:

      ①:第一个枚举成员的默认值为整型的 0,后续枚举成员的值在前一个成员上加 1

      ②:可以在定义枚举时改变枚举元素的值,那么没有指定值的枚举元素,其值为前一元素加 1

    枚举变量的定义:

// 1、先定义枚举类型,再定义枚举变量
enum DAY
{
      MON=1, TUE, WED, THU, FRI, SAT, SUN
};
enum DAY day;

// 2、定义枚举类型的同时定义枚举变量
enum DAY
{
      MON=1, TUE, WED, THU, FRI, SAT, SUN
} day;

// 3、省略枚举名称,直接定义枚举变量(推荐)
enum
{
      MON=1, TUE, WED, THU, FRI, SAT, SUN
} day;

  5、指针

    通过指针,可以简化一些C编程任务的执行,还有一些任务,如动态分配内存,没有指针是无法执行的。

   什么是指针?

    指针也就是内存地址,指针变量是用来存放内存地址的变量。

    指针声明:

type *var-name;

    *星号是用来指定一个变量是指针。如:

int    *ip;    /* 一个整型的指针 */
double *dp;    /* 一个 double 型的指针 */
float  *fp;    /* 一个浮点型的指针 */
char   *ch;    /* 一个字符型的指针 */

    所有实际数据类型,不管是整型、浮点型、字符型,还是其他的数据类型,对应指针的值的类型都是一样的,都是一个代表内存地址的长的十六进制数

   如何使用指针?

    使用指针时会频繁进行以下几个操作:定义一个指针变量、把变量地址赋值给指针、访问指针变量中可用地址的值。这些是通过使用一元运算符 * 来返回位于操作数所指定地址的变量的值。

    空指针:

    在指针变量声明的时候,如果没有确切的地址可以赋值,为指针变量赋一个 NULL 值是一个良好的编程习惯。赋为 NULL 值的指针被称为空指针。

    NULL 指针是一个定义在标准库中的值为零的常量

// 定义指针变量赋值为NULL,ptr 的地址是 0x0
int  *ptr = NULL;
// 判断一个指针变量是否是空指针
if(ptr)     /* 如果 p 非空,则完成 */
if(!ptr)    /* 如果 p 为空,则完成 */

    在大多数的操作系统上,程序不允许访问地址为 0 的内存,因为该内存是操作系统保留的。然而,内存地址 0 有特别重要的意义,它表明该指针不指向一个可访问的内存位置。但按照惯例,如果指针包含空值(零值),则假定它不指向任何东西

  6、字符串

    在 C 语言中,字符串实际上是使用 null 字符 \0 终止的一维字符数组。

    因此,一个以 null 结尾的字符串,包含了组成字符串的字符。即实际上C存储的字符串比字符串本身多了一个字符\0

    操作字符串的函数:

函数 & 目的
strcpy(s1, s2);
复制字符串 s2 到字符串 s1。
strcat(s1, s2);
连接字符串 s2 到字符串 s1 的末尾。
strlen(s1);
返回字符串 s1 的长度。
strcmp(s1, s2);
如果 s1 和 s2 是相同的,则返回 0;如果 s1s2 则返回大于 0。
strchr(s1, ch);
返回一个指针,指向字符串 s1 中字符 ch 的第一次出现的位置。
strstr(s1, s2);
返回一个指针,指向字符串 s1 中字符串 s2 的第一次出现的位置

  7、结构体

    C 数组允许定义可存储相同类型数据项的变量,结构是 C 编程中另一种用户自定义的可用的数据类型,它允许您存储不同类型的数据项   

    ①:定义结构:

     为了定义结构,您必须使用 struct 语句。struct 语句定义了一个包含多个成员的新的数据类型,struct 语句的格式如下:

struct tag {       // tag 是结构体标签
    member-list  // member-list 是标准的变量定义,比如 int i; 或者 float f,或者其他有效的变量定义
    member-list 
    member-list  
    ...
} variable-list ; // variable-list 结构变量,定义在结构的末尾,最后一个分号之前,您可以指定一个或多个结构变量

    在一般情况下,tag、member-list、variable-list 这 3 部分至少要出现 2 个

    结构体定义示例:

struct Books
{
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
} book;

    ②:结构体变量的初始化:

     对结构体变量可以在定义时指定初始值,如:

struct Books
{
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
} book = {"C 语言", "RUNOOB", "编程语言", 123456};

    ③:访问结构成员

     为了访问结构的成员,我们使用成员访问运算符(.)

     结构变量名.结构成员

struct Books
{
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
};
 
int main( )
{
   struct Books Book1;        /* 声明 Book1,类型为 Books */
 
   /* Book1 详述 */
   strcpy( Book1.title, "C Programming");
   strcpy( Book1.author, "Nuha Ali"); 
   strcpy( Book1.subject, "C Programming Tutorial");
   Book1.book_id = 6495407;
}

    ④:结构指针

struct Books *struct_pointer;

         

  8、共用体

    共用体是一种特殊的数据类型,允许您在相同的内存位置存储不同的数据类型。您可以定义一个带有多成员的共用体,但是任何时候只能有一个成员带有值。共用体提供了一种使用相同的内存位置的有效方式

    共同体定义:

union [union tag]
{
   member definition;
   member definition;
   ...
   member definition;
} [one or more union variables];

    union tag 是可选的,每个 member definition 是标准的变量定义,比如 int i; 或者 float f; 或者其他有效的变量定义。在共用体定义的末尾,最后一个分号之前,您可以指定一个或多个共用体变量,这是可选的。如:

union Data
{
   int i;
   float f;
   char  str[20];
} data;

    现在,Data 类型的变量可以存储一个整数、一个浮点数,或者一个字符串。这意味着一个变量(相同的内存位置)可以存储多个多种类型的数据

     共用体占用的内存应足够存储共用体中最大的成员

END.

C