类似寻宝图,先把地址存储到指针变量里面,然后去找这个地址
指针大小
当64bit——8bit
当32bit——4bit
定义指针一定要和里面的数定义一样类型的
指针的使用场景:传递和偏移
(不需要的话就别用指针)
传递
#include
#include
void change(j)
{
j=5;
}
int main() {
int i=10;
printf("before i=%d\n",i);
change(i);//C语言的函数调用是值传递,实参赋值给形参,j=i
printf("after i=%d\n",i);
return 0;
}
i并没有改变,原因是这两个变量的地址根本不是一个,他们类似于在两个平行宇宙,各干各的
#include
#include
void change(int *j)
{
*j=5;//间接访问 *j等价于变量i
}
int main() {
int i=10;
printf("before i=%d\n",i);
change(&i);//i的地址
printf("after i=%d\n",i);
return 0;
}
传入的参数是地址,上面函数要取地址,这两个参数就可以对应
偏移
类似于住楼房,一共14层,指针加减指向不同的楼层里面的住户
指针+1里面偏移的是类型的bit数,int就是4
#include
#include
//指针的偏移使用场景,也就是对指针进行加减
#define N 5
int main() {
int a[N]={1,2,3,4,5};
int *p;
p=a;//这里不是p=&a的原因是:数组名字里面存储了数组的起始地址
for(int i=0;i<N;i++)
{
printf("%3d",*(p+i));
}
return 0;
}
把*(p+1)拆开看
p+1这一句用了上面知识点,加一是加在数据类型上的,在地址上是跳了四个字节,eg:0x61fdf0——0x61fdf4
也就是从这样
变成了这样
*(p+1)取地址,此时就是2这个方块的地址
指针与一位数组
#include
#include
//指针与一维数组的传递
//数组名作为实参传递给子函数时,是弱化为指针的
//练习传递与偏移
void change(char *d)
{
//这三种是利用指针修改数组的数据,一和三本质上是一样的
*d='H';
d[1]='E';
*(d+2)='L';
}
int main() {
char c[10]="hello";
change(c);
puts(c);
return 0;
}
一般数组一开始就定义了比如a[10]但用着用着发现数组长度这些不够用了,所以引入了动态内存申请
malloc返回的是无类型指针,好比向校长申请一块空地,但是校长不知道我要用这块空地干什么,而且直接分给我,我在自己分配
无类型指针不能偏移,也就是作用上少,所以强制类型转换
#include
#include
#include
int main() {
int size;//代表我们要申请多大字节的空间
char *p;
scanf("%d",&size);
//malloc返回的void*代表无类型指针,而void*类型的指针是不能偏移的
p= (char*)malloc(size);//所以这里要强制类型转换
p[0]='H';
p[1]='O';
p[2]='W';
p[3]='\0';
// strcpy(p,"malloc success");
puts(p);
return 0;
}
或者直接把一段字符串复制给p数组
#include
#include
#include
int main() {
int size;//代表我们要申请多大字节的空间
char *p;
scanf("%d",&size);
//malloc返回的void*代表无类型指针,而void*类型的指针是不能偏移的
p= (char*)malloc(size);//所以这里要强制类型转换
// p[0]='H';
// p[1]='O';
// p[2]='W';
// p[3]='\0';
strcpy(p,"malloc success");
puts(p);
return 0;
}
#include
#include
#include
int main() {
int size;//代表我们要申请多大字节的空间
char *p;
scanf("%d",&size);
//malloc返回的void*代表无类型指针,而void*类型的指针是不能偏移的
p= (char*)malloc(size);//所以这里要强制类型转换
// p[0]='H';
// p[1]='O';
// p[2]='W';
// p[3]='\0';
strcpy(p,"malloc success");
puts(p);
free(p);//释放申请的空间
return 0;
}
我们自己申请的空间就要还,不是申请的就不用
#include
#include
#include
char *print_stack()
{
char c[30]="I am print_stack func";
char *p;
p=c;
puts(p);
return p;
}
int main() {
char *p;
p=print_stack();//这里之后调用完了就释放了
puts(p);
return 0;
}
输出结果为:
因为操作系统对于栈内存里面的东西是用完就删的,所以读不到数据
下面是堆空间,堆空间不会因为调用完就消亡
#include
#include
#include
char *print_stack()
{
char c[30]="I am print_stack func";
char *p;
p=c;
puts(p);
return p;
}
char *print_malloc()
{
char *p=(char*) malloc(30);
strcpy(p,"I am print_malloc func");
puts(p);
return p;
}
int main() {
char *p;
p=print_stack();
puts(p);
p=print_malloc();
puts(p);
free(p);//只有free的时候,堆空间才会消亡
return 0;
}
#include
#include
#include
void change(i){
printf("%d\n",i/2);
}
int main() {
int i;
scanf("%d",&i);
change(i);
}
老师写的:
#include
#include
#include
void change(int *j){
*j=*j/2;
}
int main() {
int i;
scanf("%d",&i);
change(&i);
printf("%d\n",i);
return 0;
}
第二题:
老师写的:
#include
#include
#include
int main() {
int n;
scanf("%d",&n);
char c;
scanf("%c",&c);//清除标准输入缓冲区的\n
char *p;
p=(char*)malloc(n);
gets(p);//可以使用fgets(p,n,stdin);
puts(p);
return 0;
}
自己写的(啥也不是,毫无逻辑,但怪异的跑了起来,建议别看)
#include
#include
#include
int main() {
int size;
char *p;
scanf("%d",&size);
p=(char*)malloc(size);
scanf("%c",&p);
gets(p);
puts(p);
return 0;
}
指针这一部分学的时候就没学好,上课摸鱼,建议多看!!!