解析C/C++指针、函数、结构体、共用体

 更新时间:2022年1月23日 16:02  点击:255 作者:梦中的拉布拉多

指针

变量与地址

变量给谁用的?
变量是对某一块空间的抽象命名。
变量名就是你抽象出来的某块空间的别名。
指针就是地址。指向某个地址。

指针与指针变量

指针是指向某块地址。指针(地址)是常量。
指针变量是可以发生变化的。

#include <stdio.h>

int main()
{
    int i = 1;
    int *p = &i;
    
    printf("i = %d  \n", i);
    printf("&i = %p \n", &i);
    printf(" p = %p \n", p);
    printf("&p = %p \n", &p);
    printf("*p = %d \n", *p);
    // 为什么不用char* p = &i;
    //TYPE  NAME = VALUE
    //int*  p    = &i;
    //int   i    = 1;
}

直接访问间接访问

占内存空间

都是8字节,linux 64 位中。

空指针 野指针 空类型

int * i= NULL;

指针运算

两个指针同时指向一个数组。++ 、--、比较、关系、&、*

指针与一维数组

数组名和 指针的区别?
a是数组名字是一个表示地址的常量。
指针是一个变量。
a++;
p++;

#include <stdio.h>

int main()
{
    int a[3] = {1,2,3};
    int *p = a;
    int i;
    for(i = 0;i < sizeof(a)/sizeof(*a); i++) {
        printf("%d %d %d %d \n",a[i],*(a+i),p[i],*(p+i)); // a[i]
        printf("%p %p %p %p \n",a+i, &a[i],p+i, p+i); // &a[i]
    }
    printf("\n");
}

这里代码体现什么是指针常量什么是指针变量?

#include <stdio.h>

int main()
{
    int a[3];
    int i;
    int *p = a;
    for(i = 0;i < sizeof(a)/sizeof(*a); i++) {
        printf("%p -> %d\n",&a[i],a[i]);
    }
    for(i = 0;i <sizeof(a)/sizeof(*a); i++) {
        scanf("%d",p++);
    //p = a;
    for(i = 0;i < sizeof(a)/sizeof(*a); i++,p++) {
        printf("%p -> %d\n",p,*p);
    printf("\n");
}

指针与二维数组

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

int main()
{
    int a[2][3] = {1,2,3,4,5,9};
    int i,j;
    int *p;
//(W)    p = a; 
    //wall等号右边a是在行间跳转的指针
    // 等号左边是列间跳转的指针
    p = *(a+0);
    //p = &a[0][0];//*(a+0),*a;
    printf("%p->%p \n", a, a + 1);
    // printf("%p -> %d \n\n",p,*p);
    
   
    // for(i = 0; i < 6; i++,p++) {
    //     printf("%d ",*p);
    // }
    // printf("\n");
    for(i = 0;i < 2; i++) {
        for(j = 0; j < 3; j++) {
            printf("%p->%d\n",&a[i][j],a[i][j]);
            printf("%p->%d\n",*(a+i)+j,*(*(a+i)+j));
            //printf("%p->%d\n",a[i]+j,*(*(a+i)+j));
            //printf("%d ",a[i][j]);
        }
        printf("\n");
    }
    exit(0);
}

指针与字符数组

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

// 字符指针和字符数组之间的使用
// 
// 练习 定义数组后定义指针 后面操作都用指针实现
int main()
{
#if 0
    char* str = "hello"; // "hello" 串常量
    printf("%d %d \n",sizeof(str),strlen(str));// 8 5
    //strcpy(str,"world"); //err 为什么不可以?区分字符指针和字符数组的区别  :企图用"world" 覆盖串常量 
    str = "world";
    puts(str);
#endif 
    char str[] = "hello";
    printf("%d %d \n",sizeof(str),strlen(str));// 6 5
// (F) str = "hhhh"; // 数组名是一个地址常量怎么可能放到等号左边???
    strcpy(str,"jjjj");
    char str[] = "hello  world";
    char *p = str + 7;
    puts(p);
    exit(0);
}

const与指针

#include <stdio.h>
#include <stdlib.h>
/*
    常见const 
    const int a;
    int const a;

    const int *p; // 常量指针 
    int const *p;
    int *const p; // 指针常量
    const int *const p;
    define 不检查语法
*/
int main()
{
    #if 0
        // cosnt修饰常规变量的使用特点
        // 这个警告已经构成error
        const float pi = 1.14159;
        // pi = 9999.2;
        float *p = &pi; // initialization discards ‘const' qualifier from pointer target type [enabled by default]
        *p = 1223.333333; 
        // 修改方法 const float *p = &pi; 
        printf("%f\n",pi); // 1223.333333
        printf("%f\n",*p);
    #endif
    // 常量指针:指针的指向可以发生变化但是指针所指向的目标值是不能变化的
    // const  *p
    // 值不能变
    // 指向可以发生变化
    
    int i = 1;
    const int *p1 = &i;
    int j = 88;
//T    i= 10;   
//F    *p1 = 99;
//T    p1 = &j;
    printf("%d\n",i);
    printf("%d\n",*p1);
    // 指针常量:指针的指向不能发生变化,指针所指向的目标变量的值可以发生变化。
    int j= 100;
    int * const p1 = &i;
//T    *p1 = 10;
//F     p1 = &j;
    //const 左右都有 指向和值都不能变
    int num = 10;
    const int* const p3 = &num;
    // *p3 = 99;
    // p3 = &i;
    exit(0);
}

指针数组和数组指针的区别

数组指针

#include <stdio.h>
#include <stdlib.h>
/*
    数组指针: [存储类型] 数据类型 (* 指针名) [下标] = 值;
    int (*p)[3]; -> type name; -> int[3] *p;
*/
int main()
{
    // 数组指针
    int a[2][3] = {1,2,3,4,5,9};
    int i,j;
    int *p = *a;
    int (*q)[3] = a;
    //printf("%d \n", *a); // a[0][0]的地址
    //printf("%d \n", **a); //1
    #if 0
    // printf("%d \n",*p);//q
    //int *p = *a;
    //printf("%d \n",*p); //q
    // int (*q)[3] = a+1;
    // printf("%d \n",**q); // 4
    printf("\n");
    for(i = 0;i < 2; i++) {
        for(j = 0; j < 3; j++) {
            // printf("%p->%d\n",*(a+i)+j,*(*(a+i)+j));
            printf("%p->%d\n",*(q+i)+j,*(*(q+i)+j));
        }
        printf("\n");
    }
    #endif 
}

指针数组:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
    int *arr[3]; -> TYPE NAME; -> int *[3] arr;

*/
int main()
{
    char *name[5] ={"english","math","cpp","teacher","computer"};
    int i,j;
    for(i = 0; i < 5; i++) {
        puts(name[i]);
    }
    
    for(i = 0; i < 5 ;i++) {
        int k = i;
        for(j = i+1;j < 5; j++) {
            if(strcmp(name[k],name[j]) > 0) {
                k = j;
            }
        }
        if(k != i) {
            char *tmp = name[i];
            name[i] = name[k];
            name[k] = tmp;
        
    printf("排序后:\n");
    exit(0);
}

指针和函数

函数:

echo $? // 显示上个命令的返回值

#include <iostream>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */

/*
	定义: 
	int a[N] = {1,2,3,4,5,6};
	int *p = a; 
	
->    a     *a    a[0]    &a[3]   p[i]   p     *p   p+1
->	  int*	int   int 	  int *	  int    int*  int  int*
  
*/
//void func1(int *a,int n)
void func1(int* a,int n,int *b)
{
	cout << "== b =" << *b<< endl; // 1
	for(int i = 0;i < n; i++)
	{
		printf("%d ",*(a+i));
	}
	printf("\n");
	return ;
}
int main(int argc, char** argv) {
	int arr[3] = {1,2,3};
	func1(arr,3,&arr[1]);//&(*(ar+1))
	return 0;

用指针与一维数组的使用:

void func2(int *p,int n)
{
	int m = n / 2;
	for(int i = 0;m--;i ++)
	{
		int j = n - i -1;
		int tmp = *(p+i);
		*(p+i) = *(p+j);
		*(p+j) = tmp;
	}
}
int main(int argc, char** argv) {
	int arr[] = {1,2,3,6,4,2,38,4,2,23};
	
	//func1(arr,3,&arr[1]);//&(*(ar+1))
	func2(arr,10);
	for(int i = 0;i < 10;i ++)
		cout << arr[i] << ' ' ;
	cout <<endl;
	return 0;

函数与二维数组:

#include <iostream>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */

/*
	int a[M][N] = {......};
	int *p = a;
	int (*q)[N] = a;
	
->    a[i][j]    *(a+i)       a[i]+j    p[i]        *p
	  int        int *        int *     int         int
	  
->    q[i][j]    *q           q             p+3         q+2
	   int       int*         int(*)[N]     int *        int (*)[N]
*/
void func(int *p,int n)
{
	for(int i = 0;i < n; i++)
	{
		cout << *p << ' ';
		p++;
	}
}
void print_arr(int (*p)[3])
	for(int i = 0;i < 3;i++)
		for(int j = 0;j < 3;j++)
		{
			cout << *(*(p+i)+j) << ' ';
		}
		cout<< endl;
int main(int argc, char** argv) {
	int arr[3][3] = {1,2,3,6,4,2,38,4,2};
	func(arr[0],9); // *arr &arr[0][0]  arr[0]
	//  这里func(arr,9)  形参是int *p 就报错  p是一个列指针,二维数组不一样 
	print_arr(arr);
	return 0;

案例使用二维数组传参

float average_score(int *a,int n)
{
	float sum = 0.0;
	for(int i = 0;i < n; i++)
	{
		sum += *(a+i);
	}
	
	return sum/n;
}
void find_num(int(*p)[3],int num)
{
	for(int i = 0;i < 3 ;i++)
		printf("%d ",*(*(p+num) + i));
	cout << endl;
	return ;
}
int main(int argc, char** argv) {
	int arr[3][3] = {1,2,3,6,4,2,38,4,2};
	
	float ave = 0.0;
	ave = average_score(*arr,9);
	printf("%f \n",ave);
	
	find_num(arr,0);
	
	
	return 0;
}

函数与指针关系的详细剖析

指针函数

返回值 * 函数名(参数)

#if 0
void find_num(int(*p)[3],int num)
{
	for(int i = 0;i < 3 ;i++)
		printf("%d ",*(*(p+num) + i));
	cout << endl;
	return ;
}
#else 
int * find_num(int(*p)[3],int num)
	return 	*(p+num);
#endif
int main(int argc, char** argv) {
	int arr[3][3] = {1,2,3,6,4,2,38,4,2};
	
	float ave = 0.0;
	ave = average_score(*arr,9);
	printf("%f \n",ave);
	int * res;
	res = find_num(arr,0);
	if(res != NULL)
	{
		for(int i = 0;i < 3;i++)
			printf("%d ",res[i]);
		cout <<endl;
	}
	else 
		printf("can not find\n");
	return 0;

函数指针

#include <iostream>
using namespace std;

int add(int a,int b)
{
	return a+b;
} 
int sub(int a,int b)
{
	return a-b;
}
int main(int argc, char** argv) 
{
	int a = 2, b = 3;
	int (*p)(int,int);
	int (*q)(int,int);
	
	int ret;
	p = add;
	q = sub;
		
	printf("%d \n",p(a,b));
	printf("%d \n",q(a,b));
	
	return 0;
}

回调函数

函数指针数组

类型 (*数组名[下标])(形参);

#include <iostream>
using namespace std;

int add(int a,int b)
{
	return a+b;
} 
int sub(int a,int b)
{
	return a-b;
}
int main(int argc, char** argv) 
{
	int a = 2, b = 3;
	int (*funcp[2])(int,int);
	
	int ret;
	funcp[0] = add;
	funcp[1] = sub;
		
	for(int i = 0;i < 2; i++)
	{
		ret = funcp[i](a,b);
		printf("%d \n",ret);
	}
		
	return 0;
}

指向指针函数的函数指针数组
数组存放指针,指针指向函数,函数返回值是指针类型。

结构体

  • 产生的意义
  • 类型描述
  • 嵌套定义
  • 定义变量、初始化及引用
  • 占用内存大小

定义和使用:

#include <iostream>
using namespace std;

#define NAMESIZE 100
struct simp_st 
{
	int i,j;
	float f;
	char ch;	
};
struct birthday_st
	int year,month,day;
struct student_st
	int id;
	char name[NAMESIZE];
	struct birthday_st birthday;
	int math;
	int chinese;
int main(int argc, char** argv) 
	
	struct student_st stu = {10011,"Alan",{3011,22,11},22,54};
	struct student_st *p = &stu;
	printf("%d %s %d-%d-%d %d %d \n",stu.id,stu.name,stu.birthday.year,stu.birthday.month,stu.birthday.day,stu.math,stu.chinese);	
	printf("%d %s %d-%d-%d %d %d \n",p->id,p->name,p->birthday.year,p->birthday.month,p->birthday.day,p->math,p->chinese);
	struct student_st stu[2] = {{10011,"Alan",{3011,22,11},22,54},{10012,"salay",{2021,2,12},88,66}};
	struct student_st *p = &stu[0];// &stu[0]  stu
	for(int i = 0;i < 2;i++,p++)
	{
		printf("%d %s %d-%d-%d %d %d \n",p->id,p->name,p->birthday.year,p->birthday.month,p->birthday.day,p->math,p->chinese);
	}
	return 0;
}

内存对齐问题
addr/sizeof()

构造类型-结构体内存问题及函数传参

为后面linux高级铺垫。

  • 可以实现一个学生管理系统。
  • 产生及意义
  • 类型描述
  • 嵌套定义
  • 定义变量
  • 占用内存大小
  • 函数传参
  • 位域

union 名{
	数据类型 成员名1;
	数据类型 成员名2;
};

枚举类型

enum 名{
	成员1;
	成员2;
	成员3;
}

到此这篇关于C/C++指针、函数、结构体、共用体的文章就介绍到这了,更多相关C++指针 函数 结构体 共用体内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!

原文出处:https://www.cnblogs.com/yaozhenhua/p/15831430.html

[!--infotagslink--]

相关文章

  • php正确禁用eval函数与误区介绍

    eval函数在php中是一个函数并不是系统组件函数,我们在php.ini中的disable_functions是无法禁止它的,因这他不是一个php_function哦。 eval()针对php安全来说具有很...2016-11-25
  • php中eval()函数操作数组的方法

    在php中eval是一个函数并且不能直接禁用了,但eval函数又相当的危险了经常会出现一些问题了,今天我们就一起来看看eval函数对数组的操作 例子, <?php $data="array...2016-11-25
  • C++ STL标准库std::vector的使用详解

    vector是表示可以改变大小的数组的序列容器,本文主要介绍了C++STL标准库std::vector的使用详解,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2022-03-06
  • Python astype(np.float)函数使用方法解析

    这篇文章主要介绍了Python astype(np.float)函数使用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-06-08
  • C++中取余运算的实现

    这篇文章主要介绍了C++中取余运算的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-23
  • Python中的imread()函数用法说明

    这篇文章主要介绍了Python中的imread()函数用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-16
  • 详解C++ string常用截取字符串方法

    这篇文章主要介绍了C++ string常用截取字符串方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-04-25
  • C++调用C#的DLL程序实现方法

    本文通过例子,讲述了C++调用C#的DLL程序的方法,作出了以下总结,下面就让我们一起来学习吧。...2020-06-25
  • C# 中如何取绝对值函数

    本文主要介绍了C# 中取绝对值的函数。具有很好的参考价值。下面跟着小编一起来看下吧...2020-06-25
  • C#学习笔记- 随机函数Random()的用法详解

    下面小编就为大家带来一篇C#学习笔记- 随机函数Random()的用法详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
  • C++中四种加密算法之AES源代码

    本篇文章主要介绍了C++中四种加密算法之AES源代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。...2020-04-25
  • C++ 整数拆分方法详解

    整数拆分,指把一个整数分解成若干个整数的和。本文重点给大家介绍C++ 整数拆分方法详解,非常不错,感兴趣的朋友一起学习吧...2020-04-25
  • 金额阿拉伯数字转换为中文的自定义函数

    CREATE FUNCTION ChangeBigSmall (@ChangeMoney money) RETURNS VarChar(100) AS BEGIN Declare @String1 char(20) Declare @String2 char...2016-11-25
  • Android开发中findViewById()函数用法与简化

    findViewById方法在android开发中是获取页面控件的值了,有没有发现我们一个页面控件多了会反复研究写findViewById呢,下面我们一起来看它的简化方法。 Android中Fin...2016-09-20
  • C++中 Sort函数详细解析

    这篇文章主要介绍了C++中Sort函数详细解析,sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变...2022-08-18
  • PHP用strstr()函数阻止垃圾评论(通过判断a标记)

    strstr() 函数搜索一个字符串在另一个字符串中的第一次出现。该函数返回字符串的其余部分(从匹配点)。如果未找到所搜索的字符串,则返回 false。语法:strstr(string,search)参数string,必需。规定被搜索的字符串。 参数sea...2013-10-04
  • C++万能库头文件在vs中的安装步骤(图文)

    这篇文章主要介绍了C++万能库头文件在vs中的安装步骤(图文),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-23
  • PHP函数分享之curl方式取得数据、模拟登陆、POST数据

    废话不多说直接上代码复制代码 代码如下:/********************** curl 系列 ***********************///直接通过curl方式取得数据(包含POST、HEADER等)/* * $url: 如果非数组,则为http;如是数组,则为https * $header:...2014-06-07
  • php中的foreach函数的2种用法

    Foreach 函数(PHP4/PHP5)foreach 语法结构提供了遍历数组的简单方式。foreach 仅能够应用于数组和对象,如果尝试应用于其他数据类型的变量,或者未初始化的变量将发出错误信息。...2013-09-28
  • C语言中free函数的使用详解

    free函数是释放之前某一次malloc函数申请的空间,而且只是释放空间,并不改变指针的值。下面我们就来详细探讨下...2020-04-25