C语言程序与设计——指针地址与main函数

指针变量

在C语言中,最重要的就是对于指针和地址的理解,因为C语言是更接近底层的编程语言,所以它可以允许开发者对内存操作,这也是区别于其它编程语言的一个重要特性。
如何对内存进行操作呢。我们知道在编程过程中,在任何语言中,我们在定定义一个变量的过程中,实际上就是向操作系统申请了一块内存,但由于其它编程语言不支持我们对于内存进行操作,所以我们只知道申请了一块内存,但不知道该位置在哪。由于C语言支持我们对于内存的操作,所以我们可以通过在变量前加一个取地址符&,得到该内存的地址,数组的话无需加取地址符。

#include<stdio.h>
int main(){int a[5];int b;printf("&b = %p, sizeof(&b) = %lu\n", &b, sizeof(&b));printf("a[0] = %p\n", a);printf("a[1] = %p\n", a + 1);printf("a[2] = %p\n", a + 2);printf("a[3] = %p\n", a + 3);printf("a[4] = %p\n", a + 4);
}运行结果
>>&b = 0x7fffe87408ec, sizeof(&b) = 8
a[0] = 0x7fffe87408f0
a[1] = 0x7fffe87408f4
a[2] = 0x7fffe87408f8
a[3] = 0x7fffe87408fc
a[4] = 0x7fffe8740900

可以看到整型数组的地址间隔刚好为4,也就是说明整型变量大小是四个字节。而且指针的大小是8个字节。

指针的大小
在我所演示的运行环境是在64位操作系统下运行的,64bit刚好是8字节,也就是说如果在32位操作系统下运行该程序的话sizeof(&b)会是4字节

  • 指针的大小是与系统环境相关的
  • 以int为例,int占用四个字节,在取地址时从相关地址的首地址开始
  • 在一个32bit操作系统中,地址最多为4GB,所以假设插入一个8GB的内存条则会有另外4GB无法使用

变量的地址

指针变量也是变量,也就说,指针变量同样也有地址。由此,我们就可以对数组的各个地址取地址符,这样就构成了二维数组。

#include<stdio.h>int main(){int a;int *p = &a;int arr[3][3];printf(" &a = %p\n p = %p\n &p = %p\n", &a, p, &p);printf(" arr[0][0] = %p, sizeof(arr[0][0]) = %lu\n", arr, sizeof(&arr));printf(" arr[1][0] = %p, sizeof(arr[1][0]) = %lu\n", arr + 3, sizeof(arr + 3));printf(" arr[1][0] = %p, sizeof(arr[2][0]) = %lu\n", &arr + 1, sizeof(arr + 3 + 3 + 1));}运行结果>> &a = 0x7fff350f5c54p = 0x7fff350f5c54&p = 0x7fff350f5c58arr[0][0] = 0x7fff350f5c60, sizeof(arr[0][0]) = 8arr[1][0] = 0x7fff350f5c84, sizeof(arr[1][0]) = 8arr[1][0] = 0x7fff350f5c84, sizeof(arr[2][0]) = 8

理解了双重指针以及二维数组之后,那么就可以尝试高维数组的实现形式。

所以在scanf(“%d”, &n);这行代码中,我们传入的是地址,因为我们要改变的是n所代表的这块内存上的值,所以需要找到内存的所在地址然后存入数据。

函数指针

在之前函数的章节,已经涉及到了函数指针,但只是把函数作为传入参数的形式,下面我们将演示函数指针的声明形式

#include<stdio.h>int add(int a, int b){return a + b;
}
int main(){int (*func)(int, int);func = add;printf("%d", func(1,1));
}
#include<stdio.h>int add(int a, int b){return a + b;
}
int main(){typedef int (*func)(int, int);func f = add;printf("%d", f(1, 1));
}

可以看到我们使用了两种方式定义了函数指针。可以看到以第一种是直接声明的了一个函数指针,而后将指针指向了add()函数,那么第二种的话用到了一个关键字typedef,而后func变成了一个类型的样子,随后定义了f指针指向了add()函数。二者的定义形式的区别就是

声明一个函数指针变量: int (*add)(int, int);
定义一个函数指针类型: typedef int (*add)(int, int);

Main函数

我们知道在C语言中,一个程序运行必须要有main函数,但是我们在使用main函数中,基本都是无参数的形式,但实际上的main函数有三种形式,如下。下面就简单了解一下main函数的其他两种形式

int main();
int main(int argc, char *argv[]);
int main(int argc, char *argv[], char **env);

参数解释:
argc: 命令行参数个数(例如 ls -al al就是参数)
*argv[ ]:命令行内容(注意这是一个二位数组)
**env:环境变量

#include<stdio.h>void output(int argc, char *argv[], char **env){printf("argc = %d\n", argc);for(int i = 0; i < argc; i++){printf("argv[%d] = %s\n ", i, argv[i]);
}int main(int argc, char *argv[], char **env){output (argc, argv,env);return 0;
}

在这里插入图片描述
可以看到示例 ./a.out -a -l -s。其中作为参数全部传入了程序中,值得一提的是./a.out也作为了一个参数传入了,也就是说程序在运行时至少会有一个命令行参数。我们也不难发现空格是参数的分隔符,但是我们可以通过加\转义字符,使其可以把空格传入。

#include<stdio.h>void output(int argc, char *argv[], char **env){printf("argc = %d\n", argc);for(int i = 0; i < argc; i++){printf("argv[%d] = %s\n ", i, argv[i]);}for(int i = 0; env[i]; i++){printf("env[%d] = %s\n", i, env[i]);}
}int main(int argc, char *argv[], char **env){output (argc, argv,env);return 0;
}

在这里插入图片描述
可以看到env参数包含了很多我们的环境变量,包括用户路径语言等等。这些都是操作系统为我们提供的接口允许我们可以做在操作系统中做一些底层的操作。

main()返回值

在我们初学C语言时就接触了main()函数,我们可以不用返回值,但是又会经常见到return 0。那么main的返回值是返回给谁,又有什么作用呢?从函数上来讲,当然是谁调用就返回给谁,该函数是操作系统调用的,所以就是返回给操作系统的。
我们可以通过echo $?的命令查看上一次运行是不是成功运行,如果返回值为0,代表执行失败。如果是1则是成功执行,所以说可能对于我们来讲程序的功能是成功执行的,但是对于操作系统来讲我们的程序没有执行成功。所以我们应尽量在主函数中加入返回值。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/798599.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

突破编程_前端_SVG(基础元素介绍)

1 rect 矩形 在 SVG 中&#xff0c;<rect> 元素用于创建圆形。 &#xff08;1&#xff09;基本语法 <rectx"x坐标"y"y坐标"width"宽度"height"高度"rx"可选&#xff1a;圆角x半径"ry"可选&#xff1a;圆角…

用可视化案例讲Rust编程5.用泛型和特性实现自适配绘制和颜色设置

上一节我们讲了用泛型实现返回结果&#xff0c;这一节我们来讲讲在函数签名里面使用泛型来对输入参数进行自适配。 先看UML设计图&#xff1a; 好吧&#xff0c;看起来有点复杂&#xff0c;我们一个个来解释。 首先定义的是一个生成绘图元素需要的参数结构,并且定义个特性&am…

Spring Security——09,解决跨域

解决跨域 一、SpringBoot配置二、配置SpringSecurity三、修改端口四、修改vue项目4.1 拿到token4.2 前端存储token4.3 前端请求头携带token 五、测试5.1 认证测试5.2 授权测试 一键三连有没有捏~~ 浏览器出于安全的考虑&#xff0c;使用 XMLHttpRequest对象发起 HTTP请求时必须…

day 74 js

js脚本 JS的作用&#xff1a; 描述显示的内容&#xff08;HTML&#xff09;修饰 HTML 标签&#xff08;CSS&#xff09;设置 HTML 标签的动作&#xff08;JS&#xff09;JS特点&#xff1a;基于对象的编程语言&#xff0c;通过浏览器解释执行作用&#xff1a;表单验证、改变标签…

使用阿里云服务器可以做什么?太多了

阿里云服务器可以干嘛&#xff1f;能干啥你还不知道么&#xff01;简单来讲可用来搭建网站、个人博客、企业官网、论坛、电子商务、AI、LLM大语言模型、测试环境等&#xff0c;阿里云百科aliyunbaike.com整理阿里云服务器的用途&#xff1a; 阿里云服务器活动 aliyunbaike.com…

AcWing 4. 多重背包问题 I

解题思路 相关思路 import java.util.Scanner; public class Main {public static void main(String[] args){Scanner scanner new Scanner(System.in);int N scanner.nextInt();int V scanner.nextInt();int v[] new int[N1];int w[] new int[N1];int s[] new int[N1];…

揭秘AI幻觉:GPT-4V存在视觉编码漏洞,清华联合NUS提出LLaVA-UHD

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 新建了免费的人工智能中文站https://ai.weoknow.com 新建了收费的人工智能中文站https://ai.hzytsoft.cn/ 更多资源欢迎关注 GPT-4V 的推出引爆了多模态大模型的研究。GPT-4V 在包括多模态问答、推理、交互在内的多个领…

二. CUDA编程入门-双线性插值计算

目录 前言0. 简述1. 执行一下我们的第十个CUDA程序2. Bilinear interpolation3. 代码分析总结参考 前言 自动驾驶之心推出的 《CUDA与TensorRT部署实战课程》&#xff0c;链接。记录下个人学习笔记&#xff0c;仅供自己参考 Note&#xff1a;关于 CUDA 加速双线程插值的内容博主…

爬虫逆向非对称加密和对称加密案例

注意&#xff01;&#xff01;&#xff01;&#xff01;某XX网站逆向实例仅作为学习案例&#xff0c;禁止其他个人以及团体做谋利用途&#xff01;&#xff01;&#xff01; 案例--aHR0cHM6Ly9jcmVkaXQuaGxqLmdvdi5jbi94eWdzL3l6d2ZzeHF5bWQv 第一步&#xff1a;分析页面、请求…

CTF 之Zhuanxv

拿到题目进行目录遍历发现有一个/list文件 打开/list文件&#xff0c;发现是一个登录界面 尝试过爆破&#xff0c;毫无疑问不可能成功。 刷新页面&#xff0c;抓包&#xff0c;然后放一个包&#xff0c;发现又发了一个请求。 GET /loadimage?fileNameweb_login_bg.jpg HTTP/…

1995-2021年各省分品种能源产量和消费量数据

1995-2021年各省分品种能源产量和消费量数据 1、时间&#xff1a;1995-2021年 2、来源&#xff1a;能源统计年鉴、各省年鉴 3、指标&#xff1a;能源消费总量、煤炭消费量、焦炭消费量、原油消费量、汽油消费量、煤油消费量、柴油消费量、燃料油消费量、天然气消费量、电力消…

不开玩笑,你应该像「搬砖」一样写代码!斯坦福大学研究如是说

由于程序员不可避免要进行很多重复性的工作&#xff0c;并且工作强度很高&#xff0c;导致有一种自嘲的说法出现&#xff1a;程序员们自称自己每天都在搬砖&#xff08;实际上很多职场人都这么自嘲&#xff09;。我相信当我们说工作像「搬砖」的时候&#xff0c;只是在表达一种…

非关系型数据库——三万字Redis数据库详解

目录 前言 一、Redis概述 1.主要特点 2.Redis优缺点 3.Redis为什么这么快 4.Redis那么快&#xff0c;为什么不用它做主数据库&#xff0c;只用它做缓存 5.线程模型 5.1单线程架构 5.2多线程IO处理&#xff08;Redis 6及以上&#xff09; 5.3线程模型的优化 6.作用 …

回归预测 | Matlab实现WOA-GPR鲸鱼算法优化高斯过程回归多变量回归预测

回归预测 | Matlab实现WOA-GPR鲸鱼算法优化高斯过程回归多变量回归预测 目录 回归预测 | Matlab实现WOA-GPR鲸鱼算法优化高斯过程回归多变量回归预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 Matlab实现WOA-GPR鲸鱼算法优化高斯过程回归多变量回归预测 1.Matlab实现…

吹爆!遥感高光谱分类(Python)

目录 一、数据集下载 二、安装包 三、数据处理 四、模型训练 五、模型推理 六、踩坑记录 一、数据集下载 Hyperspectral Remote Sensing Scenes - Grupo de Inteligencia Computacional (GIC) (ehu.eus) Installing SPy — Spectral Python 0.21 documentation 二、安装…

算法打卡day36|动态规划篇04| 01背包理论基础、416. 分割等和子集

目录 01背包理论基础 01背包问题描述 01背包解法 二维数组 一维数组 算法题 Leetcode 416. 分割等和子集 个人思路 解法 动态规划 01背包理论基础 不同的背包种类&#xff0c;虽然有那么多中南背包&#xff0c;但其中01背包和完全背包是重中之重&#xff1b; 01背包问…

Python + Appium 自动化操作微信入门看这一篇就够了

Appium 是一个开源的自动化测试工具&#xff0c;支持 Android、iOS 平台上的原生应用&#xff0c;支持 Java、Python、PHP 等多种语言。 Appium 封装了 Selenium&#xff0c;能够为用户提供所有常见的 JSON 格式的 Selenium 命令以及额外的移动设备相关的控制命令&#xff0c;…

LABVIEW--正弦+高斯噪声信号及滤波

前面板信号 后面板 LABVIEW源程序链接&#xff1a;https://pan.baidu.com/s/11B-75i4fHZwWQyjxn9yCyQ?pwd7tfj 提取码&#xff1a;7tfj

中文地址分词器源码阅读(jiedi)

文章目录 structure.p文件pd.read_excelenumerate思维导图核心源码讲解jiedi.pytrain.py 总结 structure 点击左边的Structure按钮就如Structure界面。从Structure我们可以看出当前代码文件中有多少个全局变量、函数、类以及类中有多少个成员变量和成员函数。 其中V图标表示全…

AI普及时代,【AI书童】助你提升自我竞争力

AI运营官招募令&#xff01;&#xff01;&#xff01; 【AI书童】运营官 未来智慧人工智能 2024-03-26 12:00 浙江 微信公众号&#xff1a;未来智慧人工智能 助力个人和企业在人工智能时代持续成功 随着ChatGPT、GPT-4和Sora等创新技术的推出&#xff0c;人工智能在多模态领…