C 语言教程 在线

1580c-return-arrays-from-function

srand((unsigned)time(NULL))是初始化随机函数种子:

  • 1、是拿当前系统时间作为种子,由于时间是变化的,种子变化,可以产生不相同的随机数。计算机中的随机数实际上都不是真正的随机数,如果两次给的种子一样,是会生成同样的随机序列的。 所以,一般都会以当前的时间作为种子来生成随机数,这样更加的随机。
  • 2、使用时,参数可以是unsigned型的任意数据,比如srand(10);
  • 3、如果不使用srand,用rand()产生的随机数,在多次运行,结果是一样的。

参考如下:

void test_rand(void)
{
    unsigned long n;
    srand((unsigned)time(NULL));
    for(int i = 0; i < 100; i++)
    {
        n = rand();
        printf("d\n", n);
    }
}

1579c-passing-arrays-to-functions

利用数组传参求平均数:

#include<stdio.h>

double outputs(float arr2[],int size);  //声明一个求平均数的函数

int main()
{
    int k;
    printf("你想求几个数的平均数:");
    scanf("%d",&k);
    int arr1[k];              // 创建一个存放k个数的一维数组
    for(int n = 0;n < k;n++)    // 使用 for 循环依次向数组添加元素
    {
        printf("请输入第%d个数:",n+1);
        scanf("%f",&arr1[n]);
    }
    printf("平均数为:%.4f\n",outputs(arr1,k));  // 向平均数函数赋值并输出结果(保留4位小数)
}
double outputs(float arr2[],int size)    // 定义平均数函数并传值
{
    double sum = 0;
    for(int i = 0;i < size;i++)   // 使用 for 循环求和
    {
        sum += arr2[i];
    }
    return sum/size;       // 返回平均值
}

1578c-passing-arrays-to-functions

二维数组传递给函数

列举 C 语言传递二维数组的方法。

方法1: 第一维的长度可以不指定,但必须指定第二维的长度:

void print_a(int a[][5], int n, int m)

方法2: 指向一个有5个元素一维数组的指针:

void print_b(int (*a)[5], int n, int m)

方法3: 利用数组是顺序存储的特性,通过降维来访问原数组!

void print_c(int *a, int n, int m)

如果知道二维数组的长度,当然选择第一或者第二种方式,但是长度不确定时,只能传入数组大小来遍历元素啦。

#include <stdio.h>
/*********************************
* 方法1: 第一维的长度可以不指定
*        但必须指定第二维的长度
*********************************/ 
void print_a(int a[][5], int n, int m){ 
    int i, j;
    for(i = 0; i < n; i++) {
        for(j = 0; j < m; j++) 
            printf("%d ", a[i][j]); 
        printf("\n"); 
    } 
} 

/***************************************** 
* 方法2: 指向一个有5个元素一维数组的指针
*****************************************/ 
void print_b(int (*a)[5], int n, int m) { 
    int i, j;
    for(i = 0; i < n; i++) { 
        for(j = 0; j < m; j++) 
            printf("%d ", a[i][j]);
        printf("\n"); 
    } 
}

/*********************************** 
* 方法3: 利用数组是顺序存储的特性, 
*       通过降维来访问原数组!
***********************************/ 
void print_c(int *a, int n, int m) { 
    int i, j; 
    for(i = 0; i < n; i++) { 
        for(j = 0; j < m; j++) 
            printf("%d ", *(a + i*m + j));
        printf("\n"); 
    } 
}
int main(void) 
{ 
    int a[5][5] = {{1, 2}, {3, 4, 5}, {6}, {7}, {0, 8}}; 

    printf("\n方法1:\n");   
    print_a(a, 5, 5); 

    printf("\n方法2:\n");   
    print_b(a, 5, 5);   

    printf("\n方法3:\n");   
    print_c(&a[0][0], 5, 5); 

//    getch(); 
    return 0; 
} 

1577c-passing-arrays-to-functions

二维数组传递给函数

如果我们想将二维数组作为实参传递给某个函数,如下代码是有问题的:

double * MatrixMultiple(double a[][], double b[][]);

原因可以简单理解为:编译器并没有那么高级,在二维以上的数组一定要规定一个最高维数:

double * MatrixMultiple(double a[][2], double b[][3]);  /* 这才是正确的 */

1576c-multi-dimensional-arrays

二维数组在逻辑上是方阵,由行和列组成。

但是二维数组在物理上是线性的,按行来依次进行存放,内存是连续的。

二维数组名的步长是一行的长度,比如一下例子中:

age + 1 address is 00EFFC04
age + 2 address is 00EFFC14

因为每一行有四个元素,每个int类型的元素占四个字节,一行有16个字节,所以数组名age加1后地址增加了16个字节说明数组名的步长位一行的长度。

具体到每一个元素加1的时候,地址增加的是一个元素所占字节的大小,因此元素的步长即为元素本身的大小,例如:

age[2][0] + 0 address is 00EFFC14
age[2][0] + 1 address is 00EFFC18

示例及运行结果:

#include <stdio.h>

int main()
{
    int age[6][4];
    for (int i = 0; i < sizeof(age)/sizeof(age[0]) ; i++)
    {
        printf("age + %d address is %p\n",i, age + i);
    }
    for (int i = 0; i < sizeof(age) / sizeof(age[0]); i++)
    {
        for (int j = 0; j < sizeof(age[0]) / sizeof(int); j++)
        {
            printf("age[%d][0] + %d address is %p\n",i,j,&age[i][0]+j);
        }

    }
}

输出结果:

age + 0 address is 0x7fffd98b9400
age + 1 address is 0x7fffd98b9410
age + 2 address is 0x7fffd98b9420
age + 3 address is 0x7fffd98b9430
age + 4 address is 0x7fffd98b9440
age + 5 address is 0x7fffd98b9450
age[0][0] + 0 address is 0x7fffd98b9400
age[0][0] + 1 address is 0x7fffd98b9404
age[0][0] + 2 address is 0x7fffd98b9408
age[0][0] + 3 address is 0x7fffd98b940c
age[1][0] + 0 address is 0x7fffd98b9410
age[1][0] + 1 address is 0x7fffd98b9414
age[1][0] + 2 address is 0x7fffd98b9418
age[1][0] + 3 address is 0x7fffd98b941c
age[2][0] + 0 address is 0x7fffd98b9420
age[2][0] + 1 address is 0x7fffd98b9424
age[2][0] + 2 address is 0x7fffd98b9428
age[2][0] + 3 address is 0x7fffd98b942c
age[3][0] + 0 address is 0x7fffd98b9430
age[3][0] + 1 address is 0x7fffd98b9434
age[3][0] + 2 address is 0x7fffd98b9438
age[3][0] + 3 address is 0x7fffd98b943c
age[4][0] + 0 address is 0x7fffd98b9440
age[4][0] + 1 address is 0x7fffd98b9444
age[4][0] + 2 address is 0x7fffd98b9448
age[4][0] + 3 address is 0x7fffd98b944c
age[5][0] + 0 address is 0x7fffd98b9450
age[5][0] + 1 address is 0x7fffd98b9454
age[5][0] + 2 address is 0x7fffd98b9458
age[5][0] + 3 address is 0x7fffd98b945c

可以看到每一个元素占了四个字节的大小,并且这24的元素的地址是连续的。