使用指向作为函数参数传递的数组的指针
Using a pointer to an array passed as a parameter of a function
我是 C 的初学者,我想在我的函数中使用指针。
我试图通过使用作为函数参数传递的指针来填充 int
的数组,但我不知道如何正确地完成它。
如何正确执行此操作?
函数
int validate_ip(char *ip, int *ptid) { /*function where I want to use it*/ }
ip
是一个包含 ipv4 地址的字符数组。
主要
int main() {
int ipv4[4];
int *ptid = ipv4;
//rest of my programm
}
您可以将 ipv4 int
数组传递给指向 int
参数的指针,将会发生的是它将衰减为指向其第一个元素的指针,以便与内部数组正常工作您还应该传递数组大小的函数。
例如:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int validate_ip(char *ip, int *ptid, size_t size) {
const char delim[] = ".";
char *token;
size_t i = 0;
//tokenize the ip and convert it to int
//this is for sample purposes, octet validation should be performed
token = strtok(ip, delim);
while (token != NULL && i < size) {
ptid[i++] = atoi(token);
token = strtok(NULL, delim);
}
return 1;
}
int main()
{
char ip[] = {"192.168.0.3"}; //sample ip
int ipv4[4];
if(validate_ip(ip, ipv4, 4)){
for (int i = 0; i < 4; i++)
{
printf("%d ", ipv4[i]);
}
}
}
这将需要验证以检查 ip 字符数组中的八位字节是否正确,但我相信您已经做到了。
关于我的示例代码的最后一点说明,strtok
将在 ip char
数组中进行更改,如果您想防止这种情况发生,请复制它并将其传递给函数原来的ip。
在 C 中,如果你声明一个数组(ipv4[4]),它有存储他的元素,它的指针是它的名字(ipv4),它的元素是 ipv4[0],ipv4[1],ipv4[2 ]、ipv4[3]。因此,如果您想将数组传递给修改数组的函数(void function(int * array)),您应该只使用指针 function(ipv4);
但是在这种情况下,您没有将数组声明为数组,而是声明了一个指针,那么您就没有这些指针指向的内存。
有很多方法可以为这些指针获取内存,例如函数 malloc 或 calloc。在这里你试图将一个 char* 分配给一个 int* 这不是最好的主意,因为当你做 ipv4[2] 相当于 (ipv4+2) 时,因为 ipv4 是一个 char 当你执行 ipv4+2 时,ipv4 增长 2*sizeof(char)。所以现在如果你做 *(ptid+2) ptid 递增 2*sizeof(int) 这可以或不可以与 chars 相同。
希望对您有所帮助。
如果您尝试直接均衡指向数组的指针,可能会出现警告和问题。所以我解决这个问题的方法是创建一个函数:
void equalize(int * pointer, int[] array , int size){
int i;
for(i=0;i<size;i++){
pointer[i]=array[i];}
}
}
在将 IP 地址的点分符号的 ASCII 字符串转换为 "int" 时,您必须记住的一件事是它需要采用网络字节顺序(相对于主机字节顺序)以用于各种套接字例程。
https://www.ibm.com/support/knowledgecenter/en/SSB27U_6.4.0/com.ibm.zvm.v640.kiml0/asonetw.htm
有多种函数可用于进行这种转换(并返回到 ASCII)。查看 "inet_addr()"、"inet_aton()" 和相关函数的手册页以获得更详细的描述。
现在,您在评论中说 ipv4 应该是 16 个数组,但您在代码中将其声明为 4 个数组。你需要改变它。如果每个 inet 例程都是以点分符号字符串作为参数的函数之一,则它会期望一个以空字符结尾的字符串。
https://linux.die.net/man/3/inet_aton
这些功能之一可能也有您想要在 "validate" 例程中执行的操作。
另一方面,如果您的问题只是如何将通用的点分符号字符串转换为 int 或 byte 值序列,那将采用不同的方法。如果您不知道有多少个值由点分隔,您可能需要考虑使用 'strtok' 来解析字符串。例如:
void main (int argc, char *arg )
{
int i;
char buffer[128];
char *token;
for (i = 1; i < argv[i]; i++) {
strcpy(buffer, argv[i]);
printf("Converting '%s'... Bytes =", argv[i]);
for (token = strtok(buffer, "."); token != NULL; token = strtok(NULL, ".")) {
printf(" %d", atoi(token));
}
printf("\n");
}
}
'strtok' 函数在很多情况下都非常有用,但如果某些字段为空,则它无法解析文件中包含逗号或制表符分隔字段的行。例如,假设您正在解析包含以下内容的逗号分隔文件:
one,two,,four,,six
使用strtok,你会得到
'one'
'two'
'four'
'six'
而你可能想要
'one'
'two'
''
'four'
''
'six'
为此,您需要编写自己的例程,如下所示:
char *ParseDelimited( char *str, char delimiter, char **resumePtr )
{
char *token;
char *p;
if (str == NULL) {
if (*resumePtr == NULL)
return (NULL);
token = *resumePtr;
if (*token == '[=14=]') {
*resumePtr = NULL;
return (token);
}
} else {
token = str;
if (*token == '[=14=]') {
*resumePtr = NULL;
return (NULL);
}
}
p = token;
while (*p != '[=14=]') {
if (*p == delimiter) {
break;
}
p++;
}
/* At this point, p either points to a delimiter or a null character */
if (*p != '[=14=]') {
*p = '[=14=]';
*resumePtr = p + 1;
} else {
*resumePtr = NULL;
}
return (token);
}
然后您将像这样使用此例程:
char buffer[1024];
char *token;
char resume;
strcpy(buffer, "one,two,,four,,six");
for (token = ParseDelimited(buffer, ',', &resume); token != NULL; token = ParseDelimited(NULL, ',', &resume)) {
printf("'%s'\n", token);
}
哪个会给你:
'one'
'two'
''
'four'
''
'six'
我是 C 的初学者,我想在我的函数中使用指针。
我试图通过使用作为函数参数传递的指针来填充 int
的数组,但我不知道如何正确地完成它。
如何正确执行此操作?
函数
int validate_ip(char *ip, int *ptid) { /*function where I want to use it*/ }
ip
是一个包含 ipv4 地址的字符数组。
主要
int main() {
int ipv4[4];
int *ptid = ipv4;
//rest of my programm
}
您可以将 ipv4 int
数组传递给指向 int
参数的指针,将会发生的是它将衰减为指向其第一个元素的指针,以便与内部数组正常工作您还应该传递数组大小的函数。
例如:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int validate_ip(char *ip, int *ptid, size_t size) {
const char delim[] = ".";
char *token;
size_t i = 0;
//tokenize the ip and convert it to int
//this is for sample purposes, octet validation should be performed
token = strtok(ip, delim);
while (token != NULL && i < size) {
ptid[i++] = atoi(token);
token = strtok(NULL, delim);
}
return 1;
}
int main()
{
char ip[] = {"192.168.0.3"}; //sample ip
int ipv4[4];
if(validate_ip(ip, ipv4, 4)){
for (int i = 0; i < 4; i++)
{
printf("%d ", ipv4[i]);
}
}
}
这将需要验证以检查 ip 字符数组中的八位字节是否正确,但我相信您已经做到了。
关于我的示例代码的最后一点说明,strtok
将在 ip char
数组中进行更改,如果您想防止这种情况发生,请复制它并将其传递给函数原来的ip。
在 C 中,如果你声明一个数组(ipv4[4]),它有存储他的元素,它的指针是它的名字(ipv4),它的元素是 ipv4[0],ipv4[1],ipv4[2 ]、ipv4[3]。因此,如果您想将数组传递给修改数组的函数(void function(int * array)),您应该只使用指针 function(ipv4);
但是在这种情况下,您没有将数组声明为数组,而是声明了一个指针,那么您就没有这些指针指向的内存。 有很多方法可以为这些指针获取内存,例如函数 malloc 或 calloc。在这里你试图将一个 char* 分配给一个 int* 这不是最好的主意,因为当你做 ipv4[2] 相当于 (ipv4+2) 时,因为 ipv4 是一个 char 当你执行 ipv4+2 时,ipv4 增长 2*sizeof(char)。所以现在如果你做 *(ptid+2) ptid 递增 2*sizeof(int) 这可以或不可以与 chars 相同。
希望对您有所帮助。
如果您尝试直接均衡指向数组的指针,可能会出现警告和问题。所以我解决这个问题的方法是创建一个函数:
void equalize(int * pointer, int[] array , int size){
int i;
for(i=0;i<size;i++){
pointer[i]=array[i];}
}
}
在将 IP 地址的点分符号的 ASCII 字符串转换为 "int" 时,您必须记住的一件事是它需要采用网络字节顺序(相对于主机字节顺序)以用于各种套接字例程。
https://www.ibm.com/support/knowledgecenter/en/SSB27U_6.4.0/com.ibm.zvm.v640.kiml0/asonetw.htm
有多种函数可用于进行这种转换(并返回到 ASCII)。查看 "inet_addr()"、"inet_aton()" 和相关函数的手册页以获得更详细的描述。
现在,您在评论中说 ipv4 应该是 16 个数组,但您在代码中将其声明为 4 个数组。你需要改变它。如果每个 inet 例程都是以点分符号字符串作为参数的函数之一,则它会期望一个以空字符结尾的字符串。
https://linux.die.net/man/3/inet_aton
这些功能之一可能也有您想要在 "validate" 例程中执行的操作。
另一方面,如果您的问题只是如何将通用的点分符号字符串转换为 int 或 byte 值序列,那将采用不同的方法。如果您不知道有多少个值由点分隔,您可能需要考虑使用 'strtok' 来解析字符串。例如:
void main (int argc, char *arg )
{
int i;
char buffer[128];
char *token;
for (i = 1; i < argv[i]; i++) {
strcpy(buffer, argv[i]);
printf("Converting '%s'... Bytes =", argv[i]);
for (token = strtok(buffer, "."); token != NULL; token = strtok(NULL, ".")) {
printf(" %d", atoi(token));
}
printf("\n");
}
}
'strtok' 函数在很多情况下都非常有用,但如果某些字段为空,则它无法解析文件中包含逗号或制表符分隔字段的行。例如,假设您正在解析包含以下内容的逗号分隔文件:
one,two,,four,,six
使用strtok,你会得到
'one'
'two'
'four'
'six'
而你可能想要
'one'
'two'
''
'four'
''
'six'
为此,您需要编写自己的例程,如下所示:
char *ParseDelimited( char *str, char delimiter, char **resumePtr )
{
char *token;
char *p;
if (str == NULL) {
if (*resumePtr == NULL)
return (NULL);
token = *resumePtr;
if (*token == '[=14=]') {
*resumePtr = NULL;
return (token);
}
} else {
token = str;
if (*token == '[=14=]') {
*resumePtr = NULL;
return (NULL);
}
}
p = token;
while (*p != '[=14=]') {
if (*p == delimiter) {
break;
}
p++;
}
/* At this point, p either points to a delimiter or a null character */
if (*p != '[=14=]') {
*p = '[=14=]';
*resumePtr = p + 1;
} else {
*resumePtr = NULL;
}
return (token);
}
然后您将像这样使用此例程:
char buffer[1024];
char *token;
char resume;
strcpy(buffer, "one,two,,four,,six");
for (token = ParseDelimited(buffer, ',', &resume); token != NULL; token = ParseDelimited(NULL, ',', &resume)) {
printf("'%s'\n", token);
}
哪个会给你:
'one'
'two'
''
'four'
''
'six'