首页 > 其他分享 >C语言数组

C语言数组

时间:2023-06-01 18:03:09浏览次数:31  
标签:aaa int C语言 数组 array include 指针


数组概念

在C语言中, 数组属于构造数据类型。一个数组可以分解为多个数组元素,这些数组元素可以是基本数据类型或是构造类型。因此按数组元素的类型不同,数组又可分为数值数组、字符数组、指针数组、结构数组等各种类别。

C语言数组_c语言

  • 从内存角度,是一片连续的内存空间
    数组初始化:
//在编译时明确指定全部元素为0
int a[10] = {0};
//在程序运行时,重置内存块为0
memset(a,0,sizeof(a));

数组元素个数在初始化的时候可以明确指出也可以根据初始化列表元素个数确定。

数组类型

  • 数据类型:固定大小内存块的别名
  • 指针类型:依赖于指针所指向的内存空间的大小

C语言中的数组有自己特定的类型:由元素类型和数组长度决定
例:int array[5]的类型为int [5]
可以重命名数组类型,并用新的数组类型名命名数组变量,使用typedef关键字进行重命名

typedef int (MYINT5)[5];//MYINT5表示一个含有5个元素的int类型的数组 
MYINT5 array;//相当于int array[5];

数组名的技术盲点:

  1. 数组首元素的地址和数组地址是两个不同的概念
  2. 数组名代表数组首元素的地址,它是个常量
  3. 变量本质是内存空间的别名,一定义数组,就分配内存,内存就固定了。所以数组名起名以后就不能被修改了。
  4. 数组首元素的地址和数组的地址值相等,但只是值相等而已

C语言规定:

int a[10];
printf("得到整个数组的地址a: %d \n", &a);
printf("数组的首元素的地址a: %d \n", a);

数组指针类型

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#define ARRAY_SIZE 5
int main(void)
{
    int i = 0;

    typedef int (myArray)[ARRAY_SIZE];//重命名一个数组类型myArray,表示int [5]
    myArray array;//相当于int array[5];

    myArray * p_array = NULL;//使用数组类型定义一个(myArray数组类型的)指针,用于指向一个myArray的变量
    p_array = &array;//将指针变量指向数组类型的变量array,此时指针的步长是整个数组长度

    for(i= 0;i<ARRAY_SIZE;i++){
        (*p_array)[i] = i+1;//通过指针操作数组内存空间
    }

    for(i= 0;i<ARRAY_SIZE;i++){
        printf("%d\n",(*p_array)[i]);
    }


    printf("Hello World!\n");
    return 0;
}
直接定义数组指针变量

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#define ARRAY_SIZE 5

int main(void)
{
    int i = 0;

    int (*p_array)[ARRAY_SIZE] = NULL;//告诉编译器 给我分配一个指针变量
                                        //直接定义一个数组指针,相当于int (*p_myArray)[5];


    int array[ARRAY_SIZE]={0};

    p_array = &array;//将指针变量指向数组类型的变量array,此时指针的步长是整个数组长度

    for(i= 0;i<ARRAY_SIZE;i++){
        (*p_array)[i] = 2*i+2;//通过指针操作数组内存空间
    }

    for(i= 0;i<ARRAY_SIZE;i++){
        printf("%d\n",(*p_array)[i]);
    }


    printf("Hello World!\n");
    return 0;
}

多维数组

本质推演

多维数组名就是一个数组指针变量,指向除了最高维以外的剩余维数的数组

多维数组名是一个多级指针,取以后减少一级指针。同样的对于二级指针,取*以后变成一级指针,二级指针指向一块内存,常是一个数组,一级指针指向一个数组里面的元素。
n级指针的值和n-1级指针的值(就是地址相等)重合,拿二维数组来说,就是某一行整个行的地址(一个数组地址)和该行首元素的地址在相等,这是必然的,他们都是该片内存的起始位置,必然相等。但是他们的数据类型不一样。n级指针指向的内存块更多,n-1级指针指向的只是n级指针指向的内存块的一部分,常是其中的一个元素。
多维数组char a[i][j] ==> ((a+i)+j)转换技巧分析

示例程序

#define  _CRT_SECURE_NO_WARNINGS 
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
void main()
{
    int aaa[5][3];
    for (i = 0; i<5; i++)

    {
        for (j = 0; j < 3; j++)
        {
            aaa[i][j] = j + i + 1;
        }

    }
    for (i = 0; i<5; i++)

    {
        printf("\n");
        for (j = 0; j < 3; j++)
        {
            printf("aaa[%d][%d] = %d\t",i,j, aaa[i][j]);
        }
        printf("\n");
    }
    printf("aaa地址:%d\n", aaa);
    printf("aaa[0][0]地址:%d\n", &aaa[0][0]);
    printf("aaa+1地址:%d\n", aaa+1);
    printf("aaa[1][0]地址:%d\n", &aaa[1][0]);
    printf("*(aaa+1)地址:%d\n", *(aaa + 1));
    printf("*(aaa + 1)+1地址:%d\n", *(aaa + 1)+1);
    printf("aaa[1][1]地址:%d\n", &aaa[1][1]);
    printf("&aaa+1地址:%d\n", &aaa+1);
    printf("aaa[4][2]地址:%d\n", &aaa[4][2]);
    printf("hello...\n");
    system("pause");
    return;
}
运行结果

/**************
aaa[0][0] = 1   aaa[0][1] = 2   aaa[0][2] = 3

aaa[1][0] = 2   aaa[1][1] = 3   aaa[1][2] = 4

aaa[2][0] = 3   aaa[2][1] = 4   aaa[2][2] = 5

aaa[3][0] = 4   aaa[3][1] = 5   aaa[3][2] = 6

aaa[4][0] = 5   aaa[4][1] = 6   aaa[4][2] = 7
aaa地址:14023660
aaa[0][0]地址:14023660
aaa+1地址:14023672
aaa[1][0]地址:14023672
*(aaa+1)地址:14023672
*(aaa + 1)+1地址:14023676
aaa[1][1]地址:14023676
&aaa+1地址:14023720
aaa[4][2]地址:14023716
hello...
请按任意键继续. . .
************************/
a[i][j] === a[0+i][j] ==> *(a+i)[j] ===> *(a+i)[0 + j] ==> *( *(a+i) + j)

C语言数组_数组_02

参数退化

void printArray01(int a[3][5]) //最不好的代码
{
    int i, j, tmp = 0;
    for (i=0; i<3; i++)
    {
        for (j=0; j<5; j++)
        {
            printf("%d ", a[i][j]);
        }
    }
}

void printArray02(int a[][5]) //二维数组是一个指向一维数组的指针。所以函数参数不用关心有多少行,只需要给出每一行有多少列确定指针步长即可
{
    int i, j, tmp = 0;
    for (i=0; i<3; i++)
    {
        for (j=0; j<5; j++)
        {
            printf("%d ", a[i][j]);
        }
    }
}

void printArray03( int (*b)[5]) //直接定义一个指向int  [5]的数组指针
{
    int i, j, tmp = 0;
    for (i=0; i<3; i++)
    {
        for (j=0; j<5; j++)
        {
            printf("%d ", b[i][j]);
        }
    }
}

数组作函数参数

void f(int a[5]) ====》void f(int a[]); ===》 void f(int* a); 
void g(int a[3][3])====》 void g(int a[][3]); ====》 void g(int (*a)[3]);
一维数组 char a[30]====》    指针 char*
指针数组 char *a[30]    ====》指针的指针 char **a
二维数组 char a[10][30] ====》   数组的指针 char(*a)[30]

证明多维数组内存中是连续存储的

#define  _CRT_SECURE_NO_WARNINGS 
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

void printfArray01(int *array, int size)
{
    int  i = 0;
    for (i = 0; i < size; i++)
    {
        printf("%d ", array[i]);
    }
}
void main()
{
    int a[3][5];
    int i, j, tmp = 1;

    for (i = 0; i < 3; i++)
    {
        for (j = 0; j < 5; j++)
        {
            a[i][j] = tmp++;
        }
    }

    //把二维数组 当成  1维数组 来打印 证明线性存储
    printfArray01(*a, 15);

    printf("hello...\n");
    system("pause");
    return;
}

指针数组示例程序

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

int searchKeyword(char * table[],int count,char *keyword,int *pos)
{
    ////字符串数组char *table[]做函数参数
    int ret = 0;
    int i = 0;
    if (table == NULL || keyword == NULL || pos == NULL){
        ret = -1;
        return ret;
    }
    for (i = 0; i < count; i++){
        if (strcmp(table[i], keyword) == 0){
            *pos = i;
            return ret;
        }
    }
    if (i == count)
    {
        *pos = -1;
    }
    return ret;
}
#define DIM(a)  (sizeof(a)/sizeof(*a))
void main()
{
    char * src[] = {
        "while",
        "case",
        "static",
        "break"
    };
    int pos;

    searchKeyword(src, DIM(src), "case", &pos);
    printf("case is :%d\n",pos);

    searchKeyword(src, DIM(src), "break", &pos);
    printf("break is :%d\n", pos);

    system("pause");
    return;
}

指针数组的自我结束功能

指针数组最后一个元素用NULL或者’\0’或者0结尾可以表示指针数组结束,实现自我结束功能,而且三者实质一样

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
void main()
{
    int inum = 0;
    int pos = 0;
    int a[10];
    int i = 0;
    //指针数组  自我结束能力
    char*   c_keyword[] = {
        "while",
        "case",
        "static",
        "do",
        '\0'
    };

    char*   c_keyword2[] = {
        "while",
        "case",
        "static",
        "do",
        0
    };


    char*   c_keyword3[] = {
        "while",
        "case",
        "static",
        "do",
        NULL
    };

    for (i = 0; c_keyword[i] != NULL; i++)
    {
        printf("%s\n", c_keyword[i]);
    }
    printf("\n....\n");
    for (i = 0; c_keyword2[i] != NULL; i++)
    {
        printf("%s\n", c_keyword2[i]);
    }
    printf("\n....\n");
    for (i = 0; c_keyword3[i] != NULL; i++)
    {
        printf("%s\n", c_keyword3[i]);
    }

//三个运行效果一模一样
    system("pause");
}


标签:aaa,int,C语言,数组,array,include,指针
From: https://blog.51cto.com/u_16147764/6397245

相关文章

  • c语言结构体
    定义结构体变量structStudent{char*name;intage;intscore;};voidmain(){structStudentst1;system("pause");}#include<stdlib.h>#include<string.h>#include<stdio.h>typedefstructStudent{char*nam......
  • C语言链表
    #define_CRT_SECURE_NO_WARNINGS#include<stdlib.h>#include<string.h>#include<stdio.h>/*structTeacher{charname[64];intid;char*p;char**p2;};typedefstructTeacherTeacher;*/typedefstructStudent......
  • 数组的应用以及二维数组
    1.Arrays工具类的使用类的全路径:java.util.Arrays举例:sort()方法作用:升序查询2.求最大值int[]scores=newint[5];intmax=0;System.out.println("请输入5位学员的成绩:");Scannerscanner=newScanner(System.in);for(inti=0;i<scores.length;i++){scores[i]=sc......
  • 数组去重方法总结
    //基于单key或无key去重,单key一般是对象的id,无key就是元素本身是非对象exportfunctionuniqueArr(arr,key){letres;if(key){res=[...newMap(arr.map(t=>[t[key],t])).values()]}else{res=[...newSet(arr)]}returnre......
  • Mysql json数组解析方法
    一、背景在表job_position需要对json数组进行解析,查找json数组对象中的数据 首先想到查找mysql的关于json的函数,这边做个记录。二、解决方案2.1 JSON_EXTRACT(json字段,'$.属性名称')需要了解函数 JSON_EXTRACT(json_doc, path[, path]...)  从json中提取数据,JSON_E......
  • 单元测试及C语言的几个例子
     一、单元测试介绍单元测试是软件开发中的一种测试方式,它主要是对代码中最小可测试单元进行检查和验证。通常来说,单元测试的实施应该在整个软件开发周期的早期就开始,最好是在代码编写过程中就边写边测试,以及在执行集成和系统测试之前启动。下面是单元测试的详解:单元测试的目的:单元......
  • 删除有序数组中的重复项
      给你一个升序排列的数组nums,请你原地删除重复出现的元素,使每个元素只出现一次,返回删除后数组的新长度。元素的相对顺序应该保持一致。然后返回nums中唯一元素的个数。考虑nums的唯一元素的数量为k,你需要做以下事情确保你的题解可以被通过:更改数组nums......
  • 如何在Java中创建数组列表
    为了在Java中存储动态大小的元素,我们使用了ArrayList。每当添加新元素时,它会自动增加其大小。ArrayList实现Java的List接口和Java的Collection的一部分。由于其功能和灵活性,它被广泛使用。ArrayList的关键点An ArrayList是一个可调整大小的数组,也称为动态数组。它根据新元素增加其......
  • Linux系统下C语言的编程技巧
    Linux系统能够为人们提供更加安全实用的效果,保证计算机系统能够稳定的运行。利用Linux系统下首先要进行C语言的编程,掌握编程的技巧能够更好的发挥计算机的作用。如何掌握Linux系统下计算机C语言的编程技巧是计算机发展的关键要素。本文对Linux系统下计算机C语言的编程技巧进行相......
  • 6567: 清点人数 树状数组
    描述 NK中学组织同学们去五云山寨参加社会实践活动,按惯例要乘坐火车去。由于NK中学的学生很多,在火车开之前必须清点好人数。初始时,火车上没有学生。当同学们开始上火车时,年级主任从第一节车厢出发走到最后一节车厢,每节车厢随时都有可能有同学上下。年级主任走到第m节车......