每日三百行代码 第四天

函数指针:是指向函数的指针变量。

通常我们说的指针变量是指向一个整型、字符型或数组等变量,而函数指针是指向函数。

函数指针可以像一般函数一样,用于调用函数、传递参数。

函数指针变量的声明:

typedef int (*fun_ptr )(int,int);
//声明一个指向相同参数,返回值的函数指针类型
#include<stdio.h>

int max(int x,int y){
   
	return x>y?x:y;
}

int main(){
   
	int (*p)(int,int)=&max;//&可省略
	//*p是函数指针
	int a,b,c,d;
	
	printf("请输入三个数字:");
	scanf("%d %d %d",&a,&b,&c);
	d=p(p(a,b),c);
	printf("最大的数:%d",d);
	return 0; 
}

回调函数

函数指针作为某个函数的参数

函数指针变量可以作为某个函数的参数来使用,回调函数就是一个通过函数指针调用的函数。

#include<stdio.h>
#include<stdlib.h>

void populate_array(int *array, size_t arraySize,int(*getNextValue)(void) )
{
   
	for(size_t i=0;i<arraySize;i++){
   
		array[i]=getNextValue();
	}
}//回调函数

int getNextRandomValue(void){
   
	return rand();
} //获得随机值

int main(){
   
	int myarray[10];
	populate_array(myarray,10,getNextRandomValue);
	for(int i=0;i<10;i++){
   
		printf("%d ",myarray[i]);
	}
	printf("\n");
	return 0;
} 

C字符串

是使用null字符\0终止的一维字符数组。因此,一个以null结尾的字符串,包含了形成字符串的字符。

字符串的初始化

char str[10]="";

char str[10]={
   '\0'};

char str[10];str[0]='\0';

#include<string.h>

strcpy(s1,s2);
复制字符串s2到字符串s1。

char *strcpy(char *dest, const char *src)
参数
dest -- 指向用于存储复制内容的目标数组。
src -- 要复制的字符串。

#include <stdio.h>
#include <string.h>
 
int main()
{
   
   char src[40];
   char dest[100];
  
   memset(dest, '\0', sizeof(dest));//字符串dest为空
   strcpy(src, "www.eternity_G.com");
   strcpy(dest, src);
 
   printf("最终的目标字符串: %s\n", dest);
   
   return(0);
}

memset(str, c, n)
复制字符 c(一个无符号字符)到参数 str 所指向的字符串的前 n 个字符。

void *memset(void *str, int c, size_t n)
参数
str -- 指向要填充的内存块。
c -- 要被设置的值。该值以 int 形式传递,但是函数在填充内存块时是使用该值的无符号字符形式。
n -- 要被设置为该值的字符数。

#include <stdio.h>
#include <string.h>
 
int main ()
{
   
   char str[50];
 
   strcpy(str,"This is string.h library.");
   puts(str);
 
   memset(str,'%',8);
   puts(str);
   
   return(0);
}

memcpy(dest,src,n);
从 src 复制 n 个字符到 dest。

void *memcpy(void *str1, const void *str2, size_t n)
参数
str1 -- 指向用于存储复制内容的目标数组,类型强制转换为 void* 指针。
str2 -- 指向要复制的数据源,类型强制转换为 void* 指针。
n -- 要被复制的字节数。

#include <stdio.h>
#include<string.h>
 
int main()
 //将 s 中第 11 个字符开始的 6个连续字符复制到 d 中:
{
   
  char *s="http://www.eternity_G.com";
  char d[20];
  memcpy(d, s+11, 6);// 从第 11 个字符(r)开始复制,连续复制 6 个字符(runoob)
  // 或者 memcpy(d, s+11*sizeof(char), 6*sizeof(char));
  d[6]='\0';
  printf("%s", d);
  return 0;
}

strcat(s1,s2);
连接字符串s2到字符串s1的末尾。

char *strcat(char *dest, const char *src)
参数
dest -- 指向目标数组,该数组包含了一个 C 字符串,且足够容纳追加后的字符串。
src -- 指向要追加的字符串,该字符串不会覆盖目标字符串。

#include <stdio.h>
#include <string.h>
 
int main ()
{
   
   char src[50], dest[50];
 
   strcpy(src,  "This is source");
   strcpy(dest, "This is destination");
 
   strcat(dest, src);
 
   printf("最终的目标字符串: %s", dest);
   
   return(0);
}

strncat(dest,src,n);
把 src 所指向的字符串追加到 dest 所指向的字符串的结尾,直到 n 字符长度为止

char *strncat(char *dest, const char *src, size_t n)
参数
dest -- 指向目标数组,该数组包含了一个 C 字符串,且足够容纳追加后的字符串,包括额外的空字符。
src -- 要追加的字符串。
n -- 要追加的最大字符数。

#include <stdio.h>
#include <string.h>

int main ()
{
   
   char src[50], dest[50];

   strcpy(src,  "This is source");//strlen(src)=14 但是还有\0 ,一共15位
   strcpy(dest, "This is destination");

   strncat(dest, src, 15);

   printf("最终的目标字符串: |%s|", dest);
   
   return(0);
}

strlen(s1);
返回s1的长度。

size_t strlen(const char *str)
参数
str -- 要计算长度的字符串。

#include <stdio.h>
#include <string.h>

int main ()
{
   
   char str[50];
   int len;

   strcpy(str, "www.eternity_G.com");

   len = strlen(str);
   printf("|%s| 的长度是 |%d|\n", str, len);
   
   return(0);
}

strcmp(s1,s2);
如果s1和s2是相同的,则返回0;如果s1<s2则返回小于0;如果s1>s2则返回大于0。

int strcmp(const char *str1, const char *str2)
参数
str1 -- 要进行比较的第一个字符串。
str2 -- 要进行比较的第二个字符串。

#include <stdio.h>
#include <string.h>
 
int main ()
{
   
   char str1[15];
   char str2[15];
   int ret;
 
 
   strcpy(str1, "abcdef");
   strcpy(str2, "qwerty");
 
   ret = strcmp(str1, str2);
 
   if(ret < 0)
   {
   
      printf("str1 小于 str2");
   }
   else if(ret > 0) 
   {
   
      printf("str1 大于 str2");
   }
   else 
   {
   
      printf("str1 等于 str2");
   }
   
   return(0);
}


注意比较两个字符串时要主动使用strcmp()函数,
str1==str2,是对他们的地址进行判断,结果肯定不相等
在c语言中   sh=="End";   是错误的表达,但是c++允许使用
判断是否相同用strcmp(str1,str2)==0来判断

strchr(s1,ch);
返回一个指针,指向字符串s1中的字符ch的第一次出现的位置。

char *strchr(const char *str, int c)
参数
str -- 要被检索的 C 字符串。
c -- 在 str 中要搜索的字符。

#include <stdio.h>
#include <string.h>

int main ()
{
   
   const char str[] = "http://www.eternity_G.com";
   const char ch = '.';
   char *ret;

   ret = strchr(str, ch);

   printf("|%c| 之后的字符串是 - |%s|\n", ch, ret);
   
   return(0);
}

strstr(s1,s2);
返回一个指针,指向字符串s1中字符串s2第一次出现的位置。

char *strstr(const char *haystack, const char *needle)
参数
haystack -- 要被检索的 C 字符串。
needle -- 在 haystack 字符串内要搜索的小字符串。

#include <stdio.h>
#include <string.h>
 
 
int main()
{
   
   const char haystack[20] = "ETERNITY";
   const char needle[10] = "NITY";
   char *ret;
 
   ret = strstr(haystack, needle);
 
   printf("子字符串是: %s\n", ret);
   
   return(0);
}