数组应用小结(一)

来源:互联网 发布:ai技术 编程语言 编辑:程序博客网 时间:2024/05/22 00:10

数组是类型相同的对象的序列,其中的对象称为数组元素。
数组是C/C++中最常用的数据结构,由于数组名类似于指针,加上C/C++不会对数组边界进行检查,所以在数组运用过程中很容易出错。
下面总结下自己对数组的理解:

1. 数组名是一个"常量地址"(函数名也是),不能作为左值。
(按道理是不能对数组名再“取地址”的,编译系统做了“容错”处理,就是把“取常数地址的地址”与“常数地址”等价成一回事,如把 &hello处理成与 hello等同 , 所以,它们是一样的,编译程序这样做是故意的行为,仅仅是为了“容错”。)

数据名作为函数形参时,其全面沦落为一个普通指针。在失去其内涵的同时,它还失去了其常量特性,可以作自增、自减等操作,可以被修改。

为什么字符数组输出数组名为数组内容,而不是地址?
输出字符数组时,就会把首地址转换成char *p的,以字符串的形式输出。

2.数组传值(址)
一维数组,可以直接作为参数传值(同时传数组长度或定义结束标志)。
二位数组,可以转换为指针数组(char c[1][2] 转为 char (*c)[2]),再进行传递。
三维或以上,分解为一维数组(char c[1][2][3] 转换为 char (*(*c))[3]),再进行传递。

数组名做形参时,是传值还是传址?
数组就是一块内存, 数组名就是内存的首地址, 和指针是一样的, 传参传数组, 其实就是传了个指针, 不会复制一份的,

3.数组和指针
数组和指针被编译器按照不同方式处理,产生不同的代码;对于编译器来说,一个数组就是一个地址,而指针是一个地址的地址。
例如p[3]和*(p+3)都得到一样结果,但访问过程不一样,指针其实是多了一步,就是指针必须先去取它的地址的内容;而数组不用,直接加偏移地址取元素就可以了。

4.数组越界,strcpy
C/C++并不会对数组边界进行检查,当对数组赋值大于数组长度时,就会覆盖周边变量的值。

注意:
在使用strcpy时,数组不能作为源参数(const char *src),因为对src的拷贝以'\0'作为终止符,数组没有'\0',就会越界一直往下找,直到找到为至。
char *strcpy(char *dest, const char *src);

5.零长度数组应用
零长度数组不是所有的c标准都支持,gnu c支持,ansi c不支持,c++不支持。
 
零长度数组(通常是长度为1数组)一般放在结构体的结尾,用于不定长数据的“动态扩展”,所以在给结构体分配内存时必须预先分配足够的内存,保证后面扩展时不会超过预先分配的内存的大小。(结构体的里面的数据在内存中按顺序存储的。)

#include <iostream.h>/*测试数组边界*/void test_array_boundary(){    char array[] = {'a', 'b'};  char *p0 = array;//输出p0包含a,b和之后的随机值  char *p1 = "abcdefgh\0xyz"; //输出p1不包含\0之后的值       char p[1];    for(int i = 0;i<0xffff; i++)  {p[i]='a'+i; //程序将在某一时刻Segmentation fault,p[i]踩到了非法内存 cout<<p[i]<<endl;;  }}  /*测试数组越界,踩内存这个例子里x的值会被str的值覆盖。*/int test_overstep(){int x=35; char str[12];     //str = "abcdefghijk"; //数组名不能作为左值strcpy(str,"abcdefghijkl"); //共13个字母/*for(int i = 0; i<25; i++) //i = 24时 {  str[i] = 'a';}*/cout<<x<<endl;cout<<&x<<endl;cout<<str<<endl;cout<<&str<<endl;return 1;}/*0长度数组测试注意,当结构体中只包含零数组时候,求sizeof时值为0*/struct zeroStruct{  int length;  //char  bytes[1];  char  bytes[0];//这里的 bytes 可以作为扩展数组用};void test_zeroStruct(){  int length = 100;  zeroStruct *zero_p = (zeroStruct*)malloc(sizeof(zeroStruct)+length);    for(int i = 0; i<100; i++)    zero_p->bytes[i] = 'a'+i; } /*strcpy应用,输出为随机值strcpy结束标志是'\0',数组是不以'\0'为结束标志,所以这里直到拷贝找到'\0'*/void test_array_strcpy(){  char string[10], str1[10];  for(int i=0; i<10; i++)  {    str1[i] = 'a';  }  strcpy(string, str1 );  cout<<string<<endl; //输出为随机值}int main(){  //test_array_boundary();  test_overstep();  test_zeroStruct();   test_array_strcpy();    return 1;}


 


 

0 0
原创粉丝点击