c语言指针p->k=2,C语言指针(二)

数组指针和指向数组的指针变量

C语言规定:如果指针变量p已指向数组中的一个元素,则p+1指向同一数组中的下一个元素,因为在C语言中数组名代表数组的首地址。

int a[5], *pa;

pa = a; /* 数组名表示数组的首地址,故可赋予指向数组的指针变量pa */

//等价于

pa = &a[0]; /* 数组第一个元素的地址也是整个数组的首地址, 也可赋予pa */

//当然也可采取初始化赋值的方法:

int a[5], *pa = a;

举例1.

#include

main(){

char a[10] = {'T', 'h', 'i', 's', ' ', 'i', 's', ' ', 'A'};

char *p;

p = a;

printf("p = %d, *p = %c, *(p + 2) = %c\n", p, *p, *(p + 2));

//p = 1245044, *p = T, *(p + 2) = i

}

734ff056da46a37fc4512b9626086458.png

举例2.通过不同方式输出数组元素

#include

main(){

//(1)./(2).int a[10];

int a[10], *p = a;

for(int i = 0; i < 10; i++) {

//(1.)a[i] = i;

//(2).*(a + i) = i;

* (p + i) = i; //注意这里只能是(p + i)而不能为p++

}

puts("---------------------------");

for(int j = 0; j < 10; j++) {

//(1).printf("a[%d] = %d\n", j, a[j]);

//(2).printf("a[%d] = %d\n", j, *(a + j));

printf("a[%d] = %d\n", j, *(p + j));

}

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

}

举例3.使用指针的++而不是+i来输出数组元素

#include

main(){

int a[10], *p = a;

for(int i = 0; i < 10; i++) {

* p++ = i;

}

puts("---------------------------");

for(int j = 0; j < 10; j++) {

printf("a[%d] = %d\n", j, *p++);

}

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

}

d98daa05ae44c36ce2e01d684ff00cf1.png

注意:

(1).虽然定义数组时指定它包含10个元素,但指针变量可以指到数组以后的内存单元(

由两处p++导致),系统并不认为非法。

(2).*p++,由于++和*同优先级,结合方向自右而左,等价于*(p++)

(3).*(p++)与*(++p)作用不同。若p的初值为a,则*(p++)等价a[0],*(++p)等价a[1]。

(4).(*p)++表示p所指向的元素值加1。

举例3.数组作为函数参数

#define TOTAL 7

#include

void reverse (int b[]) {

int temp = -1;

for (int m = 0 ; m < float(TOTAL / 2) ; m++) {

temp = b[m];

b[m] = b[TOTAL - m - 1];

b[TOTAL - m - 1] = temp;

}

}

main(){

int a[TOTAL];

for(int i = 0 ; i < TOTAL ; i++) {

a[i] = i;

}

puts("-----------before reverse----------------");

for(int j = 0 ; j < TOTAL ; j++) {

printf("a[%d] = %d\n", j, a[j]);

}

reverse(a);

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

for(int k = 0 ; k < TOTAL ; k++) {

printf("a[%d] = %d\n", k, a[k]);

}

}

说明:当执行了第一个for循环为数组各元素赋予了从0到TOTAL的数值后,其内存模型如下(左图)。当我们将数组作为参数传递后,b也指向了数组a的地址(右图)。

b29b4b6e1b79258c6e1db9b4dde402ce.png        

02821b84f4f5251fda72ec0cba919b8d.png

实际上也可以通过指针来实现逆序,即将上面的reverse代码使用如下代码替换即可。

void reverse (int *p) {

int temp = -1;

for (int m = 0 ; m < float(TOTAL / 2) ; m++) {

temp = *(p + m);

*(p + m) = *(p + TOTAL - m -1);

*(p + TOTAL - m -1) = temp;

}

}

归纳起来,如果有一个实参数组,想在函数中改变此数组的元素的值,实参与形参的对应关系有以下4种:

1).形参和实参都是数组名(a, b)。

2).实用数组,形参用指针变量(a, *p)。

3).实参、形参都用指针变量(略)。

4).实参为指针变量,形参为数组名(略)。

二维数组指针变量说明的一般形式为:

类型说明符 (*指针变量名)[长度]

其中“类型说明符”为所指数组的数据类型。“*”表示其后的变量是指针类型。“长度”表示二维数组分解为多个一维数组时,一维数组的长度,也就是二维数组的列数。应注意“(*指针变量名)”两边的括号不可少,如缺少括号则表示是指针数组。

举例4.二维数组的地址

#include

main(){

int a[3][COLUMN]={{0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}};

printf("a = %d, a[0] = %d, &a[0][0] = %d\n", a, a[0], &a[0][0]);

printf("a[1] = %d, &a[1][0] = %d\n", a[1], &a[1][0]);

printf("\n");

printf("(a[0] + 1) = %d, &a[0][1] = %d\n", (a[0] + 1), &a[0][1]);

printf("(a[1] + 1) = %d, &a[1][1] = %d\n", (a[1] + 1), &a[1][1]);

}

a7e1a23662985a209620dbce36aae535.png

举例5.使用指针实现二维数组

#define COLUMN 4

#include

main(){

int a[3][COLUMN]={{0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}};

int (*p)[COLUMN];

p = a;

printf("a = %d, p = %d\n", a, p);

printf("a[0] = %d, &a[0][0] = %d\n", a[0], &a[0][0]);

printf("a[1] = %d, &a[1][0] = %d\n", a[1], &a[1][0]);

printf("a[2] = %d, &a[2][0] = %d\n", a[2], &a[2][0]);

for (int i = 0 ; i < 3 ; i++ ) {

printf("*(p + %d) = %d\n", i, *(p + i));

for (int j = 0 ; j < 4 ; j++) {

printf("\t*(*(p + %d) + %d) = %d\n", i, j, *(*(p + i) + j));

}

}

}

78750be8557ec9f7a1a50fbc67da2a95.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值