目录
1.内存
内存是沟通CPU与硬盘的桥梁:
暂存放CPU中的运算数据
暂存与硬盘等外部存储器交换的数据
2.内存地址
内存中的每一个数据都会分配相应的地址
3.指针
内存区的每一个字节都有一个编号,这就是“地址”
指针的实质就是内存“地址”。指针就是地址,地址就是指针
指针是内存单元的编号,指针变量是存放地址的变量
4指针变量
指针也是一种数据类型,指针变量也是一种变量
“*”操作符操作的是指针变量指向的内存空间
char *c1;
通过指针修改变量
int main(){
int a =9;
int *p = &a;
//修改指针变量指向的内容
*p =100;
printf("%d\n", a);//100
printf("%d\n", *p);//100
printf("%p\n", p);//0x7ffeeb70e8ec
}
5.野指针 空指针
野指针:没有有效的地址空间的指针,没有意义,叫野指针。
空指针:把指针变量赋值为NULL
int *p =NULL;
6 万能指针 void*
可以指向任意变量的内存空间 ,32位系统-内存大小为4字节
void *p = NULL;
int a = 10;
p = (void *)&a; //指向变量时,最好转换为void *
//使用指针变量指向的内存时,转换为int *
*( (int *)p ) = 11;
printf("a = %d\n", a);
7 const 修饰的指针变量
const int *p;
可以修改p的值,不能修改*p的值
int const *p;
可以修改p的值,不能修改*p的值
int * const p:
不可以修改p的值,能修改*p的值
const int *const p;
不可以修改p的值,不能修改*p的值
int a =100;
//使用const 修饰指针,代表内存区域不能修改。
const int * p1 = &a; /
8 指针和数组
数组名字是数组的首元素地址,但是一个地址常量,无法修改。
arr = arr[0];
int arr[] ={1,2,3,4,5};
int *p = arr;
for (i = 0; i < n; i++)
//遍历获取每个元素
a[i]
*(a+i)
*(p+i)
p[i]
9 指针加减运算
//p代表内存地址,++意味着内存地址的向后位移。
//如oxffff00 —oxffff04,因为int类型四个字节。
int a;
int *p = &a;
printf("%p\n", p);
p++;
printf("%p\n", p);
结果:
0x7ffee4c778dc
0x7ffee4c778e0
同理,减号和加号类似。
10 指针数组
数组里存放的类型是指针类型。
数组里每个指针代表每个变量。
//指针数组
int *p[3];
int a = 1;
int b = 2;
int c = 3;
int i = 0;
p[0] = &a;
p[1] = &b;
p[2] = &c;
for (i = 0; i < sizeof(p) / sizeof(p[0]); i++ )
{
printf("%d, ", *(p[i]));
}
printf("\n");
return 0;
11 多级指针
C语言允许有多级指针存在,在实际的程序中一级指针最常用,其次是二级指针。
二级指针就是指向一个一级指针变量地址的指针。
三级指针基本用不着
int a = 10;
int *p = &a; //一级指针
*p = 100; //*p就是a
int **q = &p;
//*q就是p
//**q就是a
int ***t = &q;
//*t就是q
//**t就是p
//***t就是a
12指针与函数
1.函数参数如果传送是指针类型,会改变变量的值;
2.如果传送的变量参数,不会改变变量原理的值。
3.函数参数为数组名,会转换为指针形式。
4.指针可以作为函数的返回值
13指针字符串
1.定义字符串
char str1[] = {‘h’, ‘i’, ‘\0’}; 变量,可读可写
char str2[] = “hi”; 变量,可读可写
char *str3 = “hi”; 常量,只读
2.操作字符串,赋值,获取
char str[] = "hello world";
char *p = str;
//指针代表数组的首元素地址
*p = 'm';//改变首元素内容
p++;//向右位移
*p = 'i';//改变第二个元素内容
printf("%s\n", str);
p = "mike jiang";
printf("%s\n", p);
char *q = "test";
printf("%s\n", q);
3 字符串函数
char *strcpy(char *dest,const char *src);
//复制字符串,‘\0’也会复制
//返回:dest首地址 或者NULL
char *strncpy(char *dest, const char *src, size_t n);
//把src指向字符串的前n个字符复制到dest所指向的空间
char *strcat(char *dest, const char *src);
//将src字符串连接到dest的尾部,‘\0’也会追加过去
char *strncat(char *dest, const char *src, size_t n);
//将src字符串前n个字符连接到dest的尾部,‘\0’也会追加过去
int strcmp(const char *s1, const char *s2);
//比较 s1 和 s2 的大小,比较的是字符ASCII码大小
//返回ASCII差值
int strncmp(const char *s1, const char *s2, size_t n);
类同上述方法,
char *strchr(const char *s, int c);
//在字符串s中查找字母c出现的位置
//返回第一次出现的c地址
char *strstr(const char *haystack, const char *needle);
//功能:在字符串haystack中查找字符串needle出现的位置
//返回第一次出现的needle地址 或者NULL
char *strtok(char *str, const char *delim);
int atoi(const char *nptr);