1.指针简介
- 指针Pointer是C语言的一个重要知识点,使用灵活,功能强大
- 指针和底层硬件联系紧密(寄存器),使用指针可操作数据的地址,实现数据的间接访问
2.计算机存储机制
每个区域都是一个字节,线性分配下去,每个字节对应一个地址。
注:一个字节是8bit
int a = 0x12345678;//十六进制,八位也就是32bit,即4个字节,如下图(小端在低地址,为小端模式)
short b = 0x5A6B;
char c[] = {0x33, 0x34, 0x35};//数组是按顺序存的
3.定义指针
- 指针即指针变量,用于存放其他数据单元(变量/数组/结构体/函数等)的**首地址。**若指针存放了某个数据单元的首地址,则这个指针指向了这个数据单元,若指针存放的值为0,则这个指针为空指针
- 定义一个指针变量:
#include <stdio.h>
int main(void)
{
int a;
int *p, p1; //p是int指针变量, p1是int型
}
4.指针的操作
int a; // 定义一个int型数据
int *p; // 定义一个指向int型数据的指针
/*对指针p的操作方式
取地址 p=&a; 将数据a的首地址赋值给p
取内容 *p; 取出指针指向的数据单元
加 p++; 使指针向下移动1个数据宽度
p=p+5; 使指针向下移动5个数据宽度
减 p--; 使指针向上移动1个数据宽度
p=p-5; 使指针向上移动5个数据宽度
*/
#include <stdio.h>
int main()
{
char a = 0x66;
char *p;
p = &a;
printf("%x\n", a);
printf("%x\n",p);
printf("%x\n",*p);
}
/*输出为
66
5ffe97
66
*/
地址 | 内存 | 说明 |
---|---|---|
5ffe97 | 66 | a的值 |
97 | 指针p的值 | |
fe | 八行是因为电脑为64位 | |
5f | ||
0 | ||
0 | ||
0 | ||
0 | ||
0 | ||
打印a,就是66;打印p就是5ffe97;打印*p是间接访问,找到p对应的地址,再打印该地址的内容 |
#include <stdio.h>
int main()
{
int a = 0x66;
int *p;
p = &a;
printf("%x\n", a);
printf("%x\n",p);
printf("%x\n",*p);
p++;
printf("%x\n",p);
return 0;
}
/*输出为
66
5ffe94
66
5ffe98 可以看到是加了一个数据宽度 int四个字节
*/
指针加加减减用在数组,作用在单独的变量没有意义。
5.数组与指针
- 数组是一些相同数据类型的变量组成的集合,其数组名即为指向该数据类型的指针。数组的定义等效于申请内存、定义指针和初始化
#include <stdio.h>
int main()
{
char a[] = {0x33, 0x34, 0x35};
char *p;
p = a;
printf("a[0] = %x\n", a[0]);
printf("a[1] = %x\n", a[1]);
printf("a[2] = %x\n", a[2]);
printf("*p = %x\n", *p);
printf("*(p+1) = %x\n", *(p+1));
printf("*(p+2) = %x\n", *(p+2));
return 0;
}
/*结果:
a[0] = 33
a[1] = 34
a[2] = 35
*p = 33
*(p+1) = 34
*(p+2) = 35
*/
数组其实就是指针,如上下图
#include <stdio.h>
#include <stdlib.h>
int main()
{
//char a[] = {0x33, 0x34, 0x35};
int *a;
a = malloc(3*4);
*a = 0x33;
*(a+1)=0x34;
*(a+2)=0x35;
printf("a[0] = %x\n", a[0]);
printf("a[1] = %x\n", a[1]);
printf("a[2] = %x\n", a[2]);
printf("*a = %x\n", *a);
printf("*(a+1) = %x\n", *(a+1));
printf("*(a+2) = %x\n", *(a+2));
return 0;
}
/*输出为
a[0] = 33
a[1] = 34
a[2] = 35
*a = 33
*(a+1) = 34
*(a+2) = 35
*/
6.指针的注意事项
7.指针的应用
7.1.传递参数
- 使用指针传递大容量的参数,主函数和子函数使用的是同一套数据,避免了参数传递过程中的数据复制,提高了运行效率,减少了内存占用
#include <stdio.h>
/*执行过程
数组a占了7*4个字节的内存
Max占了4个字节内存
FindMax的形参指针占了8个字节内存(64位计算机)
把a赋给array,然后在子函数FindMax中间接引用a中的数据,然后遍历
*/
int FindMax(int *array, int Count)
{
int i;
int max = array[0];
for(i=1;i<Count;i++)
{
if(array[i]>max)
{
max = array[i];
}
}
return max;
}
int main(void)
{
int a[] = {1, 2, 30, 4, 5, 4, 2};
int Max;
Max = FindMax(a,7);
printf("Max=%d\n", Max);
return 0;
}
- 使用指针传递输出参数,利用主函数和子函数使用同一套数据的特性,实现数据的返回,可实现多返回值函数的设计
#include <stdio.h>
void FindMaxAndCount(int *max, int *count, const int *array, int length)
{
int i;
*max = array[0];
*count = 1;
for(i=1;i<length;i++)
{
if(array[i]>*max)
{
*max = array[i];
*count = 1;
}
else if(array[i]==*max)
{
(*count)++;
}
}
}
int main(void)
{
int a[] = {1, 2, 30, 4, 30, 4, 2};
int Max;
int Count;
FindMaxAndCount(&Max,&Count, a, 7);
printf("Max=%d\n", Max);
printf("Count=%d\n",Count);
return 0;
}
7.2.传递返回值
#include <stdio.h>
/*************************/
//外部时钟函数
int Time[] = {23, 59, 55}; //全局变量(如果是局部变量,在函数结束后,
局部变量会被销毁)
int *GetTime(void)
{
return Time;
}
/*************************/
int main(void)
{
int *pt;
pt = GetTime();
printf("pt[0]= %d\n", pt[0]);
printf("pt[1]= %d\n", pt[1]);
printf("pt[2]= %d\n", pt[2]);
return 0;
}
7.2.1.C语言文件操作
#include <stdio.h>
int main(void)
{
FILE *f = fopen("E:\\etest.txt","w");
fputc('A', f);
fputs("HelloWorld",f);
fclose(f);
return 0;
}
标签:main,01,大S,int,江科,printf,array,include,指针
From: https://blog.csdn.net/weixin_45337658/article/details/144370718