小甲鱼C语言学习笔记之~指针
一、指针和指针变量
指针就是内存地址
指针变量存储的是一个地址,它的类型就是存放地址指向数据的类型
二、取地址运算符合取值运算符
代码部分
int main()
{
char a = 'F';
int f = 123;
char *pa = &a;
int *pb =&f;
printf("a = %c\n",*pa);
printf("f = %d\n",*pb);
*pa = 'C';
*pb += 1;
printf("now,pa = %c\n",*pa);
printf("now,pb = %d\n",*pb);
printf("size of pa =%lu\n", sizeof(pa));
printf("size of pb =%lu\n", sizeof(pb));
printf("the addr of pa is %p\n",pa);
printf("the addr of pa is %p\n",pb);
return 0;
}
二、指针和数组
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <unistd.h>
int main()
{
int a;
int *p = &a;
printf("请输入一个整数:\n");
scanf("%d",&a);
printf("a = %d\n",a);
printf("请重新输入一个整数:\n");
scanf("%d",p);
printf(" *p = %d\n",a);
return 0;
}
执行结果
请输入一个整数:
2
a = 2
请重新输入一个整数:
3
*p = 3
int main()
{
char str[123];
printf("请输入一个字符串\n");
scanf("%s",str);
printf("%s\n",str);
return 0;
}
执行结果:
请输入一个字符串
liuzhaoming
liuzhaoming
数组名其实是数组第一个元素的地址
int main()
{
char str[123];
printf("请输入一个字符串\n");
scanf("%s",str);
printf("%s\n",str);
printf("str的地址是%p\n",str);
printf("str的地址是%p\n",&str[0]);
return 0;
}
执行结果:
请输入一个字符串
123
123
str的地址是0x7ffd0cfb62a0
str的地址是0x7ffd0cfb62a0
int main()
{
char a[123] = "liuzhaoming";
int b[5] = {1,2,3,4,5};
float c[5] = {1.1, 2.2, 3.3, 4.4, 5.5};
double d[5] = {1.1, 2.2, 3.3, 4};
printf("a[0] -> %p, a[1] -> %p, a[2] -> %p\n",&a[0], &a[1],&a[2]);
printf("b[0] -> %p, b[1] -> %p, b[2] -> %p\n",&b[0], &b[1],&b[2]);
printf("c[0] -> %p, c[1] -> %p, c[2] -> %p\n",&c[0], &c[1],&c[2]);
printf("d[0] -> %p, d[1] -> %p, d[2] -> %p\n",&d[0], &d[1],&d[2]);
return 0;
}
执行结果:
a[0] -> 0x7fffe9c85a60, a[1] -> 0x7fffe9c85a61, a[2] -> 0x7fffe9c85a62
b[0] -> 0x7fffe9c859f0, b[1] -> 0x7fffe9c859f4, b[2] -> 0x7fffe9c859f8
c[0] -> 0x7fffe9c85a10, c[1] -> 0x7fffe9c85a14, c[2] -> 0x7fffe9c85a18
d[0] -> 0x7fffe9c85a30, d[1] -> 0x7fffe9c85a38, d[2] -> 0x7fffe9c85a40
三、指向数组的指针
char *p;
p = a;
p =&a[0];
三、指针的运算
int main()
{
char a[123] = "liuzhaoming";
int b[5] = {1,2,3,4,5};
float c[5] = {1.1, 2.2, 3.3, 4.4, 5.5};
double d[5] = {1.1, 2.2, 3.3, 4};
char *p=a;
printf("*p=%c,*(p+1)=%c,*(p+2)=%c\n",*p,*(p+1),*(p+2));
int *pa = b;
printf("*p=%d,*(p+1)=%d,*(p+2)=%d\n",*pa,*(pa+1),*(pa+2));
/*
printf("a[0] -> %p, a[1] -> %p, a[2] -> %p\n",&a[0], &a[1],&a[2]);
printf("b[0] -> %p, b[1] -> %p, b[2] -> %p\n",&b[0], &b[1],&b[2]);
printf("c[0] -> %p, c[1] -> %p, c[2] -> %p\n",&c[0], &c[1],&c[2]);
printf("d[0] -> %p, d[1] -> %p, d[2] -> %p\n",&d[0], &d[1],&d[2]);
*/
return 0;
}
执行结果:
a[0] -> 0x7fffe9c85a60, a[1] -> 0x7fffe9c85a61, a[2] -> 0x7fffe9c85a62
b[0] -> 0x7fffe9c859f0, b[1] -> 0x7fffe9c859f4, b[2] -> 0x7fffe9c859f8
c[0] -> 0x7fffe9c85a10, c[1] -> 0x7fffe9c85a14, c[2] -> 0x7fffe9c85a18
d[0] -> 0x7fffe9c85a30, d[1] -> 0x7fffe9c85a38, d[2] -> 0x7fffe9c85a40
*p=l,*(p+1)=i,*(p+2)=u
*p=108,*(p+1)=105,*(p+2)=117
指针定义,数组名访问字符串
int main()
{
char *str = "liuzhaoming";
int i,len;
len = strlen(str);
for(i=0; i<len;i++)
{
printf("%c",str[i]);
}
printf("\n");
return 0;
}
执行结果:
liuzhaoming
三、指针数组和数组指针
指针和数组的区别
int main()
{
char str[] = "liuzhaoming";
int count = 0;
char *p = str;
//while(*str++ != '\0')
while(*p++ != '\0')
{
count++;
}
printf("总共有%d个字符串。\n",count);
return 0;
}
执行结果:
总共有11个字符串。
指针数组和数组指针
int *p[5] --指针数组。是一个数组,每一个元素存放一个指针变量
int main()
{
int a = 1;
int b = 2;
int c = 3;
int d = 4;
int e = 5;
int *p[5] ={&a, &b, &c, &d, &e};
int i;
for(i = 0; i< 5; i++)
{
printf("the value is %d\n",*p[i]);
}
return 0;
}
执行结果:
the value is 1
the value is 2
the value is 3
the value is 4
the value is 5
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <unistd.h>
int main()
{
char *p[5] ={
"aaaa",
"bbbb",
"cccc",
"dddd",
"eeee",
};
int i;
for(i = 0; i< 5; i++)
{
printf("the value is %s\n",p[i]);
}
return 0;
}
执行结果:
the value is aaaa
the value is bbbb
the value is cccc
the value is dddd
the value is eeee
int (*p)[5]; 数组指针是一个指针,它指向的是一个数组
int main()
{
int tmp[5]= {1, 2, 3, 4, 5};
int (*p)[5] = &tmp;
int i;
for(i = 0; i< 5; i++)
{
printf("the value is %d\n",*(*p+i));
}
return 0;
}
执行结果:
the value is 1
the value is 2
the value is 3
the value is 4
the value is 5
通过这个程序我们可以得出以下结论:
1、数组的地址和数组的首元素的地址 值相同 但是含义不同 区别于步长。
2、步长取决于地址所代表的空间的大小:
对于数组的地址的步长 取决于 数组的大小
对于数组的首元素的地址的步长 取决于 数组中的元素的类型
3、对于二维数组,二维数组的首元素的地址,即其所存放的第一个一维小数组的起始地址
三、指针和二维数组
二维数组的定义:
int b[4][5];
int 表示指向5个数组元素的指针
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <unistd.h>
int main()
{
int array[4][5]= {
0,1,2,3,4,
5,6,7,8,9,
10,11,12,13,14,
15,16,17,18,19,
};
printf("size of int is %lu\n", sizeof(int));
printf("the value of array is %p\n",array);
printf("the value of array+1 is %p\n",array+1);
printf("the value of array+1 is %p\n",*(array+1));
printf("the value of array+1 is %d\n",**(array+1));
printf("the value of array+1 is %d\n",*(*(array+1)+3));
return 0;
}
执行结果:
size of int is 4
the value of array is 0x7ffcd1b0c460
the value of array+1 is 0x7ffcd1b0c474
the value of array+1 is 0x7ffcd1b0c474
the value of array+1 is 5
the value of array+1 is 8
解引用:引用指针指向的变量值,引用其实就是引用该变量的地址,“解”就是把该地址对应的东西解开,解出来,就像打开一个包裹一样,那就是该变量的值了,所以称为“解引用”。也就是说,解引用是返回内存地址中对应的对象。
三、数组指针和二维数组
int array[2][3] = {{0,1,2},{3,4,5}};
int (*p)[3] = array; //指向第一行的数组
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <unistd.h>
int main()
{
int array[2][3] = {{0,1,2},{3,4,5}};
int (*p)[3] = array;
int i;
for(i=0;i<3;i++)
{
printf("the value is %d\n",*(*p+i));
}
return 0;
}
执行结果:
the value is 0
the value is 1
the value is 2
四、void指针和NULL指针
*void指针
int main()
{
void *pv; //通用指针,可以指向任何类型的指针
int num = 1024;
int *pi = #
char *str = "liuzhaoming";
char *ps = str;
pv = pi;
printf("pi:%p pv:%p\n", pi, pv);
printf("*pv:%d\n", *(int *)pv);
pv = ps;
printf("ps:%p pv:%p\n", ps, pv);
printf("*pv = %s\n", (char *)pv);
return 0;
}
执行结果:
pi:0x7fff6ec18874 pv:0x7fff6ec18874
*pv:1024
ps:0x55baada59804 pv:0x55baada59804
*pv = liuzhaoming
浅红色文字:不能对void指针进行解引用
、
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <unistd.h>
int main()
{
int *p1; //野指针
int *p2 = NULL;
printf("%d\n", *p1);
printf("%d\n", *p2);
return 0;
}
执行结果:
Segmentation fault (core dumped)
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程