Unclear pointer and array


 
Thread Tools Search this Thread
Top Forums Programming Unclear pointer and array
# 22  
Old 01-19-2014
Quote:
Originally Posted by yifangt
The format specification pointers and address with printf() is one of the most difficult part for me. Whenever I saw warning or error msgs like:
Code:
warning: format ‘%c’ expects type ‘int’, but argument 2 has type ‘char *’ [-Wformat]
warning: format ‘%c’ expects type ‘int’, but argument 2 has type ‘size_t *’ [-Wformat] etc.

I panic and bang my head on the table.
The error is clear enough. You are feeding a 'something *' into %c when it wants a 'something' without the *. Most of the various kinds of integers can be converted between, but %c does not print strings. It prints single characters, only single characters, and nothing but single characters.

To convert a 'something *' into a 'something', you either do (*something) or something[0] to dereference it. If 'something' was a string, these would get you the first character of it.

Last edited by Corona688; 01-19-2014 at 06:02 PM..
# 23  
Old 01-19-2014
unmatching format argument for printf

Thanks Corona!
What I meant panic is to match the format arguments of printf(), especially when pointers are involved. My bad part is the not-enough-understanding of the pointer, as I did not realize my wrong catches until I saw the warnings/errors.
Go back to the original post of this thread, First, I was wondering why array worked but pointer not. After the discussion I seemed to have some ideas that when array is used, the memory is automatically allocated, but memory was only allocated to the variable address if a pointer is used, such that enough memory needs to be allocated to the pointers of the string/substring.
The second question is what the correct way is if pointer is used. (Maybe using pointer is not the correct way, but that is another story.) But this topic was distracted by other problems with sprintf() and printf() format arguments like Don's tricks.
The most difficult parts with C to me are: 1) dynamic memory allocation of pointers, 2) match the format arguments of printf() when pointers are involved. That's what I am always panic with. The critical point is still the pointer manipulation. Need more read and study. Could not find a good course around that digs C deep as I want. Neither could I find a good instruction/book on this topic yet, or too many diverse information about this for me to catch the critical points, I should say. Thanks you lots any way. Any suggestion?
# 24  
Old 01-19-2014
Quote:
The most difficult parts with C to me are: 1) dynamic memory allocation of pointers
I think you're overthinking this quite a whole lot. You've divided this into a lot of separate categories like "the correct way to use pointers when malloc is involved", "the correct way to use pointers when printf is involved", "the correct way to use pointers when sprintf is involved", "the correct way to use pointers when strtok is involved", etc -- as if these things had nothing to do with each other.

If you look at them though, their arguments help give you an idea how they work.

Code:
$ man malloc

void *malloc(size_t size);

$ man strtok

char *strtok(char *str, const char *delim);

$ man strcpy

char *strcpy(char *dest, const char *src);

$ man sprintf

int sprintf(char *str, const char *format, ...);

$

malloc returns a 'void *'. It's not const, so the memory it returns is memory you're allowed to write to. 'void' means its of no particular type, that you're expected to cast it into the type you need. So malloc returns memory which you're supposed to cast into some other type, memory which you're allowed to write to.

strtok takes a 'char *', which means you're giving it memory that strtok's allowed to alter, as well as a 'const char *', memory it's not allowed to change -- the list of tokens. It returns a 'char *', a pointer to memory you're allowed to write to. (As it turns out, a pointer to the same memory, even.)

strcpy's arguments show you which one is src and which one is dest, even without their names -- the 'const char *' has to be the source because that's memory strcpy can't write to.

and sprintf takes a pointer to memory it can write to(the output string), memory it can't write to(the command string), and a variable number of arguments just like printf.

As for the way printf and sscanf demand pointers and non-pointers, there's nothing really deep to learn about C there, it's just the way the printf and scanf calls were built. They could have made printf demand everything be pointers, just like scanf does, but didn't.
# 25  
Old 01-19-2014
Quote:
Originally Posted by yifangt
....
The most difficult parts with C to me are
....
Hai yifangt please do post your difficulties in forum as you posted in current thread, we shall discuss Don is there, Corona is there...many other experienced experts are there.. it's good for me also, I can recall "Let Us C" which I read during my college days... and many people who refer this forum also will learn..Smilie
This User Gave Thanks to Akshay Hegde For This Post:
# 26  
Old 01-20-2014
I am reading this book too, but as self-study. That's why I have so many questions. Here is another one that I found at link which is a function to replace a substring from original string:
Code:
char *replace_str(char *str, char *orig, char *rep)
{
    static char buffer[1024];
    char *p;                             //Line 4: 
    if (!(p = strstr(str, orig)))        //Line 5: p is the position of first occurrence of 'orig' in 'str', i.e. 6 (real position maybe something as 5f0076) at "Hello world!"
            return str;                  //Line 6: 'str' is a string, returned if 'orig' not found
    }   
    strncpy(buffer, str, p - str);      //Line 8: Copy 'p-str' (6=5f0076 - 5f0070) characters from 'str'(where 'orig' starts at) to 'buffer', i.e. from the "start"(letter 'H') to the first occurrence of "orig" (letter 'w')
    buffer[p - str] = '\0';              //Line 9: put '\0' to the end of buffer, now '\0' is at the position letter "w" of world used to stay. buffer[] becomes "Hello \0".

    sprintf(buffer + (p - str), "%s%s", rep, p + strlen(orig)); //Line 11: Now 'rep' is copied to buffer, buffer[] becomes "Hello Miami" but what about p+strlen(orig)?????
    return buffer;
}

I put my understanding at the end of each line. Line 11 bugs me again, which is closely related to previous pages of this thread. The question is: what is the pointer movement for "p + strlen(orig)" to "buffer+(p-str)" ?
In another way, how 'rep' and 'p+strlen(orig)' is concatenated/combined?
The author used Hello world! to Hello Miami! as example. Thanks a lot!

---------- Post updated at 12:21 PM ---------- Previous update was at 12:04 PM ----------

Ah ha!
p+strlen(orig) is ' ! ', i.e. the rest of the string after the match 'world', here is the exclamation mark ' ! '. Am I right?

Last edited by yifangt; 01-20-2014 at 12:27 PM..
# 27  
Old 01-20-2014
Yes, you are correct. That is a pretty convoluted example. I'd have done the pointer arithmetic in a separate statement, like char *rest=p+strlen(orig); // Go past the original word for the rest of the string
This User Gave Thanks to Corona688 For This Post:
# 28  
Old 01-20-2014
Thanks Corona!
Your way is clearer and easier to understand. I have to admit that some programmer like to use tricks so that I had hard time to understand. However their code is very concise with lots information hiding behind. I was warned better not do that way, but actually I admire them very much as I think you can do that only you have really good catch of the idea.

About the warnings I panic at, here is an example that I had thought my code is fine while I tried another program to do the calculation of pointer positions.
Quote:
warning: format ‘%c’ expects type ‘int’, but argument 2 has type ‘char *’ [-Wformat]
warning: format ‘%c’ expects type ‘int’, but argument 2 has type ‘size_t *’ [-Wformat] etc.
Here is my code:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Try the calculation of char pointers cf. array subscription
// I did not figure out the char pointer can be implicitly converted to integer number
//

int main()
{
    char str[] = "The quick brown fox jumps over the lazy dog!";
    char *line;
    char *p, *q, *l, *m;

    line = (char *) malloc(sizeof(str));    //Line 15 allocate memory 

    strcpy(line, str);            //Line 17 copy char array to char pointer 

    p = strstr(line, "fox");    // Find the position of "fox" in line
    q = strstr(line, "dog");    // Find the position of "dog" in line

    l = strstr(line, "quick");    // Find the position of "quick" in line
    m = strstr(line, "lazy");   // Find the position of "lazy" in line

    printf("Postion subtraction q(%p) - p(%p) = %d\n", p, q, q - p);        //Line 25
    printf("Postion subtraction m(%p) - l(%p) = %d\n", m, l, m - l);        //Line 26

    printf("Char value subtractn: o(%c) - q(%c) = %d\n", str[12], str[4], str[12] - str[4]);
    printf("Char Value subtractn: q(%c) - e(%c) = %d\n", str[4], str[2], str[4] - str[2]);
    printf("Position subtraction: &q - &e = %d\n", &str[4] - &str[2]);        //Line 30

    return 0;
}

and the warnings are:
Code:
$ gcc -Wall ptr_substraction001b.c
ptr_substraction001b.c: In function ‘main’:
ptr_substraction001b.c:25:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘long int’ [-Wformat]
ptr_substraction001b.c:26:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘long int’ [-Wformat]
ptr_substraction001b.c:30:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long int’ [-Wformat]

$ ./a.out
Postion subtraction q(0x987020) - p(0x987038) = 24
Postion subtraction m(0x987033) - l(0x987014) = 31
Char value subtractn: o(o) - q(q) = -2
Char Value subtractn: q(q) - e(e) = 12
Position subtraction: &q - &e = 2

And I changed to %ld according to the warnings, the warnings went away. Now, the point is I must have missed something before I saw the warnings. Why should I use %ld, or, why the pointer address subtraction should be long int? Thanks a lot!

Last edited by yifangt; 01-20-2014 at 02:02 PM..
Login or Register to Ask a Question

Previous Thread | Next Thread

9 More Discussions You Might Find Interesting

1. Programming

Pointer for 2D array seems to be 3D in C

I am struggling with the pointer to 2D-array (cf: 2D array of pointers). Can anybody help me elaborate how the pointer x moves in the memory to access the individual of y, especially the high lighted lines? I have talked to one of the curators of the forum, but I am still not quite clear. Here... (1 Reply)
Discussion started by: yifangt
1 Replies

2. Programming

Character pointer to Character array

how to copy content of character pointer to character array in c programming.. char *num; char name=num; (1 Reply)
Discussion started by: zinat
1 Replies

3. Shell Programming and Scripting

best practises for scripting + a few unclear points

Hi guys, Besides the points bellow, what would best practices for scripting be ? 1) set the PATH 2) unset the current environment (set -u ?) 3) (re)set the IFS to default value - space (IFS="" <- is this correct ?) 4) check the return code for each action inside the script (cd, rsync,... (1 Reply)
Discussion started by: da1
1 Replies

4. Programming

structure pointer array as function parameters

if i create an array of pointers to a structure "struct node" as: struct node *r; and create "n" number of "linked lists" and assign it to the various struct pointers r using some function with a return type as structure pointer as: r=multiplty(.......) /*some parameters*/ is... (2 Replies)
Discussion started by: mscoder
2 Replies

5. Programming

help with char pointer array in C

i have an array like #define NUM 8 .... new_socket_fd = accept(socket_fd, (struct sockaddr *) &cli_addr, &client_length); char *items = {"one", "two", "three", "four", "five", "six", "seven", "eight"}; char *item_name_length = {"3", "3", "5", "4", "4", "3", "5", "5"}; ... (1 Reply)
Discussion started by: omega666
1 Replies

6. Programming

C pointer/array duality confusion

Hi all, Can anyone provide help with getting the right syntax regarding array/pointers in C in the following code? Can't locate a specific example which clarifies this... Say I declare a typedef to an array of pointers to some type... /** * An array of ptrs to sections */ typedef... (4 Replies)
Discussion started by: gorga
4 Replies

7. Programming

pass a pointer-to-pointer, or return a pointer?

If one wants to get a start address of a array or a string or a block of memory via a function, there are at least two methods to achieve it: (1) one is to pass a pointer-to-pointer parameter, like: int my_malloc(int size, char **pmem) { *pmem=(char *)malloc(size); if(*pmem==NULL)... (11 Replies)
Discussion started by: aaronwong
11 Replies

8. UNIX for Dummies Questions & Answers

Storing pointer array in C

All .. I am having a pointer array . And trying to store the addess into that pointer array . please see below the problem i faced code: int cnt1; char *t_array; char *f_array; for(cnt1=0; cnt1<1000; cnt1++) { t_array =... (1 Reply)
Discussion started by: arunkumar_mca
1 Replies

9. Programming

pointer

void main() { int a={1,2,3,4,5,6,7,8,9,10}; int *p=a; int *q=&a; cout<<q-p+1<<endl; } The output is 10, how? if we give cout<<q it will print the address, value won't print.... if we give cout<<p it will print the address, value won't print.... p has the base addr; q... (1 Reply)
Discussion started by: sarwan
1 Replies
Login or Register to Ask a Question