c语言函数,数组和字符串

目录

函数和程序结构:

函数的定义和调用:

函数的参数传递方式(按值传递,按引用传递)

局部变量和全局变量

头文件和库函数的使用

数组和字符串

一维数组的定义和使用 

二维数组的定义和使用

字符串的定义和使用

字符串处理函数


函数和程序结构:

在C语言中,函数是程序的基本组成单元。函数用于封装可重用的代码块,并通过调用函数来执行特定的任务。每个C程序至少包含一个名为main的函数,该函数作为程序的入口点。

下面是一个简单的C语言程序的结构,以及函数的声明和定义示例:

// 预处理指令:包含其他头文件和宏定义等
#include 

// 函数声明(函数原型)
int add(int a, int b);

// main函数:程序的入口点
int main() {
    // 变量声明和初始化
    int num1 = 10;
    int num2 = 20;
    int sum;

    // 函数调用
    sum = add(num1, num2);

    // 输出结果
    printf("Sum: %d\n", sum);

    return 0;
}

// 函数定义
int add(int a, int b) {
    return a + b;
}

上述示例程序的结构如下:

  1. 第一行是预处理指令,用于包含其他头文件和宏定义等。

  2. 紧接着是函数的声明或函数原型。函数原型指定了函数的名称、参数类型和返回值类型,以便在程序的其他位置使用该函数。

  3. main函数是程序的入口点。它不接受任何参数,并且必须返回一个整数值(通常为int类型)。在main函数中,你可以声明和初始化变量,调用其他函数,执行任务,并输出结果。

  4. main函数之后是其他函数的定义。函数定义包括函数的返回类型、函数名和参数列表,以及函数体中的代码。在示例中,add函数计算两个整数的和。

  5. 程序使用了printf函数来输出结果。printf是C语言标准库提供的一个函数,用于在控制台输出文本。

注意事项:

  • 函数之间的顺序是无关紧要的,但如果在使用函数之前没有进行函数声明或定义,则需要在使用之前提前进行声明。
  • 函数可以有参数(输入)和返回值(输出),也可以没有参数或返回值。
  • C语言中的变量必须在使用之前声明并初始化。

函数的定义和调用:

  1. 函数的定义: 函数的定义包括函数的返回类型、函数名、参数列表以及函数体的代码实现。函数定义告诉编译器如何执行特定任务。

    返回类型 函数名(参数列表) {
        // 函数体代码
        // 执行特定任务
        return 返回值;
    }
    

    示例:

    // 函数的定义
    int add(int a, int b) {
        int sum = a + b;
        return sum;
    }
    

    在上述示例中,add函数的定义具有返回类型int,函数名称为add,参数列表为(int a, int b)。函数体内部计算两个整数的和并将结果作为返回值。

  2. 函数的调用: 调用函数即使用函数的名称及其参数来执行函数体内部的代码,并获取函数的返回值(如果有返回值)。

    返回类型 变量名 = 函数名(参数列表);
    

    示例:

    // 函数的调用
    int result = add(3, 4);
    

    在上述示例中,我们调用了之前定义的add函数,将参数34传递给函数,并将返回的结果保存在result变量中。

函数的定义和调用使得我们能够封装和重用代码,从而提高代码的可读性、维护性和模块化程度。

需要注意的几点:

  • 函数的名称应该唯一,不能与其他变量或函数重名。
  • 调用函数时,传递给函数的参数应与函数定义中的参数类型、数量和顺序相匹配。
  • 如果函数没有返回值,则函数的返回类型应为void,不需要在调用时将返回值赋给任何变量。

函数的参数传递方式(按值传递,按引用传递)

在C语言中,函数的参数传递方式可以是按值传递(pass-by-value)或按引用传递(pass-by-reference)。

  1. 按值传递(pass-by-value): 在按值传递中,函数接收参数的副本,而不是原始的数据。在函数内部对参数的修改不会影响到函数外部的原始数据。

    示例:

    void square(int num) {
        num = num * num;
    }
    
    int main() {
        int x = 5;
        square(x);
        printf("x: %d\n", x);  // 输出:x: 5
        return 0;
    }
    

    在上述示例中,square函数接收一个整数参数,并在函数内部将其平方。然而,对num的修改只是在函数内部生效,并不影响main函数中的变量x

  2. 按引用传递(pass-by-reference): 在按引用传递中,函数接收参数的引用或指针,可以直接操作原始数据。在函数内部对参数的修改也会影响到函数外部的原始数据。

    示范:

    void square(int* numPtr) {
        *numPtr = (*numPtr) * (*numPtr);
    }
    
    int main() {
        int x = 5;
        square(&x);
        printf("x: %d\n", x);  // 输出:x: 25
        return 0;
    }
    

  3. 在上述示例中,square函数接收一个整数指针参数numPtr,通过解引用该指针并修改指向的内存中的值来实现参数的平方。这样在main函数中调用square函数后,x的值也被修改为25。

  4. 需要注意的是,按引用传递需要使用指针来处理参数,而且要小心处理指针为空的情况。

    总结:

  5. 按值传递将参数的副本传递给函数,对参数的修改不会影响原始数据。
  6. 按引用传递将参数的引用或指针传递给函数,可以直接操作原始数据,对参数的修改会影响到原始数据。
  7. 根据需要选择合适的传递方式,在一般情况下,按值传递是常用的方式。如果想通过函数修改原始数据,可以使用指针进行按引用传递。

局部变量和全局变量

在C语言中,局部变量(local variable)和全局变量(global variable)是两种不同的变量类型,它们具有以下特点:

  1. 局部变量:

    • 局部变量定义在函数内部或一个代码块内部,只在其所在的函数或代码块内可见。
    • 局部变量在其所在的函数或代码块执行结束后会被销毁。
    • 局部变量的作用域(scope)限定在定义它的函数或代码块内部,外部的函数或代码块无法访问它。

    示例:

    void foo() {
        int x = 5;  // 局部变量x
        printf("x: %d\n", x);
    }
    
    int main() {
        foo();  // 调用foo函数
        // printf("%d\n", x);  // 错误:无法访问局部变量x
        return 0;
    }
    

  2. 在上述示例中,xfoo()函数内部的局部变量。它只能在foo()函数内部使用,对于main()函数来说是不可见的。

  3. 全局变量:

    • 全局变量定义在函数之外,可以被程序中的所有函数访问。
    • 全局变量的作用域跨越整个程序,从定义它的位置开始,直到程序结束。
    • 全局变量的生命周期与整个程序的运行时间相同,即在程序启动时创建,在程序结束时销毁。

    示例:

    int globalVar = 10;  // 全局变量
    
    void foo() {
        printf("globalVar: %d\n", globalVar);
    }
    
    int main() {
        foo();  // 调用foo函数访问全局变量globalVar
        printf("globalVar: %d\n", globalVar);  // 在main函数中也可以访问全局变量
        return 0;
    }
    

头文件和库函数的使用

头文件(Header Files):

  • 头文件通常包含函数声明、宏定义、类型定义和结构声明等信息。
  • 头文件的扩展名为.h,例如stdio.hstdlib.h等。
  • 头文件通过#include预处理指令引入到源代码文件中。
  • 引入头文件可以让源代码文件访问到头文件中声明的函数、变量和类型。

示例:

// header.h 头文件
#ifndef HEADER_H  // 防止头文件重复包含
#define HEADER_H

// 声明函数
int add(int a, int b);

#endif

// main.c 源代码文件
#include 
#include "header.h"  // 引入自定义的头文件

int main() {
    int result = add(3, 4);  // 使用头文件中声明的函数
    printf("Result: %d\n", result);
    return 0;
}
  1. 在上述示例中,header.h是自定义的头文件,其中声明了一个add函数。在main.c源代码文件中通过#include "header.h"引入了该头文件,并可以在main函数中调用add函数。

  2. 库函数(Library Functions):

    • 库函数是一组预定义好的函数,提供了各种通用的功能,如字符串处理、数学运算、文件操作等。
    • 库函数以函数的形式存在于库文件中,可以被多个程序共享使用。
    • 库函数通常是封装好的二进制代码,通过链接(linking)将其与程序一起编译。
    • 在C语言中,常见的标准库函数位于标准库(Standard Library),如stdio.hstdlib.hmath.h等。

    示例:

    #include 
    #include 
    
    int main() {
        double x = 2.5;
        double result = sqrt(x);  // 使用库函数sqrt计算平方根
        printf("Square root of %.1lf is %.2lf\n", x, result);
        return 0;
    }
    

  3. 在上述示例中,通过#include 引入了数学库函数的头文件,然后在main函数中使用sqrt函数计算给定数字的平方根。

  4. 需要注意的是,在使用库函数时,有时需要链接相应的库文件。对于标准库函数,编译器通常会自动链接相应的库文件。对于其他库函数,可能需要手动指定链接选项来告诉编译器使用哪个库文件。

数组和字符串

一维数组的定义和使用 

定义一维数组:

  • 一维数组的定义格式是:数据类型 数组名[数组长度];
  • 数组类型可以是任意合法的数据类型,如整型、字符型、浮点型等。
  • 数组名是标识符,用于标识该数组,在程序中唯一标识该数组。
  • 数组长度是一个非负整数,指定了数组可以容纳的元素个数。

示例:

int numbers[5];          // 定义一个包含5个整数的数组
float grades[10];        // 定义一个包含10个浮点数的数组
char characters[100];    // 定义一个包含100个字符的数组

访问和操作一维数组的元素:

  • 一维数组的元素可以通过索引来访问和操作,索引从0开始,到数组长度减1结束。
  • 通过数组名和索引,可以读取或修改数组元素的值。

示例:

int numbers[5] = {1, 2, 3, 4, 5};  // 初始化整型数组

int firstElement = numbers[0];    // 读取第一个元素
numbers[2] = 10;                   // 修改第三个元素的值

float average = (numbers[1] + numbers[3]) / 2.0;  // 使用数组元素进行计算

在上述示例中,我们定义了一个整型数组numbers,并对其进行初始化。然后通过索引读取和修改数组中的元素。另外,我们还可以使用数组元素进行其他的计算。

需要注意的是,数组索引越界会导致未定义的行为,确保在访问数组元素时不超出数组范围。

二维数组的定义和使用

定义二维数组:

  • 二维数组的定义格式是:数据类型 数组名[行数][列数];
  • 行数和列数是非负整数,分别指定了二维数组的行数和列数。
  • 数据类型可以是任意合法的数据类型,如整型、字符型、浮点型等。

示例:

int matrix[3][4];          // 定义一个3行4列的整型二维数组
float table[2][5];         // 定义一个2行5列的浮点型二维数组
char chessboard[8][8];     // 定义一个8行8列的字符型二维数组

访问和操作二维数组的元素:

  • 二维数组的元素可以通过行索引和列索引来访问和操作。
  • 行索引和列索引都从0开始,到对应的行数和列数减1结束。
  • 通过数组名、行索引和列索引,可以读取或修改数组元素的值。

示例:

int matrix[3][4] = {
    {1, 2, 3, 4},
    {5, 6, 7, 8},
    {9, 10, 11, 12}
};  // 初始化整型二维数组

int firstElement = matrix[0][0];      // 读取左上角元素
matrix[1][2] = 15;                     // 修改第二行第三列的元素值

float average = (matrix[0][1] + matrix[2][3]) / 2.0;  // 使用数组元素进行计算

在上述示例中,我们定义了一个整型二维数组matrix,并对其进行了初始化。然后通过行索引和列索引,读取和修改数组中的元素。另外,我们还可以使用数组元素进行其他的计算。

字符串的定义和使用

定义字符串:

  • 字符串的定义格式是:char 字符数组名[数组长度] = "字符串内容";
  • 字符数组名是标识符,用于标识该字符串,在程序中唯一标识该字符串。
  • 数组长度是一个非负整数,指定了字符数组的最大容量,应该至少比字符串内容的长度多1个字节(用于存储空字符)。

示例:

char greeting[20] = "Hello, world!";    // 定义一个包含20个字符的字符串
char name[] = "John";                   // 自动确定数组长度,足够存储字符内容和空字符

访问和操作字符串:

  • 可以通过数组名和索引来访问和操作字符串中的字符。
  • 字符串中的每个字符都有一个对应的索引,从0开始,到字符串长度减1结束。
  • 可以通过循环遍历字符串中的字符,或使用各种字符串处理函数来进行操作。

示例:

char greeting[20] = "Hello, world!";

char firstChar = greeting[0];                // 读取第一个字符
greeting[7] = 'W';                           // 修改第8个字符为大写

int length = strlen(greeting);               // 获取字符串长度
int compareResult = strcmp(greeting, "Hi");  // 比较字符串

printf("%s\n", greeting);                    // 输出字符串内容

在上述示例中,我们定义了一个字符数组greeting作为字符串,并对其进行初始化。然后通过索引读取和修改字符串中的字符。另外,通过调用字符串处理函数strlen获取字符串长度,strcmp比较字符串内容。最后使用printf函数输出字符串内容。

需要注意的是,在使用字符串时要确保不越界,并且为字符串留出足够的容量存储空字符。

字符串处理函数

在C语言中,有一些常用的字符串处理函数可以帮助我们进行字符串操作和处理。下面我列举一些常见的字符串处理函数及其功能:

  1. strlen:计算字符串的长度。

    #include 
    
    size_t strlen(const char *str);
    

  2. strcpy:将一个字符串复制到另一个字符串中。

    #include 
    
    char *strcpy(char *dest, const char *src);
    

  3. strcat:将一个字符串拼接到另一个字符串的末尾。

    #include 
    
    char *strcat(char *dest, const char *src);
    

  4. strcmp:比较两个字符串的大小。

    #include 
    
    int strcmp(const char *str1, const char *str2);
    

  5. strstr:在一个字符串中搜索指定子串的出现位置。

    #include 
    
    char *strstr(const char *str, const char *substr);
    

  6. strtok:将一个字符串分割为多个子串

    #include 
    
    char *strtok(char *str, const char *delimiters);
    

    这些只是一些常见的字符串处理函数,还有其他更多的函数可供使用。这些函数的使用方法需要查看相应的函数文档,并且要确保在使用这些函数之前正确包含对应的头文件。

你可能感兴趣的:(C语言学习,c语言,c++,算法)