1、指针的运算
前提:两个指针必须指向同一个数组
运算:减法
实质:计算两个指针之间关系,两个指针之间跨过了几个数组元素
作用:
判断指针的位置
p = a; p1 =&a[3]
p1 - p > 0 表示p1在高位置
p1 - p < 0 表示p1在低位置
p1 - p = 0 表示p1和p指向了同一个位置
注意:
指针的运算,不能有加法的
2、指针和二维数组
指针和一维数组:1)数组的指针指向数组元素
2)指针数组 数组的每一个元素还是一个指针
a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
a[0] <--1 2 3 4
a[1] <--5 6 7 8
a[2] <--9 10 11 12
a[0]+1 == a[0][1] 地址
*(a[0]+1)== a[0][1] 的值
*(a[i]+j) == a[i][j]的值
一维数组:a[i]的值 用数组地址表示:*(a+i)
用数组名访问数组的每一个元素:*(*(a+i)+j)
指针和二维数组:
1)指针指向二维数组的元素
int (*p)[4]; //指针变量名 p
p = a;
2)二维的指针数组
char *str[2][3]={{"abc","acb","ade"},{"abc","ddd","eee"}};
3、指针和字符串
1)字符串指针,用来保存字符串
char *s="agadsf"; // 有\0
2) 用字符串数组的方法
char ch[]="dafasdf";// 有\0
3) char *c = 'a';
注意点:
1)字符串指针和字符指针的区别:
字符串指针保存的是字符串的首地址,字符指针保存的是字符变量的地址
根据赋值是否使用“”来区别是否是字符串指针
2)字符串指针和字符数组的的区别
1)区别一,能否重新赋值问题
char ch[20]="xxxxx";
ch = "asdfasdf"; // 不可以的 ch是常量,存储的是数组的首地址
char *ss="xxxxxx"; //"xxxxxx" 0x01
ss = "xxx"; // 可以的,ss是指针变量,
2)区别二,存储的区别
char ch[10]="xxxx"; 存放的是栈区(可读可写)
x x x x \0 0 0 0 0 0 0 0
ch[4]='A'
char *str ="pppp"; 存放的是常量去(只读)
0123
4、字符串数组
存储字符串的几种方式
1)二维的字符数组
char name[10][20]={
"fengjie",
"suibian",
"xxxxxx"
}
2)用一维的指针数组存放字符串
char *name[10]={
"fengjie",
"suibian",
"xxxxxx"
}
5、安全的字符串读取和输出的函数
读取字符串的方法:
1)scanf 缺点:遇到空格就认为输入结束了,空格之后的字符都不会被接受
2) gets 优点:可以接受含有空格的字符串
1)2)都是不安全的
char ch[10];
安全:9+\0
不安全:10
3) fgets(); 优点:可以帮我们根据数组的长度自动截取适当的长度保存
fgets(ch,sizeof(ch),stdin);
输出字符串的方法:
1)printf() %s 缺点:不能自动换行
2) puts() 优点:可以自动换行
3) fputs(); 不可以的自动换行
fputs(ch,stdout); //默认的是写入到文件中,stdout表示输出
6、const修饰符的使用
const作用可以把变量变成只读的(常量)
1)修饰变量
const int a=23;
a = 20; (错误的)
2)修饰指针
const int *p; //p指向的变量的值不能修改,指向可以修改
int const *p; //同上
int * const p; //值可以变,指向不能变
const int* const p;// 指向和值都不能变
技巧:
const 在 * 的左侧 //指向可变,值不能变
const 在 * 的右侧 //指向不可变 值可变
const 在 * 的两侧 //指向和值都不可以变
7)C语言中的内存管理
内存分为5大区域
栈区 -- 存放局部变量
堆区 -- 程序运行过程中,动态分配的内存
BSS区 -- 未初始化的全局变量和静态变量
数据段 -- 已经初始化的全局变量和静态变量
代码段 -- 程序编译产生的二进制的数据