C语言指针2
一:指针的运算
两个指针之间的减法运算
前提:
两个指针必须指向同一个数组
int a[5]={1,2,3,4,5};
int *p = &a[1];
int *p1 = &a[4];
printf("%d\n",p1-p); // &a[1]-&a[4]是地址差值,而p1-p是元素个数差值
注意:
指针之间是没有加法运算的
两个指针相加的话,可能会越界
二:指针和二维数组
int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
//定义一个行指针,[4]表示这一行有四个元素
int (*p)[4];//二维数组的行指针
//表示把二维数组名赋值给指针变量p
p = a;
for (int i=0; i<3; i++)
for (int j=0; j<4; j++)
//a[i] 每一个行的地址
//a[i]+j a[i][j]的地址
//*(a[i]+j) a[i][j]的元素的值
//在一维数组中 a[i]值,*(a+i)
//printf("%d ",*(a[i]+j));
//printf("%d ",*(*(a+i)+j));
printf("%d ",*(*(p+i)+j));
注意:数组名为数组首地址,并且是常量,不能赋值
三:字符串存储方式:
1)使用字符数组
char c1[]="adsfasdfas";
//c1是数组的首地址,常量
c1 = "asdfasdfasdf";(错误的)
2)字符串指针
格式:char *指针变量名
1)字符串指针跟字符指针的区别
赋值区别
char c='a';
char *s=&c; //字符指针
char *s1="dafasdfdsa"; //字符串指针
2)字符数组和字符串指针的区别
1)字符数组存放在 内存的栈 区
2) 字符串指针指向的字符串存储在 内存常量区
char *str="asdfsdfas"; //str指针变量,把字符串的首地址存放到str中
char *str2; //指针变量
str2 = "adsfasdfasdf";
注意:
//定义char类型的数组
//存放到内存的栈区,可以读也可以写
char c[10]="itcast!";
c[5]='A';
//str存放的是常量字符串的首地址
//str可以重新指向一个新的字符串,但是字符串的内容不能改
char *str="itcast!";
printf("%s\n",str);
//str[5]='A';
四: 字符数组
char ch[]="I need AV";
char ch1[]="I need AV";
字符串数组
1)二维的字符数组存储
char arr[3][20]={"dafasdf","I need AV","I need AV"};
for(int i=0;i<3;i++){
printf("%s\n",arr[i]);
}
存在栈区:arr[0] arr[1] arr[2] //可读可写
2)char型的一维指针数组
//数组中每一个元素都是指针
char *name[5]={"china","usa","hanguo","chaoxian","I need AV"}
for(int i=0;i<5;i++){
printf("%s",name[i]);
}
name[0] name[1] //常量区,不能改
五:1)为什么说scanf和gets是不安全的
char ch[10];
//从键盘接收一个字符串
scanf("%s",ch); //如果输入的字符串有空格,scanf就认为输入结束了,空格之后的字符都不会被报存
gets(ch); //可以接收用户输入的字符中含有空格
//scanf和gets都有一个缺点:
用户输入多少东西,就帮你保存多少东西
aaaaaaaaaABBBBB
假设用户输入的长度>10 15 = 10存数组 5连续存了(不安全的)
puts() //输出到缓冲区
2)fgets() fputs() //安全的函数
char ch1[10];
9个字符+'\0' 安全的
fgets函数主要功能是从文件中读取数据到字符数组
格式:fgets(数组名,长度,stdin); stdin 表示标准的输入,从输入缓冲区获取数据
注意:
1)fgets() 读取'\n' 换行符 fgets获取的字符长度小与数组长度的时候,能看到
2) 如果输入的长度大于数组长度,会自动截断
3) if (ch[strlen(ch)-1]=='\n') ch[strlen(ch)-1]='\0';
fputs()//可以写入字符串到文件中
格式:fputs(数组名,stdout); //stdout表示输出到控制台
注意:fputs不能换行,puts可以自动换行,printf也不能自动换行
六: // 1、修饰变量,可以让变量变成只读的(常量)
const int a = 10; 一般情况不能修改
int *p;
p = (int *)&a;
*p = 5; printf("%d\n",*p);// 但是不要这么用
// 2、const修饰指针
1)const的作用是指针的指向可以改变,指针指向的变量的值不能改
// const int *p=&b;
// int const *p=&b;
// p = &c; 能改
// *p = 10; 不行
//2)const的作用是,指针的指向不能改变,指针的指向的变量的值可以改变
// int * const p1 = &b;
// p1 = &c; 不可以
// *p1 = 30; 可以
//3)此处的const表示,指针的指向和指向变量的值都不能改变
// const int * const p2 = &b; //可以这样写
// p2 = &c; 不可以
// *p2 = 40; 不可以