赞
踩
目录
提示:这里可以添加本文要记录的大概内容:
本文主要介绍指针数组、数组指针、二维数组
指针数组是多个指针变量,以数组的形式存储在内存中,数组中的每个元素都是一个地址,占有多个指针的存储空间。指针数组即存放指针的数组,如:char *array[5];含义是一个存放了5个指向字符型数据的指针的数组。
- #includeint main(void)
- {
- char **p, i;
- char *strings[] ={"one", "two", "three"};
- p = strings; //strings是地址的地址,所以要定义**p
- for(i = 0; i < 3; i++)
- printf("%s\n", *(p++)); //这里*(p++)是取出存储在数组中的每一个字符串的地址return 0;
- }
-
- //在string[0]存放字符串“one”的首字符的地址,
- //string[1]存放字符串“two”的首字符的地址,
- //string[3]存放字符串“three”的首字符的地址。
-
- /*****************************************/
- void func(char **p) {
- char *t;
- t = (p += 3)[-1];
- printf("%s\n",*p);
- printf("%s\n",t);
- }
-
- int main() {
- int *arr[] = {"ab","ce","ef","gh","ij","kl"};//指针数组
- func(arr);
-
- return 0;
- }
-
- //输出
- //gh
- //ef

数组指针是一个指针变量,占有内存中一个指针的存储空间;数组指针即指向数组的指针,如:char (*array)[5];含义是一个指向存放5个字符的数组的指针。
数组指针的定义,如:int (*p)[3]; 首先()的优先级高,所以首先p 和*结合,说明 p是一个指针,然后int 和[3]都是修饰这个指针的,意思是,这个指针指向了一个里面有3个int型元素的数组。
- int main() {
- int a[3] = {1,2,3};
- int (*p)[3] = a;//compile warning: initialization from incompatible pointer type
- printf("%p,%p,%p,%p,%d,%d\n",a,&a,p,*p,**p,*p[0]);
- return 0;
- }
-
- //输出
- //0060FEF0,0060FEF0,0060FEF0,0060FEF0,1,1
分析:
p是一个指向数组的指针(这里的p只不过是指针变量的名字,说p指向一个数组,其实就是p变量保存了数组的首地址)那么,在上面的例子中我们把 a 数组的地址给了这个指针变量(注意:&a取得是整个数组的地址)所以p指向了这个数组,p的值是数组首字节的地址。
这里要注意的是*p的类型是int * 类型,为甚么呢?不是 *p应该是这个数组吗?这是因为在C语言中规定,数组“本身”出现在非sizeof,非 & 后面时,会自动转换为指向数组首元素的指针,也就是说,这里的*p转化为数组首元素的指针了(这个指针的值为第一个首元素第一个字节的地址,映射的是四个字节)。
在这个数组中的首元素的类型是int ,所以*p的类型就为int * ,所以 *p的值就和p的值相等了,**p的值就为第一个元素的值 1 ,而*p[0]则因为[]的优先级高,所以 p[0]就是数组首元素的地址,*p[0]就为数组首元素了。
- int main() {
-
- int a[5] = { 1, 2, 3, 4, 5 }; //步长为5的数组指针,即数组里有5个元素
- int (*p)[5];
- p = &a; //把数组a的地址赋给p,则p为数组a的地址,则*p表示数组a本身
- printf("%p\n", a); //输出数组a的地址,一般用数组的首元素地址来标识一个数组
- printf("%p\n", p); //p为数组a的地址
- printf("%p\n", *p); //*p表示数组a本身,一般用数组的首元素地址来标识一个数组
- printf("%p\n", &a[0]); //a[0]的地址
- printf("%p\n", &a[1]); //a[1]的地址
- printf("%p\n", p[0]); //数组首元素的地址
- printf("%d\n", **p); //*p表示地址,则*(*p)表示值,当*p表示数组首元素地址时,**p表示首元素本身,即首元素的值1
- printf("%d\n", *p[0]); //根据优先级,p[0] 表示首元素地址,则*p[0]表示首元素本身,即首元素的值1
- printf("%d\n", *p[1]); //错误,不表示a[1]...表示什么我还不知道
-
- int *p;
- p = a;
- printf("%c", *p++);
- printf("%c", p[1]); //利用数组形式输出printf("%c", *a++); //这里不能改变数组的地址,会报错printf("%c", *(p+1)); //没有改变数组地址,可行

- int main() {
- int arr[][3] = {1,2,3,4,5,6};
- int (*ptr)[3] = arr;
- printf("%d,%d\n",(*ptr)[0],(*ptr)[1]);
- ptr++; //ptr = ptr + 1;ptr跨过了a[0][],指向了a[1][]
- printf("%d,%d\n",(*ptr)[0],(*ptr)[1]);
- return 0;
- }
-
- //输出
- //1,2
- //4,5
- int main() {
- int a[10];
- printf("a:/t%p/n", a);
- printf("&a:/t%p/n", &a);
- printf("a+1:/t%p/n", a+1);
- printf("&a+1:/t%p/n", &a+1);
- return 0;
- }
-
- //输出:
- //a: 0012FF20
- //&a: 0012FF20
- //a+1: 0012FF24
- /&a+1: 0012FF48
注意:
(1)、a(a+0)表示&a[0],也即对数组首元素取地址。数组名的值是个指针常量,也就是数组第一个元素的地址。 它的类型取决于数组元素的类型。
(2)、取一个数组名的地址(&a)所产生的是一个指向整个数组的指针,而不是一个指向某个指针常量的指针。所以&a后返回的指针便是指向整个数组的指针,跟a(一个指向a[0]的指针)在指针的类型上是有区别。
(3)、a和&a指向的是同一块地址,但他们+1后的效果不同,a+1是增加一个元素的内存大小(增加4字节)即&a[1],而&a+1增加的是整个数组的内存大小(增加40)。
(4)、当数组名作为sizeof操作符和单目操作符&的操作数时。 sizeof返回整个数组的长度,而不是指向数组的指针的长度。a+1表示首地址+sizeof(元素类型)。&a虽然值为数组首元素地址,但类型为:类型 (*)[数组元素个数],所以&a+1大小为:首地址+sizeof(a)。
若有定义语句:char s[3][10],(*k)[3],*p;,则如下赋值语句正确的是( )
A. p=s;
B. p=k;
C. p=s[0];
D. k=s;
正确答案:C
- #define TOUCHKEY_BT_SHORT \
- /*00*/ NO_MSG,\
- /*01*/ NO_MSG,\
- /*02*/ NO_MSG,\
- /*03*/ NO_MSG,\
- /*04*/ NO_MSG,\
- /*05*/ NO_MSG,\
- /*06*/ NO_MSG,\
- /*07*/ NO_MSG,\
- /*08*/ NO_MSG,\
- /*09*/ NO_MSG,
- #define TOUCHKEY_BT_LONG \
- /*00*/ NO_MSG,\
- /*01*/ NO_MSG,\
- /*02*/ NO_MSG,\
- /*03*/ NO_MSG,\
- /*04*/ NO_MSG,\
- /*05*/ NO_MSG,\
- /*06*/ NO_MSG,\
- /*07*/ NO_MSG,\
- /*08*/ NO_MSG,\
- /*09*/ NO_MSG,
- #define TOUCHKEY_BT_HOLD \
- /*00*/ NO_MSG,\
- /*01*/ NO_MSG,\
- /*02*/ NO_MSG,\
- /*03*/ NO_MSG,\
- /*04*/ NO_MSG,\
- /*05*/ NO_MSG,\
- /*06*/ NO_MSG,\
- /*07*/ NO_MSG,\
- /*08*/ NO_MSG,\
- /*09*/ NO_MSG,
- #define TOUCHKEY_BT_LONG_UP \
- /*00*/ NO_MSG,\
- /*01*/ NO_MSG,\
- /*02*/ NO_MSG,\
- /*03*/ NO_MSG,\
- /*04*/ NO_MSG,\
- /*05*/ NO_MSG,\
- /*06*/ NO_MSG,\
- /*07*/ NO_MSG,\
- /*08*/ NO_MSG,\
- /*09*/ NO_MSG,
-
- #define KEY_REG_AD_MAX (10)
- #define KEY_REG_IO_MAX (10)
- #define KEY_REG_IR_MAX (21)
- #define KEY_REG_TOUCH_MAX (10)
- #define KEY_REG_UART_MAX (10)
-
- const u16 task_bt_touch_table[4][KEY_REG_TOUCH_MAX] = {
- /*短按*/ {TOUCHKEY_BT_SHORT},
- /*长按*/ {TOUCHKEY_BT_LONG},
- /*连按*/ {TOUCHKEY_BT_HOLD},
- /*长按抬起*/ {TOUCHKEY_BT_LONG_UP},
- };
-
- typedef struct __KEY_REG {
- const u16(*_ad)[KEY_REG_AD_MAX];
- const u16(*_io)[KEY_REG_IO_MAX];
- const u16(*_ir)[KEY_REG_IR_MAX];
- const u16(*_touch)[KEY_REG_TOUCH_MAX];
- const u16(*_uart)[KEY_REG_UART_MAX];
- } KEY_REG;
-
- const KEY_REG task_bt_key = {
- ._ad = task_bt_ad_table,
- ._io = task_bt_io_table,
- ._ir = task_bt_ir_table,
- ._touch = task_bt_touch_table,
- ._uart = task_bt_io_table,//task_bt_touch_table,
- };
-
- typedef struct __TASK_APP {
- // const char *name;
- tbool(*skip_check)(void **priv);
- void *(*init)(void *priv);
- void (*exit)(void **priv);
- void (*task)(void *priv);
- const KEY_REG *key;
- } TASK_APP;
-
- const TASK_APP task_bt_hid_info = {
- .skip_check = NULL,
- .init = task_bt_hid_init,
- .exit = task_bt_exit,
- .task = task_bt_deal,
- .key = &task_bt_key,
- };

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。