C语言学习之数组名和指针的关系区别

  1. 数组名是一个常量,不能赋值,包括自增自减( arr++ ,arr–, ++arr, --arr)

  2. 一级指针可以接收一维数组的数组名,然后一级指针可以被赋值。如 int *p=arr; 时,p++ p-- ++p --p还有p=…都是允许的。

  3. 二级指针不可以直接接收二维数组名,但可以用数组指针来接收(一个指针,指向的是数组)接收,如下:

    int arr[4][5] = {0};
    int **p = arr; //错误,后面解释
    int (*p1)[5] = arr;//正确, 使用方法:  *(*(p1+i)+j) 等价于 arr[i][j]
    

    在访问数组时,可以用数组名加减的方式(只要不改变数组名的值就行,因为它是常量,不允许被赋值),如:arr[i][j] 等价于 *(*(arr+i)+j)

    int **p = arr错误的原因在于,p是一个二级指针,当我想访问一个值时*(*(p+i)+j), 首先看*(p+i),这代表选中二维数组的某一行,然后 加上 j就代表选中i行,j列(i,j可以为0),再整体加上一个* 值就被取出来了。但是在 int **p = arr时,p会把整个arr数组当成一个整体,也就是说, p+1指向arr数组的结尾的下个地址。而我们期望的是p+1指向下标为1的行。所以,int **p =arr,如果取值(*(p+i)+j),ij不同时为0(同时为0是可以读出正确结果的,只有p进行加法时,+1的跨度就会是整个数组导致出错)。同理,如果声明数组指针int (*p1)[5] = arr; 就可以,因为这个指针p1的含义是p1是一个指针,它指向了一个长度为5个int整型数的数组,即它指向数组,它加1的话,会指向下一个数组(当然,小心使用,如果下边没有了数组,它同样会去访问,即使后边的空间已经不是数组了),它知道自身如果+1的话该指向哪里(p1每加1,实际上arr的地址会增加sizeof(int)*5, 即指向了下一行)

内存:

  1. 声明的局部变量、形参都在栈里,当声明一个char *str; 然后再 *str = ‘c’,这样写是不正确的。首先,char *str会在栈开辟一个4字节(32位系统)空间,用来存储一个指向char类型的地址值,但是由于没有初始化,里面的值是无用的,如果直接 *str,相当于访问了一个未知的地址,并将里面的值改为了’c’.
     
    如果声明一个局部变量 char str[20]; char *str2 = “hello”; 给数组名直接赋值是不正确的:str=str2。因为当声明数组时,是在栈中开辟20个char大小的内存,然后将首地址作为常量给str,也就是说,str代表的是栈的某个地址,我们可以给str所指向的空间及其后边的空间(共20B)赋值,但是如果想改变str的值,相当于是 地址 = 地址是不合法的,相反,如果我们开始声明的就不是数组而是char指针char *str,就可以,并且应该是必须给它赋上值初始化它,此时就不是地址=地址了,而是变量=地址,即将一个值赋给一个变量。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值