int num = 0; // 类型: int
int arr[10] = {}; // 类型: int [10]
int* MuShan = {1,2,3};
//去掉名字,剩下的就是类型
*: 定义时,表示定义的是一个指针 其他的时候表示解析引用
&: 取地址符(用于取地址)
指针的定义有多种理解方式;
int* p; // 类型: int
// 变量名: *p
int* p; // 指针本身的类型: int*
// 指针名: p
int* p; // 指针指向的类型: int
// 指针名: p
反推:
int****** p1; // p1本身的类型: int******
// p1指向的类型: int***** (6级指针可以指向5级指针)
#include
int main()
{
char* pch;
short* psh;
int* pn;
float* pf;
double* pd;
printf("%d\n", sizeof(pch)); // 4
printf("%d\n", sizeof(psh)); // 4
printf("%d\n", sizeof(pn)); // 4
printf("%d\n", sizeof(pf)); // 4
printf("%d\n", sizeof(pd)); // 4
return 0;
}
int num = 10;
int* p = #
int num = 10;
int* pn = # //初始化
float f = 3.14f;
float* pf;
pf = &f; //赋值
int num = 10;
int* pn = # // 初始值
int* p1 = pn; // 初始化
int* p2;
p2 = pn; // 赋值
int* p = (int*)0x36;
一级指针可以接受一堆一位数组的数组名
int arr[5] = { 1,2,3,4,5 };
int* p = arr;
#include
int main()
{
// 数组名就是数组的首地址
char arr[5] = { 'a','b','c' };
char* p = arr;
printf("%s\n",p); //输出:abc
char str[5] = "abcd";
p = str;
printf("%s\n", str); //输出:abcd
printf("%s\n", p); //输出:abcd
// ==> char*类型的指针可以直接用来打印整个字符串到'\0'停止
const char* p1;
p1 = "1234";
printf("%s\n",p1); //输出:1234
const char* p2 = "Mushan";
printf("%s\n",p2); //输出:Mushan
return 0;
}
int* p = NULL;
int* p1 = (int*)0x0;
/*
NULL: #define NULL 0
0地址
有时候,指针定义好了,但是暂时没有指向
或者是,指针用完了,没有指向了
指针不知道指向哪里(会随机指向)
此时的指针,很危险(野指针)
所以 这些情况下的指针
统一安排一个地址给他们指向
指向0地址
*/
#include
int main() {
int num = 10;
printf(" num = %d\n", num); // num = 10;
printf("&num = %X\n", &num); // &num = 10FFA78
int* p = #
printf("*p = %d\n", *p); // *p = 10 (num值)
printf(" p = %X\n", p); // p = 10FFA78 (num的地址)
printf("&p = %X\n", &p); // &p = 10FFA6C
int** pp = &p; // 一个二级指针
printf("**pp = %d\n", **pp); // **pp = 10 (num值)
printf(" *pp = %X\n", *pp); // *pp = 10FFA78 (num的地址)
printf(" pp = %X\n", pp); // pp = 10FFA6C (p的地址)
printf(" &pp = %X\n", &pp); // &pp = 10FFA60
int*** ppp = &pp; // 一个三级指针
printf("***ppp = %d\n", ***ppp); // ***ppp = 10 (num值)
printf(" **ppp = %X\n", **ppp); // **ppp = 10FFA78 (num地址)
printf(" *ppp = %X\n", *ppp); // *ppp = 10FFA6C (p的地址)
printf(" ppp = %X\n", ppp); // ppp = 10FFA60 (pp的地址)
printf(" &ppp = %X\n", &ppp); // &ppp = 10FFA54
return 0;
}
核心:指针本身的值(指向)没有变化
#include
int main()
{
int num = 10;
int* p = #
printf("%X\n", p); // EFFB5C
printf("%X\n", p + 1); // EFFB60
return 0;
}
自增自减,会改变指针指向
++:表示指针向后移动一个单位
– :表示指针向前移动一个单位
单位:指针指向的类型在内存所占内存中所占的字节数
#include
int main()
{
int num = 10;
int* p = #
printf("%X\n", p); // EFFB5C
printf("%X\n", p + 1); // EFFB60
printf("%d\n",*p); // 10
printf("%X\n", p += 1); // EFFB60
printf("%d\n",*p); // -858993460(无意义)
return 0;
}
#include
int main()
{
int arr[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
for (size_t i = 0; i < 10; i++)
{
printf("%2d", arr[i]);
}
printf("\n");
int* p = arr;
// p和arr,除了arr是一个常量之外,其他几乎是一样的
for (size_t i = 0; i < 10; i++)
{
printf("%2d", p[i]);
}
printf("\n");
printf("%d\n", p[0]); // 0
printf("%d\n", *(p + 0)); // 0
printf("%d\n", p[1]); // 1(先偏移 后取值)
printf("%d\n", *(p + 1)); // 1
// p[n] <==> *(p+n)
return 0;
}
// p[n]:叫做下标形式
// *(p+n):叫做指针偏移的形式
#include
int main()
{
int arr[3][4] = {
{1,2,3,4},
{5,6,7,8},
{9,10,11,12}
};
for (size_t i = 0; i < 3; i++)
{
for (size_t j = 0; j < 4; j++)
{
printf("%3d", arr[i][j]);
}
printf("\n");
}
int* p0 = arr[0];
int* p1 = arr[1];
int* p2 = arr[2];
printf("\n");
// 1:
for (size_t i = 0; i < 4; i++)
{
printf("%3d", p0[i]); // 1 2 3 4
}
printf("\n");
for (int i = -4; i <= 7; i++)
{
printf("%3d", p1[i]); // 1 2 3 4 5 6 7 8 9 10 11 12
}
printf("\n");
for (int i = 0; i < 12; i++)
{
printf("%3d", arr[0][i]); // 1 2 3 4 5 6 7 8 9 10 11 12
}
printf("\n");
// 下标: 保证数组不越界即可
// 2:
int* p = &arr[0][0];
for (int i = 0; i < 12; i++)
{
printf("%3d", arr[0][i]); // 1 2 3 4 5 6 7 8 9 10 11 12
}
printf("\n");
for (int i = 0; i < 12; i++)
{
printf("%3d", *p); // 1 2 3 4 5 6 7 8 9 10 11 12
p++;
}
printf("\n");
return 0;
}