您的位置:首页 > 编程语言 > C语言/C++

数组及指针-C语言

2018-03-10 23:01 393 查看
    在今天的学习过程中,我掌握了C语言中数组及指针的相关概念及用法。
一、数组
     在此我将分数组的定义及使用两个方面进行整理。
1.数组的定义
    数组在定义时,无数据类型,例:  定义一个整型数组:int arr[10],且其中的10表示的是数组的长度。
2.数组的使用
    数组在使用时,无数据类型,例:  arr[3]=10,其中3表示的是下标。
3.在数组中,还有一个特别重要的概念-初始化。
    若完全不初始化,则在数组使用时,各位置上的值将为计算机随机赋值(例:int brr[10]//计算机将会为数组赋随机值);
    若只初始化一部分,则优先紧着前面的位置存放。即聚合类型若只初始化一部分,则剩余部分为0(例:int crr[10]={1,2,3,4}即为int crr[10]={1,2,3,4,0,0,0,0,0,0});
    在此,我将给出一个易出错的地方,即: int drr[2] = {1};
printf("%d\n",drr[0]/drr[1]);     在以上这段代码实现过程中,编译器将会出现报错,其原因为:drr[0]=1,drr[1]=0,而0不能做分母。
4.写一个数组打印函数#include <stdio.h>
void Show(int arr[10])
{
for(int i=0;i<10;i++)
{
printf("%d ",arr[i]);
}
printf("\n");
}
int main()
{
int arr[] = {1,2,3,4,5,6,7,8,9,10};

Show(arr);

return 0;
}     在以上代码循环部分,需注意一个问题‘i<10’比‘i<=9’要更好,那是因为在C中一般遵循“左闭右开”(即左边取等号,而右边不取)原则。
5.数组越界(非法访问内存,修改了别人的内存)问题的处理
     首先,在此需介绍一个问题,那就是局部变量的位置-栈。在此,我也将通过一段代码对数组越界问题进行分析,如下:#include <stdio.h>
int main()
{
int i;
int arr[10];
for(i=0;i<=10;i++)
{
printf("%d\n",i);
arr[i] = 0;
}
return 0;
}     以上代码为典型的栈处理数组越界打印问题,因为在循环过程,循环次数11超过数组长度10,即arr[10]越界修改了i的值,导致出现死循环。
    在此值得一提的是,VC6.0、DEV和Visual studio 2012的区别。
    VC6.0、DEV在数组存放时,无‘地雷’设置,是挨着存放的,且每次地址都一样,而Visual studio 2012不同,它会在两变量之间设置有两个‘地雷’防止越界,并且每次的地址都不同。对如下代码进行分析: int a;
int b;
int arr[10];
printf("%d,%d,%d\n",&a,&b,&arr);    在 VC6.0、DEV中,a与b地址间距为4,仅为b本身所占字节,b与数组arr地址间距则为40,仅为arr本身所占字节。
    在Visual studio 2012中,a与b地址间距为12,即两个‘地雷’所占字节+b本身所占字节(2*4+4),b与数组arr地址间距则为48,即两个‘地雷’所占字节+arr本身所占字节(2*4+10*4)。    但Visual studio 2012对于处理越界问题也不是万能的,例如:
#include <stdio.h>
int main()
{
int i;
int arr[10];

for(i=0;i<=10;i++)
{
printf("%d\n",i);
if(i == 10)
{
i += 2;
}
arr[i] = 0;
}
return 0;
}
     在if语句中‘ i+=2’操作由于跨越了‘地雷’的设防,导致程序也将出现bug。
6.一维数组数组名arr在如下两种情况表示整个数组
    (1)在定义数组的同一个函数中,sizeof(arr)
    (2)在定义数组的同一个函数中,&arr+1

     其它情况数组名arr表示数组首元素的地址。如下代码实现:#include <stdio.h>
int main()
{
int arr[] = {1,2,3,4,5,6,7,8,9,10,11};

printf("%d\n",sizeof(arr));//44
printf("%d,%d\n",&arr,&arr+1);//arr与arr+1地址间隔为44
return 0;
}
二、指针
    首先,需要了解一个概念,即‘指针==地址’。(int *p//整型的指针变量p;int x=10//整型变量存放整型值;int *p=100//整型地址变量存放整型地址值)
    (在此,穿插一个关于左右值的问题。例:a=50//a做左值;b=a//a做右值。)
    我将通过如下代码对有关指针进行理解: int a = 10;
int b = 20;
int *p = &a;//即p保存了a的地址
*p = 100;//a = 100;(跳到了它所保存的地址即a,p引用了a) 解引用(间接引用符 *)
p = &b;
*p = 200; // b = 200
int **pp = &p;
*pp = &a;//p = &a;
**pp = 1000;//a = 1000;
*pp = &b;//p = &b;
**pp = 2000;//b = 2000;    在以上代码中,应用到了解引用(间接引用符 *),那是因为指针变量比其它变量多了一个解引用(指针变量和其它变量一样,都是一个变量而已)。
    且通过以上代码可知:a-整型变量   、&a-整型地址变量  、 p-int * 、   &p-int **(二级指针)。(取一次地址,多一个*)
    注:有关‘*' 的有关用法:
    1.乘法(双目运算符   例:3*4)
    2.指针变量(在定义时体现,例:int *p=&a)
    3.解引用(也即间接引用符 *,在使用时体现,无数据类型,例:*p=100)
    有关指针的字节占用问题:在X86(32位平台)占4字节;在X64(64位平台)占8字节。
    有关赋值成立的条件:(1)数据类型一样;(2)窄的赋值给宽的,例:char可以赋值给int。
    以上为我在数组及指针的学习过程中总结的,希望各位同仁指正。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: