C语言初始数组+指针
文章目录
- 数组
- 一维数组
- 二维数组
- 数组名是数组首元素的地址
- 指针
- 指针类型的意义
- 野指针
- 1.非法访问
- 2.越界访问,数组越界
- 3.局部变量销毁
- 如何规律避免野指针
- 1.指针进行初始化
- 2.小心指针越界
- 3.指针指向的空间及时释放 ,既是值为NULL。
- 4.指针使用之前检查有效性
- 指针减指针
- 指针的关系运算
- 数组和指针
- 二级指针
数组
一维数组
int arr[10]={
0};
只初始第一个位置为0,剩下默认为0
[]为下标引用操作符。
数组名是数组首元素的地址。
一维数组在内存中连续存放。
一维数组在内存中连续存放。
随着下标的增长,地址是由低到高持续增长的。
二维数组
int arr[3][4]={
1,2,3,4,5,6,7,8,9,10,11,12};
其中第一个[]操作符表示行,第二个操作符[]表示列。
int arr[3][4]={
{
1,2,3,4},{
5,6,7,8},{
9,10,11,12}};
int arr[][4]={
{
1,2,3,4},{
5,6,7,8},{
9,10,11,12}};
在二维数组中,行可以省略,列不可以省略。
数组名是数组首元素的地址
但有两个例外
1.sizeof(数组名),在这里的数组名表示整个数组,计算的是整个数组的大小单位是字节。
2.&数组名,数组名表示整个数组,取出的是整个数组的地址。
指针
&a
拿到的是a的4个字节中第一个字节的地址
指针类型的意义
1.指针类型决定了,指针解引用的权限有多大。
2.指针类型决定了,指针走一步能走多远(步长)。
野指针
1.非法访问
int main()
{
int *p;
//p是一个局部的指针变量,局部变量不初始化的话,默认是随机值。
*p=20;
//非法访问内存
return 0;
}
2.越界访问,数组越界
int main()
{
int arr[10]={
0};
int* p=arr;
int i=0;
for(i=0;i<12;i++)
{
printf("%d",*(p+i));
}
//数组只占了10个位置,
//但访问的时候一直访问到了第12个位置
//导致了数组越界访问
return 0;
}
3.局部变量销毁
int *test()
{
int a=10;
return &a;
}
//这里的a是局部变量,在出
//test()函数时就被销毁了
int main()
{
int* p=test();
*p=20;
return 0;
}
如何规律避免野指针
1.指针进行初始化
当前不知道p应该初始化为什么地址的时候,直接初始化为 NULL
int* p=NULL;
2.小心指针越界
3.指针指向的空间及时释放 ,既是值为NULL。
free(p);
p=NULL;
4.指针使用之前检查有效性
int main()
{
int* p=NULL;
if(p!=NULL)
{
*p=10;
}
return 0;
}
总结: 一个指针变量不知道指向什么地方地时候,指向空指针。当它指向地空间被释放地时候也指向空指针。
指针减指针
得到是两个指针之间的元素变量个数(两个指针要指向同一块空间)
一小段strlen函数的实现
如果不懂可以在这篇博客中理解strlen函数http://t.csdn.cn/jxemH
int my_strlen(char* str)
{
char* start=str;
//将字符串首地址进行备份
while(*str!='\0')
{
str++;
}
//当没有遇到字符'\0'时,指针向后每次移动一位
return str-start;
}
指针的关系运算
标准规定
允许指向数组元素的指针与指向数组最后一个元素,后面的那个内存位置的指针进行比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。
数组和指针
int arr[2]={
0};
int *p=arr;
//以上*p=arr又可以表示为
arr[2]<==>*(arr+2)<==>*(p+2)<==>*(2+p)<==>*(2+arr)<==>2[arr];
二级指针
int main()
{
int a=10;
int* pa=&a;
//pa是指针变量,一级指针
int * *paa=&pa;
//paa也是个变量,&pa取出pa在内存中起始地址
//paa就是一个二级指针变量
return 0;
}
学的不是技术,更是梦想。
还没有评论,来说两句吧...