——- android培训、java培训、期待与您交流! ———-
1.地址的概念
内存地址——内存中存储单元的编号。
变量地址——系统分配给变量的内存单元的起始地址
2.指针的基本概念
通常把内存地址也叫做指针。
注意:内存单元的指针和内容是两种概念。
3.变量的存取方式
存取方式分为两种:直接存取和间接存取。
int a = 3;
int b = a;//直接存取
//直接存取:变量的赋值与取值(通过变量名进行存取)
//间接存取:通过指针(地址)间接完成操作
4.指针变量概念及定义方法
用来存放指针的变量,叫做指针变量。
定义格式:类型说明符 *变量名
5.指针变量的初始化和引用
//定义的同时初始化
//完全初始化
int *p = &a;
//部分初始化
int *p2 = &a,*p3;
//先定义再初始化(不推荐)
int *p7;
*p = NULL;
//先不指向,就置空
int *p = NULL;
int *P = 0;
//指针没有初始化为野指针,里面存垃圾值
使用*获取指针指向的内容。
int value = *p;//获取指针变量指向的内存空间的内容
//*的两种用法
//定义一个指针变量
//获取地址对应的存储单元
6.用函数进行变量交换
#include <stdio.h>
void swap(int *p1,int *p2){
/*
交换存储单元里面的内容
*/
int temp;
temp = *p1;
*p1 = *p2;
*p2 = temp;
}
int main(int argc, const char * argv[]) {
int a = 1;
int b = 2;
swap(&a, &b);
printf("%d%d",a,b);
return 0;
}
7.指针常见的应用场景
//在被调函数中改变主调函数中的值
#include <stdio.h>
void test(int *p1){
*p1 = 100;//修改a的值
}
int main(int argc, const char * argv[]) {
int a = 1;
int *p = &a;
test(p);
printf("%d\n",a);
return 0;
}
//让函数有多个返回值
#include <stdio.h>
//并不是真正的返回多个值
void test(int x,int y,int *p1,int *p2){
*p1 = x+y;
*p2 = x-y;
}
int main(int argc, const char * argv[]) {
int p1;
int p2;
test(10, 5, &p1, &p2);
printf("%d\n%d\n",p1,p2);
return 0;
}
8.二级指针
一个指针存放的是另一个指针变量的地址,叫作二级指针。
#include <stdio.h>
int main(int argc, const char * argv[]) {
int a = 1;
int *p1 = &a;
int **p2 = &p1;//将一级指针的地址给二级指针
printf("%d\n",a);
printf("%d\n",*p1);
printf("%d\n",**p2);
return 0;
}
9.指针为什么区分类型
指针变量占用的内存是固定的。
#include <stdio.h>
int main(int argc, const char * argv[]) {
int *p1;
char *p2;
double *p3;
float *p4;
void *p5;//空
//任何类型的指针变量内存大小都是一样的
printf("%ld\n",sizeof(p1));
printf("%ld\n",sizeof(p2));
printf("%ld\n",sizeof(p3));
printf("%ld\n",sizeof(p4));
printf("%ld\n",sizeof(p5));
return 0;
}
#include <stdio.h>
int main(int argc, const char * argv[]) {
int a = 266;
int *p1 = &a;
char *p2 = &a;
double *p3 = &a;
//定义什么样的指针就指向什么样的内存
//指针类型小了丢失数据,指针类型大了访问了别的数据
printf("%d\n",*p1);//266
printf("%d\n",*p2);//10
printf("%d\n",*p3);//512
return 0;
}
10.数组指针的概念及定义
可以用一个指针变量指向一个数组元素。
#include <stdio.h>
int main(int argc, const char * argv[]) {
int a[] = {1,2,3};
int *p = &a[0];//指针指向数组第一个元素
printf("%d\n",*p);
return 0;
}
11.数组指针的初始化和使用方法
指针指向数组元素的时候,允许运算。
+1,-1表示指向上一个或下一个元素:p+i = a[i];
指针可以自增自减:*p++,*p–。
注意:数组名为常量,不能有a++;
#include <stdio.h>
int main(int argc, const char * argv[]) {
int a[] = {1,2,3,4,5,6,7};
int *p = a;//等价于 int *p = &a[0];
printf("%d\n",*p+3);//p跨越内存单元的大小和类型有关
//p + sizeof(int)
printf("%d\n",a[3]);
printf("%d\n",*(p+3));
return 0;
}
12.逆序数组
#include <stdio.h>
void nixu(int a[],int len){
int i = 0, j = len-1;
//交换元素值
while (i<j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
i++;
j--;
}
}
int main(int argc, const char * argv[]) {
int a[] = {1,2,3,4,5,6,7,8,9,10,11,22,33,44,55,66,77,88,99,0};
int len = sizeof(a)/sizeof(int);//获取数组长度
nixu(a, len);
for (int i = 0; i < len; i++) {
printf("%d\t",a[i]);
}
return 0;
}
13.一维指针数组
一个数组的元素值为指针叫作指针数组。
必须指向相同数据类型。
格式:类型说明符*数组名[数组长度]
#include <stdio.h>
int main(int argc, const char * argv[]) {
int a = 3,b = 4,c = 5;
int *p[3] = {&a,&b,&c};
printf("%p\n",&a);
printf("%p\n",p[0]);
printf("%d\n",a);
printf("%d\n",*p[0]);
printf("%d\n",**p); //*p = p[0]
printf("-----——————————————————\n");
int d[2][2] = {1,2,3,4};
int *p1[] = {d[0],d[1]};
printf("%d\n",**p1);
printf("%d\n",*(*p1+1));//取值符号优先级大于运算符但和自增自减相同,由右向左
printf("%d\n",d[0][0]+6);
printf("%d\n",**p1+6);
printf("%d\n",**(p1+1));
return 0;
}
14.指针变量之间的运算
#include <stdio.h>
int main(int argc, const char * argv[]) {
int a[] = {1,2,3,4,5};
int *p1 = a;
int *p2 = &a[3];
printf("%ld\n",p2-p1);//相差元素个数
printf("%ld\n",(p2-p1)*sizeof(int));//相差内存单元数
printf("%d\n",p2>p1);//1 p2在高位
return 0;
}
15.用数组名访问二维数组
#include <stdio.h>
int main(int argc, const char * argv[]) {
int a[3][4] = {1,2,3,4,5,6,7,8,9,10};
printf("%d\n",**a);
printf("%d\n",*a[0]);//二维数组中a[0]为指向第一行的第一个元素的指针
//*(*(a+i)+j) == a[i][j]
//列指针
//a[0] == &a[0][0] a[0]+1 == &a[0][1] a[0]+2 == a[0][2]
printf("%p\n",&a[0][1]);
printf("%p\n",a[0]+1);
printf("%d\n",*a[0]+1);
printf("%d\n",*(a[0]+1));//*(a[i]+j)
//行指针 a[0] a[1] a[2]
printf("%p\n",a[1]);
printf("%p\n",a+1);
printf("%p\n",*(a+1));
printf("%d\n",**(a+1));//**(a+1) ==a[1][0]
return 0;
}
16.普通指针访问二维数组(最好不用)
#include <stdio.h>
int main(int argc, const char * argv[]) {
int a[3][4] = {1,2,3,4,5,6,7,8,9,10};
int *p = a;//利用数组连续排列 p指向a[0][0]
for (int i = 0; i<10; i++) {
printf("%d\t",*(p+i));
}
return 0;
}
17.二维数组的指针(行指针)定义和初始化
行指针格式:数据类型 (*指针变量名)[二维数组列数]
int (*p)[4] 表示指向含有4个元素的一维数组。
#include <stdio.h>
int main(int argc, const char * argv[]) {
//二维数组指针
//指向二维数组的每一行,行的首地址
int a[3][4] = {1,2,3,4,5,6,7,8,9,10};
int (*p)[4] = a;
for (int i = 0; i< 3; i++) {
for (int j = 0; j<4; j++) {
printf("%d\t",*(*(p+i)+j));//p+i指向二维数组第i行,
}
printf("\n");
}
return 0;
}
18.字符串指针的介绍和使用
char *变量名 = “字符串内容“//字符串内容为常量
#include <stdio.h>
#include <string.h>
int main(int argc, const char * argv[]) {
char *str = "asdjkhafjkhg";//存在常量区无法修改
printf("%s\n",str);
printf("%ld\n",sizeof(str));
printf("%ld\n",strlen(str));
char ch[] = "abcd";//存在栈区
ch[2] = 'Z';
printf("%s\n",ch);
char *str2;
str2 = malloc(100);//开辟100字节内存
scanf("%s",str2);
printf("%s\n",str2);
return 0;
}
19.二维字符数组概念
#include <stdio.h>
#include <string.h>
int main(int argc, const char * argv[]) {
char ch[3][5] = {"abc","def","kkkk"};//一个二维数组
ch[1][3] = 'Z';//在栈区
for (int i = 0; i<3; i++) {
printf("%s\n",ch[i]);
}
return 0;
}
20.char类型的指针数组
//都是常量地址,不能修改
char *str[] = {
"abc",
"abc",
"abc",
"abc",
"abc"
};
#include <stdio.h>
#include <string.h>
int main(int argc, const char * argv[]) {
char *name[] = {
"abc",
"def",
"kkk"
};
for (int i = 0; i < 3; i++) {
printf("%s\n",name[i]);
printf("%s\n",*(name+i));
}
return 0;
}
21.字符串大小排序
#include <stdio.h>
#include <string.h>
void sortString(char *name[],int len){
for (int i = 0; i<len; i++) {
for (int j = 0; j<len-1-i; j++) {
if (strcmp(name[j], name[j+1])>0) {//比较字符串大小
/*
改变指针指向的字符串地址
*/
char *temp;
temp = name[j];
name[j] = name[j+1];
name[j+1] = temp;
}
}
}
}
int main(int argc, const char * argv[]) {
char *name[] = {
"kkk",
"abc",
"sfasf",
"def",
"aaaa"
};
for (int i = 0; i < 5; i++) {
printf("%s\n",name[i]);
// printf("%s\n",*(name+i));
}
sortString(name, 5);
printf("\n");
for (int i = 0; i < 5; i++) {
printf("%s\n",name[i]);
// printf("%s\n",*(name+i));
}
return 0;
}