指针与数组

概念

数组:数组是存储多个相同类型数据元素的集合。

指针:是一种特殊类型的变量,存储其他类型的内存地址。

数组的存储方式

数组在内存中就是一段连续的空间,每个元素的类型都是一样的。

数组的大小

sizeof();

sizeof(数组名)     //所占内存的大小

sizeof(类型)      //某类型在内存中的大小

sizeof(数组名)/sizeof(类型)//内存中元素的个数

数组的初始化

一维数组

int array[] = {1,2,3};    //定义数组并维数组成员初试化值
int array[10] = {1,2,3,4,5,6,7,8,9,10};
int array[10] = {1,2,3,4,5}; //前5个成员初试化值,其余为0
int array[10] = {0}; //初试化值为0

//字符数组
char buf[] = "Hello world!";
char buf[10] = {1,2,3,4,5,6,7,8,9,10};

二维数组

int array[2][3] = {{1,2,3},{4,5,6}}; //定义一个2行3列二维数组,并初始化初值

通过指针访问字符串数组

在C语言当中,大多数字符串操作其实就是指针操作

char s[] = "hello world";
char *p = s;
p[0] = 'a';
printf("s = %s\n",s);  //aello world

char buf[100] = "hello world";
char *p = buf;
//*(p + 5) = 'a';
//p[5] = 'b';
p += 5;
*p = 'c';
p[3] = ' ';   
printf("buf = %s\n", buf);  //hellocwo ld

注意上面代码中的p[3] = ' ';这个p[3]所访问的位置是在p+=5;的基础上。

char buf[10] = {0,1,2,3,4,5,6,7,8,9};
char *p = buf;//数组首元素的首地址
char *p1 = &buf[0];
char *p2 = &buf[1];
char *p3 = &buf[2];

p3 += 1;
*p3 = 100;

p3 -= 2;
*p3 = 70;

printf("%d,%d,%d,%d\n",p,p1,p2,p3);
printf("%d,%d,%d,%d\n",*p,*p1,*p2,*p3);
printf("%d\n",p3-p1);

//p = buf;指针p指向了数据buf的首地址
//p3 += 1;指针向后移动一个字节指向地址 &buf[3]
//p3 -= 2;指针向前移动两个字节指向地址 &buf[1]
//p3-p1;两个指针相减可以得到两个数组元素的相对距离

注意:在写代码中遇到一个问题,在C语言中,char *p = &buf和char *p = buf都可以运行通过,而在C++中会报错

"int (*)[5]" 类型的值不能用于初始化 "int *" 类型的实体

原因是在C语言中类型检查不严格,不会报错,在C++中类型检查严格,赋值符号“=”号两边的数据类型必须是相同的,如果不同,则需要显示或隐式类型转换。在这里的p都是指针,数组首元素的地址。(&buf是指整个数组的首地址,而buf是指数组首元素的首地址

打印数组元素

int buf[10] = { 24,43,65,23,1,22,74,33,45,99 }

//通过指针来遍历输出
void MyPrint(int buf[])
{
    for(int i = 0;i < 10; i++)
    {
        printf("%d\n",*(buf + i));
    }
}

数组逆置

int array[10] = { 24,43,65,23,1,22,74,33,45,99 };

void InverseOperation(int array[])
{
    int *start = &array;
    int *end = start + 9;
    
    while( start < end )
    {
        int temp = *start;
        *start = *end;
        *end = temp;
        
        start++;
        end--;
    } 
}

求数组最大值

int array[10] = { 24,43,65,23,1,22,74,33,45,99 };

int Max(int *s)
{
    int value = *s;
    for(int i = 0; i < 10; i++)
    {
        if(*(s + i) > value)
            value = *(s + i)
    }
    return value;
}

求数组第二大值

int array[10] = { 24,43,65,23,1,22,74,33,45,99 };

int SMax(int *s)
{
    int max = *s;
    int s_max = *(s + 1);
    
    for(int i = 2; i < 10; i++)
    {
        if(max < *(s + i))//如果比最大值还大,那么当前值存放到最大值max中,而之前max的值存放到s_max中
        {
            max = *(s + i);
            s_max = max;
        }
        else if(max > *(s + i) && *(s +i) > s_max)//当前的值小于最大值,并且大于第二大值,则存放到s_max中
        {
            s_max = *(s +i);
        }
    }
    
    return s_max;
}

例子(IP地址的保存方法,通过一个int传递IPv4的地址)

IPv4地址的大小

最大:“255.255.255.255” = 15个字节

最小:“1.1.1.1” = 7个字节

通常:“192.168.0.1” = 11个字节

IP在网络中传递的时候是一个DWORD,就是一个int

将一个ip为192.168.3.1的地址存储到4个字节大小的int类型中(10进制转为16进制) <==>(16进制转10进制)

//假如有IP = 192.168.3.1

int ip = 0;
unsigned char *p = &ip;
*p = 192;
p++;
*p = 168;
P++;
*p = 3;
P++;
*p = 1;
printf("ip = %d\n",ip);


//整数转换为字符

void IpTochar(int n)
{
    unsigned char *p = &n;
    printf("%u.%u.%u.%u\n",*p,*(p+1),*(p+2),*(p+3));
}

将一个字符数组转换为整数

char s[100] = "192.168.3.1";

int CharToIp(char s[])
{
    int a;
    int b;
    int c;
    int d;
    
    sscanf(s,"%d.%d.%d.%d".&a,&b,&c,&d);
    
    int ip = 0;
    char *p = &ip;
    *p = a;
    p++;
    *p = b;
    p++;
    *p = c;
    p++;
    *p = d;
    
    return ip;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值