第32课 数组指针和指针数组分析

1. 数组的类型

(1)C语言中的数组有自己特定的类型

(2)数组的类型由元素类型数组大小共同决定。(如int array[5]类型为int[5]

2. 定义数组类型

(1)C语言中通过typedef为数组类型重命名:typedef type(name)[size];

  ①数组类型:如typedef int (AINT5)[5]; typedef float (AFLOAT10)[10];

  ②数组定义:AINT5 iArray; AFLOAT10 fArray;

3. 数组指针

(1)数组指针用于指向一个数组

(2)数组名是数组首元素的起始地址,但并不是数组的起始地址。

(3)通过将&作用于数组名可以得到数组的起始地址

(4)定义数组指针的两种方式:

  ①可通过数组类型定义数组指针:ArrayType* pointer;

  ②可以直接定义:type (*pointer)[n]; //其中pointer为数组指针变量名,type为数组的元素类型n为数组的大小

【实例分析】数组类型与数组指针

#include <stdio.h>

typedef int (AINT5)[5];       //数组类型:int[5]
typedef float (AFLOAT10)[10]; //数组类型:float[10]
typedef char (ACHAR9)[9];     //数组类型:char[9]

int main(){

    AINT5 a1;  //定义变量a1为int[5]类型的数组
    float fArray[10];//普通定义数组的方法
    AFLOAT10* pf = &fArray;//合法。&表示取的是整个数组地址(相当于
                           //float[10]类型的数组指针。
    ACHAR9 cArray;

    char(*pc)[9] = &cArray;//定义pc指针,并指向cArray数组。类型一致,合法。
    //char(*pcw)[4] = cArray;//错误,数组名cArray为首元素的地址(相当于char*)与pcw指针类型不匹配
    char(*pcw)[4] = (char(*)[4])cArray;

    int i = 0;

    printf("%d, %d\n", sizeof(AINT5),sizeof(a1));//4*5=20

    for(i=0; i<10; i++)
    {
        (*pf)[i] = (float)i; //pf指向整个数组,即相当于&a。而*pf等价于(*&a),即相当于a
                             //即*pf等价于数组名fArray,所以表达式相当于fArray[i] = (float)i;
    }

    printf("pf = %X, pf + 1 = %X\n", pf, pf+1); //pf + 1,指向数组最后一个元素的后面

    for(i=0; i<10; i++)
    {
        printf("%f\n",fArray[i]);//打印0到9
    }

    printf("%p, %p ,%p\n", &cArray, pc+1, pcw+1);//pc+1==>(unsigned int)pc + 1*sizeof(*pc)
                                                 //    ==>(unsigned int)pc + 1*9
                                                 //同理pcw + 1 = pcw + 4

    return 0;
}

4. 指针数组

(1)指针数组是一个普通的数组,其中的每个元素为一个指针

(2)指针数组的定义:type* pArray[n];//其中的type*为数组中元素的类型,pArray为数组名,n为数组的大小(如float* a[3])

【实例分析】指针数组的应用

#include <stdio.h>
#include <string.h>

//sizeof(a)表示整个元素的大小
//a表示首元素地址,*a即取出第1个元素
#define DIM(a) (sizeof(a)/sizeof(*a))

//table指向一个指针数组,即每个元素为指针类型
int lookup_keyword(const char* key, const char* table[], const int size)
{
    int ret = -1;

    int i = 0;

    for(i=0; i<size; i++)
    {
        if(strcmp(key, table[i]) == 0)
        {
            ret = i;
            break;
        }
    }

    return ret;
}

int main()
{

    const char* keyword[]={
           "do",
           "for",
           "if",
           "register",
           "return",
           "switch",
           "while",
           "case",
           "static"
    };

    printf("%d\n", lookup_keyword("return",keyword,DIM(keyword)));//4
    printf("%d\n", lookup_keyword("main",keyword,DIM(keyword))); //-1

    return 0;
}

5. 小结

(1)数组的类型由元素类型数组大小共同决定

(2)数组指针是一个指针,指向对应类型的数组。

(3)指针数组是一个数组,其中每个元素都为指针

(4)数组指针遵循指针运算法则

(5)指针数组拥有C语言数组的各种特性

时间: 2024-10-09 07:59:50

第32课 数组指针和指针数组分析的相关文章

第35课 数组参数和指针参数分析

1. 数组参数退化为指针的意义 (1)C语言中只会以值拷贝的方式传递参数,当向函数传递数组时,将整个数组拷贝一份传入函数导致执行效率低下,C语言以高效作是最初的设计目标,所以这种方法是不可取的. (2)参数位于栈上,太大的数组拷贝将导致栈溢出. (3)将数组名看做常量指针,传递的是数组的首元素地址,而不是整个数组. 2. 二维数组参数 (1)二维数组参数同样存在退化的问题: 二维数组可以看做是一维数组,其中的每个元素又是一个一维数组 (2)二维数维参数中第一维的参数可以省略 ①void f(in

C语言-第32课 - 野指针和内存操作分析

第32课 - 野指针和内存操作分析 一.概念 初识野指针 l 野指针通常是因为指针变量中保存的值不是一个合法的内存地址而造成的. l 野指针不是NULL指针,是指向不可用内存的指针. l NULL指针不容易用错,因为if语句很好判断一个指针是不是NULL. l C语言中没有任何手段可以判断一个指针是否为野指针. 野指针的由来 (1)局部指针变量没有被初始化. 例: #include <stdio.h> #include <string.h> struct Student { cha

qsort 函数的使用——对普通数组、指针数组、二维数组中的元素进行排序

在ANSI C中,qsort函数的原型是 #include <stdlib.h> void qsort(void *base, size_t nmemb, size_t size, int (*compar) (const void *, const void *)); 解释:qsort函数对含有nmemb个元素的数组进行排序,而base指针指向数组的第一个元素.这个数组的元素个数由size指定. compar函数对qsort的比较操作进行定义,所以可以定制数字的比较,字符串的比较,甚至结构体

(C/C++)区别:数组与指针,指针与引用

1.数组跟指针的区别 数组要么在静态存储区被创建(如全局数组),要么在栈上被创建.数组名对应着(而不是指向)一块内存,其地址与容量在生命期内保持不变,只有数组的内容可以改变. 指针可以随时指向任意类型的内存块,它的特征是“可变”,所以我们常用指针来操作动态内存.指针远比数组灵活,但也更危险. 数组和指针特点的简单比较: 数组 指针 保存数据 保存地址 直接访问数据 间接访问数据,先取得指针的内容,然后以它为地址取得数据 用于存储数目固定且类型相同的数据 通常用于动态数据结构 编译器自动分配和删除

数组指针和指针数组

1 // 数值指针和指针数组 2 // C语言环境 3 4 #include "stdafx.h" 5 6 int main(int argc, char* argv[]) 7 { 8 //数组指针,是一个指针. 这个指针指向一个数组. 9 //指针数组,是一个数组. 这个数组里面存放的元素是指针. 10 //怎么看? 11 //看谁的优先级高,优先高的就是重点. 12 13 char p[] ={'A','B','C','D'} ; 14 //这是一个名字叫p的字符数组,这个数组有4

(转)数组指针和指针数组的区别

数组指针(也称行指针)定义 int (*p)[n];()优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长.也就是说执行p+1时,p要跨过n个整型数据的长度. 如要将二维数组赋给一指针,应这样赋值:int a[3][4];int (*p)[4]; //该语句是定义一个数组指针,指向含4个元素的一维数组. p=a;        //将该二维数组的首地址赋给p,也就是a[0]或&a[0][0] p++;       //该语句执行过后,也就是p=p+

数组指针和指针数组的区别(转)

数组指针(也称行指针)定义 int (*p)[n];()优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长.也就是说执行p+1时,p要跨过n个整型数据的长度. 如要将二维数组赋给一指针,应这样赋值:int a[3][4];int (*p)[4]; //该语句是定义一个数组指针,指向含4个元素的一维数组. p=a;        //将该二维数组的首地址赋给p,也就是a[0]或&a[0][0] p++;       //该语句执行过后,也就是p=p+

c - 对数组进行排序(通过指针的指针)

通过指针的指针,以及一个指针数组,对实际数组元素进行排序,有一个优点,就是排序过程交换的只有指针数组中的值,而不是实际的数组的元素.当实际元素中的对象很大,特别是结构体等类型时,这样做是很有好处. 下面的图表示了排序前和排序后,内存中的变化情况: 以下代码是上图的实现: 1 #include <stdio.h> 2 3 #define SIZE 5 4 5 //这里用冒泡排序. 6 void 7 bubbleSort(int **pArr) { 8 int *tmp; 9 int isSwap

一维数组,二维数组,三维数组,数组与指针,结构体数组,通过改变指针类型改变访问数组的方式

 打印数组中的每个元素,打印每个元素的地址: #include <stdio.h> #include <stdlib.h> void main(void) { int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; for (int *p = a; p < a + 10;p++)  //指针类型决定4个字节 { printf("\n%p,%d", p, *p); } getchar(); } 指针数组 #inclu