C语言-指针数组

指针数组

本质是数组 只是每个元素的类型是指针。

图示

代码示例

#include <stdio.h>

int main() {
    int num1 = 10;
    int num2 = 20;
    int num3 = 30;
    int num4 = 40;

    int *arr[4] = {&num1, &num2,&num3,&num4};
    int n = sizeof(arr) / sizeof(arr[0]);

    for (size_t i = 0; i < n; i++)
    {
        printf("%d ", *arr[i]);
    }
    return 0;
}

一维数组

代码示例

#include <stdio.h>

int main() {
    // 1.定义数组
    int arr[5] = { 10,20,30,40,50 };
    //arr作为类型
    printf("sizeof(arr) = %d\n",sizeof(arr));//数组的总大小

    //arr作为地址 代表首元素的地址
    printf("arr = %u\n", arr);//int *
    printf("arr+1 = %u\n", arr+1);

    printf("arr[1] = %d\n", arr[1]);//20
    printf("*(arr+1) = %d\n", *(arr+1));//20

    printf("---------------------\n");

    //arr[1]展开成*(arr+1):[]外边的值 在+的左边  []里面的值在+的右边
    printf("*(1+arr) = %d\n", *(1 + arr));//20
    printf("1[arr] = %d\n", 1[arr]);//20

    //[] 是 *() 的缩写(重要)
    for (int i = 0; i < sizeof(arr)/sizeof(arr[0]); i++)
    {
        //printf("%d ", arr[i]);
        printf("%d ", i[arr]);
    }
    printf("\n");

    //arr 作为地址 是首元素的地址
    //&arr[0] == &*(arr+0) == arr+0 == arr
    return 0;
}

程序运行结果

一维数组名

一维数组名是个指针常量,他存放的是一维数组第一个元素的地址 。

代码示例

#include <stdio.h>

int main(void)
{
	int a[5]; //a是数组名  5是数组元素的个数 元素就是变量  a[0]  -- a[4]
	//int a[3][4]; //3行4列 a[0][0]是第一个元素 a[i][j]第i+1行j+1列
	int b[5];
	
	//a = b;//error a是常量
	printf("%#X\n", &a[0]);
	printf("%#X\n", a);

	return 0;
}

程序运行结果

总结

  • 一维数组名是个指针常量

  • 它存放的是一维数组第一个元素的地址。

  • 常量是不能被改变的,也就是说,一维数组名是不能被改变的。

  • 数组名a存放的是一维数组第一个元素的地址,也就是a = &a。

下标和指针的关系

如果p是个指针变量,则p[i]永远等价于*(p+i)

# include <stdio.h>

int main(void)
{
	int a[5] = {1,2,3,4,5};
	int i;

	for (i=0; i<5; ++i)
		printf("%d\n", a[i]);  //a[i] == *(a+i) 
	return 0;
}

数组元素指针

代码示例

#include <stdio.h>

int main() {
    /**
     * 需求:定义一个指针变量 保存arr数组元素的地址
     */
     
    // 声明一个数组
    int arr[5] = { 10,20,30,40,50 };
    
    int *p = arr;//int *p;  p=arr;

    for (int i = 0; i < sizeof(arr)/sizeof(arr[0]); i++)
    {
        //printf("%d ", *(p + i));
        printf("%d ", p[i]);
    }
    printf("\n");
    
    printf("sizeof(arr) = %d\n", sizeof(arr));//20
    printf("sizeof(p) = %d\n", sizeof(p));//4
    
    /**
     *不要认为p只能保存首元素地址
     * 指针变量 起始指向哪儿?  p[x] == *(p+x)
     */
    int *p1 = &arr[2];
    printf("p1[1] = %d\n", p1[1]);//40

    printf("p1[-1] = %d\n", p1[-1]);//20
    
    return 0;
}

程序运行结果

案例说明

#include <stdio.h>

int main() {
    int arr[5] = { 10,20,30,40,50 };
    int *p = arr;
    printf("%d\n", *p++);//10;; *p;  p++
    printf("%d\n", (*p)++);//20 ; *p; (*p) = (*p) +1
    printf("%d\n", *(p++));//21
    printf("\n");
    return 0;
}

程序运行结果

10
20
21

同一数组的两个元素指针的关系

  • 指向同一数组的两个元素指针变量相减,是两指针变量间元素的个数
  • 指向同一数组的两个元素指针变量相加,无意义。
  • 指向同一数组的两个元素指针变量 p1 = p2(p1和p2指向同一处)。

一维数组需要几个参数

代码示例

# include <stdio.h>
/*
 a是个指针变量,所以上面局部函数f的pArr则要定义成指针函数才可以,而len则是int类型。
 代表接收的是整型的数字。fmin函数可以输出任何一个一维数组的内容
*/
// 声明函数
void fmax(int * pArr, int len)
{
    int i;

    for (i=0; i<len; ++i)
        printf("%d  ", pArr[i] );  //*pArr *(pArr+1) *(pArr+2)
    printf("\n");
}

int main(void)
{
    int a[5] = {1,2,3,4,5};
    int b[6] = {-1,-2,-3,4,5,-6};
    
    // 调用函数
    fmax(a, 5);  //a是 int *
    fmax(b, 6);

    return 0;
}

总结:

因为数组a的名称代表的是a的第一个元素的地址,所以在函数fmax中所定义的指针变量pArr和a是相同的,因为a也是指针变量类型。
也就是说pArr=a=a[0],pArr[1]=a[1]=*(pArr+1)=*(a+1),pArr[2]=a[2]=*(pArr+2) =*(a+2).

二级指针

图示

代码示例

#include <stdio.h>

int main() {
    int num = 10;
    int *p = &num;
    int **q = &p;

    printf("&num = %u\n", &num);
    printf("p = %u\n", p);
    printf("&p = %u\n", &p);
    printf("q = %u\n", q);
    printf("*q = %u\n", *q);
    printf("**q = %u\n", **q);
    return 0;
}

程序运行结果

&num = 6422036
p = 6422036
&p = 6422024
q = 6422024
*q = 6422036
**q = 10

地址变量

1、Sizeof(变量名/数据类型) 其返回值就是该变量或数据类型所占字节数

2、一个指针变量无论其指向变量占几个字节,其本身所占大小都是4字节。

3、*p具体指向几个字节,要靠前面类型确定,如果为int则为4字节,如果double则占8字节。

4、CPU与内存交互时有32根线,每根线只能是1或0两个状态,所有总共有232个状态。1 个状态对应 一个单元。

5、所有每个地址(硬件所能访问)的用4个字节保存(而不是一 位bit)

代码示例

# include <stdio.h>

int main(void)
{
	char ch = 'A';
	int i = 99;
	double x = 66.6;
	char * p = &ch;
	int * q = &i;
	double * r = &x;

	printf("%d %d %d\n", sizeof(p), sizeof(q), sizeof(r));

	return 0;
}

总结

一个变量的地址—用该变量首字节的地址表示。这也就是为什么指针变量始终只占4字节的原因。
posted @ 2020-05-17 14:33  guardwhy  阅读(563)  评论(0编辑  收藏  举报