2011-12-17 1 views
3

Я только начал изучать указатели, и после того, как много добавления и удаления * S мой код для преобразования введенной строки в верхний регистр, наконец, работает ..Передача строки с помощью функции программирования (C)

#include <stdio.h> 
char* upper(char *word); 
int main() 
{ 
    char word[100]; 
    printf("Enter a string: "); 
    gets(word); 
    printf("\nThe uppercase equivalent is: %s\n",upper(word)); 
    return 0; 
} 

char* upper(char *word) 
{ 
    int i; 
    for (i=0;i<strlen(word);i++) word[i]=(word[i]>96&&word[i]<123)?word[i]-32:word[i]; 
    return word; 
} 

Мой вопрос , при вызове функции, которую я отправил word, которая является указателем, поэтому в char* upper(char *word) почему мне нужно использовать *word? Является ли это указателем на указатель? Кроме того, char* есть потому, что он возвращает указатель на символ/строку вправо? Просьба разъяснить мне, как это работает.

+0

Я смущен, что вы просите. Вы спрашиваете, почему это верхний (char * word), а не верхний (char word)? – Corbin

+0

функция upper запрашивает указатель как параметр, и вы указываете указатель (слово). насколько я знаю, это правильный путь. –

+0

Чтобы устранить путаницу, измените имя параметра 'word' на' upper' или локальную переменную 'word' в вашем коде. – Mat

ответ

4

Это потому, что тип вам нужно здесь просто «указатель на символ», который обозначается как char *, звездочка (*) является частью спецификации типа параметра. Это не «указатель на указатель на символ», который должен быть записан в виде char **

Некоторые дополнительные замечания:

  1. Это, кажется, ты путаешь оператор разыменовывания* (используется для доступа к фрагменту где указывает указатель) со звездочкой в ​​качестве указателя указателя в спецификациях типа; вы не используете оператор разыменования в любом месте вашего кода; вы используете только звездочку как часть спецификации типа! Смотрите следующие примеры: объявить переменную как указатель на символ, вы бы написать:

    char * a; 
    

    Чтобы присвоить значение в пространстве, где a наведен на (с помощью оператора разыменования), вы бы написать:

    *a = 'c'; 
    
  2. массива (полукокс) не в точности равен указатель (СИМВОЛ) (см the question here). Однако в большинстве случаев массив (из char) может быть преобразован в указатель (char).

  3. Ваша функция фактически изменяет внешний массив символов (и возвращает указатель на него); не только верхний регистр введенного печатается printf, но и переменная word функции main будет изменена так, чтобы она удерживала верхний регистр введенного слова. Позаботьтесь о таком побочном эффекте - это на самом деле то, что вы хотите. Если вы не хотите, чтобы функция могла изменять внешнюю переменную, вы могли бы написать char* upper(char const *word) - но тогда вам также придется изменить определение функции, чтобы она напрямую не изменяла переменную word, в противном случае Компилятор будет жаловаться.

2

char upper(char c) будет функцией, которая принимает символ и возвращает символ. Если вы хотите работать со строками, соглашение состоит в том, что строки - это последовательность символов, заканчивающихся нулевым символом. Вы не можете передать полную строку в функцию, чтобы передать указатель на первый символ, поэтому char *upper(char *s). Указатель на указатель будет иметь два * как в char **pp:

char *str = "my string"; 
char **ptr_to_ptr = &str; 
char c = **ptr_ptr_ptr; // same as *str, same as str[0], 'm' 

верхний также может быть реализован как void upper(char *str), но это более удобно иметь верхнюю стяжную переданную строку.Вы использовали это в своем примере, когда printf строку, возвращаемую верхним.

Как комментарий, вы можете оптимизировать свою верхнюю функцию. Вы звоните strlen за каждые i. Строки C всегда имеют нулевое завершение, поэтому вы можете заменить i < strlen(word) на word[i] != '\0' (или word[i] != 0). Кроме того, код лучше читать, если вы не сравниваете его с 96 и 123 и вычитаете 32, но если вы проверите и вычислите с помощью «a», «z», «A», «Z» или любого другого персонажа, который вы имеете в виду.

0

* слова даже при указании bt слова массива в функции, и слово-указатель фактически указывает на одно и то же, передавая аргументы jst копия «pointee», т.е. введенное слово передается и любая операция выполняется над словом указателя, поэтому в конце мы должны вернуть указатель, чтобы возвращаемый тип указывался как *.