C语言从“hello word”到深入【第三节·c语言函数+数组】

目录

c语言中的函数

c语言中的函数的组成格式

函数的封装实例

c语言中函数的调用

函数参数

指针作为函数参数问题

数组作为函数参数问题

c语言中的作用域

局部变量

全局变量

形式参数

c语言中的数组

一维整型数组的定义

一维整型数组成员访问

一维整数数组的赋值

数组成员的个数

一维整型数组的实例

sizeof关键字

C语言中sizeof和strlen的区别

一维字符数组

一维字符数组的定义

一维字符数据的成员访问

一维字符数组赋初值(单个字符)

一维字符数组赋值(字符串)

一维数组地址及地址加1问题

二维整型数组

二维整型数组成员赋值

二维字符数组

二维字符数组定义格式

二维数组地址加1问题

多维数组


c语言中的函数

函数是一组一起执行一个任务的语句。每个 C 程序都至少有一个函数,即主函数 main() ;
您可以把代码划分到不同的函数中。在需要使用具体功能时随时调用;
函数声明告诉编译器函数的名称、返回类型和参数。函数定义提供了函数的实际主体。
C 标准库提供了大量的程序可以调用的内置函数。如printf,scanf等函数;

c语言中的函数的组成格式

在 C 语言中,函数由一个函数头和一个函数主体组成。

返回值类型  函数名(参数列表)

{

    //函数主体;

    return 0;

}

函数的封装实例

封装求和的函数;

int add(int a,int b) //封装一个名称为add的函数,其中有a,b 两个int类型的参数;
{
	return (a+b);  //返回值返回a+b;
}

c语言中函数的调用

函数在调用前需要将函数的声明;
调用函数时,传递所需参数,如果函数返回一个值,则可以存储返回值。

求和的函数的调用

int sum;   //定义一个int类型的sum;
sum = add(10,20); //将add函数的两个参数a,b传参为10和20;并用sum接收函数返回的值;

函数参数

如果函数要使用参数,则必须声明接受参数值的变量。这些变量称为函数的形式参数

形式参数就像函数内的其他局部变量,在进入函数时被创建,退出函数时被销毁。

当调用函数时,有两种向函数传递参数的方式:

调用类型描述
传值调用把参数的实际值复制给函数的形式参数。修改函数内的形式参数不会影响实际参数。
引用调用通过指针传递方式,形参为指向实参地址的指针,当对形参的指向操作时,就相当于对实参本身进行的操作。

指针作为函数参数问题

C语言中,指针作为函数参数是一种非常强大的功能,它允许我们将函数内部的操作影响到函数外部的变量。这是通过值传递的方式实现的,但在某些情况下可能会造成误解。
当我们在函数定义时看到 void swap(int p1, int p2),这里的 p1 和 p2 是形式参数,也称为形参。在函数调用时,如 swap(a, b),a 和 b 是实际参数,也称为实参。在函数调用过程中,实参的值会被复制到形参中,而不是形参指向内存地址的引用。因此,形参 p1 和 p2 是独立的,它们在函数内部进行的操作不会影响外部的 a 和 b。
为了解决这个问题,我们可以通过指针传递实参的地址。例如:


void swap(int *p1, int *p2) {
    int temp = *p1;  // 取出 p1 指向的值
    *p1 = *p2;      // 将 p2 指向的值赋给 p1 指向的位置
    *p2 = temp;     // 将 temp 的值赋给 p2 指向的位置
}


在这个 swap 函数中,p1 和 p2 是指向整数的指针。当调用 swap(&a, &b) 时,a 和 b 的地址被传递到函数中。函数内部通过指针操作交换了这两个地址指向的值,因此外部变量的值也被交换了。
指针作为函数参数的其他应用场景包括动态内存分配、数组操作和实现复杂的数据结构等。使用指针可以提高程序的效率,减少内存的使用,并允许更灵活的数据操作。然而,使用指针也需要谨慎,因为错误的指针使用可能导致内存泄漏、野指针访问和其他运行时错误。
总之,C语言中指针作为函数参数是提高程序性能和灵活性的关键,但也需要合理和谨慎地使用,以确保程序的正确性和稳定性。

数组作为函数参数问题

在C语言中,数组作为函数参数时,实际上传递的是数组的首地址,而不是整个数组。这意味着,如果你在函数内部修改了数组的值,那么这些更改会影响到函数外部的原始数组。下面是一个简单的示例,演示了如何将一个数组作为参数传递给函数,并在函数内部修改数组的值:

#include <stdio.h>

void func(int arr[], int size) {
    for (int i = 0; i < size; i++) {
        arr[i] *= 2;
    }
}

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    for (int i = 0; i < 5; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    func(arr, 5);
    for (int i = 0; i < 5; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    return 0;
}

在上面的示例中,我们定义了一个名为func的函数,该函数接受一个整数数组和数组的大小作为参数。在函数内部,我们通过遍历数组并将每个元素乘以2来修改数组的值。然后,在main函数中,我们声明了一个整数数组arr,并将其传递给func函数。最后,我们打印出修改后的数组。

需要注意的是,当数组作为函数参数传递时,如果数组的大小是固定的,那么它将被作为常量处理。这意味着你不能在函数内部更改数组的大小。如果你需要动态大小的数组,可以考虑使用指针来代替数组作为函数参数。

c语言中的作用域

局部变量

在某个函数或块的内部声明的变量称为局部变量。它们只能被该函数或该代码块内部使用。局部变量在函数外部是不可知的。

全局变量

全局变量是定义在函数外部。全局变量在整个程序生命周期内都是有效的,全局变量可以被任何函数访问。也就是说,全局变量在声明后整个程序中都是可用的。

注意:在程序中,局部变量和全局变量的名称可以相同,但是在函数内,如果两个名字相同,会使用局部变量,全局变量不会被使用。


形式参数

函数的参数,形式参数,被当作该函数内的局部变量,如果与全局变量同名它们会优先使用。
 

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

  • 全局变量保存在内存的全局存储区中,占用静态的存储单元;
  • 局部变量保存在栈中,只有在所在函数被调用时才动态地为变量分配存储单元。

c语言中的数组
 

一维整型数组的定义

int a[3];

一维整型数组成员访问

a[0] a[1] a[2]

C 语言支持数组数据结构,它可以存储一个固定大小的相同类型元素的顺序集合。

一维整数数组的赋值

定义时候赋初值

int a[3] = {1,2,3};
如果数组中赋值了个别成员后面没有赋值的成员都是0。
如果定义的时候不赋初值,后面只能通过遍历的形式挨个赋值。

数组成员的个数

  1. 数组成员的个数取决于方括号内的常量

    int a[6] = {123,456,789};

  2. 数组成员个数取决于赋值的成员个数

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

  1. 数组是构造类型,因为数组所占用字节的大小取决于数组成员的个数

  2. 数组是同种类型元素的集合。数组在内存上是连续存储的。

  3. 数组名是数组的首地址,它是一个常量(不能够自增或自减)

  4. 数组定义的格式:成员类型 数组名[成员个数];数组的类型是char [10],int [10];

  5. 数组中的成员表示a[0],a[1],...a[9]。c语言的编译器不会对数组进行越界检查

  6. 数组分为一维数组,二维数组和多维数组。

一维整型数组的实例

#include <stdio.h>

int main(int argc, const char *argv[])
{
    int arr[5]; //定义一维整型数组arr,内部有5个成员

    printf("请输入5个整数>");
    for(int i=0;i<5;i++){
        scanf("%d",&arr[i]);
    }   
    for(int i=0;i<5;i++){
        printf("arr[%d] = %d\n",i,arr[i]);
    }   
    return 0;                                                                                    
}

sizeof关键字


在C语言中,sizeof 是一个关键字,而不是一个函数。它用于获取数据类型或者变量所占用的内存大小,并以字节为单位返回结果。

#include <stdio.h>

int main(int argc, const char *argv[])
{
    int arr[5];
    printf("请输入> ");
    //sizeof是关键字,它的作用是获取类型所占的字节数
    //在如下实例中sizeof(arr) = 20字节
    //sizeof(arr[0])=4字节,两者相除就是数组成员的个数
    for(int i=0;i<sizeof(arr)/sizeof(arr[0]);i++){
        scanf("%d",&arr[i]);
    }   
                                                                                                 
    for(int i=0;i<sizeof(arr)/sizeof(arr[0]);i++){
        printf("arr[%d] = %d\n",i,arr[i]);
    }   
    return 0;
}

C语言中sizeof和strlen的区别

sizeof是关键字,sizeof可以用来求类型所占的字节数,

也可以用来获取变量所占的字节数。

strlen是一个函数,strlen只能用来获取字符串中字符的个数;

strlen在获取大小的时候遇到'\0'才会停止,而sizeof和'\0'无关;

strlen如果没有'\0',就无法获取大小;

一维字符数组

一维字符数组的定义

char arr[3];

一维字符数据的成员访问

arr[0] arr[1] arr[2]

一维字符数组赋初值(单个字符)

定义的时候赋初值

char arr[5] = {'h','e','l','l','o'};

char arr[3] = {0}; #将数组中所有的成员都赋值为0
先定义后赋值

char arr[5];

arr[0] = 'h';

arr[1] = 'e';

arr[2] = 'l';

arr[3] = 'l';

arr[4] = 'o';

一维字符数组赋值(字符串)

char arr[] = "hello";

注意:

如果上述的arr被赋值为"hello"字符串,字符数组的成员的个数是6。数组内部的成员分别是'h','e','l','l','o','\0'。('\0'为字符串结束符);

一维数组地址及地址加1问题

int a[3] = {111,222,333};

假如:a的地址0x1111;

&a[0] = 0x1111

&a[1] = 0x1115

&a[2] = 0x1119

a:数组名,它是数组的首地址,是一个常量(0x1111)

a[0]:数组中的第0个成员,a[0]对应的值是1111

&a[0]:数组中第0个成员的地址,是0x1111

&a:取整个数组的首地址,获取的地址是0x1111

a+1:地址移动一个元素类型的大小移动了int(4)字节,地址是0x1115

a[0]+1:a[0]中的值加了1,是112

&a[0]+1:地址移动一个元素的大小移动了四个字节,地址是0x1115

&a+1:移动了整个数组的大小,移动了12个字节,地址是0x111d

二维整型数组

二维整型数组的定义格式

 定义类型:类型名 数组名[ 行表达式 ][ 列表达式];行与列用常量表达式。

int arr[3][2];

arr:是二维数组的名字,它是常量,也是二维数组的首地址;

3:它有三行

2:它有两列

注:一个二维数组,在本质上是有多个一维数组构成。(每个一维数的大小必须相同)

二维整型数组成员赋值

把二维数组看作一维数组赋值

int arr[3][2] = {1,2,3,4,5,6};

把二维数组看作二维维数组赋值

int arr[3][2] = {{5,},{6,},{7,8}}

二维字符数组

二维字符数组定义格式

char arr[10][10]

二维字符数组赋初值

将二维字符数组看作一维数组赋值

char a[3][3] = {'h','e','l','l','o'};

将二维字符数组当成二维数组赋值

char a[3][3] = {{'h','e',},{'l','l','o'},};

对二维数组赋初值的时候可以缺省行成员(不能缺省列成员)

char a[][3] = {{'h','e',},{'l','l','o'}};

对二维数组赋值字符串

char a[][10] = {"ni","hao","beijing"};

二维数组地址加1问题

int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};

假如二维数组的首地址是0x1111

&a[0][0]:它是二维数组首个元素的地址,它的地址值是0x1111

a[0]:第0行的地址,它的地址值是0x1111

&a:对二维数组取地址,它的地址值是0x1111

&a[0][0]+1:移动了4字节

a[0]+1:移动4字节

&a[0]+1:移动了16字节

a+1:移动了16字节

&a+1:移动了48字节

多维数组

C 语言支持多维数组。多维数组声明的一般形式如下:

type name[size1][size2]...[sizeN];
例如,下面的声明创建了一个三维整型数组:
int threedim[5][10][4];

注意:可以创建任意维度的数组,但是一般情况下,我们创建的数组是一维数组和二维数组。
由于一般使用一维数组或二维数组,在这里多维数组我们就不详细介绍了;

本节完!

下一节我们会详细介绍c语言中很重要的部分,也是c语言中的重难点 "指针"!icon-default.png?t=N7T8http://t.csdnimg.cn/EbhMG

有问题或反馈请联系邮箱z1600306511@163.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

倾~~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值