菜鸟学习历程【4】数组(2)、函数

来源:互联网 发布:淘宝买的lol号安全吗 编辑:程序博客网 时间:2024/06/06 07:35

数组(2)


一、一维数组


1.定义格式:类型说明符   数组名[常量表达式];

例如:int  a[10];


2.定义数组时,需要指定数组中元素的个数;

   若不指定数组元素的个数,可以通过初始化来确定。

   例如:int a[ ]  = {1, 2, 3, 4, 5};

   那么我们可以知道这个数组包含5个元素  


3.常量表达式可以包括常量和符号常量

   

4.初始化的几种方式

    1) 全部初始化:int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

  2) 部分初始化:int a[10] = {1, 2, 3, 4, 5};

         那么没有初始化的元素,系统默认设置为0;

  3)对一个数组全部初始化为0,可以写成如下形式:

                  int a[10] = {0};

        建议大家在涉及到数组时,要先初始化为0;


5.数组的地址

   声明:本作者习惯上称数组首元素为第0元素,这样符合数组下标含义;

   定义一个数组,以便进行说明: int a[5] = {1, 2, 3, 4, 5};



   假设数组首元素地址为0x100,那么对于一个整型数组元素而言,每个元素占4个字节,则第二个元素的地址是0x104;依次类推,最后一个元素的地址就是0x110;

   要说明的地方如下:

   1)数组名a表示数组首元素的地址,也就是a[0]的地址;

   2)数组名a+1与a[1]共同表示指向第1个元素的地址;

   3)&a表示a整个数组的首地址,因此&a、a 、a[0]表示的地址一致;

   4)&a与a的区别在于a的步长是一个元素,而&a的步长是一个数组,因此&a + 1表示的是下一个数组的首地址(或者说a这个数组最后一个元素的地址的下一个地址更为准确。)

1.printf("%p\n",a);printf("%p\n",&a[0]);printf("%p\n",&a);结果是:0x1000x1000x1002.printf("%p\n",a+1);printf("%p\n",&a[1]);printf("%p\n",&a+1);结果是:0x1040x1040x114

二、二维数组

1.定义格式:类型说明符   数组名[常量表达式1][常量表达式2];

   例如: int a[3][4];

   对于二维数组的理解,可以认为是存在一个一维数组,并且它的每一个元素也是一个一维数组;

2.数组的初始化

 1)全部初始化

       例如: int a[2][3] = {{1, 2, 3}, {4, 5, 6}};

 2)部分初始化

       例如: int a[3][4] = {{1, 2}, {0}, {1, 4, 5}};

       其余元素都为0

       另外一种形式为:

                  int a[3][4] = {0, 1, 2, 3, 4, 5, 6, 7};

       这种形式会按照数组元素的顺序进行初始化,其余的为0;

 3)如果在初始化数组时,并不完全指定数组的常量表达式,那么一定要确认数组的列数,否则编译不通过。

       例如:int a[][4] = {1, 2, 3, 4, 5, 6, 7};


 思考:对于数组a[3][4],下面哪一个不能表示a[1][1]?

 1)*(a[1] + 1)  a[1]表示第一行的首地址,也就是a[1][0]的地址,那么a[1]+1,就表示向后挪一个,而*表示取值

 2)*(&a[1][1]) &表示取地址,而*表示取值

 3)(*(a + 1))[1]   对于二维数组而言,a不再以元素作为步长,而是以一行元素作为步长,因此a+1表示第1行的首地址

 4)*(a + 5)错误,a+5表示第5行的地址,但对于a[3][4]而言,并不知道其指向何处


Tips:求数组长度

        int length  = sizeof(a) /siizeof(int);              //所有数组的长度都可以这么求



三、字符数组

1.定义格式:类型说明符   数组名[常量表达式];

   例如:char ch[10];

2.初始化:

   char ch[10] = {‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’};

   char ch[10] = "hello";

3.获取与输出:

    用scanf获取字符串:scanf("%s",ch);

    用scanf获取单个字符:scanf("%c",&ch);

    用scanf获取带有空格的字符串:scanf("%[^\n]",ch);

   

四、字符串处理函数

1.puts函数(输出)

puts(ch);     //作用等同于printf

2.gets函数(输入)

gets(ch);    //作用等同于获取带空格的字符数组

3.strcat函数(头文件string.h)

格式:strcat(字符数组1,字符数组2);

作用:连接两个字符数组中的字符串,把字符数组2接到字符数组1后面。输出字符数组1时,会输出两个连接的结果;

4.strcpy函数

格式:strcpy(字符数组1,字符数组2);

作用:拷贝字符数组2中的内容到字符数组1中,并且会覆盖字符数组1的内容

注意:字符数组1必须写的足够大;字符数组2也可以用一个字符串代替,例如:“hello world”。


Tips:strncpy函数

作用:指定拷贝的字节数;

strncpy(str, ptr, 2);   //指定ptr的前两个字节拷贝到str中

strncpy(str, ptr+1, 2);  //指定从ptr+1地址开始的两个字节拷贝到str中

strncpy(str+1, ptr+1, 2);  //指定从ptr+1地址开始的两个字节拷贝到str+1的地址

5.strcmp函数

格式:strcmp(字符数组1,字符数组2);

作用:逐字节比较两个字符数组的大小

           当str > ptr 时,返回值 > 0;

           当str < ptr 时,返回值 < 0;

           当str = ptr 时,返回值 = 0;


思考:往字符串的指定位置插入字符的方法;

1)可将插入位置后的字符向后挪一位;

2)可将插入位置后的字符copy到另一个数组,再将字符插入到原数组中,最后拼接两个数组;



函数

格式:

函数类型  函数名(形参列表)

{

      声明部分;

      执行部分;

}


Tips:声明与定义的区别

声明:例如:extern int i;

定义:例如:int i = 0;

声明不会分配内存空间,而定义会分配内存空间。


函数调用执行的6个过程(important!!!)

1)通过函数名找到函数的入口地址;

2)为形参分配内存空间;

3)值传递;

4)执行;

5)返回;

6)释放内存空间。


形参:定义函数时,括号内的参数,形参要加上数据类型;

实参:函数调用时,括号内的参数


注意:

1)尽量将非main函数写在main函数之前,如果要将函数写到main函数的后面,则必须在main函数之前声明该函数;

2)未初始化的全局变量为0,未初始化的局部变量为垃圾值;

3)不要返回局部变量的地址,因为返回后,会释放内存空间。


参数传递:值传递、地址传递

值传递:函数调用时,为形参分配单元,并将实参的值复制到形参中;调用结束,形参单元被释放,实参单元仍保留并维持原值;

特点:形参与实参占用不同的内存单元;单向传递


地址传递:函数调用时,将数据的存储地址作为参数传递给形参
特点:形参与实参占用同样的存储单元;“双向”传递;实参和形参必须是地址常量或变量;节约内存空间;


                                         

原创粉丝点击