指针的初步使用(C语言)
发布日期:2022-02-27 02:37:48 浏览次数:51 分类:技术文章

本文共 8347 字,大约阅读时间需要 27 分钟。

地址与指针:

  • 指针是C语言中广泛使用的一种数据类型,利用指针变量可以更加灵活地组织具有复杂关系的数据,实现动态内存分配,方便地使用数组和字符串。正确而灵活地运用指针,可以编出精炼高效的程序、
  • 在C语言中定义一个变量,系统会根据变量的类型为其分配一定个数的存储单元,其中第一个存储单元的地址称为变量的地址,相应存储单元的内容就是变量的值。
  • 每个变量都通过变量名与相应的存储单元相联系,存储单元中的内容发生改变,对应的变量值也发送改变。

对变量的操作方式:

  • 通过变量名对变量操作:实际上就是根据变量的地址对变量对应的存储单元进行操作;

  • 通过定义一种专门存放存储单元或变量地址的变量,将存储单元或变量的地址存放到该变量中,然后再根据该变量去操作相应的存储单元。这种专门存放地址(指针)的变量,称为指针变量。

    **【指针与指针变量是不同的概念。指针是存储单元地址,是常量;指针变量是存放存储单元地址(指针)的变量,能被赋予不同的指针值。】**

指针变量:

  1. 指针变量赋值的一般形式:

    //初始化赋值:定义的同时赋值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秒