C语言数组和指针相关细节

目录

一维数组

一、存储

 二、传参

三、使用malloc申请一维数组

1.溢出攻击

2.数组与sizeof相关使用

多维数组

1、基本类型多维数组

2、结构体类型多维数组

3、使用malloc申请多维数组

5.指针数组:可以存放该类型的指针或者该类型的数组

6.注意


一维数组

一、存储

在计算机存储数据时,只记开头第一个字节的地址,一个字节8bit

  • 为什么指针可以指向数组?(结构体指针可以指向结构体数组也是这样)

因为数组的地址和第一个数的地址一

 二、传参

1.借助指针

如果想把一个数组作为参数传入函数中,可以借助指针,具体如下 :

void m1(int*m)//参数是指针类型
{printf("%d\n",m);}
int main(arc(),char *argv[])
{int arr[]={1,2,3,4,5,6,7,8,9};
int w=100;
int *m1=&w;//指向一个整数
int *m2=arr;//指向一个数组
m1(&w);//传参传w的地址
m1(arr);//传参传数组首地址

2.直接传数组

特别注意:在写函数传参时,通过传递数组名参数,试图在函数内部求数组长度是不可以的

int fuction(int[]arr)
{
    int le;
    le=sizeof(arr)/sizeof(arr[0]);//不可以
    return le; 
}


因此:写函数时传参如果是指针类型且指向的是数组,要传入另外一个代表数组长度的数。如果传参仅仅是指针类型则代表传参是指针类型所指向的是一个数。

三、使用malloc申请一维数组

int*k=(int*)malloc(60);//申请60个字节的空间并按照int类型的数组进行切分
//int型是占4个字节,所以上面申请的是长度15的数组
k[20]=99;
printf("%d\n",k[20]);//越界操作,高级语言不允许这么操作,例如java会自动拦截,c和c++可能出现

1.溢出攻击

越界操作造成本程序占用其它程序的内存,这时其它程序戛然而止

2.数组与sizeof相关使用

int arr={1,2,3,4}//16
int*k=(int*)malloc(60);//指针类型
int m1=sizeof(k)//8,不能用sizeof输出指针所指向的大小,输出的是指针的大小
int m2=sizeof(*k)//4  此时输出的是指针所指向第一个数字的大小
int m3=sizeof(arr)//输出arr的内存大小4*4=16

 如果想通过sizeof来获取数组长度,应该这样写:

sizeof(arr)/sizeof(arr[0]);

多维数组

1、基本类型多维数组

#include<stdio.h>
#include<stdlib.h>
int main(int argc,char*argv[])
{int arr1[]={1,1,2,3};//层层递进,对应那个数由内到外代表层数
int arr2[3][4]={{1,1,3,5},{3,3,5,8},{2,2,8,9}};
int arr3[2][2][5]={
    {
        {1,1,1,3,7},{5,5,7,8,9}    
    },
    {
        {3,3,3,3,6},{1,1,1,6,9}    
    }
};
return 0;
}

2、结构体类型多维数组

注意:定义数组赋值时是拷贝,数组内的数据改变不会对原来的数据产生影响。

#include<stdio.h>
#include<stdlib.h>
typedef struct AA{
    int x1;
    int x2;
}A,B;
int main(int argc,char *argv[])
{
    A k1,k2,k3,k4,k5,k6,k7,k8,k9;
    int n1,n2,n3,n4,n5;
    A arr[]={k1,k2,k3};
    A arr2[[2][3]]={{k1,k2,k3},{k4,k5,k6}};
    //这里arr2[1][2]=k6,相当于拷贝了k6过去,如果修改了k6.x1不影响arr2[1][2].x1的值
    //************此处和java不一样,java相当于就是同一份
    k6.x1=66;//通过结构体
    arr2[1][2]=66;//通过结构体数组索引
    return 0;
}

arr[2][3]内存图示:

函数传参:结构体是拷贝了一份,数组是指同一个。(与数组赋值然后修改值区别开来)

#include<stdio.h>
#include<stdlib.h>
typedef struct AA{
    int x1;
    int x2;
}A,B;
void m1(A k)
{
    k.x1=11;
}
void m2(int k[])
{
    k[0]=100;
}
int main(int argc,char *argv[])
{  A k;
   int s1={1,2,3};
    m1(k);//传参结构体拷贝,修改不影响数值
    m2(s1);//数组是同一个,修改影响数值
}

3、使用malloc申请多维数组

int s1[]={1,2,3};
int *f1=(int*)malloc(40);//int*f1相当于一个一维数组,申请40个bit的空间按照int划分
//int*f1=(int*)malloc(sizeof(int)*10)等同上行
int**f2=(int**)malloc(sizeof(int*)*5);//二维数组:相当于申请了一个存放地址的指针数组,每个指针指向不同的数组
f2[0]=f1;
f2[1]=(int*)malloc(8);
f2[2]=s1;
int***f3=(int***)malloc(sizeof(int**)*2);//三维数组,指针的※数量代表了数组的维度。

5.指针数组:可以存放该类型的指针或者该类型的数组

例子:当声明A**arr:可以直接存放结构体指针,也可以存放一维结构体数组,也可以两者混存。

A**arr3=(A**)malloc(sizeof(A*)*10);
//申请十个结构体指针类型的空间,形成一个数组
A x;
A*K1=&x;
arr3[0]=k1;
arr3[0]->a=20;

再如以下指针数组可存放,int*和int的数组

int *s=&s1;
int box[]={0,1,2};
int**arr=(int**)malloc(sizeof(int*)*10);
arr[0]=s;
arr[0]=box;

6.注意(以下是由于语言演变引发的不规范性)

  • 对于基本数据类型:

 int*f1=(int*)malloc(sizeof(int)*10);//申请空间存放整形,但是可以存放整形的指针;
 int**bxx=(int**)malloc(sizeof(int*)*5);//申请空间存放指针,但是仍然可以存放整形int数;
  以上两个例子:(基本数据类型指针的特殊性)
虽然malloc申请的是指针/基本数据类型空间仍然可以存放基本数据类型/指针

  • 对于结构体类型

 A*arr=(A*)malloc(sizeof(A)*10);//申请的空间是按照结构体,不能存放结构体指针
A**arr=(A**)malloc(sizeof(A*)*10);申请的是结构体指针空间,不能存放结构体

 

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值