数组与指针
int b[5];
int *bptr;
想想看
&b[0]是不是取出数组b的地址,这样一个数组名可以看出一个指针,指针可以用于任何涉及数组下标的操作。由于(不带下标的)数组名b就是指向数组第一个元素的指针。所以我们可以将bptr看为数组b第一个元素的地址。
bptr = b;
等价于
bptr = &b[0];
指针偏移
(bptr + 3)
当bptr指向数组的起始位置时,偏移量就表示要引用数组中的哪一个元素,偏移量的值于数组的下标是相同的
由于’*'的优先级大于+,所以()是不能省去的
若省去就会将3 于表达式bptr的值相加(也就是b[0]与3相加)
&b+3
bptr + 3
*(b+3)
都是相同的
指针/下标表示法
若bptr的值是数组名b
int *bptr = b;
bptr[1] = b[1];
bptr[1]也是数组元素b[1]
字符于指针
简单来说,用上%s,系统就会自动把string的字符打出来。
char *string = "heart";
printf("%s",string);//会直接打出heart
printf("%c",*string);//打出h
printf("%c",*(string+1));//打出e
//以此类推说明指针确实会自动向前
字符数组的烦恼
char string [40];
string[0] = 1;//合法,对其中一个元素赋值
string = "i am hero";//不合法,因为数组名是地址
//所以我们用数组解决这种问题
char string [40];
char *ptr;
ptr = "i am hero";
string = ptr;//然而是不行的,因为数组名虽然也是指针,但应该看成指针常量,是不能修改的.
//正确操作
char a[] = " iam herp";
char *ptr;
ptr = a;
while(*ptr != '\0')
{
printf("%c",*ptr);
ptr ++;
}
确定指针的指向
指针数组
数组元素可以是指针,也就是说指针数组里的每一个元素都存放着一个地址
指针数组通常用来构造一个字符串的数组,简称字符串数组
数组每一个元素都是一个字符串。
注:字符串数组与字符数组是不一样的
const char *suit[4] = {"heart","diamods","club","spades"};
来定义一个指针数组
int *ptr[2];
//[]的优先级比*高
int (*ptr)[2];
//两者是不同的,(*p)表示了p是个指向数组的指针
int *ptr = p;//数组名
int *ptr = &p[0];
所以先看p[],这是个数组形式,
再与*结合,表示数组是指针类型的,每个数组元素都可指向一个整型变量。
const char *suit[4] = {"hearts","diamods","clubs","spades"};
//这些字母是数组suit元素的值,不是地址;
//再把它的元素看成指针
//指针指向每个字符串的第一个字符
指针指向数组
void function (int (*p)[4]);
//等价于
void function(int p[][4]);
//空的方括号表示p是个指针
注意:只有在函数原型或函数定义头中,才可以用int ar[]代替int * ar
标题
例子 多维数组
int main(void)
{ int zippo[4][2] = { { 2, 4 }, { 6, 8 }, { 1, 3 },{ 5, 7 } };
int(*pz)[2];
pz = zippo;//指针指向数组zippo
printf(" pz = %p, pz + 1 = %p\n", pz, pz + 1);
//pz+1的地址加八个字节,事实上是zippo[0][0]变为zippo【1】【0】
printf("pz[0] = %p, pz[0] + 1 = %p\n", pz[0], pz[0] + 1);
//因为zippo是二维数组,所以zippo[0]是地址,不是元素的值
//且这也说明了为什么是加八个字节
printf(" *pz = %p, *pz + 1 = %p\n", *pz, *pz + 1);
printf("pz[0][0] = %d\n", pz[0][0]);
printf(" *pz[0] = %d\n", *pz[0]);
printf(" **pz = %d\n", **pz);
printf(" pz[2][1] = %d\n", pz[2][1]);
printf("*(*(pz+2) + 1) = %d\n", *(*(pz + 2) + 1));
return 0;
}
Q:计算每行数组元素的总和
#include <stdio.h>
#define ROWS 3
#define COLS 4
void sum_rows(int ar[][COLS], int rows);//ar是指针,指向有4个整型的数组
void sum_cols(int [][COLS], int); // 省略形参名, 没问题
int sum2d(int(*ar)[COLS], int rows); // 另一种语法
int main(void)
{ int junk[ROWS][COLS] = {{ 2, 4, 6, 8 },{ 3, 5, 7, 9 },{ 12, 10, 8, 6 }};
sum_rows(junk, ROWS);
sum_cols(junk, ROWS);
printf("Sum of all elements = %d\n", sum2d(junk, ROWS));
return 0;
}
void sum_rows(int ar[][COLS], int rows)
{ int r;
int c;
int tot;
for (r = 0; r < rows; r++)
{ tot = 0;
for (c = 0; c < COLS; c++)
tot += ar[r][c];//把同行的数相加起来
printf("row %d: sum = %d\n", r, tot);//再将其打印出来
}
}
void sum_cols(int ar[][COLS], int rows)
{ int r;
int c;
int tot;
for (c = 0; c < COLS; c++)
{
tot = 0;
for (r = 0; r < rows; r++)//将同列的数相加起来,实际上用来下标表示法
tot += ar[r][c];
printf("col %d: sum = %d\n", c, tot);//打印
}
}
int sum2d(int ar[][COLS], int rows)
{ int r;
int c;
int tot = 0;
for (r = 0; r < rows; r++)
for (c = 0; c < COLS; c++)
tot += ar[r][c];
return tot;
}