第九章、指针
9.1 指针变量和取地址符
#include<stdio.h>
int main()
{
int a=0,b=1;
char c='A';
/*定义了指针变量一定要赋值,只能同种类型之间.*/
int *pa=&a,*pb=&b;
char *pc=&c;
/*%p表示地址格式,*p表示地址指向的值*/
printf("&a=%p,pa=%p,*pa=%d\n",&a,pa,*pa);
return 0;
}
输出:
&a=0023FF74,pa=0023FF74,*pa=0;
而:&pa=0023FF68
9.2 传值调用和引用调用
#include<stdio.h>
/*
void fun(int a)
{
a=2;//属于两个不同作用域的a,所以main函数中输出为1。
}
*/
/*
void fun(int *a)
{
*a=2;//引用调用,属于同一个a,所以main函数中输出为2。
}
*/
int fun(int a)
{
a=2;
return a;//仅限返回一个值
}
int main()
{
int a=1;
//fun(a);
//fun(&a);
a=fun(a);
printf("a=%d\n",a);
}
9.3 函数指针及其应用
函数指针是指向函数的指针,指向存储这个函数第一条指令的地址,称为函数的入口地址。
函数名如同数组名,代表函数的入口地址。而基本变量类型的变量名代表的则是变量值,获得基本变量类型的变量地址需要用到&操作符。
#include<stdio.h>
int Ascending(int a,int b);
{
return a<b;
}
int Descending(int a,int b);
{
return a>b;
}
void SelectionSort(int a[],int n,int (*compare)(int a,int b));
{
int i,j,k;
for(i=0;i<n;i++)
{
k=i;
for(j=i+1;j<n;j++)
{
if((*compare)(a[j],a[k]))
k=j;
}
if(k!=i)
Swap(&a[k],&a[j]);
}
}
int main()
{
SelectionSort(score,n,Ascending);
SelectionSort(score,n,Descending);
return 0;
}
9.4 课后习题
求函数的定积分:
、
#include<stdio.h>
float fun1(float x)
{
return 1+x*x;//定义第一个函数
}
float fun2(float x)
{
return x/(1+x*x);//定义第二个函数
}
float fun(float (*f)(float),float a,float b)//定义一个函数指针
{
flaot i,sum,n;
sum=0;
n=(b-a)/100;//微元法,分为100份
for(i=a+n/2;i<b;i+=n)
{
sum+=n*(*f)(i);
}
return sum;
}
int main()
{
float sum1,sum2;
sum1=fun(fun1,0,1);
sum2=fun(fun2,0,3);
printf("sum1=%f,sum2=%f\n",sum1,sum2);
return 0;
}
第十章、字符串
10.1 字符串相关问题
字符串常量:是由一对双引号括起来的字符序列。如"Hello",以字符’\0’作为结束。
字符串的存储: char str[6]={‘H’,‘e’,‘l’,‘l’,‘o’,’\0’}; 数组定义的长度应大于等于字符串中包括’\0’在内的字符个数。
char str[]={‘H’,‘e’,‘l’,‘l’,‘o’,’\0’}; 省略数组的长度,必须人为在数组后面加一个’\0’。
char str[]={‘H’,‘e’,‘l’,‘l’,‘o’}; 否则只会初始化大小为5的数组,无法放置’\0’,也就无法当作字符串来处理。
char str[]={“Hello”}; char str[]=“Hello”; 这种可以省略数组的长度,且不用加’\0’,因为字符串常量后面自动会加上’\0’
char weekday[7][10]={“Sunday”,“Monday”,“Tuesday”,“Wednessday”,“Thursday”,“Friday”,“Saturday”}; 第一维的长度可以省略,但是第二维的长度不能省略,因为二维数组按行存储。
char weekday[][10]={“Sunday”,“Monday”,“Tuesday”,“Wednessday”,“Thursday”,“Friday”,“Saturday”}; 当字符串长度小于10时,,剩余的单元自动初始化为’\0’。
字符指针: char *ptr=“Hello”; 等价于 char *ptr; ptr=“Hello”; *ptr=‘w’;//错误的做法 将保存在常量存储区中的"Hello",的首地址赋值给ptr; 因为"Hello"保存在常量存储区,所以可以修改指针变量ptr的指向,但是不能对ptr指向的存储单元进行写操作。
char str[10]=“Hello”; char *ptr=str;//数组名是一个常量值,不可以修改,但是ptr指向可以修改, 并且ptr指向的字符串也可以修改,因为数组存储不是在常量存储区。。 等价于 char *ptr=&str[0]; *ptr=‘w’;//等价于:ptr[0]=‘w’,str[0]=‘w’;
?10.2 字符串输入与输出
访问字符串的单个字符: (ptr+i);(str+i);str[i];用来访问字符串中的第i+1个字符。 注意:对于数组名str,不能使用str++操作使其指向字符串中的某个字符,因为数组名是一个地址常量,其值不能被改变。
字符串的输入和输出:
第一种:
for(i=0;i<10;i++)
{
scanf("%c".&str[i]);//输入
}
for(i=0;i<10;/str[i]!=’\0’/ i++)
{
printf("%c ",str[i]);//输出
}
第二种:
scanf("%s",str);
//整体的输入和输出,读入直到遇到空格,回车符和制表符为止;
//str代表数组的首地址,不用加&.
printf("%s",str);
#include<stdio.h>
int main()
{
char name[12];
scanf("%s",name);//遇到空格,只读入一个Yang
printf("%s\n",name);
scanf("%s",name);//读入缓冲区余下的上次未被读走的字符。
printf("%s\n",name);
return 0;
}
输出: Yang Li Yang Li
第三种:gets()可以输入带空格的字符串,以回车符作为终止符,同时将回车符从输入缓冲区读走,但不作为字符串的一部分。而scanf()不读走回车符,回车符仍然留在输入缓冲区中。
#include<stdio.h>
int main()
{
char name[12];
/*
gets(name);
puts(name);//当遇到第一个'\0',输出结束;并且自动输出一个换行符。
*/
char *ptr=name;
gets(ptr);
printf("%s\n",ptr);
return 0;
}
第四种:fgets()。因为函数gets()不能限制输入字符串的长度,很容易引起输入缓冲区溢出。
#include<stdio.h>
int main()
{
char name[12];
//限制输入字符长度不超过数组大小.多余的字符都被舍弃掉了.
fgets(name,sizeof(name),stdin);
printf("%s\n",name);
return 0;
}
10.3 字符串与函数
要包含头文件 : #include<stdlib.h>
- strlen(str),求字符串长度,不包括’\0’。
- strcpy(str1,str2),str2复制到str1,str1必须发的下str2。
- strcmp(str1,str2),str1大于str2,返回值大于0;str1等于str2,返回值等于0;str1小于str2,返回值小于0。
- strcat(str1,str2),str2添加到str1中。str1必须有足够的大小
- strncpy(str1,str2,n),str2至多前n个字符复制到str1中。
- strncmp(str1,str2,n),最多比较n个字符。
- strncat(str1,str2,n),str2中至多前n个字符放到str1后面
将字符串进行排序,利用数组进行排序,以行优先进行存储。
#include<stdio.h>
#include<stdlib.h>
#define MAX_LEN 10
#define N 10
void SortSting(char str[][MAX_LEN],int n)
{
int i,j;
char temp[MAX_LEN];
for(i=0;i<n-1;i++)
{
for(j=i+1;i<n;j++)
{
if(strcmp(str[i],str[j])>0)
{
strcpy(temp,str[i]);
strcpy(str[i],str[j]);
strcpy(str[j],temp);
}
}
}
}
int main()
{
int i,n;
char str[N][MAX_LEN];
scanf("%d",&n);
getchar();//读走输入缓冲区里的回车符,防止gets读入了。
for(i=0;i<n;i++)
{
gets(str[i]);
}
SortString(str,n);
for(i=0;i<n;i++)
{
puts(str[i]);
}
return 0;
}
对于单个字符进行赋值可以用赋值运算符(=),但是对于赋值运算符进行赋值,只能用strcpy(); 比较字符串不能用关系运算符,而应该用strcmp()。
将一个字符串赋值到另一个字符串中:
#include<stdio.h>
#define N 80
/*
void MyStrcpy(char a[],char b[])
{
int i;
for(i=0;a[i]!='\0';i++)
{
b[i]=a[i];
}
b[i]='\0';
}
*/
void MyStrcpy(char *pa,char *pb)
{
while(*pa!='\0')
{
*pb++=*pa++;
}
*pb='\0';
}
int main()
{
char a[N],b[N];
gets(a);
MyStrcpy(b,a);
puts(b);
return 0;
}
返回指针值的函数与函数指针是截然不同的:
- char *f();返回字符指针的函数;
- char (*f)();函数指针指向的函数,返回值是字符型。
实现字符串连接功能:
#include<stdio.h>
#define N 80
char *MyStrcat(char *first,char *second)
{
char *temp;
temp=first;//保存第一个字符串的首地址
while(*first!='\0')
{
first++;
}
for(;*second!='\0';second++,first++)
{
*first==*second;
}
*first='\0';
return temp;
}
int main()
{
char a[2*N],b[N];
gets(a);
gets(b);
printf("%s\n",MyStrcat(a,b));
return 0;
}
10.4本章扩充内容
const类型的限定符: int a; const int *p=&a; int const *p=&a; *p是一个常量,而p不是。 int *const p=&a; p是一个常量,而*p不是,可以*p=10。 const int *const p=&a; p和*p都是常量。
字符处理函数:
- int isdigit(int c);是数字返回真,否则为假。
- int isalpha(int c);是字母返回真,否则为假。
- int isalnum(int c);是数字或字母返回真,否则为假。
- int islower(int c);是小写字母返回真,否则为假。
- int issupper(int c);是大写字母返回真,否则为假。
- int tolower(int c);将大写字母变为小写字母。返回字母。
- int toupper(int c);将小写字母变为大写字母。
- int isspace(int c);是空白字符,返回真。’\n’、’ ‘、’\f’、’\r’、’\t’、’\v’。
- int iscntrl(int c);是控制字符,返回真。
- int isprint(int c);是打印字符,返回真。
- int isgraph(int c);是除了空格之外的打印字符,返回真。
统计各种类型的字符的个数:
#include<stdio.h>
#define N 80
int main()
{
char str[N];
int i,letter=0,number=0,space=0,others=0;
gets(str);
for(i=0;str[i]!='\0';i++)
{
if(str[i]>='a'&&str[i]<='z'||str[i]>='A'&&str[i]<='Z')
letter++;
else if(str[i]>='0'&&str[i]<='9')
number++;
else if(str[i]==' ')
space++;
else
others++;
}
printf("letter=%d,number=%d,space=%d,others=%d\n",letter,number,space,others);
return 0;
}
将名和姓的第一个字母转换为大写字母:
#include<stdio.h>
#include<ctype.h>
#define N 20
int main()
{
char str[N];
int i=1;
gets(str);
str[0]=toupper(str[0]);
while(!isspace(str[i]))
{
i++;
}
while(isspace(str[i]))
{
i++;
}
str[i]=toupper(str[i]);
printf("%s\n",str);
return 0;
}
数值字符串向数值转换:
- double atof(const char *nptr);将字符串转换成双精度浮点数,返回这个双精度浮点数
- int atoi(const char *nptr);将字符串转换成整数,返回这个整数
- long atol(const char *nptr);将字符串转换成长整型数,返回这个长整型数
#include<stdio.h>
#include<stlib.h>//包含相应的头文件
int main()
{
char str[]=" 123.5";
int a;
double b;
long c;
a=atoi(str);
b=atof(str);
c=atol(str);
printf("a=%d,b=%f,c=%ld\n",a,b,c);
return 0;
}
|