您的位置:首页 > 其它

C:数组和指针

2016-06-19 11:16 204 查看

1. 数组和指针

数组是相同类型的对象集合,可以用一个名称引用。
指针是一个变量,它的值是给定类型的另一个变量或常量的地址。
使用指针可以在不同的时间访问不同的变量,只要它们的类型相同即可。

区别: 
可以改变指针包含的地址,但不能改变数组名称的引用的地址。

2. 一维数组和指针

char multiple[] = "My string.";

char *p = &multiple[0];
printf("first element address: %p\n", p);

p = multiple;
printf("first element address: %p\n", p);

//执行
$ ./a.out
first element address: 0x7fff560dfbfd
first element address: 0x7fff560dfbfd
可以看到 &multiple[0] 和 multiple 的值是相同的。因为 multiple 等于数组第一个字节的地址。

扩展下程序。看看p+1
char multiple[] = "My string.";

char *p = &multiple[0];
printf("first element address: %p\n", p);

p = multiple;
printf("first element address: %p\n", p);

for(int i = 0; i < strlen(multiple); i++){
printf("multiple[%d] = %c, *(p+%d) = %c, &multiple[%d] = %p, p+%d=%p\n",
i, multiple[i], i, *(p+i), i, &multiple[i], i, p+i);
}

//执行
$ ./a.out
first element address: 0x7fff5192bbf5
first element address: 0x7fff5192bbf5
multiple[0] = M, *(p+0) = M, &multiple[0] = 0x7fff5192bbf5, p+0=0x7fff5192bbf5
multiple[1] = y, *(p+1) = y, &multiple[1] = 0x7fff5192bbf6, p+1=0x7fff5192bbf6
multiple[2] =  , *(p+2) =  , &multiple[2] = 0x7fff5192bbf7, p+2=0x7fff5192bbf7
multiple[3] = s, *(p+3) = s, &multiple[3] = 0x7fff5192bbf8, p+3=0x7fff5192bbf8
multiple[4] = t, *(p+4) = t, &multiple[4] = 0x7fff5192bbf9, p+4=0x7fff5192bbf9
multiple[5] = r, *(p+5) = r, &multiple[5] = 0x7fff5192bbfa, p+5=0x7fff5192bbfa
multiple[6] = i, *(p+6) = i, &multiple[6] = 0x7fff5192bbfb, p+6=0x7fff5192bbfb
multiple[7] = n, *(p+7) = n, &multiple[7] = 0x7fff5192bbfc, p+7=0x7fff5192bbfc
multiple[8] = g, *(p+8) = g, &multiple[8] = 0x7fff5192bbfd, p+8=0x7fff5192bbfd
multiple[9] = ., *(p+9) = ., &multiple[9] = 0x7fff5192bbfe, p+9=0x7fff5192bbfe
p设置为multiple的地址, p+n 就等于 multiple+n, 所以 multiple
与 *(multiple+n)是相同的

整数类型
long number[] = {15L, 25L, 35L, 45L};
long *pnum = number;

for(int i = 0; i<sizeof(number)/sizeof(number[0]); i++){
printf("address p+%d (&number[%d]): %p, *(p+%d) value:%ld\n", i, i, pnum+i, i, *(pnum+i));
}
printf("long type occupies %ld bytes.\n", sizeof(long));

//执行
address p+0 (&number[0]): 0x7fff5e03dbd0, *(p+0) value:15
address p+1 (&number[1]): 0x7fff5e03dbd8, *(p+1) value:25
address p+2 (&number[2]): 0x7fff5e03dbe0, *(p+2) value:35
address p+3 (&number[3]): 0x7fff5e03dbe8, *(p+3) value:45
long type occupies 8 bytes.

pnum+1由于是long类型, 每次增加了8个字节。

3. 多维数组

取多维元素第一个元素的地址和值
int board[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};

printf("address of board : %p\n", board);
printf("address of board[0][0] : %p\n", &board[0][0]);
printf("address of board[0] : %p\n", board[0]);

printf("value of board[0][0] : %d\n", board[0][0]);
printf("value of *board[0] : %d\n", *board[0]);
printf("value of **board : %d\n", **board);

//执行
$ ./a.out
address of board : 0x7fff5a96ebe0
address of board[0][0] : 0x7fff5a96ebe0
address of board[0] : 0x7fff5a96ebe0
value of board[0][0] : 1
value of *board[0] : 1
value of **board : 1
可以看出, board, board[0], &board[0][0] 的数值相同。
声明一个二维数组时,就是在创建一个数组的数组, 
用数组名称和索引值访问这个二维数组时,如 board[0] ,就是在引用子数组的地址,
直接使用二维数组名称, board, 就是引用该二维数组的开始地址, 也是第一个子数组的开始地址。

board[0][0], *board[0], **board 三个的值相同,
*board表示子数组的第一个元素, 如果是二维数组,要获取第一个元素的值,要使用**board。
board[0], board[1], board[2], 分别代表3个子数组的第一个元素的地址, 所以要获取第一个元素, 要使用 *board[0],

获取数组中所有的值

int board[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
for(int i = 0; i < 9; i++){
printf("board %d, address: %p\n", *(*board + i), *board + i);
}

//执行
board 1, address: 0x7fff5501dbe0
board 2, address: 0x7fff5501dbe4
board 3, address: 0x7fff5501dbe8
board 4, address: 0x7fff5501dbec
board 5, address: 0x7fff5501dbf0
board 6, address: 0x7fff5501dbf4
board 7, address: 0x7fff5501dbf8
board 8, address: 0x7fff5501dbfc
board 9, address: 0x7fff5501dc00
*board + i , 会得到数组中偏移量为 i 的元素的地址, 取消引用 *(*board + i)会得到这个地址中的值。
括号不能省略,如果省略, **board+i,表示第一个值**board加上偏移量。

声明一个指针, 给它指定数组的地址。就可以用该指针访问数组的成员。
int board[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
int *pboard = *board;
for(int i = 0; i < 9; i++){
printf("board %d \n", *(pboard + i));
}

//执行
board 1
board 2
board 3
board 4
board 5
board 6
board 7
board 8
board 9
用数组中的第一个元素*board 初始化指针。
也可以用下面方法初始化
int *pboard = &board[0][0];

4. 使用指针处理字符串

getchar()从键盘读入一个字符,并以int类型返回。
char buffer[100];
char *pbuffer = buffer;
while((*pbuffer++ = getchar()) != '\n');

*pbuffer = '\0';
getchar()读取一个字符,并存储在 pbuffer 的地址中,
递增 pbuffer 中的地址,以指向下一个字符。

5. 使用指针数组

要处理多个字符串时,可以在堆上使用指针数组存储对字符串的引用。
char *pS[3] = { NULL };
声明一个数组 pS, 包含3个指针。

地址: http://blog.csdn.net/yonggang7/article/details/51704851
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C 指针 array