• C语言指针和数组


    数组

    数组由一系列类型相同的元素构成,数组声明中包括数组元素的数目和元素的类型。

    int main() {
    	float candy[365];
    	int arr[3]={1,2,3}; //数组初始化:只有初始化的时候才可以这样赋值
    	int arr[3]={[2]=1}; //指定初始化第三个数为1
    	arr={1,2,3};//不起作用
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 方括号[]表示candy为数组,方括号内的数字指明了数字所包含的元素数目。
    • 如果要访问数组元素,可以使用下标数字来表示单个元素。下标数字也称索引,从0开始计数。

    只读数组:数组中的每个元素都是常量,需要在声明时进行初始化,因为声明之后,不可以再对它赋值。

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

    指针

    指针提供了一种用来使用地址的符号方法。数组标记实际上是一种变相使用指针的形式。

    数组名同时也是该数组首元素的地址。(常量)
    int arr[3] = {1,2,3};
    arr == &arr[0]; //数组名是该数组首元素的地址
    arr, &arr[0] 都代表首元素的内存地址,两者都是常量,可以将其作为赋给指针变量的值。

    在C中,对一个指针加1的结果是对该指针增加一个存储单元,对于数组而言,地址会增加到下一个元素的地址,而不是下一个字节。
    在这里插入图片描述
    声明指针时必须声明它所指向对象的类型,因为计算机需要知道存储对象所用的字节数,指针自增和自减时与字节数有关。

    • 指针的数值就是它所指向的对象的地址。地址的内部表现方式是由硬件来决定的。
    • 在指针前运用运算符*就可以得到该指针所指向的对象的数值。
    • 对指针加1,等价于对该指针的值加上它指向的对象的字节大小。
      dates + 2 == &date[2]; //相同的地址,dates+index是元素date[index]的地址。
      *(dates + 2) == dates[2]; // 相同的值

    函数,指针和数组

    可以在指针符号中使用数组名,也可以在数组符号中使用指针。

    //第一个参数是数组的地址,第二个参数是数组长度
    int sum(int *ar,int n){
    	int total = 0;
    	for(int i = 0;i < n;i++)
    		total += ar[i]; 
    	return total;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    只有在函数原型或者函数定义头的场合中,可以用int *ar代替int ar[]。无论在任何情况下,形式int *ar都表示ar是指向int的指针。int ar[]可以表示ar是指向int的指针,但是只是在声明形式参量时才可以使用。使用第二种形式可以提醒读者ar不仅是指向一个int数值,而且它指向的这个int是一个数组中的元素。

    正常定义的数组,其数组名存储的是数组第一个元素的地址,是一个常量,赋值或者自增自减运算不合法。

    把一个定义好的数组作为函数的形参时,此时数组名在编译时就会被当作指针变量来处理(形参肯定是一个指针变量,只有指针变量才能存放地址),此时这个形参的赋值或者自增自减运算是合法的。

    以指针传进去,而指针是一个地址变量,可以进行操作。
    在这里插入图片描述

    指针变量的操作

    • 赋值int *p = &a
    • 求值 int a = *p
    • 取指针地址int **q = &p
    • 将一个整数加给指针,这个整数都会和指针所指类型的字节数相乘,然后所得的结果会加到初始地址上,如果相加的结果超出了初始指针所指向的数组范围,那么这个结果是不确定的。

    保护数组内容

    在处理普通变量时,可以进行值传递,不改变原本的值。对于处理数组的函数,只能传递指针,原因是这样能使程序的效率更高,如果通过值向函数传递数组,那么函数中必须分配足够存放一份原数组的拷贝的存储空间,然后把原数组的所有数据赋值到这个新数组中,效率不够高。

    如果我们不希望修改该数组的值,可以用const
    int sum(const int ar[],int n);//函数声明
    此时数组的值无法修改。

    指针和多维数组的关系

    int arr[4][2];
    数组名arr是数组首元素的地址,首元素包含了两个int的数组,因此arr也是包含两个int的数组的地址。

    • arr=&arr[0], arr[0]=&arr[0][0],
    • arr+1 下一行,arr[0]+1,下一个
    • arr[0]是首元素arr[0][0]的地址,所以*arr[0] == arr[0][0], *arr = &arr[0][0], **arr = *&arr[0][0] = arr[0][0].

    图中的arr作为指针使用
    在这里插入图片描述

    定义指向多维数组的指针

    int (* pz)[2]; pz指向一个包含两个int值的数组。[]的优先级高于*,如果不加括号,那么定义的就是由两个指针组成的数组。

    参考《c primer(第五版)》

  • 相关阅读:
    区块链技术与人工智能如何相互赋能
    java mysql ssm框架的同城配送系统源码
    网络工程师的网络安全之路:应对威胁与保障数据
    基于 V2X 的车联网安全互信体系架构分析
    TCP/IP网络编程(9) 进程间通信
    使用gen 结合gorm 生成表模型文件
    Java基础练习(运算符的使用、Java的连续输入与输出、Java中分别输出整数、小数、字符串)
    块元素、行内元素、行内块元素
    (完整版)《光学教程》(姚启钧)课后习题解答
    【博学谷学习记录】超强总结,用心分享|架构师-基于redis的分布式锁
  • 原文地址:https://blog.csdn.net/wenningker/article/details/126122856