C语言学习——指针精华(2)

简介: C语言学习——指针精华(2)



字符指针作函数参数


[用函数调用实现字符串的复制]


⑴用字符数组作参数

#include <stdio.h>
void copy_string(char  from[], char to[]);
int main()
{ 
  char a[] = "I am a teacher.";
  char b[] = "You are a student.";
  printf("string_a=%s\n string_b=%s\n", a, b);
  printf("copy string_a to string_b : \n");
    copy_string(a, b);   /* 数组名作参数是地址传递*/
  printf("\nstring_a = %s\nstring_b = %s\n",a,b);
  return 0;
}
void copy_string(char  from[], char to[])
{
  int i = 0;
  while (from[i] != '\0')
  {
    to[i] = from[i];  i++;
  }
  to[i] = '\0';
}


结果:



【字符指针变量作形参】

#include <stdio.h>
void FuncPArs(char *s)
 {
  printf("Result:%s\n", s);
}
int main()
{
  char rsa[] = "Welcome To C/C++.\n";
  FuncPArs(rsa);
  return 0;
}

结果:


对使用字符指针变量和字符数组的讨论


char *cp; 与 char str[20]; 的区别


str由若干元素组成,每个元素放一个字符;而cp中存放字符串首地址


赋值方式:


字符数组只能对元素赋值。 char str[20];


str=“I love China!”; ()


字符指针变量可以用: char *cp;


cp=“I love China!”; ()


赋初值:char *cp=“China!”; 等价 char *cp; cp=“China!”;


char str[14]={“China”};不等价char str[14]; str[ ]=“China” ()


【用下标法引用指针变量所指的字符串中的字符】


#include <stdio.h>
int main()
{
  char *a = "I love China!"; int i;
  printf("The sixth charcter is %c\n", a[5]);
  for (i = 0; a[i] != '\0'; i++)
    printf("%c", a[i]);
  printf("\n");
  return 0;
}


结果如下:




用指针变量指向的格式字符串代替printf中的格式字符串(可变格式输出函数)char *format; format="a=%d,b=%f\n"; printf(format,a,b);相对于:` printf("a=%d,b=%f\n"a,b);


可以用字符数组实现:


   char format[ ]="a=%d,b=%f\n";
   printf(format,a,b);



二、函数指针与指针函数


函数指针的实质(还是指针变量)


函数指针定义格式


类型名 (*函数名)(函数参数列表);


int (*pfun)(int, int);


函数指针的定义_赋值_调用


void FuncTest(void) //定义一个函数,以方便下面定义函数指针

{

printf(“FunPointer DemoTestFunc.\n”);

}


【案例如下】


void (*pFunc)(void);// 函数指针定义
pFunc = FuncTest;   // 函数指针赋值
(*pFunc)();         // 函数指针调用;用函数指针来调用以调用该函数,注意*pFunc要用()括起来
pFunc();            // 调用的第二种写法,效果和上面一样


函数指针作用:函数指针有两个用途:调用函数和做函数的参数。


注意:函数指针声明为指针,它与变量指针不同之处是,它不是指向变量,而是指向函数。


(1)函数指针的实质还是指针,还是指针变量。本身占4字节;


(2)函数指针、数组指针、普通指针之间并没有本质区别,区别在于指针指向的内容是什么;


(3)函数的实质是一段代码,这一段代码在内存中是连续分布的(一个函数的大括号括起来的所有语句将来编译出来生成的可执行程序是连续的),所以对于函数来说很关键的就是函数中的第一句代码的地址,这个地址就是所谓的函数地址,在C语言中用函数名这个符号来表示;


(4)结合函数的实质,函数指针其实就是一个普通变量,这个普通变量的类型是函数指针变量类型,它的值就是某个函数的地址(也就是它的函数名这个符号在编译器中对应的地址值)。


指针函数实质是一个函数


指针函数实质是一个函数。函数都有返回类型(如果不返回值,则为无值型),只不过指针函数返回类型是某一类型的指针。


*指针函数定义格式:类型名 函数名(函数参数列表);

int *pfun(int, int);


指针函数的声明_定义_调用


int * sum(int x);       //指针函数的声明;返回类型位一个指针变量 可以通过*p来获取值
int * sum(int x)      //指针函数的定义
{       
  int static sum = 0;     //static 修身的变量在数据段;不会被函数栈回收
  int *p;
  int i;
  for (i = 1; i <= x; i++)
  {
    sum += i;  // sum=sum+i;
    return p;       //返回类型是某一类型的指针
  }
}
int *p1;
p1 = fun(a);            //指针函数的调用

指针函数作用:可以使代码更简洁并在一定程度节约内存;如当你需要返回一个数组中的元素时,你就只需返回首元素的地址给调用函数,调用函数即可操作该数组(让函数返回多个值)。


或者是malloc函数动态分配内存,返回该内存的地址给另外一个函数,另一个函数才好操作该内存。当然还有其他的作用,请读者自行在实践中体会。


注意:指针函数本质是一个函数,使用方法与普通函数没什么两样。既然是函数,就与变量不一样。变量需要定义、赋值、调用(比如函数指针);而函数需要声明、定义、调用。


【工程案例】


输入第几周的第几天获取这天是这个月的几号

#include<stdio.h>
int * GetDate(int wk, int dy);  // 声明指针函数
int main()
{ 
        int wk, dy; 
        do 
        {
                 printf("Enter week(1 - 5)day(1 - 7)\n");
     scanf_s("%d%d", &wk, &dy);
        } while (wk < 1 || wk>5 || dy < 1 || dy>7);
        printf("%d\n", *GetDate(wk, dy)); 
  // 调用,GetDate()函数返回的是一个指针(地址)
  // * GetDate()则是取其内容
        return 0;
}
int * GetDate(int wk, int dy)
{
         static int calendar[5][7] = { 
  { 1, 2, 3, 4, 5, 6, 7 },
  { 8, 9, 10, 11, 12, 13, 14 },
  { 15, 16, 17, 18, 19, 20, 21 },
  { 22, 23, 24, 25, 26, 27, 28 },
  { 29, 30, 31, -1 } };
        //返回一个地址
        return &calendar[wk - 1][dy - 1]; 
}

结果如下:





【工程案例】


#include <stdio.h>
int main()
{
  int x = 89;
  int y = 92;
  int *p[2];  // 指针数组  元素里面全部都是指针
  printf("x的地址:%p , y的地址:%p\n",&x,&y);
  p[0] = &x;  p[1] = &y;
  printf("p[0]的值:%p , p[1]的值:%p\n", p[0],p[1]);
  printf("\n输出指针数组所指向地址里面的值:\np[0]的值:%d , p[1]的值:%d\n", *p[0], *p[1]);
  return 0;
}




【工程案例】

#include <stdio.h>
// 函数申明
void mymemset(void *data, int num, int byteSize);
int main()
{ 
  int nums[20];
  mymemset(nums, 0, sizeof(nums));
  int i, len = sizeof(nums) / sizeof(int);
  for (i = 0; i<len; i++) 
  {
    printf("%d ", nums[i]);
  }
  printf("\n");
  return 0;
}
void mymemset(void *data, int num, int byteSize)
{ 
// char就是一个字节,而计算机中是以字节为单位存储的
  char *ptr = (char*)data;
  int i;
  for (i = 0; i<byteSize; i++) 
  {
    *ptr = num;
    ptr++;
  }
}

结果如下:




一、函数参数传递方式之一(值传递)


#include <stdio.h>
void ExceFun(int x, int y)
{
  int temp;
  temp = x;
  x = y;
  y = temp;
  printf("x=%d, y=%d\n", x, y);
}
int main()
{
  int a = 89, b = 65;
  ExceFun(a, b);
  printf("a=%d, b=%d\n", a, b);
  return 0;
}


二、函数参数传递方式之二(地址传递)


#include <stdio.h> 
void ExceFun(int *px,int *py)
{
  int temp;
  temp=*px;
  *px=*py;
  *py=temp;
  printf("*px=%d, *py=%d\n", *px,*py);
}
int main( )
{
  int a=89, b=65;
  ExceFun(&a,&b);
  printf("a=%d, b=%d\n",a,b);
  return 0;
}



相关文章
|
17天前
|
安全 C语言
【C语言】如何规避野指针
【C语言】如何规避野指针
20 0
|
18天前
|
C语言
C语言:数组和指针笔试题解析(包括一些容易混淆的指针题目)
C语言:数组和指针笔试题解析(包括一些容易混淆的指针题目)
|
7天前
|
C语言
c语言指针总结
c语言指针总结
13 1
|
4天前
|
人工智能 测试技术 C语言
C语言学习
C语言学习
11 1
|
13天前
|
存储 程序员 C语言
【C 言专栏】C 语言指针的深度解析
【4月更文挑战第30天】C 语言中的指针是程序设计的关键,它如同一把钥匙,提供直接内存操作的途径。指针是存储其他变量地址的变量,通过声明如`int *ptr`来使用。它们在动态内存分配、函数参数传递及数组操作中发挥重要作用。然而,误用指针可能导致错误,如空指针引用和内存泄漏。理解指针的运算、与数组和函数的关系,以及在结构体中的应用,是成为熟练 C 语言程序员的必经之路。虽然挑战重重,但掌握指针将增强编程效率和灵活性。不断实践和学习,我们将驾驭指针,探索更广阔的编程世界。
|
14天前
|
算法 搜索推荐 程序员
C语言中的函数指针和回调函数
C语言中的函数指针和回调函数
10 2
|
17天前
|
存储 编译器 C语言
【C语言】初步解决指针疑惑
【C语言】初步解决指针疑惑
7 0
|
18天前
|
存储 C语言
指针深入解析(C语言基础)带你走进指针,了解指针
指针深入解析(C语言基础)带你走进指针,了解指针
|
18天前
|
C语言 C++
C语言:指针运算笔试题解析(包括令人费解的指针题目)
C语言:指针运算笔试题解析(包括令人费解的指针题目)
|
2月前
|
C语言
C语言---指针进阶
C语言---指针进阶
20 0