【每日一C之八】C语言static用法

深入解析C语言中static的两大用途:修饰全局变量与函数的作用域,以及修饰局部变量的生存周期。通过实例代码展示static如何影响变量的生命周期与作用范围,包括静态全局变量与静态局部变量的特点。

 每日一C之static用法


       每天一个C语言贝壳厚积薄发积跬步以致千里

 今日贝壳:C语言static的用法与static修饰变量的空间存储特征。
           要点: static在C中主要有两个作用,一修饰作用域;二修饰生存期
                    1.static修饰全局变量:修饰作用域
                                 static修饰的静态全局变量与普通全局变量唯一的区别是:静态全局变量仅在此源文件中有效,不能被其他源文件引用。该全局变量的作用域被限定在此源文件。
                    2.static修饰函数:修饰作用域。
                                 static修饰的函数,作用域仅在此源文件,不能在其他源文件中调用。该函数的作用域被限定在此源文件。
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
            
//*******
//file1.c文件代码如下
//*******
static int n = 10 ; //静态全局变量
static void foo () //静态函数
{
printf ( "Hello world !" );
}
....
//*******
//file2.c
//*******
extern int n ; //extern声明使用file1中的n,引发错误,因为n为static静态全局变量
//如果n未用static修饰,通过extern可引用file1.c中的n
extern void foo (); //同上,引发错误,静态函数作用仅在其源文件内
....
 来自CODE的代码片
static1.c
                     3.static修饰局部变量:修饰生存期
                                  static修饰的静态局部变量,同普通局部变量的区别:
  • 静态局部变量存储在静态区,普通局部变量存储在栈区。
  • 静态局部变量未初始化时,系统自动置0;初始化仅在函数初次调用时进行一次
  • 静态局部变量在函数结束时不会释放,其生存期为整个程序运行期,并能保存上次调用的值。
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
             
#include<stdio.h>
void foo ()
{
static int counter = 0 ; //仅在初次调用foo()时初始化
printf ( "counter:%d" , counter );
counter ++ ;
}
int main ()
{
foo (); //第一次调用foo(),counter输出0
foo (); //第二次调用foo(),counter输出1
return 0 ;
}
 来自CODE的代码片
static2.c
 去掉static再运行一下程序,结果不同


                      Have a nice day !

<think>我们面对的问题是在C语言程序中调用高德地图API实现地理信息服务。由于C语言本身并不像Python或JavaScript那样有丰富的网络请求库和JSON解析库,因此我们需要使用些外部库来辅助完成HTTP请求和JSON解析。 ### 步骤分析 1. **了解高德地图API**:首先需要确定使用哪个具体的API服务。例如,地理编码(将地址转换为经纬度)、逆地理编码(将经纬度转换为地址)、路径规划等。这里以地理编码服务为例。 2. **获取API Key**:在高德开放平台注册账号并创建应用,获取Key(Web服务API的Key)。 3. **构造HTTP请求**:根据高德API文档构造请求URL。 4. **发送HTTP请求**:在C语言中发送HTTP GET请求。 5. **解析响应数据**:高德API返回JSON格式的数据,需要解析JSON获取所需信息。 ### 实现方法 #### 1. 选择HTTP客户端库 在C语言中,可以使用`libcurl`库来发送HTTP请求。它是个强大且易于使用的客户端URL传输库。 #### 2. 选择JSON解析库 解析JSON可以使用`cJSON`库,这是个轻量级的JSON解析器,使用简单。 #### 3. 安装依赖库 - 在Linux上,可以使用包管理器安装: ```bash sudo apt-get install libcurl4-openssl-dev ``` 对于`cJSON`,可以从其GitHub仓库(https://github.com/DaveGamble/cJSON)下载源码编译安装。 #### 4. 代码示例 下面是个使用`libcurl`和`cJSON`调用高德地理编码API的示例。 ```c #include <stdio.h> #include <stdlib.h> #include <curl/curl.h> #include "cJSON.h" // 用于存储HTTP响应数据的回调函数 size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata) { size_t realsize = size * nmemb; char *response = (char *)userdata; strcat(response, ptr); return realsize; } int main() { CURL *curl; CURLcode res; char response_buffer[4096] = {0}; // 初始化响应缓冲区 // 初始化libcurl curl_global_init(CURL_GLOBAL_DEFAULT); curl = curl_easy_init(); if(curl) { // 构造请求URL,请替换为你的API Key和地址 char *api_key = "你的高德API Key"; char *address = "北京市朝阳区阜通东大街6号"; char url[1024]; snprintf(url, sizeof(url), "https://restapi.amap.com/v3/geocode/geo?address=%s&key=%s", address, api_key); curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, response_buffer); // 发送请求 res = curl_easy_perform(curl); if(res != CURLE_OK) { fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); } else { // 解析JSON响应 cJSON *root = cJSON_Parse(response_buffer); if (root) { // 检查状态 cJSON *status = cJSON_GetObjectItem(root, "status"); if (status && status->valuestring && strcmp(status->valuestring, "1") == 0) { cJSON *geocodes = cJSON_GetObjectItem(root, "geocodes"); if (geocodes && cJSON_IsArray(geocodes)) { cJSON *first_item = cJSON_GetArrayItem(geocodes, 0); if (first_item) { cJSON *location = cJSON_GetObjectItem(first_item, "location"); if (location && cJSON_IsString(location)) { printf("Location: %s\n", location->valuestring); } } } } else { cJSON *info = cJSON_GetObjectItem(root, "info"); if (info) { printf("Error: %s\n", info->valuestring); } } cJSON_Delete(root); } } curl_easy_cleanup(curl); } curl_global_cleanup(); return 0; } ``` ### 注意事项 1. **URL编码**:地址中如果有特殊字符(如空格、中文等),需要进行URL编码。上面的示例没有处理,实际应用中应该使用`curl_easy_escape`函数进行编码。 2. **错误处理**:代码中应增加更详细的错误处理。 3. **多线程安全**:`libcurl`可以配置为线程安全,但在多线程环境下使用仍需注意。 4. **API调用限制**:注意高德API的调用频率限制,避免超出配额。 ### 引用说明 在实现地理信息服务时,我们参考了高德地图API的调用方式[^1]和地理位置信息转换的般方法[^3]。 §§相关问题§§ 1. 如何在C语言中进行URL编码? 2. 高德地图API还有哪些常用服务? 3. 如何优化C语言中的HTTP请求性能?</think>### C语言调用高德地图API实现方法 在C语言中调用高德地图API,主要通过以下步骤实现: #### 1. **准备工作** - **注册高德开发者账号** 访问[高德开放平台](https://lbs.amap.com/),注册账号并创建应用,获取API Key(密钥)。 - **确定所需服务** 根据需求选择API服务(如地理编码、逆地理编码、路径规划等)。 #### 2. **核心实现步骤** ##### (1) HTTP请求封装 使用`libcurl`库发送HTTP/HTTPS请求: ```c #include <curl/curl.h> // 回调函数处理API响应 static size_t write_callback(void *contents, size_t size, size_t nmemb, void *userp) { size_t realsize = size * nmemb; char *data = (char*)userp; memcpy(data, contents, realsize); data[realsize] = '\0'; return realsize; } void call_amap_api(const char *url) { CURL *curl = curl_easy_init(); if(curl) { char response[4096] = {0}; curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, response); CURLcode res = curl_easy_perform(curl); if(res == CURLE_OK) { printf("API Response: %s\n", response); // 此处解析JSON } else { fprintf(stderr, "Request failed: %s\n", curl_easy_strerror(res)); } curl_easy_cleanup(curl); } } ``` ##### (2) 构造API请求URL 以**地理编码服务**(地址转坐标)为例: ```c void get_geocode(const char *api_key, const char *address) { char url[512]; snprintf(url, sizeof(url), "https://restapi.amap.com/v3/geocode/geo?key=%s&address=%s", api_key, address); call_amap_api(url); } ``` ##### (3) 解析JSON响应 使用`cJSON`库解析返回的JSON数据: ```c #include "cJSON.h" void parse_geocode_response(const char *json) { cJSON *root = cJSON_Parse(json); if(!root) return; cJSON *status = cJSON_GetObjectItem(root, "status"); if(status && strcmp(status->valuestring, "1") == 0) { cJSON *geocodes = cJSON_GetObjectItem(root, "geocodes"); if(geocodes) { cJSON *first_item = cJSON_GetArrayItem(geocodes, 0); cJSON *location = cJSON_GetObjectItem(first_item, "location"); printf("坐标: %s\n", location->valuestring); // 如"116.480881,39.989410" } } cJSON_Delete(root); } ``` #### 3. **编译与依赖** - **安装依赖库**: ```bash # Ubuntu示例 sudo apt-get install libcurl4-openssl-dev # cJSON: https://github.com/DaveGamble/cJSON ``` - **编译命令**: ```bash gcc your_program.c -lcurl -lcjson -o amap_client ``` #### 4. **完整调用示例 ```c int main() { const char *api_key = "你的API_KEY"; // 替换为真实Key get_geocode(api_key, "北京市朝阳区阜通东大街6号"); return 0; } ``` ### 关键注意事项 1. **地址编码** 中文地址需进行URL编码,可使用`curl_easy_escape()`处理: ```c char *encoded_addr = curl_easy_escape(curl, address, 0); ``` 2. **错误处理** 检查API返回的`status`和`info`字段([参考文档](https://lbs.amap.com/api/webservice/guide/tools/info))。 3. **服务限制** 免费版每日调用限额(如地理编码5000次/日),需注意流量控制[^1]。 ### 其他服务扩展 - **逆地理编码**(坐标转地址): `https://restapi.amap.com/v3/geocode/regeo?key=YOUR_KEY&location=116.480881,39.989410` - **IP定位**: `https://restapi.amap.com/v3/ip?key=YOUR_KEY&ip=114.247.50.2` > 提示:高德API返回的数据为JSON格式,需结合具体业务解析所需字段(如坐标、地址、行政区划等)[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值