2013-10-02 3 views
1

В настоящее время я изучаю язык c, и я столкнулся с этим кодом. ptr уже является типом указателя переменной, поэтому каков эффект оператора &, потому что я знаю, что обычно оператор использует для получения адреса переменной, отличной от указателя.адрес переменной указателя

struct name { 
    int a; float b; char c[30]; 
}; 
int main() 
{ 
    struct name *ptr; 
    int i,n; 
    printf("Enter n: "); 
    scanf("%d",&n); 
    ptr = (struct name*)malloc(n*sizeof(struct name)); 
    /* Above statement allocates the memory for n structures with pointer ptr pointing to  base address */ 
    for(i=0; i<n; ++i) { 
    printf("Enter string, integer and floating number respectively:\n"); 
    scanf("%s%d%f", &(ptr+i)->c, &(ptr+i)->a, &(ptr+i)->b); 
    } 
} 
+0

@ P0W: Кодирование стиля и вредных привычек в стороне, это, по-видимому, отлично подходит для C++. –

+0

@JohnDibling Мне иногда удается скомпилировать методы C из вопросов без изменений с помощью Java, но это не значит, что эти вопросы должны быть помечены как Java, так и C. Аналогичным образом, вопрос не должен быть помечен как C, так и C++. Тег C++ часто приводит к рекомендациям на языке C++, которые просто не помогут OP. – Dukeling

+0

@ Dukeling: Возможно, но OP помечает его с обоих языков по какой-то причине. Возможно, это не повод, а причина. Помимо упоминания «c» в OP, здесь нет ничего, что подсказывает, что данный язык не может быть C++. Спроситель должен уточнить. –

ответ

2
&(ptr + i)->c 

это принимает адрес переменной с хранятся в г-й элемент PTR. Итак, ваша первая интуиция была правильной.

ptr+i 

- это просто указатель арифметический, чтобы найти i-й элемент для массива.

(ptr+i)->c 

получает доступ к полю c из этой структуры, и & принимает адрес этого переменный.

+0

, когда я пытаюсь получить доступ к члену в этом списке через poinetr, чтобы структурировать его, вышвырнул мне исключение »[Ошибка] запросила для члена 'info/next' im что-то не структурное или объединение" void struct Node_rec { \t int Информация; \t struct Node_rec * next; \t struct Node_rec * prev; }; typedef struct Node_rec Node; struct List_rec { \t Узел * последний; \t Узел * первый; \t int len; \t int sum; }; typedef struct List_rec List; void make_list (List l1, int new_info) { \t Узел * node = (Узел *) (malloc (sizeof (Node *))); \t node.info = new_info; node.next = NULL; node.prev = NULL; \t l1.first = node; \t l1.last = node; \t l1.len = 1; \t l1.sum = new_info; \t } – user2559696

0
struct name* ptr; 

Это создает указатель на name.

struct name** p = &ptr; 

Это создает указатель на указатель на name, взяв адрес указателя вы уже создали.

В вашем случае, вы передаете в указатели на scanf и имеют динамический массив name, так

&(ptr + i)->c 

находит й элемент массива и возвращает адрес его c член в scanf (то же самое с a и b).

Передача в адрес указателя позволяет изменить этот указатель (например, перераспределить). В C++ он будет практически идентичен передаче по ссылке.

2

Код &(ptr + i)->c дает вам адрес структурного элемента c, который относится к i-й структуре в вашем списке. Давайте сломаем его немного.

(ptr + i) - указатель арифметический. Он добавляет i к адресу, хранящемуся по адресу ptr.

(ptr + i)->c Доступ к структурному элементу c через указатель (ptr + i).

&(ptr + i)->c берет адрес элемента структуры c через указатель (ptr + i).

Кроме того, я знаю, что это не совсем то, что вы думали, что это делает, поскольку вы считали, что оператор адреса применяется к указателю, а просто FYI: вы действительно можете взять адрес указателя. Такая конструкция является указателем на указатель и полезна, когда вы хотите изменить указатель (а не только значение, сохраненное на указанном адресе) в функции. например

int a = 5; /* regular variable */ 
int* pa = &a; /* pointer to a */ 
int** ppa = &pa; /* pointer to pointer (which points to a) */ 
+0

Спасибо, я немного изменил его. Наверное, теперь яснее. – bstamour

+0

Определенно лучше. Приветствия. – Caleb

1

Во-первых, оператор & в языках C и C++ используется для получения адреса любой переменной.Точнее, его можно использовать для получения адреса [почти] любого lvalue (в этом отношении существуют некоторые различия между C и C++). Переменные указателя являются обычными переменными. В них нет ничего особенного, а это значит, что нет ничего необычного в том, что оператор & применяется к указателям.

Во-вторых, в коде, который вы указали, фактически нет ни одного экземпляра &, применяемого к указателю. Есть четыре приложения & в коде

&n 
&(ptr+i)->a 
&(ptr+i)->b 
&(ptr+i)->c 

В первых двух случаях она применяется к int объектов. В третьем случае применяется к объекту float. В этом последнем случае он применяется к объекту char [30]. Нет указателей.

Смежные вопросы