指针的初步使用(C语言)
发布日期:2022-02-27 02:37:48
浏览次数:51
分类:技术文章
本文共 8347 字,大约阅读时间需要 27 分钟。
地址与指针:
- 指针是C语言中广泛使用的一种数据类型,利用指针变量可以更加灵活地组织具有复杂关系的数据,实现动态内存分配,方便地使用数组和字符串。正确而灵活地运用指针,可以编出精炼高效的程序、
- 在C语言中定义一个变量,系统会根据变量的类型为其分配一定个数的存储单元,其中第一个存储单元的地址称为变量的地址,相应存储单元的内容就是变量的值。
- 每个变量都通过变量名与相应的存储单元相联系,存储单元中的内容发生改变,对应的变量值也发送改变。
对变量的操作方式:
-
通过变量名对变量操作:实际上就是根据变量的地址对变量对应的存储单元进行操作;
-
通过定义一种专门存放存储单元或变量地址的变量,将存储单元或变量的地址存放到该变量中,然后再根据该变量去操作相应的存储单元。这种专门存放地址(指针)的变量,称为指针变量。
**【指针与指针变量是不同的概念。指针是存储单元地址,是常量;指针变量是存放存储单元地址(指针)的变量,能被赋予不同的指针值。】**
指针变量:
-
指针变量赋值的一般形式:
//初始化赋值:定义的同时赋值int x;int *px = &x;//先定义,再赋值int x,*px;px = &x;//同类型指针变量之间赋值int x,*p1,*p2;p1 = &x;p2 = p1;//用变量地址对指针变量赋值或初始化时,该变量必须已经定义过!int *p1=&x,x;//语句错误,因为用变量x的地址初始化p1指针变量时,x还未定义//强制类型转换int *p; float f;p=(int *)&f;//*p在定义和引用两种情况下使用时——定义时:仅表示一种标志,说明p是一个指针变量;引用时:**是指针运算符,表示p指向的变量;// &与*的优先级相同,有从右到左的结合性,因而&*px、&(*px)和&x三者等价;*&x、*(&x)和x三者等价,*&x即x本身。
课本上:指针的样例(visual studio 2019中测试,需要把scanf() 替换成 scanf_s() 函数)
#include#include #include //指针变量的简单使用用例void out() { int a, b, x; int* p1, * p2, * p3; printf("请输入两个整数:\n"); scanf("%d %d", &a, &b); //a = 4; b = 6; if (a > b) { p1 = &a; p2 = &b; } else { p1 = &b; p2 = &a; } p3 = &x; *p3 = 5;//间接对x操作,相当于x=5 a++;//直接对a操作,&a也相应改变,进而改变*p1或*p2指向的值 b++; printf("%d,%d,x = %d\n", *p1, *p2, x);}//void空类型指针的应用void nullP() { int x = 12; char c = 'A'; float f = 0.125f; void* p; p = &x; printf("*p=%d\n", *(int*)p); p = &c; printf("*p=%c\n", *(char*)p); p = &f; printf("*p=%f\n", *(float*)p);}//指针法从键盘输入数据:直接使用数组//test data:1 2 8 6 11 88 66 51 36 25void method1() { int a[10], i; printf("请输入10个整数:\n"); for (i = 0; i < 10; i++) scanf("%d", a + i);/* 等价于scanf("%d ",&a[i]); */ printf("以相反顺序输出的结果为:\n"); for (i = 9; i >= 0; i--) printf("%-4d", *(a + i));/* 等价于printf("%-4d", a[i]); */ printf("\n");}//数组名与指针变量之间的联系:数组名VS指针变量void method2() { int a[10], i, * p; p = a; printf("请输入10个整数:\n"); for (i = 0; i < 10; i++) scanf("%d", p + i);/* 表达式p+i表示第i个元素的地址 */ printf("以相反顺序输出的结果为:\n"); for (i = 9; i >= 0; i--) printf("%-4d", *(p + i));/* 等价于printf("%-4d", p[i]); */ printf("\n");}//指针变量的“个人show”void method3() { int a[10], * p; printf("请输入10个整数:\n"); for (p = a; p <= &a[9]; p++) { scanf("%d", p); } printf("以相反顺序输出的结果为:\n"); for (p = a + 9; p >= a; p--) printf("%-4d", *p); printf("\n");}//二维数组与指针变量void method4() { int a[3][4] = { { 1,2,3,4},{ 5,6,7,8},{ 9,10,11,12} }; int x, y, z; x = *(a[0] + 3); y = *a[0]; z = *(*(a + 2) + 3); printf("x=%d, y=%d, z=%d", x, y, z);}//一级指针输出二维数组:法1void out1() { int a[3][4] = { { 1,2,3,4},{ 5,6,7,8},{ 9,10,11,12} }; int* p; //只用了一种循环,因为p指针变量可以从首地址一步步走到结尾地址 for (p = a[0]; p < (a[2] + 4); p++) { printf("%-3d", *p); if ((p - a[0]) % 4 == 3) printf("\n"); }}//法2void out2() { int a[3][4] = { { 1,2,3,4},{ 5,6,7,8},{ 9,10,11,12} }; int* p = a[0], i, j; for (i = 0; i < 3; i++) { for (j = 0; j < 4; j++) printf("%-3d", *((p + i) + j));//有问题 printf("\n"); }}//使用指向一维数组的指针变量输出二维数组:法1void out3() { int a[3][4] = { { 1,2,3,4},{ 5,6,7,8},{ 9,10,11,12} }; int(*p)[4], i, j; p = a; for (i = 0; i < 3; i++) { for (j = 0; j < 4; j++) printf("%-3d", p[i][j]); printf("\n"); }}//法2void out4() { int a[3][4] = { { 1,2,3,4},{ 5,6,7,8},{ 9,10,11,12} }; int(*p)[4], i; for (p = a; p < a + 3; p++) { for (i = 0; i < 4; i++) printf("%-3d", *(*p + i)); printf("\n"); }}//指针与字符串void login() { char user[10]; char pwd[10]; printf("请输入用户名:\n"); gets(user); //scanf("%s", user); printf("请输入密码:\n"); gets(pwd); if (strcmp(user, "xm") == 0 && strcmp(pwd, "123") == 0) printf("正确!"); else printf("不正确!");}//字符指针void divide() { char str[100]; char numstr[100]; char* p1, * p2; printf("请输入一个字符串:\n"); p1 = str; gets(p1);//从键盘输入一个字符串放到str中,此处为通过p1间接引用str p2 = numstr; while (*p1 != '\0') { if (*p1 >= '0' && *p1 <= '9') { *p2 = *p1; p2++; } p1++; } *p2 = '\0'; printf("数字字符为:%s\n", numstr);}//指针与函数:交换两变量的值void swap(int* a, int* b) { //形参为指针变量时,对应的实参可以是指针变量、数组名、变量的地址 int t; t = *a; *a = *b; *b = t;}void testSwap() { int x = 7, y = 12; printf("swap函数调用前:x=%d,y=%d\n", x, y); swap(&x, &y); printf("swap函数调用后:x=%d,y=%d\n", x, y);}//编程实现strcpy()的功能void mystrcpy(char* b, char* a) { while (*a != '\0') { *b = *a; a++; b++; } *b = '\0';}void mystrcpy1(char* a, char* b) { //形参接收到的是地址,在函数中,既可以用指针的形式也可以用下标的形式访问元素 int i = 0; while (a[i] != '\0') { b[i] = a[i]; i++; } *b = '\0';}void testMystrcpy() { char a[100], b[100]; printf("请输入一个字符串:\n"); gets(a); mystrcpy(b, a);//mystrcpy里的形参是指针变量 printf("数组b中的字符串(mystrcpy):\n"); puts(b); mystrcpy1(b, a); printf("数组b中的字符串(mystrcpy1):\n"); puts(b);}//函数返回值为指针,原理:定位到第一个字符串的结尾地址,然后循环添加第二个字符串的值,直到遇到\0结束循环,最后记得加上\0void* myStrcat(char* fst, char* snd) { char* p = fst; while (*fst != '\0') fst++; for (; *snd != '\0'; fst++, snd++) *fst = *snd; *fst = '\0'; return p;}void testmyStrcat() { char fst[100], snd[100]; char* result = NULL; printf("请输入第一个字符串:\n"); gets(fst); printf("请输入第二个字符串:\n"); gets(snd); result = myStrcat(fst, snd); printf("连接后的字符串为:%s\n", result);}//函数指针的应用double fact(int x) { double r = 1; if (x == 0 || x == 1) r = 1; else r = fact(x - 1) * x; return r;}void testFact() { double sum; double (*pfun)(); pfun = fact; sum = pfun(1) + pfun(2) + pfun(3); printf("sum = %.2lf\n", sum);}//指针数组(一个数组的所有元素都是指针,是指针数组):按顺序输出国家名字void sort(char* pstr[], int len) { int i, j; char* temp; for (i = 0; i < len; i++) { for (j = i + 1; j < len; j++) { if (strcmp(pstr[i], pstr[j]) > 0) { temp = pstr[i]; pstr[i] = pstr[j]; pstr[j] = temp; } } }}//England America Sweden China Finlandvoid testSort() { int i, n; char name[200][20]; char* pstr[200]; printf("请输入国家的个数:\n"); scanf("%d", &n); getchar();//清除键盘缓冲区中残留的换行符 printf("请输入这些国家的名字:\n"); for (i = 0; i < n; i++) { gets(name[i]); pstr[i] = name[i]; } sort(pstr, n); printf("排序后的国家名:\n"); for (i = 0; i < n; i++) puts(pstr[i]);}//程序设计题:实现strcmp()函数的功能int Strcmp(char* str1, char* str2) { int result = 0, i = 0; while (str1 != '\0') { if (*str1 != *str2) { printf("test2:str1 = %c, str2 = %c\n", *str1, *str2); return (*str1 - *str2); } str1++; str2++; } /*for (; str1 != '\0',str2!='\0'; str1++, str2++) { if ((*str1 != *str2)&&(str1 != '\0')) { printf("test%d:str1 = %c, str2 = %c\n", i, *str1, *str2); i++; return (*str1 - *str2); } else { printf("test2:str1 = %c, str2 = %c\n", *str1, *str2); //相加直接得到ascall值之差! } }*/ return result;}void testStrcmp() { char s1[100], s2[100]; int flag; printf("请输入第一个字符串:\n"); gets(s1); printf("请输入第二个字符串:\n"); gets(s2); flag = Strcmp(s1, s2); printf("调用Strcmp()函数,处理结果为:%d\n", flag);}//实现fun()函数:求奇、偶数的和,输出长度void fun(int* a, int n, int* odd, int* even) { int i = 0; printf("*a=%d\n", *a++); while (i < n) { if ((a[i]) % 2 == 0) *even += a[i]; else *odd += a[i]; i++; //printf("even=%d,odd=%d\n", *even, *odd); } *a++; printf("*a=%d\n", *a);}void testFun() { int d[10] = { 1,1,2,3,4,5,6,7,8,9 }; int odd = 0, even = 0; int len = 10; fun(d, len, &odd, &even); printf("奇数和为:%d", odd); printf("\n偶数和为:%d", even);}//反序输出字符串void order() { char str[100], * p = str; int i = -1; printf("请输入一个字符串:\n"); gets(str); printf("反向输出结果:\n"); while (*p != '\0') { p++; i++; } for (; i >= 0; i--) printf("%c", str[i]);}//统计一段文本中,单词的个数!(空格隔开,且只有字母和空格)//测试文本:(12词)hello?do you know me?emmm, let me see.Oh,it's you.void countWords() { char txt[200], * p = txt; int count = 0, flag = 0; printf("请输入一段英文文本:\n"); gets(txt); while (*p != '\0') { flag = 0; //if ((*p < 65 || (*p > 90 && *p < 97) || *p > 122) && (*(p+1)>64 && *(p + 1)<91 || *(p + 1)>96 && *(p + 1)<123) && *(p+1)!= '\0' ) if (*p > 64 && *p < 91 || *p > 96 && *p < 123) flag++; if (flag > 0) count++; p++; } printf("该文本的单词数为:%d\n", count + 1);}//字母数字划“三八线” 测试用例:a12bcd45void classify() { char str[50], * p = str; char letter[50], num[50]; char* p1 = letter, * p2 = num; int i = 0, j = 0; printf("请输入一个字符串:\n"); gets(str); printf("字母、数字分开后:\n"); while (*p != '\0') { if ((*p >= 'a' && *p <= 'z') || (*p >= 'A' && *p <= 'Z')) { *p1 = *p; p1++; } if (*p >= '0' && *p <= '9') { *p2 = *p; p2++; } p++; } *p1 = '\0'; *p2 = '\0'; printf("%s", letter); printf("%s", num);}int main(int argc, char* argv[]) { /*int a = -2, b = 0; while (a++) ++b; printf("%d,%d\n", a, b);*/ classify(); return 0;}
转载地址:https://blog.csdn.net/weixin_43376042/article/details/113695019 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
初次前来,多多关照!
[***.217.46.12]2024年04月20日 19时53分09秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
1010 一元多项式求导 (25 分)
2019-04-26
使用Python通过win32 COM接口实现Excel单元格写入
2019-04-27
使用命令行工具编译C#程序
2019-04-27
C#中的局部变量冲突
2019-04-27
C语言读取二进制文件
2019-04-27
解决GVIM中C-A组合键不起作用的问题
2019-04-27
VS中定义的DEBUG常量
2019-04-27
C#中warning预处理命令的使用
2019-04-27
C#中error预处理命令的使用
2019-04-27
MATLAB中限值模块的使用
2019-04-27
树莓派显示黑边问题解决
2019-04-27
树莓派的硬件信息了解与思考
2019-04-27
树莓派安装截图工具
2019-04-27
树莓派上创建个人用户
2019-04-27
树莓派CPU超频配置
2019-04-27
树莓派终端背景色调节
2019-04-27
树莓派U盘挂载位置
2019-04-27
对比Ubuntu与Win10的资源占用
2019-04-27
树莓派硬件启动失败log记录查看方法
2019-04-27
树莓派使用心得
2019-04-27