区别 * 和 & 的两种意思
1:
int a = 1;
int *p = &a;
* 作为说明符,说明这个变量p是指针变量,这一点和任何变量的声明逻辑都不同,说明在变量名前进行而不是数据类型处进行。
2:
printf("%d", *p);
* 作为运算符,进行取内容运算。
1:
int a = 1;
int *p = &a;
& 作为运算符,进行取地址运算。
2:
void swap(int& a, int& b) {
int temp = a;
a = b;
b = temp;
}
& 作为说明符,说明此形参将以调用(传地址至a,b)形式引用。
注:
有趣的是,在作为说明符时,这两个符号的位置并不严谨要求,如下方的写法均为正确。
void swap(int& a, int& b);
void swap(int &a, int &b);
int a = 1;
int *p1 = &a;
int* p2 = &a;
值得细心看的一点:如果写作
int a = 1;
int* p, b;
则p为指向int类的指针,a,b仍为int类
使用指针三原则:
1:清楚每个指针指向了哪里;
2:清楚每个指针指向的类型;
3:不要使用未初始化的指针,至少要赋为NULL;
数组中的指针:
访问数组a中一个元素有四种写法
int a[105];
int *p = a;
//1
a[2];
//2
*(a + 2);
//3
p[2];
//4
*(p + 2);
指针加减整数时,挪动的是整数个单位,单位大小由指针原数据类型决定;
数组名虽然是指针,但不能加减;
对多维数组:
直到最后一维前,a[i][j][k]...都还表示地址而非元素;
int a[10][10][10][10];
int *p = a[1][2][3];
//则 *(p + 1) 就等于 a[1][2][3][1] ,即 *(a[1][2][3] + 1);
//也即 *(*(a[1][2] + 3) + 1);
提及对多维数组指针:
int a[10][10];
int *p = a; //××
int (*p)[10] = a; //1:√√
int *p = a[1]; //2: √√
下面那个 1称为行指针(数组指针),2称为列指针(普通指针)
区别于指针数组
int *p[10] = {NULL, NULL, ... NULL};
指针与结构体
访问成员的方式:
struct Stu {
int age, grade;
}a, b;
Stu *p = &a;
p -> age = 18;
*P . age = 18;
二重指针
指向指针的指针全部称为二重指针,没有多重指针
int a;
int *p = &a;
int **pp = &p;
指针数组名是二重指针
指针数组与字符数组
使用char类型的指针数组比按最大长度开字符数组省空间:
char *pc[] = {"Hello", "world"};
char c[][10] = {"Hello", "world"};
二者几乎等价
注:
1. 输出时,%s占位符将按一维字符数组的首地址将数组输出为字符串,而%c将把字符输出为字符。
2. 字符串常量将存至const区,同一个字符串的地址是相同的,尽管有不同的变量名。