C:指针
知识点#
指针运算#
1、取地址运算&和去内容运算*
2、指针与整数的加减运算
3、指针相减运算
4、指针关系运算
指针与结构数组#
123456789101112131415/
/
定义结构体类型
struct info
{
short num;
char name[
5
];
};
/
/
定义指向info结构体的指针
struct info
*
p_info;
/
/
定义结构体变量
struct info myinfo;
/
/
初始化指针
p_info
=
&myinfo;
字符串指针#
1、指向字符数组的指针
2、指向字符串常量的指针
指针数组#
指向指针的指针#
又叫做“指针型指针”#include <stdio.h> #include <stdlib.h> int main() { int *q,**p; int x = 1; q = &x; p = &q; printf("q = %x\n",q); printf("*q = %d\n",*q); printf("p = %x\n",p); printf("*p = %x\n",*p); printf("**p = %d",**p); return 0; }用指针型指针输出数组元素:
#include <stdio.h> #include <stdlib.h> int main() { int a[5] = {1,2,3,4,5}; int *num[5] = {&a[0],&a[1],&a[2],&a[3],&a[4]}; int **p,i; p =num; for(i = 0;i < 5;i++) { printf("%d\t",**p); //输出:1 2 3 4 5 p++; } return 0; }习题#
1、 请指出以下程序段中的错误。#
程序中的错误有:
(1)p=i:类型不匹配。
(2)q=*p:q 是指针,*p 是指针 p 指向变量的值。
(3)t='b':t 是指针类型。解释:指针变量是一种存放地址的特殊变量,其特殊性表现在类型和值上。指针变量的
类型是指针变量所指向的变量的类型,而不是自身的类型。指针变量赋值应该是地址值。正确程序应为:
main () { int i,j,*p,*q; char ch1,ch2,*t,*s; i=3; p=&i; j=*p/2+10; q=p; ch1='a'; s=&ch1;l *s='c'; *t='b'; ch2=*t; }2、以下程序的输出结果是什么?#
main() { char *point[]={"one","two","three","four"}; while(*point[2]!='\0') printf("%c",*point[2]++); }答:输出结果是 three。
结果分析:指针数组是指数组的每一个元素都是一个指针变量的数组, 定义了指针数组 pd,它由 pd[0]~pd[3]4 个数组元素组成。main() { char *point[]={"one","two","three","four"}; point[2]=point[0]; printf("%s",point[2]++); }答:输出结果是 one。
3、请对以下程序进行修改,用指针完成对数组元素的访问:#
main() { int data[12]={12,34,56,12,34,56,3,54,6,7,89,12}; int i,sum; sum=0; for(i=0;i<12;i++) sum+=data[i]; printf("The sum is %d\n",sum); }算法分析:本题需要抓住数组和指针的联系,讨论数组时,对数组元素的访问是采用的
下标法,即是以数组的下标来确定数组元素的。在引入指针变量后,我们可以利用一个指向
数组的指针来完成对数组元素的存取操作及其他运算,这种方法称为指针法。
修改后的程序为:#include<stdio.h> main () { int data[12]={12,34,56,12,34,56,3,54,6,7,89,12}; int i,sum; int *p; //定义指针 sum=0; p=data; //指针赋值 for (i=0;i<12;i++) { sum+=*p; p++; } printf("The sum is %d\n",sum); }4、指出并更正以下程序的错误。#
main () { char data[]="There are some mistakes in the program"; char *point; char array[30]; int i,length; length=0; while(data[1ength]!='\0') length++; for(i=0;i<length;i++,point++) *point=data[i]; array=point; printf("%s\n",array); }经过分析,我们可以看出程序的目的是将这个字符串输出,原程序中的主要错误是在指
针运算前没有赋初始地址,于是进行以下修改:#include<stdio.h> main() { char data[]="there are some mistakes in the program"; char *point; char array[100];//定义一个数组 int i,length; length=0; while(data[length]!='\0')//求字符串的长度 length++; point=array;//给指针赋首地址,主要修改部分 for(i=0;i<=length;i++,point++)//输出字符串 *point=data[i]; printf("%s\n",array); }5、编写一个程序输入两个字符串 string1 和 string2,检查在 string1 中是否包含有 string2。如果有,则输出 string2 在 string1 中的起始位置;如果没有,则显示“NO”;如果 string2在 string1 中多次出现,则输出在 string1 中出现的次数以及每次出现的起始位置,#
例如:stringl="the day the month the year";
string2="the"
输出结果应为:出现三次,起始位置分别是:0,8,18
又如:
stringl="aaabacad"
string2="a"
输出结果应为:出现五次,起始位置分别是 0,1,2,4,6算法分析:
(1)本题需要对两个字符串进行循环,但与普通循环不同的是,这两个循环并不
是同时进行的。string1 开始循环后,string2 并不一定开始循环,而是需要判断 string2 的首
字母是否和 string1 中循环到的字母相同,如果相同,则两个字符串开始同时循环,并记录
下开始的位置,然后判断 string2 中后面的字母是否和 string1 中的相同,相同则继续,不同
则停止,直到 string2 循环完成。此时用当前的位置减去 string2 的长度就是 string2 的起始位
置。(2)在本题中,还需要注意的是,由于 string2 可能多次出现,所以需要一个数组来保存多
次出现的位置。代码:
#include <stdio.h> #include <stdlib.h> void main() { char string1[100],string2[10]; // 定义数组存储两个字符串,暂定第一个在 100 内,第二个在 10 内 char *p,*q; //定义指针遍历字符串 int locat[10]; //定义数组保存出现的位置 int j,len2 = 0,i = 0,posit = 0; //len2 表示第二个字符串的长度 printf("请输入字符串1:\n"); gets(string1); printf("请输入字符串2:\n"); gets(string2); q = string2; // 求第二个字符串的长度 for(j = 0;*q != '\0';j++,q++) { len2 = j + 1; } p = string1; //指针赋首地址 q = string2; //循环进行判断 do { // 字符不相同的情况 if(*p != *q) { p++; posit++; } // 第一个字符相同,继续对后面字符进行判断 else { while((*q != '\0') && (*q == *p)) { q++; p++; posit++; } // 第二个字符串循环结束 if(*q == '\0') { locat[i] = posit - len2; i++; } } q = string2; }while(*p != '\0'); printf("字符串1:%s\n字符串2:%s\n",string1,string2); printf("出现%d次,起始位置分别是:",i); //输出位置 for(j = 0;j < i;j++) { printf("%d\t",locat[j]); } }程序分析:q=string2 这句的作用是什么呢?是保证 q 循环后能再次初始化,这样才能
进行多次判断,并且防止错误。例如:q 和 p 的第 1 个、第 2 个字符相同,但第 3 个不同,
此时 q 指针已经指向了第 3 个字符,如果不再次初始化,下一步比较就将从 q 的第 3 个字符
开始,出现错误。6、给定一个整数数组:num[]={23,45,345,23};请定义一个指针变量 point,并令它指向数组的第一个元素,然后回答以下问题:#
(1) num[2]的值等于什么?
(2) *(point+2)的值等于什么?
(3) *++point 的值等于什么?答:
1int
*p = num;
(1)345,即是数组的第 3 个元素。
(2)345,指针指向了数组的第 3 个元素。
(3)45,指针指向了数组的第 2 个元素。7、【不太懂】编制一个程序显示内存中一片存储区域的内容#
#include <stdio.h> #include <stdlib.h> void main() { char *point; long int b_addr,e_addr,i,j; printf("请输入起始地址和结束地址:\n"); scanf("%lx%lx",&b_addr,&e_addr); for(i = b_addr;i < e_addr;i+=16) { printf("%05lx:",i); point = (char*)i; for(j = 0;j < 16;j++) { if(j == 8) { printf(" "); } printf("%02x",*point); point++; } printf("\n"); } }现令其按 ASCII 码的方式显示内存单元的内容:
#include <stdio.h> #include <stdlib.h> void main() { char *point; long int b_addr,e_addr,i,j; printf("please enter the beginning and the end addr in hex\n"); scanf("%lx%lx",&b_addr,&e_addr); for(i=b_addr; i<e_addr; i+=16) { printf("%05lx: ",i); // 宽度为5,的长十六进制的数输出 ??? point=(char*)i; for(j=0; j<16; j++) { if(j==8) printf(" "); printf("%3d ",*point); point++; } printf("\n"); } }8、编写程序输入一个字符串,分别统计输出该字符串中的字母个数和数字个数。#
算法分析:
判断字母和数字的核心方法是依靠 ASCII 码进行,所以对字符串中的每个
字符逐个判断即可得到结果。实现方法依然是依靠指针。代码:
#include <stdio.h> #include <stdlib.h> void main() { char str[100]; //定义一个数组存储字符串 char *p; int n_count=0,c_count=0; p=str; printf("请输入一个字符串:\n"); gets(str); //输入字符串 do { if((*p>='0')&&(*p<='9'))//判断数字 n_count++; if((*p>='a')&&(*p<='z'))//判断小写字母 c_count++; if((*p>='A')&&(*p<='Z'))//判断大写字母 c_count++; p++; }while(*p!='\0'); printf("字符串%s 中的字母个数是:%d,数字个数是%d",str,c_count,n_count); }程序分析:本题需要注意的有两点:
1.char 类型的变量,初学者往往理解为是不能直接比较大小的,【自动转换】实际上直接比较大
小时,是将类型转换为了 int 后比较的 ASCII 码值。这样的方法相对与手动转换为 ASCII
码比较而言更加高效和方便。
2.字母包含大小写,这点容易遗漏,在程序设计时应该考虑更全面。另外,这道题还可以扩展为求数字、字母和其他字符的数量:
#include <stdio.h> #include <stdlib.h> void main() { char str[100];//定义一个数组存储字符串 char *p; int n_count=0,c_count=0,o_count = 0; p=str; printf("请输入一个字符串:\n"); gets(str);//输入字符串 do { if((*p>='0')&&(*p<='9'))//判断数字 n_count++; else if(((*p>='a')&&(*p<='z')) || (*p>='A')&&(*p<='Z')) //判断字母 c_count++; else //判断其他字符 o_count++; p++; }while(*p!='\0'); printf("字符串%s 中的字母个数是:%d,数字个数是%d, 其他字符个数是: %d",str,c_count,n_count,o_count); }9、以下程序的输出结果是什么?#
main() { char *point[]= { "111111111", "222222222", "333333333", "444444444", "555555555" }; int i,j; for(i=1;i<3;i++) { for(j=1;j<5;j++) printf("%c",*(point[j]+i)); printf("\n"); } }答:
输出结果为:2 3 4 5
2 3 4 510、编写一个程序,输入两个字符串,比较它们是否相等。#
#include <stdio.h> #include <stdlib.h> int main() { char str1[100],str2[100]; char *p,*q; printf("请输入第一个字符串:\n"); gets(str1); printf("请输入第二个字符串:\n"); gets(str2); p=str1; q=str2; if(*p!=*q) printf("两个字符串不相等。"); else { while((*p==*q)&&(*p!='\0')&&(*q!='\0'))//循环判断是否每个字符相等 { p++; q++; } if((*p=='\0')&&(*q=='\0')) printf("两个字符串相等:"); else printf("两个字符串不相等:"); } }
作者:Hang Shao
出处:https://www.cnblogs.com/pam-sh/p/12381255.html
版权:本作品采用「知识共享」许可协议进行许可。
声明:欢迎交流! 原文链接 ,如有问题,可邮件(mir_soh@163.com)咨询.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)