数组及指针-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对于处理越界问题也不是万能的,例如:
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。
以上为我在数组及指针的学习过程中总结的,希望各位同仁指正。
一、数组
在此我将分数组的定义及使用两个方面进行整理。
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。
以上为我在数组及指针的学习过程中总结的,希望各位同仁指正。
相关文章推荐
- c语言,指针与数组--指针与二维数组2
- C语言——结构体与指针引用&结构体数组与指针引用
- c语言中字符串常见初始化时的问题,以及字符串数组与指针区别的分析
- C语言中的指针与数组
- C语言中的指针数组和数组指针
- 【c语言学习笔记】指针数组和数组指针以及在做题的时候遇到的问题
- C语言指针和数组
- C语言 复杂指针的申明问题 数组指针 指针数组 函数指针 指针函数一览无遗! C/C++求职面试必备考点(四)
- C语言 多维数组和指针
- 【指针篇】C语言:指针与数组的区别,数组指针与指针数组的剖析。
- C语言 指针数组详解及示例代码
- C语言数组与指针
- C语言杂谈:指针与数组 (上)
- 【嵌入式开发】C语言 指针数组 多维数组
- 20170215C语言提升08_指针_02数组指针及指针数组及函数指针
- C专家编程之为什么C语言把数组形參当做指针:数组/指针实參
- 关于C语言数组与指针的联系一起
- C语言中指针与数组之异同
- C语言中指针和数组的几种访问形式
- C语言 内存分配 地址 指针 数组 参数 实例解析