C语言:数组

# 一维数组的创建和初始化
数组的创建:在创建数组时,我们必须定义数组的类型和大小,数组的大小不能为0,数组中的元素类型都是相同的。


在内存中的储存
char a1[]={'a','b','c'}----------'a','b','c'
char a2[3]=''abc''-----------'a','b','c','\0'
char *p=''abc''-------------*p=''abc''

     

# 一维数组的使用

下标从零开始a[0];数组的大小可以通过计算得到。(sz = sizeof(a)/sizeof(a[0]));

 

# 一维数组在内存中的存储大小


结果;


由低到高 依次排序;

# 一维数组的指针访问


  **数组名其实存放的就是首元素的地址**
 


 从输出结果我们可以看出,我们定义了一个指针p,指向arr,然后我们通过指针来访问数组。

# 二维数组创建与初始化
1.列数不可以忽略
例子:

没有初始化的都按0来处理

# 二维数组的使用
二维数组的使用也是通过下标方式 

结果;

# 二维数组在内存中的存储

例子:

//将arr逆置,存放在brr中

# 有关数组的运算

关于数组我们必须要学会有关数组的一些运算。 
eg:

#include<stdio.h>

int main()
{
    //一维数组
    int a[] = { 1, 2, 3, 4 };
    printf("%d\n", sizeof(a));//16  
    //1.数组名单独放在sizeof内部,数组名表示整个数组,所以sizeof(数组名)计算的是是数组总大小,单位是字节
    //2.&数组名,数组名表示整个数组,所以&数组名取出的是整个数组的地址
    //3.除此之外,所有的数组名都表示首元素的地址
    printf("%d\n", sizeof(a + 0));//4    a代表首元素地址,a+i代表第i个元素的地址,在32位平台下所有的地址的大小都是4个字节
    printf("%d\n", sizeof(*a));//4       a是首元素地址,*a是首元素--1,int型占4个字节大小
    printf("%d\n", sizeof(a + 1));//4    a是首元素地址,a+1是第二个元素的地址,它还是一个地址
    printf("%d\n", sizeof(a[1]));//4     a[1]--第二个元素
    printf("%d\n", sizeof(&a));//4       &a虽然取出的是整个数组的地址,但它还是一个地址
    printf("%d\n", sizeof(*&a));//16     &a取出的是整个数组的地址,对它进行解引用,就是这个数组,这个数字的大小就是16
    printf("%d\n", sizeof(&a + 1));//4   &a取出的是整个数组的地址,加1跳过了整个数组(16个字节),但它还是一个地址
    printf("%d\n", sizeof(&a[0]));//4    &a[0]取的是第一个元素的地址
    printf("%d\n", sizeof(&a[0] + 1));//4   &a[0] + 1取的是第二个元素的地址

    return 0;
}

#include<stdio.h>

int main()
{
    //字符数组
    char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
    printf("%d\n", sizeof(arr));//6
    printf("%d\n", sizeof(arr + 0));//4        首元素地址
    printf("%d\n", sizeof(*arr));//1           首元素地址解引用是首元素(a),char类型占1个字节
    printf("%d\n", sizeof(arr[1]));//1         首元素
    printf("%d\n", sizeof(&arr));//4           数组的地址
    printf("%d\n", sizeof(&arr + 1));//4       下一个数组的地址,跳过了f
    printf("%d\n", sizeof(&arr[0] + 1));//4    第二个元素的地址

    printf("%d\n", strlen(arr));//随机值       strlen()求的是字符串长度,以'\0'为结束标志,这里并没有'\0',所以会一直往后数
    printf("%d\n", strlen(arr + 0));//随机值   还是从'a'开始数,但没有'\0',所以停不下来
    printf("%d\n", strlen(*arr));//程序会崩掉  strlen()接收的是一个地址,*arr是字符'a',这里把'a'的ASCII码值(97)作为一个地址访问,这一块的地址是不能被访问的
    printf("%d\n", strlen(arr[1]));//错误      传的是'b',和传的是'a'效果一样
    printf("%d\n", strlen(&arr));//随机值      &arr虽然取的是数组的地址,但数组的地址和数组首元素的地址是一样的,也是从‘a'开始数,但并没有'\0'
    printf("%d\n", strlen(&arr + 1));//随机值  但这个随机值和前边的随机值意义不同,它是把'a','b','c','d','e','f'跳过去了,从f后边开始数
    printf("%d\n", strlen(&arr[0] +1));//随机值   这个是从'b'开始往后数的


    return 0;
}

#include<stdio.h>

int main()
{
    char arr[] = "abcdef";
    printf("%d\n", sizeof(arr));//7   里边还有'\0',只不过我们看不到而已
    printf("%d\n", sizeof(arr + 0));//4     arr+0---首元素地址
    printf("%d\n", sizeof(*arr));//1   对首元素地址解引用是首元素
    printf("%d\n", sizeof(arr[1]));//1 第二个元素
    printf("%d\n", sizeof(&arr));//4    数组的地址也是地址
    printf("%d\n", sizeof(&arr + 1));//4  也是一个地址,不过这个地址在'\0'后边,跳过了整个数组
    printf("%d\n", sizeof(&arr[0] + 1));//4   从b开始的一个地址

    printf("%d\n", strlen(arr));//6   strlen()以'\0'为结束标志,但不算'\0'
    printf("%d\n", strlen(arr + 0));//6  arr+0与arr都代表首元素地址
    printf("%d\n", strlen(*arr));//错误   这传进来的不是一个地址,而是一个字符
    printf("%d\n", strlen(arr[1]));//错误
    printf("%d\n", strlen(&arr));//6    数组的地址也是首元素地址,地址的位置是一样的
    printf("%d\n", strlen(&arr + 1));//随机值   跳过了'\0',从'\0'往后数,不知道会数到哪里去
    printf("%d\n", strlen(&arr[0] + 1));//5    从第二个元素(b)开始往后数,遇到'\0'结束


    return 0;
}
2.
#include<stdio.h>

int main()
{
    char *p = "abcdef";
    printf("%d\n", sizeof(p));//4   p是指针变量,里边存的是a的地址
    printf("%d\n", sizeof(p + 1));//4   还是一个地址,不过是指向了b的地址
    printf("%d\n", sizeof(*p));//1      对a的地址解引用就是a
    printf("%d\n", sizeof(p[0]));//1    第一个元素(a)
    printf("%d\n", sizeof(&p));//4      &p取的是p的地址,p是一个指针,指向a的地址,但p的地址是什么并不知道
    printf("%d\n", sizeof(&p + 1));//4  &p+1--跳过了p的一个地址
    printf("%d\n", sizeof(&p[0] + 1));//4   还是一个地址,这个地址指向了b的地址


    printf("%d\n", strlen(p));//6        从a开始向后数
    printf("%d\n", strlen(p + 1));//5    从b开始向后数
    printf("%d\n", strlen(*p));//错误    *p就是a,strlen()要的是一个地址,而不是a的ASCII码值(97)
    printf("%d\n", strlen(p[0]));//错误
    printf("%d\n", strlen(&p));//随机值
    printf("%d\n", strlen(&p + 1));//随机值
    printf("%d\n", strlen(&p[0] + 1));//5    从b开始往后数

    return 0;
}

#include<stdio.h>

//二维数组
int main()
{    
    int a[3][4] = { 0 };
    printf("%d\n", sizeof(a));//48    整个数组有12个元素,每个元素都是int型
    printf("%d\n", sizeof(a[0][0]));//4   代表的是第一行第一列那个元素
    printf("%d\n", sizeof(a[0]));//16   a[0]--第一行数组名,第一行总共有4个元素
    printf("%d\n", sizeof(a[0] + 1));//4   a[0]降级变为a[0][0]的地址,a[0]+1是a[0][1]的地址
    printf("%d\n", sizeof(a + 1));//4    a--首元素(第一行)地址,a+1--第二行地址
    printf("%d\n", sizeof(&a[0] + 1));//4    第二行地址
    printf("%d\n", sizeof(*a));//16   对第一行地址解引用就是第一行元素
    printf("%d\n", sizeof(a[3]));//16    这里有好多人会出错,认为这个数组并没有这么大,只有3行,不能访问第4行,其实这里并没有访问第4行,它只是一个类型(1行的大小)
    return 0;
}

# 数组作为函数参数

我们在写代码的时候,会将数组作为参数传给函数。 
eg:

void bubble(int arr[])
{
    int sz = sizeof(arr)/sizeof(arr[0]);//这是错误的
    ...
}

数组作为函数参数时,不会把整个数组传递过去,实际上只是把数组的首元素地址传递过去了。

 

//字符数组

//char arr[10]={'a','b','c','d'};//剩余6个位零;

//''\0''才为字符串

//零有以下几种表达方式;

  • 0
  • '\0'
  • NULL
  • flase

//'\0'为结尾标志,包含在字符序列的末尾

//%s:输出整个字符串

//%c:  输出或输入一个字符串

 

1.用数组来实现简单的哈希表

2.

当数组作为函数的参数进行传递时,数组就自动退化为同类型的指针。因此尽管函数GetSize的参数data被声明为数组,但它会退化为指针。

3.数组(从栈分配空间)

int *p=new int[40]();  在分配空间后,对每个int进行了默认的初始化操作。即p[n]的值(n的取值范围是0-39)都是为0的。

int *p=new int[40](0);  这样是起不到对数组初始化为0的效果的,而且语法是错误的。

int *s[8]; //定义一个指针数组,该数组中每个元素是一个指针,每个指针指向哪里就需要程序中后续再定义了。 
int (*s)[8]; //定义一个数组指针,该指针指向含8个元素的一维数组(数组中每个元素是int型)。 

区分int *p[n]; 和int (*p)[n]; 就要看运算符的优先级了。 
int *p[n]; 中,运算符[ ]优先级高,先与p结合成为一个数组,再由int*说明这是一个整型指针数组。 
int (*p)[n]; 中( )优先级高,首先说明p是一个指针,指向一个整型的一维数组。

正常的应该是用大括号,int *p=new int[40]{0,1,2,3,4};  

数组指针:只是一个指针变量,指向一个一维数组,它占有内存中一个指针的存储空间,

指针数组:是多个指针变量,以数组形式存在内存当中,占有多个指针的存储空间。

4.关联数组

 “关联数组”是一种具有特殊索引方式的数组。不仅可以通过整数来索引它,还可以使用字符串或者其他类型的值(除了NULL)来索引它。   详情查看:   http://baike.baidu.com/link?url=yYrNB5t4PrCvs-XfxfEM0ZZfALpsEi3FYopk1v0BuopUSWOr7mS0Lou8C-SzhDnSuv7BH5vKIoIblvi8GgUmGq

       关联数组和数组类似,由以名称作为键的字段和方法组成。   它包含标量数据,可用索引值来单独选择这些数据,和数组不同的是, 关联数组的索引值不是非负的整数而是任意的标量。这些标量称为Keys,可以在以后用于检索数组中的数值。

       关联数组的元素没有特定的顺序,你可以把它们想象为一组卡片。每张卡片上半部分是索引而下半部分是数值。

5.将字符串赋值给字符数组:

1.定义时直接用字符串赋值。 char a[10]="hello";但是不能先定义再赋值,即以下非法:char a[10];a[10]="hello";  

2.利用strcpy。 char a[10]; strcpy(a,"hello"); 

3.利用指针。 char *p; p="hello";这里字符串返回首字母地址赋值给指针p。另外以下非法:char a[10]; a="hello"; a已经指向在堆栈中分配的10个字符空间,不能再指向数据区中的"hello"常量。可以理解为a是一个地址常量,不可变,p是一个地址变量。

4.数组中的字符。

\n     换行
\r     回车
\f     换页符
\b     退格
\0     空格
\s     字符串
\t     制表符

\”     双引号

\’     单引号
\ddd     八进制字符串(ddd)
\uxxxx     16进制unicode字符串(xxxx)

5.存储方式

1。按列存储:(行长度 * (所在列 - 1) + 所在行 - 1) * 单元长度 + 起始地址 (6 * (6 - 1) + 6 - 1) * 5 + 1000 = 1175 

2.求地址:基地址+(n(i-1)+j-1)b=10+(100*5+5)*2=1020

6.关键字

slice和concat方法均返回新数组,

splice方法的主要作用就是对原数组进行增删改操作,返回值为截取删除掉的子数组

7.三维数组

每维个数=上限-下限+1

所以:

4-0+1 =5;

-3-(-1)+1 = 3;

7-5+1=3

最后就是:5*3*3 = 45

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值