Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何在代码中正确使用指针?_C - Fatal编程技术网

C 如何在代码中正确使用指针?

C 如何在代码中正确使用指针?,c,C,大家好,我刚开始学习如何使用指针,我陷入了我的代码中。我需要编写一个代码来修改(更正大小写并找出每个公民的年份)并对公民列表进行排序。例如,如果用户条目为: 4//仅仅是公民的数量 拉娜·拉尼奇1999 拉娜·拉纳克1999 拉娜·拉内克1989 拉娜拉诺克1999 显示器必须: 十八,;拉纳克,拉娜 十八,;拉尼奇,拉娜 十八,;拉娜,拉诺克 二十八,;拉内克,拉娜 #include <stdio.h> #include <string.h> #include <

大家好,我刚开始学习如何使用指针,我陷入了我的代码中。我需要编写一个代码来修改(更正大小写并找出每个公民的年份)并对公民列表进行排序。例如,如果用户条目为:

4//仅仅是公民的数量

拉娜·拉尼奇1999

拉娜·拉纳克1999

拉娜·拉内克1989

拉娜拉诺克1999

显示器必须:

十八,;拉纳克,拉娜

十八,;拉尼奇,拉娜

十八,;拉娜,拉诺克

二十八,;拉内克,拉娜

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

typedef struct {
char name[26];
char surname[26];
int birth;
}   citizen;   //the structer for the citizen

void modify(citizen *g);
int compare(citizen g1, citizen g2); //compares citizens by birth or          surname or name 
void sort(citizen g[], int);  //insertion sort

int main()
{   
    int n, i;
    citizen g[100];

    scanf("%d", &n);

    for(i = 0; i < n; i++) {
       scanf("%s %s %d", g[i].name, g[i].surname, &g[i].birth);
       modify(g + i);
    }

    sort(g, n);

    for (i = 0; i < n; i++) {
         printf("%2d; %s %s\n", g[i].birth, g[i].surname, g[i].name);
    }

    return 0;
}

void modify(citizen *g) { //here I'm having trouble
    int i = 0; 

    //trying to correct the name
    if(isalpha(*g[i].name[0])) {   
       *g[i].name[0] = toupper(*g[i].name[0]);
     }
    for(i = 1; i < strlen(*g[i].name); i++) {
       *g[i].name = toupper(*g[i].name);
     }
    //then the surname

    if(isalpha(*g[i].surname[0])) {
        *g[i].surnma[0] = toupper(*g[i].surname[0]);
     }
     for(i = 1; i < strlen(*g[i].surname); i++) {
        *g[i].surname = toupper(*g[i].surname);

     }
     *g[i].birth = 2017 - *g[i].birth; //finding how old is the citizen

 }


int compare(citizen g1, citizen g2) {
    if(g1.birth == g2.birth) {
        if(!strcmp(g1.surname, g2.surname)) {
               return strcmp(g1.name,g2.name);
        }
        else {
              return strcmp(g1.surname, g2.surname);
        }
     }
    else if (g1.birth > g2.birth) {
              return 1;
    }
              return -1;
}



void sort(citizen g[], int n) { //insertion sort
   int i, j;
   citizen tmp;

   for(i = 0; i < n; i++) {
       tmp = g[i];
       j = i;
       while(j > 0 && compare(g[j-1], tmp)) {
            g[j] = g[j - 1];
            j--;
        }
        g[j] = tmp;

     }
 }  
#包括
#包括
#包括
类型定义结构{
字符名[26];
查氏[26];
婴儿出生;
}公民//公民的建构者
无效修改(公民*g);
int比较(公民g1、公民g2)//按出生、姓氏或姓名对公民进行比较
无效排序(公民g[],整数)//插入排序
int main()
{   
int n,i;
公民g[100];
scanf(“%d”和“&n”);
对于(i=0;ig2.birth){
返回1;
}
返回-1;
}
void排序(citizen g[],int n){//插入排序
int i,j;
公民tmp;
对于(i=0;i0&&compare(g[j-1],tmp)){
g[j]=g[j-1];
j--;
}
g[j]=tmp;
}
}  

我将在这里给您答案,而不是按您的方式取消引用指针:

void modify(citizen *g) { //here I'm having trouble
    int i = 0; 

    //trying to correct the name
    //Is this really necessary?
    if (isalpha(g->name[0])) {   
        g->name[0] = toupper(g->name[0]);
    }
    for (i = 1; i < strlen(g->name); i++) {
        g->name[i] = toupper(g->name[i]);
    }

    //then the surname
    //Is this really necessary?
    if (isalpha(g->surname[0])) {
        g->surname[0] = toupper(g->surname[0]);
    }
    for (i = 1; i < strlen(g->surname); i++) {
        g->surname[i] = toupper(g->surname[i]);
    }
    g->birth = 2017 - g->birth; //finding how old is the citizen
}
基本要素:

在您的主要功能中:

citizen g[100];
声明一个包含100个公民的数组
g
是一个不是指针的数组

在修改函数中

modify(citizen *g)
g
是指向公民的指针。它不是数组。所以你可能会问为什么这样做是合法的:

modify(g + i);
原因是,在表达式中使用
g
的上下文中,编译器将其转换为指向其第一个元素的指针。我们说“
g
衰减为指向其第一个元素的指针”

有两种方法可以访问指针指向的对象(我们称之为“取消引用指针”)。第一个是使用
*
操作符。如果
p
int*
我们可以这样做

int x = *p;
如果
p
指向
int
数组中的
int
,我们可以进行指针运算。所以我们可以

int y = *(p + 3);
int z = *(p - 2);
如果
p
指向数组中至少大小为6的第三个元素,
y
现在与第六个元素具有相同的值,
z
与第一个元素具有相同的值

取消引用指针的第二种方法是使用下标语法。语法
p[i]
完全等同于
*(p+i)
,我的意思是完全相同的。加法是可交换的,所以
p+i==i+p
这意味着
*(p+i)=*(i+p)
这意味着(在C中这是合法的)
p[i]==i[p]
无论如何,上面的每个语句都可以用下标来写

int x = p[0];
int y = p[3];
int z = p[-2];
除了为了保持理智,如果p是指向数组的第一个元素或malloc块的第一个元素的指针,我们倾向于只使用下标语法

如果
p
是指向
struct
的指针(就像您的
citizen
结构一样),您可以通过取消引用
p
并使用正常的diot语法来访问结构中的字段

int myBirth = (*p).birth;
圆括号是必需的,因为点运算符通常比*运算符具有更高的优先级。对于
*p.birth
,C编译器认为
p
s是一个结构,其中有一个名为
birth
的字段,它试图将该字段作为指针取消引用。C为
(*p)提供了一种快捷语法.出生
是什么

int myBirth = p->birth; // Exactly equivalent to (*).birth
最后,在C中,您可以使用&运算符获得指向任意对象的指针

int x = 0;
int* p = &x; // p is a pointer to x.
所以当我们说
g
衰减为指向其第一个元素的指针时,我们的意思是编译器转换

modify(g + i);
到 修改(&g[0]+i)

因此,您可以看到,modify函数接收到一个指向
g
元素的指针。查看函数的前几行:

int compare(citizen *g1, citizen *g2) {
    if (g1->birth == g2->birth) {
        int resp = strcmp(g1->surname, g2->surname);
        if (!resp) {
           return strcmp(g1->name, g2->name);
        }
        return resp;
    } else if (g1->birth > g2->birth) {
        return 1;
    }
    return -1;
}
if(isalpha(*g[i].name[0])) {   
   *g[i].name[0] = toupper(*g[i].name[0]);
 }

Because i is 0 at this point, `g[i].name` is the same as `(*g).name` or `g->name`. Use the last one for clarity. The `name` field is an array of chars, so `name[0]` is the first character of the name, which is what you want. You have an extra dereference with the leading * that you don't need. The above should be

if (isalpha(g->name[0])) {   
   g->name[0] = toupper(g->name[0]);
 }
除了
toupper
之外,
isalpha
会为您检查,所以所有这些都会变成

 g->name[0] = toupper(g->name[0]);
我将让您来修复函数的其余部分,除了在这里提到一个相当糟糕的错误:

 for(i = 1; i < strlen(*g[i].surname); i++) {
    *g[i].surname = toupper(*g[i].surname);

 }
for(i=1;i

这对我来说毫无意义。

现在怎么办,C或C?@tilz0R哦,对不起,这是C或C?因为在我看来它真的不像C。你也可以给每个人一个味道,并正确地缩进你的代码。你的问题是什么?@UnholySheep我应该如何在函数修改中使用指针?现在,你让他非常高兴地发现如何修改通过阅读一本好的手册,正确地用C语言编写指针程序……至少,你给了他一个任务,让他自己找出如何将非第一个字符格式化为小写