linux c 数组大小,linux c数组和指针(详解)

linux c数组和指针(详解)

首页 计算机相关 linux c基础 linux c数组和指针(详解)

指针是c语言中最重要的同时也是最难掌握的,因为数组跟指针息息相关,所以放在一起讲解。//声明数组

int arr[3];

int arr[3] = {1,2,3};

#非字符串

char str_arr = {'f','r','e','e','c','l','s'};

#字符串

char str = {'f','r','e','e','c','l','s','\0'};

//由编译器自动指定数组大小

int arr[] = {1,2,3}

//多维数组

int arr[2][2] = {{1,2}, {3,4}}

数组变量名本身就是数组的地址,数组跟指针的关系很密切int arr[] = {1,2,3}

//数组的地址等于数组第一个元素的地址

//这两者都是常量,不能改变,如果想改变可以赋值给一个指针,然后改变该指针的值

arr == &arr[0]

//数组名可以表示指针名,反之亦然

int *ptr = arr

ptr[0] == arr[0]

//当作为函数形参时,int [], int *是一样的

//相同的地址

arr + 2 == &arr[2]

//相同的值

*(arr + 2) == arr[2]

//第1个元素值加2,因为*的优先级高于+

*arr + 2

指针的加减会根据指针类型的存储单元倍数移动下面的例子中:int型指针+1实际上指针位置移动了4(我的centos7 64位int占4个字节)long型指针+1实际上指针位置移动了8(我的centos7 64位long占8个字节)#include

int main(){

int arr[3] = {1,2,3};

long arr_l[3] = {1,2,3};

int *ptr = arr;

long *ptr_l = arr_l;

//0x7ffd89358850 0x7ffd89358854

printf("%p %p\n", ptr, ptr+1);

//0x7ffea17892d0 0x7ffea17892d8

printf("%p %p\n", ptr_l, ptr_l+1);

}

指针求差,比较:2个指针必须在同一个数组里,差值就是他们之间相差几个存储单元#include

int main(){

int arr[6] = {1,2,3,4,5,6};

int *ptr_1 = &arr[2];

int *ptr_2 = &arr[4];

//2 -2

printf("%d %d\n", ptr_2 - ptr_1, ptr_1 - ptr_2);

//1 0

printf("%d %d\n", ptr_2 > ptr_1, ptr_2 < ptr_1);

//相加直接报错

//printf("%d %d\n", ptr_2 + ptr_1, ptr_1 + ptr_2);

}

解引用未初始化的指针int *pt;

*pt = 5; //严重错误

因为创建一个指针时系统只分配了储存指针本身的内存,并未分配存储数据的内存。

进阶例子#include

int main(){

int arr[6] = {1,2,3,4,5,6};

int *ptr = arr;

int total = 0;

//结合律优先级相同的从右往左

//所以右边的ptr指针先++再求值,所以ptr已经指向数组第二个值

//而total是先加上ptr指向的值,然后ptr++

total += *ptr++;

/*等同于

total = total + *ptr

ptr++;

*/

printf("%d %d", total, *ptr); //1 2

total += *++ptr;

/*等同于

total = total + *(ptr+1)

ptr++;

*/

printf("%d %d", total, *ptr); //4 3

}

备注:有关优先级的操作尽量使用括号,免得影响代码阅读

指针和数组int arr[2][2] = {{1,2}, {3,4}};

1.arr是数组首元素的地址,二维数组的首元素是arr[0](是arr[0][0]的地址),所以*(arr[0])就是arr[0][0]。

2.*arr代表数组首元素(arr[0])的值,而arr[0]是一个数组,数组本身是地址,所以*arr == &arr[0][0]。

3.**arr与*&arr[0][0]等价

简而言之,arr是地址的地址,要解引用2次才能得到原始值,地址的地址就是指针的指针,数组维度越大,就越复杂,这就是为啥指针那么难理解的原因。#include

int main(){

int arr[3][3] = {{1,2,3}, {3,4,5}};

//0x7ffd6688d660 0x7ffd6688d660 0x7ffd6688d660 0x7ffd6688d660

printf("%p %p %p %p\n", arr, arr[0], &arr[0], &arr[0][0]);

//0x7ffd6688d668 0x7ffd6688d664 0x7ffd6688d668 0x7ffd6688d664

printf("%p %p %p %p\n", arr+1, arr[0]+1, &arr[0]+1, &arr[0][0]+1);

}

arr                    一个指向第一个数组的指针(数组指针,也就是指针的指针)arr+1                由于arr是数组指针存储单元为数组大小,所以会往后移动一个数组,即&arr[1]

*(arr+1)            第二个数组的值即&arr[1][0]

*(arr+1)+1        即&arr[1][1]

*(*(arr+1) + 1)    即arr[1][1]#include

int main(){

int arr[3][3] = {{1,2,3}, {3,4,5}};

//0x7ffe4c7472b0 0x7ffe4c7472bc 0x7ffe4c7472bc 0x7ffe4c7472c0 4

printf("%p %p %p %p %d\n", arr, arr+1, *(arr+1), *(arr+1) + 1, *(*(arr+1) +1 ) );

//0x7ffe4c7472b0 0x7ffe4c7472bc 0x7ffe4c7472bc 0x7ffe4c7472c0 4

printf("%p %p %p %p %d\n", arr, &arr[1], &arr[1][0], &arr[1][1], arr[1][1] );

}

再来看下面2个声明的区别,它们都是指针的指针一个是指针(可以改变自己,比如说自增)一个是指针数组(不能改变自己)int (* ptr)[2];

声明了1个指针ptr,它指向了一个数组,该数组包含2个int值。

int * pax[2];

声明了一个指针数组pax,它里面包含2个int型指针。

例子#include

int main(){

int (*ptr)[2];

int arr[2][2] = {{1,2}, {3,4}};

ptr = &arr[0];

//1 2

printf("%d %d\n", ptr[0][0], ptr[0][1]);

printf("%d\n", **(++ptr)); //3

int * pax[2];

pax[0] = arr[0];

pax[1] = arr[1];

//1 2

printf("%d %d\n", pax[0][0], pax[0][1]);

//报错因为pax为数组变量,不能改变自己

printf("%d %d\n", **(++pax));

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值